Merge "MSIM: Fix to show PUK view when two sims locked on PIN."
am: 00644ec5cc

Change-Id: Ic0b0927a52f2734cccff6f977aa0dfe9cd6e8d5c
diff --git a/Android.bp b/Android.bp
index 0b09b46..02e4785 100644
--- a/Android.bp
+++ b/Android.bp
@@ -26,26 +26,26 @@
             proto: {
                 type: "full",
             },
+            srcs: [
+                "core/proto/**/*.proto",
+                "libs/incident/**/*.proto",
+            ],
         },
         android: {
             proto: {
                 type: "lite",
             },
+            // We only build the protos that are optimized for the lite
+            // runtime, as well as the only protos that are actually
+            // needed by the device.
+            srcs: [
+                "core/proto/android/service/graphicsstats.proto",
+            ],
             shared: {
-                // The proto files generate full protos, but we only use
-                // them as lite on device.  This works fine for a static
-                // library, where the unused full symbols are stripped,
-                // but fails if it is linked as a standalone shared
-                // library because it is missing the full runtime.
                 enabled: false,
             },
         },
     },
-
-    srcs: [
-        "core/proto/**/*.proto",
-        "libs/incident/**/*.proto",
-    ],
 }
 
 subdirs = [
diff --git a/Android.mk b/Android.mk
index d9a175c..b57cdcb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -159,6 +159,7 @@
 	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/om/IOverlayManager.aidl \
+	core/java/android/content/pm/IDexModuleRegisterCallback.aidl \
 	core/java/android/content/pm/ILauncherApps.aidl \
 	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
@@ -217,6 +218,9 @@
 	core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
 	core/java/android/hardware/location/IContextHubCallback.aidl \
 	core/java/android/hardware/location/IContextHubService.aidl \
+	core/java/android/hardware/radio/IRadioService.aidl \
+	core/java/android/hardware/radio/ITuner.aidl \
+	core/java/android/hardware/radio/ITunerCallback.aidl \
 	core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/ICaptivePortal.aidl \
@@ -281,6 +285,18 @@
 	core/java/android/service/carrier/ICarrierService.aidl \
 	core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
 	core/java/android/service/carrier/ICarrierMessagingService.aidl \
+	core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl \
+	core/java/android/service/euicc/IEuiccService.aidl \
+	core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl \
+	core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl \
+	core/java/android/service/euicc/IGetEidCallback.aidl \
+	core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \
+	core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \
+	core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \
+	core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
+	core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
 	core/java/android/service/gatekeeper/IGateKeeperService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
 	core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
@@ -344,6 +360,7 @@
 	core/java/android/view/IPinnedStackController.aidl \
 	core/java/android/view/IPinnedStackListener.aidl \
 	core/java/android/view/IRotationWatcher.aidl \
+	core/java/android/view/IWallpaperVisibilityListener.aidl \
 	core/java/android/view/IWindow.aidl \
 	core/java/android/view/IWindowFocusObserver.aidl \
 	core/java/android/view/IWindowId.aidl \
@@ -372,6 +389,7 @@
 	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
 	core/java/com/android/internal/backup/IBackupTransport.aidl \
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
+	core/java/com/android/internal/car/ICarServiceHelper.aidl \
 	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
 	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
@@ -527,6 +545,7 @@
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+	telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
 	wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
@@ -584,7 +603,10 @@
     android.hardware.thermal-V1.0-java-constants         \
     android.hardware.tv.input-V1.0-java-constants        \
     android.hardware.usb-V1.0-java-constants             \
+    android.hardware.usb-V1.1-java-constants             \
     android.hardware.vibrator-V1.0-java-constants        \
+    android.hardware.vibrator-V1.1-java-constants        \
+    android.hardware.wifi-V1.0-java-constants            \
 
 # Loaded with System.loadLibrary by android.view.textclassifier
 LOCAL_REQUIRED_MODULES += libtextclassifier
@@ -629,6 +651,9 @@
 	frameworks/base/telephony/java/android/telephony/IccOpenLogicalChannelResponse.aidl \
 	frameworks/base/telephony/java/android/telephony/NeighboringCellInfo.aidl \
 	frameworks/base/telephony/java/android/telephony/ModemActivityInfo.aidl \
+	frameworks/base/telephony/java/android/telephony/UiccAccessRule.aidl \
+	frameworks/base/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl \
+	frameworks/base/telephony/java/android/telephony/euicc/EuiccInfo.aidl \
 	frameworks/base/location/java/android/location/Location.aidl \
 	frameworks/base/location/java/android/location/Address.aidl \
 	frameworks/base/location/java/android/location/Criteria.aidl \
@@ -682,6 +707,7 @@
 	frameworks/base/core/java/android/print/PrinterInfo.aidl \
 	frameworks/base/core/java/android/print/PrintJobId.aidl \
 	frameworks/base/core/java/android/printservice/recommendation/RecommendationInfo.aidl \
+	frameworks/base/core/java/android/hardware/radio/RadioManager.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbDevice.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbInterface.aidl \
 	frameworks/base/core/java/android/hardware/usb/UsbEndpoint.aidl \
@@ -741,6 +767,9 @@
 	frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
 	frameworks/base/core/java/android/service/carrier/CarrierIdentifier.aidl \
 	frameworks/base/core/java/android/service/carrier/MessagePdu.aidl \
+	frameworks/base/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl \
+	frameworks/base/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl \
+	frameworks/base/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl \
 	frameworks/base/core/java/android/service/notification/Adjustment.aidl \
 	frameworks/base/core/java/android/service/notification/Condition.aidl \
 	frameworks/base/core/java/android/service/notification/SnoozeCriterion.aidl \
@@ -966,7 +995,7 @@
     -since $(SRC_API_DIR)/23.txt 23 \
     -since $(SRC_API_DIR)/24.txt 24 \
     -since $(SRC_API_DIR)/25.txt 25 \
-    -since ./frameworks/base/api/current.txt O \
+    -since $(SRC_API_DIR)/26.txt 26 \
     -werror -hide 111 -hide 113 -hide 121 \
     -overview $(LOCAL_PATH)/core/java/overview.html \
 
diff --git a/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java
new file mode 100644
index 0000000..099134f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.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.os;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SharedPreferencesTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeCachedGetSharedPreferences() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Context context = InstrumentationRegistry.getTargetContext();
+        // Do the real work once as we're only interested in cache-hit performance
+        SharedPreferences prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        while (state.keepRunning()) {
+            prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
index f56c763..e89157b 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
@@ -56,20 +56,8 @@
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class UserLifecycleTest {
-    private final int TIMEOUT_REMOVE_USER_MS = 4 * 1000; // 4 sec
-    private final int CHECK_USER_REMOVED_INTERVAL_MS = 200; // 0.2 sec
-
-    private final int TIMEOUT_USER_START_SEC = 4; // 4 sec
-
-    private final int TIMEOUT_USER_SWITCH_SEC = 8; // 8 sec
-
-    private final int TIMEOUT_USER_STOP_SEC = 1; // 1 sec
-
-    private final int TIMEOUT_MANAGED_PROFILE_UNLOCK_SEC = 2; // 2 sec
-
-    private final int TIMEOUT_LOCKED_BOOT_COMPLETE_MS = 5 * 1000; // 5 sec
-
-    private final int TIMEOUT_EPHERMAL_USER_STOP_SEC = 6; // 6 sec
+    private final int TIMEOUT_IN_SECOND = 10;
+    private final int CHECK_USER_REMOVED_INTERVAL_MS = 200;
 
     private UserManager mUm;
     private ActivityManager mAm;
@@ -109,7 +97,7 @@
             final CountDownLatch latch = new CountDownLatch(1);
             registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userInfo.id);
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_USER_START_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -142,10 +130,10 @@
             final CountDownLatch latch = new CountDownLatch(1);
             registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userInfo.id);
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_USER_START_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
             mState.resumeTiming();
 
-            stopUser(userInfo.id);
+            stopUser(userInfo.id, false);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -164,7 +152,7 @@
             mState.resumeTiming();
 
             mAm.switchUser(userInfo.id);
-            latch.await(TIMEOUT_LOCKED_BOOT_COMPLETE_MS, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             switchUser(startUser);
@@ -184,7 +172,7 @@
             mState.resumeTiming();
 
             mIam.startUserInBackground(userInfo.id);
-            latch.await(TIMEOUT_MANAGED_PROFILE_UNLOCK_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
             removeUser(userInfo.id);
@@ -215,10 +203,30 @@
             mState.resumeTiming();
 
             mAm.switchUser(startUser);
-            latch.await(TIMEOUT_EPHERMAL_USER_STOP_SEC, TimeUnit.SECONDS);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
 
             mState.pauseTiming();
-            switchLatch.await(TIMEOUT_USER_SWITCH_SEC, TimeUnit.SECONDS);
+            switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+            removeUser(userInfo.id);
+            mState.resumeTiming();
+        }
+    }
+
+    @Test
+    public void managedProfileStoppedPerf() throws Exception {
+        while (mState.keepRunning()) {
+            mState.pauseTiming();
+            final UserInfo userInfo = mUm.createProfileForUser("TestUser",
+                    UserInfo.FLAG_MANAGED_PROFILE, mAm.getCurrentUser());
+            final CountDownLatch latch = new CountDownLatch(1);
+            registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch, userInfo.id);
+            mIam.startUserInBackground(userInfo.id);
+            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+            mState.resumeTiming();
+
+            stopUser(userInfo.id, true);
+
+            mState.pauseTiming();
             removeUser(userInfo.id);
             mState.resumeTiming();
         }
@@ -228,12 +236,12 @@
         final CountDownLatch latch = new CountDownLatch(1);
         registerUserSwitchObserver(latch, null, userId);
         mAm.switchUser(userId);
-        latch.await(TIMEOUT_USER_SWITCH_SEC, TimeUnit.SECONDS);
+        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
     }
 
-    private void stopUser(int userId) throws Exception {
+    private void stopUser(int userId, boolean force) throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mIam.stopUser(userId, false /* force */, new IStopUserCallback.Stub() {
+        mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() {
             @Override
             public void userStopped(int userId) throws RemoteException {
                 latch.countDown();
@@ -243,7 +251,7 @@
             public void userStopAborted(int userId) throws RemoteException {
             }
         });
-        latch.await(TIMEOUT_USER_STOP_SEC, TimeUnit.SECONDS);
+        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
     }
 
     private void registerUserSwitchObserver(final CountDownLatch switchLatch,
@@ -283,9 +291,10 @@
         try {
             mUm.removeUser(userId);
             final long startTime = System.currentTimeMillis();
+            final long timeoutInMs = TIMEOUT_IN_SECOND * 1000;
             while (mUm.getUserInfo(userId) != null &&
-                    System.currentTimeMillis() - startTime < TIMEOUT_REMOVE_USER_MS) {
-                Thread.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
+                    System.currentTimeMillis() - startTime < timeoutInMs) {
+                TimeUnit.MILLISECONDS.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
             }
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
diff --git a/api/current.txt b/api/current.txt
index a0cd51b..1a5183e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3163,7 +3163,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3282,7 +3281,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3308,7 +3306,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3390,7 +3387,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4964,7 +4960,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -6093,6 +6088,19 @@
     method public void onDetached();
   }
 
+  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);
+    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 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;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6115,6 +6123,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaperOffsets(android.os.IBinder);
@@ -6129,6 +6139,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6137,6 +6148,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6161,6 +6173,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -11047,7 +11063,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11355,7 +11370,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13830,7 +13844,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -13911,7 +13924,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14037,7 +14049,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14104,7 +14115,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14199,7 +14209,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14240,7 +14249,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14303,7 +14311,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14345,32 +14352,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14455,7 +14457,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15065,7 +15066,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15422,7 +15422,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15501,7 +15500,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17939,7 +17937,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18765,7 +18762,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18792,7 +18788,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21316,7 +21311,6 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21421,7 +21415,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21820,7 +21813,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21860,7 +21852,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -21917,7 +21908,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22329,7 +22319,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22350,7 +22339,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22393,7 +22381,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22490,7 +22477,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22792,7 +22778,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -22988,7 +22973,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23260,7 +23244,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23380,10 +23363,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23430,7 +23409,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23484,7 +23462,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23553,7 +23530,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23686,7 +23662,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23741,7 +23716,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -23994,7 +23968,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -30720,7 +30693,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -30951,7 +30923,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -31105,7 +31076,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31405,7 +31375,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -35728,7 +35697,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -38831,8 +38799,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
-    method public java.lang.String readImmediately() throws java.io.IOException;
+    method public java.lang.String read();
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
     field public static final int RTT_MODE_FULL = 1; // 0x1
@@ -40482,7 +40449,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40693,7 +40659,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -40954,12 +40919,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -41229,10 +41192,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42480,7 +42439,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -43161,28 +43119,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -43347,9 +43291,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -45463,7 +45404,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46487,7 +46427,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47757,7 +47696,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -47829,7 +47767,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -48680,10 +48617,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -49235,7 +49168,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -49359,7 +49291,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49526,9 +49457,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -49704,6 +49632,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -50071,7 +50000,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -50193,8 +50121,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -50241,9 +50167,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50456,9 +50379,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -50845,8 +50765,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -50902,7 +50820,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -50945,7 +50862,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51489,7 +51405,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51514,7 +51429,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -51856,7 +51770,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -51868,9 +51781,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -52394,8 +52304,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -52618,10 +52526,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -52632,9 +52536,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -52660,12 +52561,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -52678,11 +52574,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -52702,17 +52596,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -52799,8 +52688,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -52900,7 +52787,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -52917,7 +52803,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -53031,8 +52916,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -53262,10 +53145,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -53277,7 +53158,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -53288,9 +53168,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -53315,8 +53193,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -53341,8 +53217,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -53354,9 +53228,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -53385,18 +53256,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53520,11 +53386,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53539,16 +53401,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53563,7 +53419,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53573,7 +53428,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -54341,7 +54195,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54446,7 +54299,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -55234,16 +55086,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -55256,18 +55100,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -55922,7 +55757,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -56038,7 +55872,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -56936,7 +56769,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -57166,6 +56998,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -58022,7 +57855,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -58988,11 +58820,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -59172,7 +59002,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -59195,30 +59024,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -59264,9 +59085,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -59813,7 +59632,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -62066,6 +61884,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62073,6 +61892,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -62148,8 +61969,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -62159,7 +61978,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -62167,7 +61985,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -62177,7 +61994,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -62192,8 +62008,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -62207,16 +62021,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -62241,8 +62051,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -62265,7 +62073,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -62279,7 +62086,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -62309,8 +62115,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -62325,7 +62129,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -62335,7 +62138,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -62352,6 +62154,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62362,6 +62165,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -62428,8 +62233,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -62447,7 +62250,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -62467,7 +62269,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62500,8 +62301,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62514,7 +62313,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62523,7 +62321,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62550,7 +62347,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -62589,8 +62385,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -62598,11 +62392,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -62627,8 +62419,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -62638,12 +62428,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -62667,6 +62455,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -62677,6 +62466,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -62697,8 +62488,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -62719,7 +62508,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -62729,12 +62517,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -62779,27 +62565,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -62816,9 +62592,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -62826,7 +62599,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -62864,9 +62636,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -62875,7 +62644,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -62942,7 +62710,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -62954,24 +62721,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -62996,7 +62762,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -63029,7 +62794,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -63041,19 +62805,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -63085,7 +62847,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -63098,17 +62859,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63138,7 +62895,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -63151,17 +62907,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63340,6 +63092,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -63387,6 +63140,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -63726,6 +63480,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -63736,7 +63491,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -64107,7 +63866,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -64448,7 +64206,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -64459,6 +64228,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -64476,11 +64246,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -64495,7 +64263,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -64505,6 +64272,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -64615,6 +64384,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -65237,7 +65007,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -65510,6 +65279,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -65521,6 +65291,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65548,6 +65321,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -65584,49 +65358,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -65639,6 +65394,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -65673,6 +65430,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -65863,9 +65621,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -65874,11 +65636,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -65898,6 +65663,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -65958,6 +65727,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -65968,6 +65738,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -65999,6 +65770,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -66006,18 +65780,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -66045,6 +65826,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -66091,7 +65873,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -66250,7 +66034,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -66260,9 +66043,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -66386,6 +66166,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -66406,6 +66187,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66425,6 +66207,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -66472,6 +66255,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66575,6 +66359,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66586,11 +66371,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -66604,7 +66387,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -67475,11 +67257,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67559,8 +67338,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -68350,7 +68127,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -68383,8 +68159,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -68415,7 +68189,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -68423,7 +68196,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68550,7 +68322,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -68657,7 +68428,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -68814,7 +68584,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -70392,7 +70161,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -71204,7 +70972,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -71475,7 +71242,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/system-current.txt b/api/system-current.txt
index c9b656b..c0d513f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3294,7 +3294,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3413,7 +3412,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3439,7 +3437,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3521,7 +3518,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -5146,7 +5142,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -6303,6 +6298,19 @@
     method public void setPersistentVrModeEnabled(boolean);
   }
 
+  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);
+    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 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;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6325,6 +6333,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaper();
@@ -6341,6 +6351,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6349,6 +6360,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6376,6 +6388,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -11827,7 +11843,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -12135,7 +12150,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -14610,7 +14624,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
@@ -14691,7 +14704,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14817,7 +14829,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14884,7 +14895,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14979,7 +14989,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -15020,7 +15029,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -15083,7 +15091,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -15125,32 +15132,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -15235,7 +15237,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15853,7 +15854,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -16214,7 +16214,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -16293,7 +16292,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -19447,7 +19445,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -20273,7 +20270,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -20300,7 +20296,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -23156,7 +23151,6 @@
     ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -23263,7 +23257,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -23662,7 +23655,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -23702,7 +23694,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -23759,7 +23750,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -24171,7 +24161,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -24192,7 +24181,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -24235,7 +24223,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -24332,7 +24319,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -24634,7 +24620,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -24830,7 +24815,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -25104,7 +25088,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -25233,10 +25216,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -25283,7 +25262,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -25337,7 +25315,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -25406,7 +25383,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -25539,7 +25515,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -25594,7 +25569,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -25847,7 +25821,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -33432,7 +33405,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -33674,7 +33646,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -33849,7 +33820,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -34149,7 +34119,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -38787,7 +38756,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -42070,8 +42038,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
-    method public java.lang.String readImmediately() throws java.io.IOException;
+    method public java.lang.String read();
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
     field public static final int RTT_MODE_FULL = 1; // 0x1
@@ -43989,7 +43956,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -44278,7 +44244,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -44539,12 +44504,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -44838,10 +44801,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -46089,7 +46048,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -46770,28 +46728,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -46956,9 +46900,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -49074,7 +49015,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -50098,7 +50038,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -50726,6 +50665,7 @@
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
+    method public abstract android.graphics.Region getCurrentImeTouchRegion();
     method public abstract android.view.Display getDefaultDisplay();
     method public abstract void removeViewImmediate(android.view.View);
   }
@@ -51372,7 +51312,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -51444,7 +51383,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -52300,10 +52238,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -52944,7 +52878,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -53339,7 +53272,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -53506,9 +53438,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -53684,6 +53613,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -54051,7 +53981,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -54173,8 +54102,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -54221,9 +54148,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -54436,9 +54360,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -54825,8 +54746,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -54882,7 +54801,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -54925,7 +54843,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -55469,7 +55386,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -55494,7 +55410,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -55836,7 +55751,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -55848,9 +55762,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -56374,8 +56285,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -56598,10 +56507,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -56612,9 +56517,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -56640,12 +56542,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -56658,11 +56555,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -56682,17 +56577,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -56779,8 +56669,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -56880,7 +56768,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -56897,7 +56784,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -57011,8 +56897,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -57242,10 +57126,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -57257,7 +57139,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -57268,9 +57149,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -57295,8 +57174,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -57321,8 +57198,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -57334,9 +57209,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -57365,18 +57237,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -57500,11 +57367,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -57519,16 +57382,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -57543,7 +57400,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -57553,7 +57409,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -58321,7 +58176,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -58426,7 +58280,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -59214,16 +59067,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -59236,18 +59081,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -59902,7 +59738,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -60018,7 +59853,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -60916,7 +60750,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -61146,6 +60979,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -62002,7 +61836,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -62968,11 +62801,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -63152,7 +62983,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -63175,30 +63005,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -63244,9 +63066,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -63793,7 +63613,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -66046,6 +65865,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -66053,6 +65873,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -66128,8 +65950,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -66139,7 +65959,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -66147,7 +65966,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -66157,7 +65975,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -66172,8 +65989,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -66187,16 +66002,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -66221,8 +66032,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -66245,7 +66054,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -66259,7 +66067,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -66289,8 +66096,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -66305,7 +66110,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -66315,7 +66119,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -66332,6 +66135,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -66342,6 +66146,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -66408,8 +66214,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -66427,7 +66231,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -66447,7 +66250,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -66480,8 +66282,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -66494,7 +66294,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -66503,7 +66302,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -66530,7 +66328,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -66569,8 +66366,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -66578,11 +66373,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -66607,8 +66400,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -66618,12 +66409,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -66647,6 +66436,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -66657,6 +66447,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -66677,8 +66469,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -66699,7 +66489,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -66709,12 +66498,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -66759,27 +66546,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -66796,9 +66573,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -66806,7 +66580,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -66844,9 +66617,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -66855,7 +66625,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -66922,7 +66691,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -66934,24 +66702,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -66976,7 +66743,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -67009,7 +66775,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -67021,19 +66786,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -67065,7 +66828,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -67078,17 +66840,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -67118,7 +66876,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -67131,17 +66888,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -67320,6 +67073,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -67367,6 +67121,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -67706,6 +67461,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -67716,7 +67472,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -68087,7 +67847,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -68428,7 +68187,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -68439,6 +68209,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -68456,11 +68227,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -68475,7 +68244,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -68485,6 +68253,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -68595,6 +68365,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -69217,7 +68988,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -69490,6 +69260,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -69501,6 +69272,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -69528,6 +69302,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -69564,49 +69339,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -69619,6 +69375,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -69653,6 +69411,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -69843,9 +69602,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -69854,11 +69617,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -69878,6 +69644,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -69938,6 +69708,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -69948,6 +69719,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -69979,6 +69751,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -69986,18 +69761,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -70025,6 +69807,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -70071,7 +69854,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -70230,7 +70015,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -70240,9 +70024,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -70366,6 +70147,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -70386,6 +70168,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70405,6 +70188,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -70452,6 +70236,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70555,6 +70340,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -70566,11 +70352,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -70584,7 +70368,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -71455,11 +71238,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -71539,8 +71319,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -72330,7 +72108,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -72363,8 +72140,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -72395,7 +72170,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -72403,7 +72177,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -72530,7 +72303,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -72637,7 +72409,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -72794,7 +72565,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -74372,7 +74142,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -75184,7 +74953,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -75455,7 +75223,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/api/test-current.txt b/api/test-current.txt
index 6936d56..7247014 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3163,7 +3163,6 @@
 
   public final class AnimatorSet extends android.animation.Animator {
     ctor public AnimatorSet();
-    method public android.animation.AnimatorSet clone();
     method public java.util.ArrayList<android.animation.Animator> getChildAnimations();
     method public long getCurrentPlayTime();
     method public long getDuration();
@@ -3282,7 +3281,6 @@
 
   public final class ObjectAnimator extends android.animation.ValueAnimator {
     ctor public ObjectAnimator();
-    method public android.animation.ObjectAnimator clone();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
     method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
@@ -3308,7 +3306,6 @@
     method public static <T, V> android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
-    method public android.animation.ObjectAnimator setDuration(long);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
@@ -3390,7 +3387,6 @@
     ctor public ValueAnimator();
     method public void addUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public static boolean areAnimatorsEnabled();
-    method public android.animation.ValueAnimator clone();
     method public float getAnimatedFraction();
     method public java.lang.Object getAnimatedValue();
     method public java.lang.Object getAnimatedValue(java.lang.String);
@@ -4977,7 +4973,6 @@
     ctor public IntentService(java.lang.String);
     method public android.os.IBinder onBind(android.content.Intent);
     method protected abstract void onHandleIntent(android.content.Intent);
-    method public void onStart(android.content.Intent, int);
     method public void setIntentRedelivery(boolean);
   }
 
@@ -5992,6 +5987,7 @@
     method public void destroy();
     method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
     method public android.os.ParcelFileDescriptor executeShellCommand(java.lang.String);
+    method public android.os.ParcelFileDescriptor[] executeShellCommandRw(java.lang.String);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -6113,6 +6109,19 @@
     method public void onDetached();
   }
 
+  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);
+    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 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;
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -6135,6 +6144,8 @@
   }
 
   public class WallpaperManager {
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
+    method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
     method public void clear() throws java.io.IOException;
     method public void clear(int) throws java.io.IOException;
     method public void clearWallpaperOffsets(android.os.IBinder);
@@ -6149,6 +6160,7 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public android.graphics.drawable.Drawable getFastDrawable();
     method public static android.app.WallpaperManager getInstance(android.content.Context);
+    method public android.app.WallpaperColors getWallpaperColors(int);
     method public android.os.ParcelFileDescriptor getWallpaperFile(int);
     method public int getWallpaperId(int);
     method public android.app.WallpaperInfo getWallpaperInfo();
@@ -6157,6 +6169,7 @@
     method public boolean isWallpaperSupported();
     method public android.graphics.drawable.Drawable peekDrawable();
     method public android.graphics.drawable.Drawable peekFastDrawable();
+    method public void removeOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener);
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
     method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
@@ -6181,6 +6194,10 @@
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
+  public static abstract interface WallpaperManager.OnColorsChangedListener {
+    method public abstract void onColorsChanged(android.app.WallpaperColors, int);
+  }
+
 }
 
 package android.app.admin {
@@ -11089,7 +11106,6 @@
 
   public static class AssetFileDescriptor.AutoCloseInputStream extends android.os.ParcelFileDescriptor.AutoCloseInputStream {
     ctor public AssetFileDescriptor.AutoCloseInputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
-    method public void mark(int);
   }
 
   public static class AssetFileDescriptor.AutoCloseOutputStream extends android.os.ParcelFileDescriptor.AutoCloseOutputStream {
@@ -11397,7 +11413,6 @@
     method public void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public void deactivate();
     method public void fillWindow(int, android.database.CursorWindow);
-    method protected void finalize();
     method public byte[] getBlob(int);
     method public int getColumnCount();
     method public int getColumnIndex(java.lang.String);
@@ -13873,7 +13888,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setOpacity(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
     field public static final float MASK_SIZE = 100.0f;
@@ -13955,7 +13969,6 @@
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setGravity(int);
     method public void setMipMap(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
@@ -14083,7 +14096,6 @@
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method protected void setConstantState(android.graphics.drawable.DrawableContainer.DrawableContainerState);
-    method public void setDither(boolean);
     method public void setEnterFadeDuration(int);
     method public void setExitFadeDuration(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
@@ -14150,7 +14162,6 @@
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
     method public void setCornerRadius(float);
-    method public void setDither(boolean);
     method public void setGradientCenter(float, float);
     method public void setGradientRadius(float);
     method public void setGradientType(int);
@@ -14245,7 +14256,6 @@
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setDrawable(int, android.graphics.drawable.Drawable);
     method public boolean setDrawableByLayerId(int, android.graphics.drawable.Drawable);
     method public void setId(int, int);
@@ -14286,7 +14296,6 @@
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
@@ -14349,7 +14358,6 @@
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
-    method public void setDither(boolean);
     method public void setIntrinsicHeight(int);
     method public void setIntrinsicWidth(int);
     method public void setPadding(int, int, int, int);
@@ -14392,32 +14400,27 @@
 
   public class ArcShape extends android.graphics.drawable.shapes.RectShape {
     ctor public ArcShape(float, float);
-    method public android.graphics.drawable.shapes.ArcShape clone() throws java.lang.CloneNotSupportedException;
     method public final float getStartAngle();
     method public final float getSweepAngle();
   }
 
   public class OvalShape extends android.graphics.drawable.shapes.RectShape {
     ctor public OvalShape();
-    method public android.graphics.drawable.shapes.OvalShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public class PathShape extends android.graphics.drawable.shapes.Shape {
     ctor public PathShape(android.graphics.Path, float, float);
-    method public android.graphics.drawable.shapes.PathShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
   }
 
   public class RectShape extends android.graphics.drawable.shapes.Shape {
     ctor public RectShape();
-    method public android.graphics.drawable.shapes.RectShape clone() throws java.lang.CloneNotSupportedException;
     method public void draw(android.graphics.Canvas, android.graphics.Paint);
     method protected final android.graphics.RectF rect();
   }
 
   public class RoundRectShape extends android.graphics.drawable.shapes.RectShape {
     ctor public RoundRectShape(float[], android.graphics.RectF, float[]);
-    method public android.graphics.drawable.shapes.RoundRectShape clone() throws java.lang.CloneNotSupportedException;
   }
 
   public abstract class Shape implements java.lang.Cloneable {
@@ -14502,7 +14505,6 @@
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
     method public final boolean enableShutterSound(boolean);
-    method protected void finalize();
     method public static void getCameraInfo(int, android.hardware.Camera.CameraInfo);
     method public static int getNumberOfCameras();
     method public android.hardware.Camera.Parameters getParameters();
@@ -15112,7 +15114,6 @@
     method public <T> T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
     method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
     method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
-    method public java.util.List<android.hardware.camera2.CameraCharacteristics.Key<?>> getKeys();
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
@@ -15473,7 +15474,6 @@
   public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
     method public int describeContents();
     method public <T> T get(android.hardware.camera2.CaptureRequest.Key<T>);
-    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getKeys();
     method public java.lang.Object getTag();
     method public boolean isReprocess();
     method public void writeToParcel(android.os.Parcel, int);
@@ -15552,7 +15552,6 @@
   public class CaptureResult extends android.hardware.camera2.CameraMetadata {
     method public <T> T get(android.hardware.camera2.CaptureResult.Key<T>);
     method public long getFrameNumber();
-    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys();
     method public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
@@ -17990,7 +17989,6 @@
   }
 
   public class DateIntervalFormat extends android.icu.text.UFormat {
-    method public synchronized java.lang.Object clone();
     method public final java.lang.StringBuffer format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.DateInterval, java.lang.StringBuffer, java.text.FieldPosition);
     method public final synchronized java.lang.StringBuffer format(android.icu.util.Calendar, android.icu.util.Calendar, java.lang.StringBuffer, java.text.FieldPosition);
@@ -18816,7 +18814,6 @@
 
   public final class RuleBasedCollator extends android.icu.text.Collator {
     ctor public RuleBasedCollator(java.lang.String) throws java.lang.Exception;
-    method public android.icu.text.RuleBasedCollator cloneAsThawed();
     method public int compare(java.lang.String, java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.lang.String);
     method public android.icu.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
@@ -18843,7 +18840,6 @@
     method public void setFrenchCollation(boolean);
     method public void setFrenchCollationDefault();
     method public void setLowerCaseFirst(boolean);
-    method public android.icu.text.RuleBasedCollator setMaxVariable(int);
     method public void setNumericCollation(boolean);
     method public void setNumericCollationDefault();
     method public void setStrengthDefault();
@@ -21425,7 +21421,6 @@
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
-    method protected void finalize();
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -21530,7 +21525,6 @@
     method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
-    method protected void finalize();
     method public void flush();
     method public int getAudioFormat();
     method public int getAudioSessionId();
@@ -21929,7 +21923,6 @@
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
     method public boolean closeJetFile();
-    method protected void finalize();
     method public static android.media.JetPlayer getJetPlayer();
     method public static int getMaxTracks();
     method public boolean loadJetFile(java.lang.String);
@@ -21969,7 +21962,6 @@
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
-    method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
     method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
@@ -22026,7 +22018,6 @@
     method public static android.view.Surface createPersistentInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
-    method protected void finalize();
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
     method public java.nio.ByteBuffer getInputBuffer(int);
@@ -22438,7 +22429,6 @@
 
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
-    method protected void finalize();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public final void release();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
@@ -22459,7 +22449,6 @@
     ctor public MediaDescrambler(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
-    method protected void finalize();
     method public final boolean requiresSecureDecoderComponent(java.lang.String);
     method public final void setMediaCasSession(android.media.MediaCas.Session);
   }
@@ -22502,7 +22491,6 @@
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
-    method protected void finalize();
     method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
     method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
     method public byte[] getPropertyByteArray(java.lang.String);
@@ -22599,7 +22587,6 @@
   public final class MediaExtractor {
     ctor public MediaExtractor();
     method public boolean advance();
-    method protected void finalize();
     method public long getCachedDuration();
     method public android.media.MediaExtractor.CasInfo getCasInfo(int);
     method public android.media.DrmInitData getDrmInitData();
@@ -22901,7 +22888,6 @@
     method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
-    method protected void finalize();
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
@@ -23097,7 +23083,6 @@
 
   public class MediaRecorder {
     ctor public MediaRecorder();
-    method protected void finalize();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.os.PersistableBundle getMetrics();
@@ -23369,7 +23354,6 @@
   public final class MediaSync {
     ctor public MediaSync();
     method public final android.view.Surface createInputSurface();
-    method protected void finalize();
     method public void flush();
     method public android.media.PlaybackParams getPlaybackParams();
     method public android.media.SyncParams getSyncParams();
@@ -23489,10 +23473,6 @@
 
   public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putObject(int, java.lang.Object) throws java.lang.IllegalArgumentException;
-    method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
 
@@ -23539,7 +23519,6 @@
   }
 
   public class Ringtone {
-    method protected void finalize();
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -23593,7 +23572,6 @@
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
-    method protected void finalize();
     method public int load(java.lang.String, int);
     method public int load(android.content.Context, int, int);
     method public int load(android.content.res.AssetFileDescriptor, int);
@@ -23662,7 +23640,6 @@
 
   public class ToneGenerator {
     ctor public ToneGenerator(int, int);
-    method protected void finalize();
     method public final int getAudioSessionId();
     method public void release();
     method public boolean startTone(int);
@@ -23795,7 +23772,6 @@
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
-    method protected void finalize();
     method public float getVolume();
     method public void replace(android.media.VolumeShaper.Configuration, android.media.VolumeShaper.Operation, boolean);
   }
@@ -23850,7 +23826,6 @@
   }
 
   public class AudioEffect {
-    method protected void finalize();
     method public android.media.audiofx.AudioEffect.Descriptor getDescriptor() throws java.lang.IllegalStateException;
     method public boolean getEnabled() throws java.lang.IllegalStateException;
     method public int getId() throws java.lang.IllegalStateException;
@@ -24103,7 +24078,6 @@
 
   public class Visualizer {
     ctor public Visualizer(int) throws java.lang.RuntimeException, java.lang.UnsupportedOperationException;
-    method protected void finalize();
     method public int getCaptureSize() throws java.lang.IllegalStateException;
     method public static int[] getCaptureSizeRange();
     method public boolean getEnabled();
@@ -30829,7 +30803,6 @@
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.Bundle> CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -31060,7 +31033,6 @@
   public abstract class FileObserver {
     ctor public FileObserver(java.lang.String);
     ctor public FileObserver(java.lang.String, int);
-    method protected void finalize();
     method public abstract void onEvent(int, java.lang.String);
     method public void startWatching();
     method public void stopWatching();
@@ -31235,7 +31207,6 @@
     ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
     method public synchronized boolean allowPurging(boolean) throws java.io.IOException;
     method public void close();
-    method protected void finalize();
     method public java.io.InputStream getInputStream();
     method public java.io.OutputStream getOutputStream();
     method public boolean isPurgingAllowed();
@@ -31535,7 +31506,6 @@
     method public int describeContents();
     method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
     method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
-    method public synchronized java.lang.String toString();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.os.PersistableBundle> CREATOR;
     field public static final android.os.PersistableBundle EMPTY;
@@ -35881,7 +35851,6 @@
     method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
     method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
-    method public synchronized void resize(int);
     method public void setFace(android.renderscript.Type.CubemapFace);
     method public void setLOD(int);
     method public void setX(int);
@@ -39037,7 +39006,7 @@
 
   public static final class Call.RttCall {
     method public int getRttAudioMode();
-    method public java.lang.String read() throws java.io.IOException;
+    method public java.lang.String read();
     method public java.lang.String readImmediately() throws java.io.IOException;
     method public void setRttMode(int);
     method public void write(java.lang.String) throws java.io.IOException;
@@ -40704,7 +40673,6 @@
 
   public static deprecated class SmsMessage.SubmitPdu {
     ctor public deprecated SmsMessage.SubmitPdu();
-    method public deprecated java.lang.String toString();
     field public deprecated byte[] encodedMessage;
     field public deprecated byte[] encodedScAddress;
   }
@@ -40915,7 +40883,6 @@
     method public java.util.List<junit.framework.TestCase> getTestCases();
     method public java.lang.String getTestClassName();
     method public junit.framework.TestResult getTestResult();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected void runFailed(java.lang.String);
     method public void runTest();
     method public void runTest(junit.framework.TestResult);
@@ -41176,12 +41143,10 @@
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
-    method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>);
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public java.lang.String getType(android.net.Uri);
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public boolean onCreate();
-    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
@@ -41455,10 +41420,6 @@
 
   public deprecated class MockResources extends android.content.res.Resources {
     ctor public MockResources();
-    method public int getColor(int) throws android.content.res.Resources.NotFoundException;
-    method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException;
-    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
-    method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics);
   }
 
 }
@@ -42706,7 +42667,6 @@
 
   public abstract class MetricAffectingSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateLayout {
     ctor public MetricAffectingSpan();
-    method public android.text.style.MetricAffectingSpan getUnderlying();
     method public abstract void updateMeasureState(android.text.TextPaint);
   }
 
@@ -43388,28 +43348,14 @@
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
-    method public android.transition.TransitionSet addListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet addTarget(android.view.View);
-    method public android.transition.TransitionSet addTarget(int);
-    method public android.transition.TransitionSet addTarget(java.lang.String);
-    method public android.transition.TransitionSet addTarget(java.lang.Class);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public android.transition.TransitionSet clone();
     method public int getOrdering();
     method public android.transition.Transition getTransitionAt(int);
     method public int getTransitionCount();
-    method public android.transition.TransitionSet removeListener(android.transition.Transition.TransitionListener);
-    method public android.transition.TransitionSet removeTarget(int);
-    method public android.transition.TransitionSet removeTarget(android.view.View);
-    method public android.transition.TransitionSet removeTarget(java.lang.Class);
-    method public android.transition.TransitionSet removeTarget(java.lang.String);
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
-    method public android.transition.TransitionSet setDuration(long);
-    method public android.transition.TransitionSet setInterpolator(android.animation.TimeInterpolator);
     method public android.transition.TransitionSet setOrdering(int);
-    method public android.transition.TransitionSet setStartDelay(long);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
     field public static final int ORDERING_TOGETHER = 0; // 0x0
   }
@@ -43574,9 +43520,6 @@
 
   public class Base64InputStream extends java.io.FilterInputStream {
     ctor public Base64InputStream(java.io.InputStream, int);
-    method public int available();
-    method public void mark(int);
-    method public void reset();
   }
 
   public class Base64OutputStream extends java.io.FilterOutputStream {
@@ -44723,6 +44666,8 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public void disable();
+    method public void enable();
     method public int getControllerNumber();
     method public java.lang.String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
@@ -45264,10 +45209,13 @@
   public final class KeyboardShortcutGroup implements android.os.Parcelable {
     ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>);
     ctor public KeyboardShortcutGroup(java.lang.CharSequence);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>, boolean);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, boolean);
     method public void addItem(android.view.KeyboardShortcutInfo);
     method public int describeContents();
     method public java.util.List<android.view.KeyboardShortcutInfo> getItems();
     method public java.lang.CharSequence getLabel();
+    method public boolean isSystemGroup();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutGroup> CREATOR;
   }
@@ -45857,7 +45805,6 @@
     method public android.graphics.Canvas lockCanvas();
     method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setOpaque(boolean);
     method public void setSurfaceTexture(android.graphics.SurfaceTexture);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
@@ -46890,7 +46837,6 @@
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
     method public int getNestedScrollAxes();
-    method public android.view.ViewGroupOverlay getOverlay();
     method public int getPersistentDrawingCache();
     method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
@@ -47746,6 +47692,7 @@
   }
 
   public final class AccessibilityManager {
+    method public void addAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
     method public void addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
@@ -47756,6 +47703,7 @@
     method public void interrupt();
     method public boolean isEnabled();
     method public boolean isTouchExplorationEnabled();
+    method public void removeAccessibilityRequestPreparer(android.view.accessibility.AccessibilityRequestPreparer);
     method public boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
     method public boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
     method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -48073,6 +48021,13 @@
     method public void setToIndex(int);
   }
 
+  public abstract class AccessibilityRequestPreparer {
+    ctor public AccessibilityRequestPreparer(android.view.View, int);
+    method public android.view.View getView();
+    method public abstract void onPrepareExtraData(int, java.lang.String, android.os.Bundle, android.os.Message);
+    field public static final int REQUEST_TYPE_EXTRA_DATA = 1; // 0x1
+  }
+
   public final class AccessibilityWindowInfo implements android.os.Parcelable {
     method public int describeContents();
     method public android.view.accessibility.AccessibilityNodeInfo getAnchor();
@@ -48166,7 +48121,6 @@
     ctor public Animation(android.content.Context, android.util.AttributeSet);
     method protected void applyTransformation(float, android.view.animation.Transformation);
     method public void cancel();
-    method protected android.view.animation.Animation clone() throws java.lang.CloneNotSupportedException;
     method public long computeDurationHint();
     method protected void ensureInterpolator();
     method public int getBackgroundColor();
@@ -48238,7 +48192,6 @@
     ctor public AnimationSet(android.content.Context, android.util.AttributeSet);
     ctor public AnimationSet(boolean);
     method public void addAnimation(android.view.animation.Animation);
-    method protected android.view.animation.AnimationSet clone() throws java.lang.CloneNotSupportedException;
     method public java.util.List<android.view.animation.Animation> getAnimations();
   }
 
@@ -49089,10 +49042,6 @@
   public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static android.webkit.CookieSyncManager getInstance();
-    method public deprecated void resetSync();
-    method public deprecated void startSync();
-    method public deprecated void stopSync();
-    method public deprecated void sync();
     method protected deprecated void syncFromRamToFlash();
     field protected static final java.lang.String LOGTAG = "websync";
     field protected android.webkit.WebViewDatabase mDataBase;
@@ -49644,7 +49593,6 @@
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public static void setWebContentsDebuggingEnabled(boolean);
     method public void setWebViewClient(android.webkit.WebViewClient);
-    method public deprecated boolean shouldDelayChildPressedState();
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
     method public void zoomBy(float);
@@ -49768,7 +49716,6 @@
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
     method public void fling(int);
-    method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -49935,9 +49882,6 @@
     ctor public ActionMenuView(android.content.Context);
     ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
     method public void dismissPopupMenus();
-    method protected android.widget.ActionMenuView.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.ActionMenuView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public android.view.Menu getMenu();
     method public android.graphics.drawable.Drawable getOverflowIcon();
     method public int getPopupTheme();
@@ -50113,6 +50057,7 @@
     method public void addAll(T...);
     method public void clear();
     method public static android.widget.ArrayAdapter<java.lang.CharSequence> createFromResource(android.content.Context, int, int);
+    method public java.lang.CharSequence[] getAutofillOptions();
     method public android.content.Context getContext();
     method public int getCount();
     method public android.content.res.Resources.Theme getDropDownViewTheme();
@@ -50484,7 +50429,6 @@
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
-    method public android.text.Editable getText();
     method public void selectAll();
     method public void setSelection(int, int);
     method public void setSelection(int);
@@ -50606,8 +50550,6 @@
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.FrameLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.FrameLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
@@ -50654,9 +50596,6 @@
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.GridLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.GridLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.GridLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -50869,9 +50808,6 @@
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method protected android.widget.LinearLayout.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.LinearLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.LinearLayout.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -51260,8 +51196,6 @@
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public boolean isAnimating();
     method public synchronized boolean isIndeterminate();
-    method protected synchronized void onDraw(android.graphics.Canvas);
-    method protected synchronized void onMeasure(int, int);
     method public void onRestoreInstanceState(android.os.Parcelable);
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
@@ -51317,7 +51251,6 @@
     ctor public RadioGroup(android.content.Context, android.util.AttributeSet);
     method public void check(int);
     method public void clearCheck();
-    method public android.widget.RadioGroup.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getCheckedRadioButtonId();
     method public void setOnCheckedChangeListener(android.widget.RadioGroup.OnCheckedChangeListener);
   }
@@ -51360,7 +51293,6 @@
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
-    method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -51905,7 +51837,6 @@
   public class TableLayout extends android.widget.LinearLayout {
     ctor public TableLayout(android.content.Context);
     ctor public TableLayout(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public boolean isColumnCollapsed(int);
     method public boolean isColumnShrinkable(int);
     method public boolean isColumnStretchable(int);
@@ -51930,7 +51861,6 @@
   public class TableRow extends android.widget.LinearLayout {
     ctor public TableRow(android.content.Context);
     ctor public TableRow(android.content.Context, android.util.AttributeSet);
-    method public android.widget.TableRow.LayoutParams generateLayoutParams(android.util.AttributeSet);
     method public android.view.View getVirtualChildAt(int);
     method public int getVirtualChildCount();
   }
@@ -52279,7 +52209,6 @@
     ctor public ToggleButton(android.content.Context);
     method public java.lang.CharSequence getTextOff();
     method public java.lang.CharSequence getTextOn();
-    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setTextOff(java.lang.CharSequence);
     method public void setTextOn(java.lang.CharSequence);
   }
@@ -52291,9 +52220,6 @@
     ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
     method public void collapseActionView();
     method public void dismissPopupMenus();
-    method protected android.widget.Toolbar.LayoutParams generateDefaultLayoutParams();
-    method public android.widget.Toolbar.LayoutParams generateLayoutParams(android.util.AttributeSet);
-    method protected android.widget.Toolbar.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
     method public int getContentInsetEnd();
     method public int getContentInsetEndWithActions();
     method public int getContentInsetLeft();
@@ -52818,8 +52744,6 @@
   public class BaseDexClassLoader extends java.lang.ClassLoader {
     ctor public BaseDexClassLoader(java.lang.String, java.io.File, java.lang.String, java.lang.ClassLoader);
     method public java.lang.String findLibrary(java.lang.String);
-    method protected java.util.Enumeration<java.net.URL> findResources(java.lang.String);
-    method protected synchronized java.lang.Package getPackage(java.lang.String);
   }
 
   public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
@@ -53042,10 +52966,6 @@
   public class BufferedInputStream extends java.io.FilterInputStream {
     ctor public BufferedInputStream(java.io.InputStream);
     ctor public BufferedInputStream(java.io.InputStream, int);
-    method public synchronized int available() throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
-    method public synchronized long skip(long) throws java.io.IOException;
     field protected volatile byte[] buf;
     field protected int count;
     field protected int marklimit;
@@ -53056,9 +52976,6 @@
   public class BufferedOutputStream extends java.io.FilterOutputStream {
     ctor public BufferedOutputStream(java.io.OutputStream);
     ctor public BufferedOutputStream(java.io.OutputStream, int);
-    method public synchronized void flush() throws java.io.IOException;
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
   }
@@ -53084,12 +53001,7 @@
   public class ByteArrayInputStream extends java.io.InputStream {
     ctor public ByteArrayInputStream(byte[]);
     ctor public ByteArrayInputStream(byte[], int, int);
-    method public synchronized int available();
-    method public void mark(int);
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected byte[] buf;
     field protected int count;
     field protected int mark;
@@ -53102,11 +53014,9 @@
     method public synchronized void reset();
     method public synchronized int size();
     method public synchronized byte[] toByteArray();
-    method public synchronized java.lang.String toString();
     method public synchronized java.lang.String toString(java.lang.String) throws java.io.UnsupportedEncodingException;
     method public deprecated synchronized java.lang.String toString(int);
     method public synchronized void write(int);
-    method public synchronized void write(byte[], int, int);
     method public synchronized void writeTo(java.io.OutputStream) throws java.io.IOException;
     field protected byte[] buf;
     field protected int count;
@@ -53126,17 +53036,12 @@
   public class CharArrayWriter extends java.io.Writer {
     ctor public CharArrayWriter();
     ctor public CharArrayWriter(int);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence);
-    method public java.io.CharArrayWriter append(java.lang.CharSequence, int, int);
-    method public java.io.CharArrayWriter append(char);
     method public void close();
     method public void flush();
     method public void reset();
     method public int size();
     method public char[] toCharArray();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String, int, int);
     method public void writeTo(java.io.Writer) throws java.io.IOException;
     field protected char[] buf;
     field protected int count;
@@ -53223,8 +53128,6 @@
   public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
     ctor public DataOutputStream(java.io.OutputStream);
     method public final int size();
-    method public synchronized void write(int) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     method public final void writeBoolean(boolean) throws java.io.IOException;
     method public final void writeByte(int) throws java.io.IOException;
     method public final void writeBytes(java.lang.String) throws java.io.IOException;
@@ -53324,7 +53227,6 @@
     ctor public FileInputStream(java.lang.String) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileInputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public int read() throws java.io.IOException;
@@ -53341,7 +53243,6 @@
     ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
     ctor public FileOutputStream(java.io.FileDescriptor);
-    method protected void finalize() throws java.io.IOException;
     method public java.nio.channels.FileChannel getChannel();
     method public final java.io.FileDescriptor getFD() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
@@ -53455,8 +53356,6 @@
   public deprecated class LineNumberInputStream extends java.io.FilterInputStream {
     ctor public LineNumberInputStream(java.io.InputStream);
     method public int getLineNumber();
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     method public void setLineNumber(int);
   }
 
@@ -53686,10 +53585,8 @@
     ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
     ctor public PipedInputStream();
     ctor public PipedInputStream(int);
-    method public synchronized int available() throws java.io.IOException;
     method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
     method public synchronized int read() throws java.io.IOException;
-    method public synchronized int read(byte[], int, int) throws java.io.IOException;
     method protected synchronized void receive(int) throws java.io.IOException;
     field protected static final int PIPE_SIZE = 1024; // 0x400
     field protected byte[] buffer;
@@ -53701,7 +53598,6 @@
     ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
     ctor public PipedOutputStream();
     method public synchronized void connect(java.io.PipedInputStream) throws java.io.IOException;
-    method public synchronized void flush() throws java.io.IOException;
     method public void write(int) throws java.io.IOException;
   }
 
@@ -53712,9 +53608,7 @@
     ctor public PipedReader(int);
     method public void close() throws java.io.IOException;
     method public void connect(java.io.PipedWriter) throws java.io.IOException;
-    method public synchronized int read() throws java.io.IOException;
     method public synchronized int read(char[], int, int) throws java.io.IOException;
-    method public synchronized boolean ready() throws java.io.IOException;
   }
 
   public class PipedWriter extends java.io.Writer {
@@ -53739,8 +53633,6 @@
     method public java.io.PrintStream append(char);
     method public boolean checkError();
     method protected void clearError();
-    method public void close();
-    method public void flush();
     method public java.io.PrintStream format(java.lang.String, java.lang.Object...);
     method public java.io.PrintStream format(java.util.Locale, java.lang.String, java.lang.Object...);
     method public void print(boolean);
@@ -53765,8 +53657,6 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
-    method public void write(byte[], int, int);
   }
 
   public class PrintWriter extends java.io.Writer {
@@ -53778,9 +53668,6 @@
     ctor public PrintWriter(java.lang.String, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
     ctor public PrintWriter(java.io.File) throws java.io.FileNotFoundException;
     ctor public PrintWriter(java.io.File, java.lang.String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
-    method public java.io.PrintWriter append(java.lang.CharSequence);
-    method public java.io.PrintWriter append(java.lang.CharSequence, int, int);
-    method public java.io.PrintWriter append(char);
     method public boolean checkError();
     method protected void clearError();
     method public void close();
@@ -53809,18 +53696,13 @@
     method public void println(java.lang.String);
     method public void println(java.lang.Object);
     method protected void setError();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(char[]);
-    method public void write(java.lang.String, int, int);
-    method public void write(java.lang.String);
     field protected java.io.Writer out;
   }
 
   public class PushbackInputStream extends java.io.FilterInputStream {
     ctor public PushbackInputStream(java.io.InputStream, int);
     ctor public PushbackInputStream(java.io.InputStream);
-    method public synchronized void close() throws java.io.IOException;
     method public void unread(int) throws java.io.IOException;
     method public void unread(byte[], int, int) throws java.io.IOException;
     method public void unread(byte[]) throws java.io.IOException;
@@ -53944,11 +53826,7 @@
 
   public deprecated class StringBufferInputStream extends java.io.InputStream {
     ctor public StringBufferInputStream(java.lang.String);
-    method public synchronized int available();
     method public synchronized int read();
-    method public synchronized int read(byte[], int, int);
-    method public synchronized void reset();
-    method public synchronized long skip(long);
     field protected java.lang.String buffer;
     field protected int count;
     field protected int pos;
@@ -53963,16 +53841,10 @@
   public class StringWriter extends java.io.Writer {
     ctor public StringWriter();
     ctor public StringWriter(int);
-    method public java.io.StringWriter append(java.lang.CharSequence);
-    method public java.io.StringWriter append(java.lang.CharSequence, int, int);
-    method public java.io.StringWriter append(char);
     method public void close() throws java.io.IOException;
     method public void flush();
     method public java.lang.StringBuffer getBuffer();
-    method public void write(int);
     method public void write(char[], int, int);
-    method public void write(java.lang.String);
-    method public void write(java.lang.String, int, int);
   }
 
   public class SyncFailedException extends java.io.IOException {
@@ -53987,7 +53859,6 @@
   public class UncheckedIOException extends java.lang.RuntimeException {
     ctor public UncheckedIOException(java.lang.String, java.io.IOException);
     ctor public UncheckedIOException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class UnsupportedEncodingException extends java.io.IOException {
@@ -53997,7 +53868,6 @@
 
   public class WriteAbortedException extends java.io.ObjectStreamException {
     ctor public WriteAbortedException(java.lang.String, java.lang.Exception);
-    method public java.lang.Throwable getCause();
     field public java.lang.Exception detail;
   }
 
@@ -54765,7 +54635,6 @@
     ctor public ClassNotFoundException();
     ctor public ClassNotFoundException(java.lang.String);
     ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -54870,7 +54739,6 @@
     ctor public ExceptionInInitializerError();
     ctor public ExceptionInInitializerError(java.lang.Throwable);
     ctor public ExceptionInInitializerError(java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
   }
 
@@ -55658,16 +55526,8 @@
     method public synchronized java.lang.StringBuffer append(float);
     method public synchronized java.lang.StringBuffer append(double);
     method public synchronized java.lang.StringBuffer appendCodePoint(int);
-    method public synchronized int capacity();
-    method public synchronized char charAt(int);
-    method public synchronized int codePointAt(int);
-    method public synchronized int codePointBefore(int);
-    method public synchronized int codePointCount(int, int);
     method public synchronized java.lang.StringBuffer delete(int, int);
     method public synchronized java.lang.StringBuffer deleteCharAt(int);
-    method public synchronized void ensureCapacity(int);
-    method public synchronized void getChars(int, int, char[], int);
-    method public synchronized int indexOf(java.lang.String, int);
     method public synchronized java.lang.StringBuffer insert(int, char[], int, int);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.Object);
     method public synchronized java.lang.StringBuffer insert(int, java.lang.String);
@@ -55680,18 +55540,9 @@
     method public java.lang.StringBuffer insert(int, long);
     method public java.lang.StringBuffer insert(int, float);
     method public java.lang.StringBuffer insert(int, double);
-    method public synchronized int lastIndexOf(java.lang.String, int);
-    method public synchronized int length();
-    method public synchronized int offsetByCodePoints(int, int);
     method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
     method public synchronized java.lang.StringBuffer reverse();
-    method public synchronized void setCharAt(int, char);
-    method public synchronized void setLength(int);
-    method public synchronized java.lang.CharSequence subSequence(int, int);
-    method public synchronized java.lang.String substring(int);
-    method public synchronized java.lang.String substring(int, int);
     method public synchronized java.lang.String toString();
-    method public synchronized void trimToSize();
   }
 
   public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.CharSequence java.io.Serializable {
@@ -56346,7 +56197,6 @@
     ctor protected InvocationTargetException();
     ctor public InvocationTargetException(java.lang.Throwable);
     ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getTargetException();
   }
 
@@ -56462,7 +56312,6 @@
   public class UndeclaredThrowableException extends java.lang.RuntimeException {
     ctor public UndeclaredThrowableException(java.lang.Throwable);
     ctor public UndeclaredThrowableException(java.lang.Throwable, java.lang.String);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getUndeclaredThrowable();
   }
 
@@ -57360,7 +57209,6 @@
     method public java.lang.String getQuery();
     method public java.lang.String getRef();
     method public java.lang.String getUserInfo();
-    method public synchronized int hashCode();
     method public java.net.URLConnection openConnection() throws java.io.IOException;
     method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
     method public final java.io.InputStream openStream() throws java.io.IOException;
@@ -57590,6 +57438,7 @@
     method public final int arrayOffset();
     method public abstract java.nio.CharBuffer asReadOnlyBuffer();
     method public final char charAt(int);
+    method public java.util.stream.IntStream chars();
     method public abstract java.nio.CharBuffer compact();
     method public int compareTo(java.nio.CharBuffer);
     method public abstract java.nio.CharBuffer duplicate();
@@ -58446,7 +58295,6 @@
 
   public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
     ctor public DirectoryIteratorException(java.io.IOException);
-    method public java.io.IOException getCause();
   }
 
   public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
@@ -59412,11 +59260,9 @@
   public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
     ctor public KeyStore.PasswordProtection(char[]);
     ctor public KeyStore.PasswordProtection(char[], java.lang.String, java.security.spec.AlgorithmParameterSpec);
-    method public synchronized void destroy() throws javax.security.auth.DestroyFailedException;
     method public synchronized char[] getPassword();
     method public java.lang.String getProtectionAlgorithm();
     method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
-    method public synchronized boolean isDestroyed();
   }
 
   public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
@@ -59596,7 +59442,6 @@
 
   public class PrivilegedActionException extends java.lang.Exception {
     ctor public PrivilegedActionException(java.lang.Exception);
-    method public java.lang.Throwable getCause();
     method public java.lang.Exception getException();
   }
 
@@ -59619,30 +59464,22 @@
     method public synchronized java.lang.Object compute(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfAbsent(java.lang.Object, java.util.function.Function<? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object computeIfPresent(java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.util.Enumeration<java.lang.Object> elements();
-    method public synchronized java.util.Set<java.util.Map.Entry<java.lang.Object, java.lang.Object>> entrySet();
     method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>);
-    method public java.lang.Object get(java.lang.Object);
     method public java.lang.String getInfo();
     method public java.lang.String getName();
     method public synchronized java.lang.Object getOrDefault(java.lang.Object, java.lang.Object);
     method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String);
     method public synchronized java.util.Set<java.security.Provider.Service> getServices();
     method public double getVersion();
-    method public java.util.Set<java.lang.Object> keySet();
-    method public java.util.Enumeration<java.lang.Object> keys();
     method public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
     method public synchronized java.lang.Object put(java.lang.Object, java.lang.Object);
     method public synchronized void putAll(java.util.Map<?, ?>);
     method public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object);
     method protected synchronized void putService(java.security.Provider.Service);
-    method public synchronized java.lang.Object remove(java.lang.Object);
     method protected synchronized void removeService(java.security.Provider.Service);
     method public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object);
     method public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super java.lang.Object, ? super java.lang.Object, ? extends java.lang.Object>);
-    method public java.lang.String toString();
-    method public java.util.Collection<java.lang.Object> values();
   }
 
   public static class Provider.Service {
@@ -59688,9 +59525,7 @@
     method public final java.security.Provider getProvider();
     method public static byte[] getSeed(int);
     method protected final int next(int);
-    method public synchronized void nextBytes(byte[]);
     method public synchronized void setSeed(byte[]);
-    method public void setSeed(long);
   }
 
   public abstract class SecureRandomSpi implements java.io.Serializable {
@@ -60237,7 +60072,6 @@
 
   public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
     ctor protected PKIXRevocationChecker();
-    method public java.security.cert.PKIXRevocationChecker clone();
     method public java.util.List<java.security.cert.Extension> getOcspExtensions();
     method public java.net.URI getOcspResponder();
     method public java.security.cert.X509Certificate getOcspResponderCert();
@@ -62490,6 +62324,7 @@
   public final class DayOfWeek extends java.lang.Enum implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62497,6 +62332,8 @@
     method public java.time.DayOfWeek minus(long);
     method public static java.time.DayOfWeek of(int);
     method public java.time.DayOfWeek plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.DayOfWeek valueOf(java.lang.String);
     method public static final java.time.DayOfWeek[] values();
     enum_constant public static final java.time.DayOfWeek FRIDAY;
@@ -62572,8 +62409,6 @@
     method public boolean isBefore(java.time.Instant);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
-    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant minusMillis(long);
     method public java.time.Instant minusNanos(long);
     method public java.time.Instant minusSeconds(long);
@@ -62583,7 +62418,6 @@
     method public static java.time.Instant ofEpochSecond(long);
     method public static java.time.Instant ofEpochSecond(long, long);
     method public static java.time.Instant parse(java.lang.CharSequence);
-    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
     method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Instant plusMillis(long);
     method public java.time.Instant plusNanos(long);
@@ -62591,7 +62425,6 @@
     method public long toEpochMilli();
     method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
     method public java.time.Instant with(java.time.temporal.TemporalField, long);
     field public static final java.time.Instant EPOCH;
     field public static final java.time.Instant MAX;
@@ -62601,7 +62434,6 @@
   public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
     method public java.time.LocalDateTime atStartOfDay();
     method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
-    method public java.time.LocalDateTime atTime(java.time.LocalTime);
     method public java.time.LocalDateTime atTime(int, int);
     method public java.time.LocalDateTime atTime(int, int, int);
     method public java.time.LocalDateTime atTime(int, int, int, int);
@@ -62616,8 +62448,6 @@
     method public int getMonthValue();
     method public int getYear();
     method public int lengthOfMonth();
-    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate minusDays(long);
     method public java.time.LocalDate minusMonths(long);
     method public java.time.LocalDate minusWeeks(long);
@@ -62631,16 +62461,12 @@
     method public static java.time.LocalDate ofYearDay(int, int);
     method public static java.time.LocalDate parse(java.lang.CharSequence);
     method public static java.time.LocalDate parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDate plusDays(long);
     method public java.time.LocalDate plusMonths(long);
     method public java.time.LocalDate plusWeeks(long);
     method public java.time.LocalDate plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public java.time.Period until(java.time.chrono.ChronoLocalDate);
-    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
-    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDate withDayOfMonth(int);
     method public java.time.LocalDate withDayOfYear(int);
     method public java.time.LocalDate withMonth(int);
@@ -62665,8 +62491,6 @@
     method public int getSecond();
     method public int getYear();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime minusDays(long);
     method public java.time.LocalDateTime minusHours(long);
     method public java.time.LocalDateTime minusMinutes(long);
@@ -62689,7 +62513,6 @@
     method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence);
     method public static java.time.LocalDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalDateTime plusDays(long);
     method public java.time.LocalDateTime plusHours(long);
@@ -62703,7 +62526,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalDateTime withDayOfMonth(int);
     method public java.time.LocalDateTime withDayOfYear(int);
@@ -62733,8 +62555,6 @@
     method public boolean isBefore(java.time.LocalTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime minusHours(long);
     method public java.time.LocalTime minusMinutes(long);
     method public java.time.LocalTime minusNanos(long);
@@ -62749,7 +62569,6 @@
     method public static java.time.LocalTime ofSecondOfDay(long);
     method public static java.time.LocalTime parse(java.lang.CharSequence);
     method public static java.time.LocalTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
     method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.LocalTime plusHours(long);
     method public java.time.LocalTime plusMinutes(long);
@@ -62759,7 +62578,6 @@
     method public int toSecondOfDay();
     method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
     method public java.time.LocalTime withHour(int);
     method public java.time.LocalTime withMinute(int);
@@ -62776,6 +62594,7 @@
     method public int firstDayOfYear(boolean);
     method public java.time.Month firstMonthOfQuarter();
     method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getDisplayName(java.time.format.TextStyle, java.util.Locale);
     method public long getLong(java.time.temporal.TemporalField);
     method public int getValue();
@@ -62786,6 +62605,8 @@
     method public java.time.Month minus(long);
     method public static java.time.Month of(int);
     method public java.time.Month plus(long);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.Month valueOf(java.lang.String);
     method public static final java.time.Month[] values();
     enum_constant public static final java.time.Month APRIL;
@@ -62852,8 +62673,6 @@
     method public boolean isEqual(java.time.OffsetDateTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime minusDays(long);
     method public java.time.OffsetDateTime minusHours(long);
     method public java.time.OffsetDateTime minusMinutes(long);
@@ -62871,7 +62690,6 @@
     method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence);
     method public static java.time.OffsetDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetDateTime plusDays(long);
     method public java.time.OffsetDateTime plusHours(long);
@@ -62891,7 +62709,6 @@
     method public java.time.ZonedDateTime toZonedDateTime();
     method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetDateTime withDayOfMonth(int);
     method public java.time.OffsetDateTime withDayOfYear(int);
@@ -62924,8 +62741,6 @@
     method public boolean isEqual(java.time.OffsetTime);
     method public boolean isSupported(java.time.temporal.TemporalField);
     method public boolean isSupported(java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime minusHours(long);
     method public java.time.OffsetTime minusMinutes(long);
     method public java.time.OffsetTime minusNanos(long);
@@ -62938,7 +62753,6 @@
     method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
     method public static java.time.OffsetTime parse(java.lang.CharSequence);
     method public static java.time.OffsetTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
     method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.OffsetTime plusHours(long);
     method public java.time.OffsetTime plusMinutes(long);
@@ -62947,7 +62761,6 @@
     method public java.time.LocalTime toLocalTime();
     method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
     method public java.time.OffsetTime withHour(int);
     method public java.time.OffsetTime withMinute(int);
@@ -62974,7 +62787,6 @@
     method public java.time.Period minusMonths(long);
     method public java.time.Period minusYears(long);
     method public java.time.Period multipliedBy(int);
-    method public java.time.Period negated();
     method public java.time.Period normalized();
     method public static java.time.Period of(int, int, int);
     method public static java.time.Period ofDays(int);
@@ -63013,8 +62825,6 @@
     method public boolean isSupported(java.time.temporal.TemporalUnit);
     method public boolean isValidMonthDay(java.time.MonthDay);
     method public int length();
-    method public java.time.Year minus(java.time.temporal.TemporalAmount);
-    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year minusYears(long);
     method public static java.time.Year now();
     method public static java.time.Year now(java.time.ZoneId);
@@ -63022,11 +62832,9 @@
     method public static java.time.Year of(int);
     method public static java.time.Year parse(java.lang.CharSequence);
     method public static java.time.Year parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.Year plus(java.time.temporal.TemporalAmount);
     method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
     method public java.time.Year plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
     method public java.time.Year with(java.time.temporal.TemporalField, long);
     field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
     field public static final int MIN_VALUE = -999999999; // 0xc4653601
@@ -63051,8 +62859,6 @@
     method public boolean isValidDay(int);
     method public int lengthOfMonth();
     method public int lengthOfYear();
-    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
-    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth minusMonths(long);
     method public java.time.YearMonth minusYears(long);
     method public static java.time.YearMonth now();
@@ -63062,12 +62868,10 @@
     method public static java.time.YearMonth of(int, int);
     method public static java.time.YearMonth parse(java.lang.CharSequence);
     method public static java.time.YearMonth parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
     method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
     method public java.time.YearMonth plusMonths(long);
     method public java.time.YearMonth plusYears(long);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
     method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
     method public java.time.YearMonth withMonth(int);
     method public java.time.YearMonth withYear(int);
@@ -63091,6 +62895,7 @@
     method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
     method public int compareTo(java.time.ZoneOffset);
     method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public int get(java.time.temporal.TemporalField);
     method public java.lang.String getId();
     method public long getLong(java.time.temporal.TemporalField);
     method public java.time.zone.ZoneRules getRules();
@@ -63101,6 +62906,8 @@
     method public static java.time.ZoneOffset ofHoursMinutes(int, int);
     method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
     method public static java.time.ZoneOffset ofTotalSeconds(int);
+    method public <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     field public static final java.time.ZoneOffset MAX;
     field public static final java.time.ZoneOffset MIN;
     field public static final java.time.ZoneOffset UTC;
@@ -63121,8 +62928,6 @@
     method public int getYear();
     method public java.time.ZoneId getZone();
     method public boolean isSupported(java.time.temporal.TemporalField);
-    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
-    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime minusDays(long);
     method public java.time.ZonedDateTime minusHours(long);
     method public java.time.ZonedDateTime minusMinutes(long);
@@ -63143,7 +62948,6 @@
     method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence);
     method public static java.time.ZonedDateTime parse(java.lang.CharSequence, java.time.format.DateTimeFormatter);
-    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
     method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
     method public java.time.ZonedDateTime plusDays(long);
     method public java.time.ZonedDateTime plusHours(long);
@@ -63153,12 +62957,10 @@
     method public java.time.ZonedDateTime plusSeconds(long);
     method public java.time.ZonedDateTime plusWeeks(long);
     method public java.time.ZonedDateTime plusYears(long);
-    method public java.time.LocalDate toLocalDate();
     method public java.time.LocalDateTime toLocalDateTime();
     method public java.time.OffsetDateTime toOffsetDateTime();
     method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
     method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
     method public java.time.ZonedDateTime withDayOfMonth(int);
     method public java.time.ZonedDateTime withDayOfYear(int);
@@ -63203,27 +63005,17 @@
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
     method public abstract int lengthOfMonth();
     method public default int lengthOfYear();
-    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
     method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
     method public default long toEpochDay();
     method public abstract java.lang.String toString();
     method public abstract long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
     method public abstract java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
     method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
   }
 
    abstract class ChronoLocalDateImpl<D extends java.time.chrono.ChronoLocalDate> implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
-    method public D minus(java.time.temporal.TemporalAmount);
-    method public D minus(long, java.time.temporal.TemporalUnit);
-    method public D plus(java.time.temporal.TemporalAmount);
-    method public D plus(long, java.time.temporal.TemporalUnit);
     method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
-    method public D with(java.time.temporal.TemporalAdjuster);
-    method public D with(java.time.temporal.TemporalField, long);
   }
 
   public abstract interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> implements java.lang.Comparable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
@@ -63240,9 +63032,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
     method public default long toEpochSecond(java.time.ZoneOffset);
@@ -63250,7 +63039,6 @@
     method public abstract D toLocalDate();
     method public abstract java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
   }
 
@@ -63288,9 +63076,6 @@
     method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
     method public abstract boolean isSupported(java.time.temporal.TemporalField);
     method public default boolean isSupported(java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
-    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
-    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
     method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
     method public default long toEpochSecond();
@@ -63299,7 +63084,6 @@
     method public abstract java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
     method public default java.time.LocalTime toLocalTime();
     method public abstract java.lang.String toString();
-    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
     method public abstract java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
@@ -63366,7 +63150,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.HijrahChronology INSTANCE;
@@ -63378,24 +63161,23 @@
     method public java.time.chrono.HijrahChronology getChronology();
     method public java.time.chrono.HijrahEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isLeapYear();
     method public int lengthOfMonth();
-    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.HijrahDate now();
     method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
     method public static java.time.chrono.HijrahDate now(java.time.Clock);
     method public static java.time.chrono.HijrahDate of(int, int, int);
-    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
     method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
   }
 
   public final class HijrahEra extends java.lang.Enum implements java.time.chrono.Era {
     method public int getValue();
     method public static java.time.chrono.HijrahEra of(int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
     method public static java.time.chrono.HijrahEra valueOf(java.lang.String);
     method public static final java.time.chrono.HijrahEra[] values();
     enum_constant public static final java.time.chrono.HijrahEra AH;
@@ -63420,7 +63202,6 @@
     method public java.time.Period period(int, int, int);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.IsoChronology INSTANCE;
@@ -63453,7 +63234,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.JapaneseChronology INSTANCE;
@@ -63465,19 +63245,17 @@
     method public java.time.chrono.JapaneseChronology getChronology();
     method public java.time.chrono.JapaneseEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public int lengthOfYear();
     method public static java.time.chrono.JapaneseDate now();
     method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
     method public static java.time.chrono.JapaneseDate now(java.time.Clock);
     method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
     method public static java.time.chrono.JapaneseDate of(int, int, int);
-    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
@@ -63509,7 +63287,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.MinguoChronology INSTANCE;
@@ -63522,17 +63299,13 @@
     method public java.time.chrono.MinguoEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.MinguoDate now();
     method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
     method public static java.time.chrono.MinguoDate now(java.time.Clock);
     method public static java.time.chrono.MinguoDate of(int, int, int);
-    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class MinguoEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63562,7 +63335,6 @@
     method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
     method public int prolepticYear(java.time.chrono.Era, int);
     method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
-    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField, java.lang.Long>, java.time.format.ResolverStyle);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
     method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
     field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
@@ -63575,17 +63347,13 @@
     method public java.time.chrono.ThaiBuddhistEra getEra();
     method public long getLong(java.time.temporal.TemporalField);
     method public int lengthOfMonth();
-    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
     method public static java.time.chrono.ThaiBuddhistDate now();
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
     method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
     method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
-    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
-    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+    method public long toEpochDay();
     method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
-    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
   }
 
   public final class ThaiBuddhistEra extends java.lang.Enum implements java.time.chrono.Era {
@@ -63764,6 +63532,7 @@
     method public int checkValidIntValue(long);
     method public long checkValidValue(long);
     method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public java.lang.String getDisplayName(java.util.Locale);
     method public long getFrom(java.time.temporal.TemporalAccessor);
     method public java.time.temporal.TemporalUnit getRangeUnit();
     method public boolean isDateBased();
@@ -63811,6 +63580,7 @@
     method public java.time.Duration getDuration();
     method public boolean isDateBased();
     method public boolean isDurationEstimated();
+    method public boolean isSupportedBy(java.time.temporal.Temporal);
     method public boolean isTimeBased();
     method public static java.time.temporal.ChronoUnit valueOf(java.lang.String);
     method public static final java.time.temporal.ChronoUnit[] values();
@@ -64150,6 +63920,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ArrayList<E> extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable {
@@ -64160,7 +63931,11 @@
     method public void ensureCapacity(int);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public E get(int);
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
+    method public void replaceAll(java.util.function.UnaryOperator<E>);
     method public int size();
+    method public void sort(java.util.Comparator<? super E>);
+    method public java.util.Spliterator<E> spliterator();
     method public void trimToSize();
   }
 
@@ -64531,7 +64306,6 @@
     method public default boolean removeIf(java.util.function.Predicate<? super E>);
     method public abstract boolean retainAll(java.util.Collection<?>);
     method public abstract int size();
-    method public default java.util.Spliterator<E> spliterator();
     method public default java.util.stream.Stream<E> stream();
     method public abstract java.lang.Object[] toArray();
     method public abstract <T> T[] toArray(T[]);
@@ -64872,7 +64646,18 @@
     ctor public HashMap();
     ctor public HashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class HashSet<E> extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set {
@@ -64883,6 +64668,7 @@
     method public java.lang.Object clone();
     method public java.util.Iterator<E> iterator();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class Hashtable<K, V> extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable {
@@ -64900,11 +64686,9 @@
     method public boolean containsValue(java.lang.Object);
     method public synchronized java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public synchronized V get(java.lang.Object);
     method public synchronized V getOrDefault(java.lang.Object, V);
-    method public synchronized int hashCode();
     method public synchronized boolean isEmpty();
     method public java.util.Set<K> keySet();
     method public synchronized java.util.Enumeration<K> keys();
@@ -64919,7 +64703,6 @@
     method public synchronized V replace(K, V);
     method public synchronized void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public synchronized int size();
-    method public synchronized java.lang.String toString();
     method public java.util.Collection<V> values();
   }
 
@@ -64929,6 +64712,8 @@
     ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.lang.Object clone();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
   public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -65039,6 +64824,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface List<E> implements java.util.Collection {
@@ -65661,7 +65447,6 @@
     ctor public SimpleTimeZone(int, java.lang.String, int, int, int, int, int, int, int, int, int, int, int);
     method public int getOffset(int, int, int, int, int, int);
     method public int getRawOffset();
-    method public synchronized int hashCode();
     method public boolean inDaylightTime(java.util.Date);
     method public void setDSTSavings(int);
     method public void setEndRule(int, int, int, int);
@@ -65934,6 +65719,7 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public java.util.NavigableMap<K, V> headMap(K, boolean);
     method public java.util.SortedMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
@@ -65945,6 +65731,9 @@
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.SortedMap<K, V> subMap(K, K);
     method public java.util.NavigableMap<K, V> tailMap(K, boolean);
@@ -65972,6 +65761,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.SortedSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -66008,49 +65798,30 @@
     ctor public Vector(int);
     ctor public Vector();
     ctor public Vector(java.util.Collection<? extends E>);
-    method public synchronized boolean add(E);
-    method public synchronized boolean addAll(java.util.Collection<? extends E>);
-    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
     method public synchronized void addElement(E);
     method public synchronized int capacity();
     method public synchronized java.lang.Object clone();
-    method public synchronized boolean containsAll(java.util.Collection<?>);
     method public synchronized void copyInto(java.lang.Object[]);
     method public synchronized E elementAt(int);
     method public java.util.Enumeration<E> elements();
     method public synchronized void ensureCapacity(int);
-    method public synchronized boolean equals(java.lang.Object);
     method public synchronized E firstElement();
     method public synchronized void forEach(java.util.function.Consumer<? super E>);
     method public synchronized E get(int);
-    method public synchronized int hashCode();
     method public synchronized int indexOf(java.lang.Object, int);
     method public synchronized void insertElementAt(E, int);
-    method public synchronized boolean isEmpty();
-    method public synchronized java.util.Iterator<E> iterator();
     method public synchronized E lastElement();
-    method public synchronized int lastIndexOf(java.lang.Object);
     method public synchronized int lastIndexOf(java.lang.Object, int);
-    method public synchronized java.util.ListIterator<E> listIterator(int);
-    method public synchronized java.util.ListIterator<E> listIterator();
-    method public synchronized E remove(int);
-    method public synchronized boolean removeAll(java.util.Collection<?>);
     method public synchronized void removeAllElements();
     method public synchronized boolean removeElement(java.lang.Object);
     method public synchronized void removeElementAt(int);
     method public synchronized boolean removeIf(java.util.function.Predicate<? super E>);
-    method protected synchronized void removeRange(int, int);
     method public synchronized void replaceAll(java.util.function.UnaryOperator<E>);
-    method public synchronized boolean retainAll(java.util.Collection<?>);
-    method public synchronized E set(int, E);
     method public synchronized void setElementAt(E, int);
     method public synchronized void setSize(int);
     method public synchronized int size();
     method public synchronized void sort(java.util.Comparator<? super E>);
-    method public synchronized java.util.List<E> subList(int, int);
-    method public synchronized java.lang.Object[] toArray();
-    method public synchronized <T> T[] toArray(T[]);
-    method public synchronized java.lang.String toString();
+    method public java.util.Spliterator<E> spliterator();
     method public synchronized void trimToSize();
     field protected int capacityIncrement;
     field protected int elementCount;
@@ -66063,6 +65834,8 @@
     ctor public WeakHashMap();
     ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
   }
 
 }
@@ -66097,6 +65870,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66287,9 +66061,13 @@
     ctor public ConcurrentHashMap(java.util.Map<? extends K, ? extends V>);
     ctor public ConcurrentHashMap(int, float);
     ctor public ConcurrentHashMap(int, float, int);
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public boolean contains(java.lang.Object);
     method public java.util.Enumeration<V> elements();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
     method public void forEach(long, java.util.function.BiConsumer<? super K, ? super V>);
     method public <U> void forEach(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachEntry(long, java.util.function.Consumer<? super java.util.Map.Entry<K, V>>);
@@ -66298,11 +66076,14 @@
     method public <U> void forEachKey(long, java.util.function.Function<? super K, ? extends U>, java.util.function.Consumer<? super U>);
     method public void forEachValue(long, java.util.function.Consumer<? super V>);
     method public <U> void forEachValue(long, java.util.function.Function<? super V, ? extends U>, java.util.function.Consumer<? super U>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentHashMap.KeySetView<K, V> keySet(V);
     method public java.util.Enumeration<K> keys();
     method public long mappingCount();
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet();
     method public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K, java.lang.Boolean> newKeySet(int);
+    method public V putIfAbsent(K, V);
     method public <U> U reduce(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
     method public java.util.Map.Entry<K, V> reduceEntries(long, java.util.function.BiFunction<java.util.Map.Entry<K, V>, java.util.Map.Entry<K, V>, ? extends java.util.Map.Entry<K, V>>);
     method public <U> U reduceEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>, java.util.function.BiFunction<? super U, ? super U, ? extends U>);
@@ -66322,6 +66103,10 @@
     method public double reduceValuesToDouble(long, java.util.function.ToDoubleFunction<? super V>, double, java.util.function.DoubleBinaryOperator);
     method public int reduceValuesToInt(long, java.util.function.ToIntFunction<? super V>, int, java.util.function.IntBinaryOperator);
     method public long reduceValuesToLong(long, java.util.function.ToLongFunction<? super V>, long, java.util.function.LongBinaryOperator);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public <U> U search(long, java.util.function.BiFunction<? super K, ? super V, ? extends U>);
     method public <U> U searchEntries(long, java.util.function.Function<java.util.Map.Entry<K, V>, ? extends U>);
     method public <U> U searchKeys(long, java.util.function.Function<? super K, ? extends U>);
@@ -66382,6 +66167,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
@@ -66392,6 +66178,7 @@
     method public E peek();
     method public E poll();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public abstract interface ConcurrentMap<K, V> implements java.util.Map {
@@ -66423,6 +66210,9 @@
     method public K ceilingKey(K);
     method public java.util.concurrent.ConcurrentSkipListMap<K, V> clone();
     method public java.util.Comparator<? super K> comparator();
+    method public V compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
+    method public V computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>);
+    method public V computeIfPresent(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> descendingKeySet();
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> descendingMap();
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
@@ -66430,18 +66220,25 @@
     method public K firstKey();
     method public java.util.Map.Entry<K, V> floorEntry(K);
     method public K floorKey(K);
+    method public void forEach(java.util.function.BiConsumer<? super K, ? super V>);
+    method public V getOrDefault(java.lang.Object, V);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> headMap(K);
     method public java.util.Map.Entry<K, V> higherEntry(K);
     method public K higherKey(K);
-    method public java.util.NavigableSet<K> keySet();
     method public java.util.Map.Entry<K, V> lastEntry();
     method public K lastKey();
     method public java.util.Map.Entry<K, V> lowerEntry(K);
     method public K lowerKey(K);
+    method public V merge(K, V, java.util.function.BiFunction<? super V, ? super V, ? extends V>);
     method public java.util.NavigableSet<K> navigableKeySet();
     method public java.util.Map.Entry<K, V> pollFirstEntry();
     method public java.util.Map.Entry<K, V> pollLastEntry();
+    method public V putIfAbsent(K, V);
+    method public boolean remove(java.lang.Object, java.lang.Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+    method public void replaceAll(java.util.function.BiFunction<? super K, ? super V, ? extends V>);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, boolean, K, boolean);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> subMap(K, K);
     method public java.util.concurrent.ConcurrentNavigableMap<K, V> tailMap(K, boolean);
@@ -66469,6 +66266,7 @@
     method public E pollFirst();
     method public E pollLast();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
     method public java.util.NavigableSet<E> subSet(E, E);
     method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -66515,7 +66313,9 @@
     ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
     method public void forEach(java.util.function.Consumer<? super E>);
     method public java.util.Iterator<E> iterator();
+    method public boolean removeIf(java.util.function.Predicate<? super E>);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
   }
 
   public class CountDownLatch {
@@ -66674,7 +66474,6 @@
     method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
     method public boolean hasQueuedSubmissions();
     method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
     method public boolean isQuiescent();
     method public boolean isShutdown();
     method public boolean isTerminated();
@@ -66684,9 +66483,6 @@
     method public void shutdown();
     method public java.util.List<java.lang.Runnable> shutdownNow();
     method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
-    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.lang.Runnable, T);
-    method public java.util.concurrent.ForkJoinTask<?> submit(java.lang.Runnable);
     field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
   }
 
@@ -66810,6 +66606,7 @@
     method public E removeLast();
     method public boolean removeLastOccurrence(java.lang.Object);
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public E takeFirst() throws java.lang.InterruptedException;
     method public E takeLast() throws java.lang.InterruptedException;
@@ -66830,6 +66627,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66849,6 +66647,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
     method public void transfer(E) throws java.lang.InterruptedException;
     method public boolean tryTransfer(E);
@@ -66896,6 +66695,7 @@
     method public void put(E);
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -66999,6 +66799,7 @@
     method public void put(E) throws java.lang.InterruptedException;
     method public int remainingCapacity();
     method public int size();
+    method public java.util.Spliterator<E> spliterator();
     method public E take() throws java.lang.InterruptedException;
   }
 
@@ -67010,11 +66811,9 @@
     method public static java.util.concurrent.ThreadLocalRandom current();
     method public double nextDouble(double);
     method public double nextDouble(double, double);
-    method public double nextGaussian();
     method public int nextInt(int, int);
     method public long nextLong(long);
     method public long nextLong(long, long);
-    method public void setSeed(long);
   }
 
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
@@ -67028,7 +66827,6 @@
     method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
     method protected void beforeExecute(java.lang.Thread, java.lang.Runnable);
     method public void execute(java.lang.Runnable);
-    method protected void finalize();
     method public int getActiveCount();
     method public long getCompletedTaskCount();
     method public int getCorePoolSize();
@@ -67899,11 +67697,8 @@
     ctor public JarFile(java.io.File) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
     ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
-    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
-    method public synchronized java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.util.jar.JarEntry getJarEntry(java.lang.String);
     method public java.util.jar.Manifest getManifest() throws java.io.IOException;
-    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
     field public static final java.lang.String MANIFEST_NAME = "META-INF/MANIFEST.MF";
   }
 
@@ -67983,8 +67778,6 @@
 
   public class ConsoleHandler extends java.util.logging.StreamHandler {
     ctor public ConsoleHandler();
-    method public void close();
-    method public void publish(java.util.logging.LogRecord);
   }
 
   public class ErrorManager {
@@ -68774,7 +68567,6 @@
     method public int deflate(byte[]);
     method public int deflate(byte[], int, int, int);
     method public void end();
-    method protected void finalize();
     method public void finish();
     method public boolean finished();
     method public int getAdler();
@@ -68807,8 +68599,6 @@
     ctor public DeflaterInputStream(java.io.InputStream);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
     ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
-    method public void mark(int);
-    method public void reset() throws java.io.IOException;
     field protected final byte[] buf;
     field protected final java.util.zip.Deflater def;
   }
@@ -68839,7 +68629,6 @@
     ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
     ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field protected java.util.zip.CRC32 crc;
   }
 
@@ -68847,7 +68636,6 @@
     ctor public Inflater(boolean);
     ctor public Inflater();
     method public void end();
-    method protected void finalize();
     method public boolean finished();
     method public int getAdler();
     method public long getBytesRead();
@@ -68974,7 +68762,6 @@
     ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
-    method protected void finalize() throws java.io.IOException;
     method public java.lang.String getComment();
     method public java.util.zip.ZipEntry getEntry(java.lang.String);
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
@@ -69081,7 +68868,6 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
-    method public synchronized void write(byte[], int, int) throws java.io.IOException;
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
@@ -69238,7 +69024,6 @@
 
   public class ExemptionMechanism {
     ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, java.lang.String);
-    method protected void finalize();
     method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
     method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
     method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
@@ -70816,7 +70601,6 @@
   public abstract class SSLSocketFactory extends javax.net.SocketFactory {
     ctor public SSLSocketFactory();
     method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
-    method public java.net.Socket createSocket(java.net.Socket, java.io.InputStream, boolean) throws java.io.IOException;
     method public static synchronized javax.net.SocketFactory getDefault();
     method public abstract java.lang.String[] getDefaultCipherSuites();
     method public abstract java.lang.String[] getSupportedCipherSuites();
@@ -71628,7 +71412,6 @@
     ctor public TransformerException(java.lang.String, java.lang.Throwable);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator);
     ctor public TransformerException(java.lang.String, javax.xml.transform.SourceLocator, java.lang.Throwable);
-    method public java.lang.Throwable getCause();
     method public java.lang.Throwable getException();
     method public java.lang.String getLocationAsString();
     method public javax.xml.transform.SourceLocator getLocator();
@@ -71899,7 +71682,6 @@
   public class XPathException extends java.lang.Exception {
     ctor public XPathException(java.lang.String);
     ctor public XPathException(java.lang.Throwable);
-    method public java.lang.Throwable getCause();
   }
 
   public abstract interface XPathExpression {
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 0e2c13e..7ab402a 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -1,15 +1,50 @@
+bootanimation_CommonCFlags = -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+bootanimation_CommonCFlags += -Wall -Werror -Wunused -Wunreachable-code
+
+
+# bootanimation executable
+# =========================================================
+
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
     bootanimation_main.cpp \
     audioplay.cpp \
+
+LOCAL_CFLAGS += ${bootanimation_CommonCFlags}
+
+LOCAL_SHARED_LIBRARIES := \
+    libOpenSLES \
+    libandroidfw \
+    libbase \
+    libbinder \
+    libbootanimation \
+    libcutils \
+    liblog \
+    libutils \
+
+LOCAL_MODULE:= bootanimation
+
+LOCAL_INIT_RC := bootanim.rc
+
+ifdef TARGET_32_BIT_SURFACEFLINGER
+LOCAL_32_BIT_ONLY := true
+endif
+
+include $(BUILD_EXECUTABLE)
+
+
+# libbootanimation
+# ===========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbootanimation
+LOCAL_CFLAGS += ${bootanimation_CommonCFlags}
+
+LOCAL_SRC_FILES:= \
     BootAnimation.cpp
 
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
 LOCAL_C_INCLUDES += \
     external/tinyalsa/include \
     frameworks/wilhelm/include
@@ -25,16 +60,11 @@
     libEGL \
     libGLESv1_CM \
     libgui \
-    libOpenSLES \
     libtinyalsa \
     libbase
 
-LOCAL_MODULE:= bootanimation
-
-LOCAL_INIT_RC := bootanim.rc
-
 ifdef TARGET_32_BIT_SURFACEFLINGER
 LOCAL_32_BIT_ONLY := true
 endif
 
-include $(BUILD_EXECUTABLE)
+include ${BUILD_SHARED_LIBRARY}
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 7394490..6b2de4b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -62,7 +62,6 @@
 #include <EGL/eglext.h>
 
 #include "BootAnimation.h"
-#include "audioplay.h"
 
 namespace android {
 
@@ -92,26 +91,18 @@
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
-static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound";
 static const int ANIM_ENTRY_NAME_MAX = 256;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
-static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed";
-static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason";
-// bootreasons list in "system/core/bootstat/bootstat.cpp".
-static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST {
-  "kernel_panic",
-  "Panic",
-  "Watchdog",
-};
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL) {
+BootAnimation::BootAnimation(InitCallback initCallback,
+                             PlayPartCallback partCallback)
+        : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
+        mTimeFormat12Hour(false), mTimeCheckThread(NULL),
+        mInitCallback(initCallback), mPlayPartCallback(partCallback) {
     mSession = new SurfaceComposerClient();
 
-    // If the system has already booted, the animation is not being used for a boot.
-    mSystemBoot = !android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false);
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
     if (powerCtl.empty()) {
         mShuttingDown = false;
@@ -142,7 +133,6 @@
     // might be blocked on a condition variable that will never be updated.
     kill( getpid(), SIGKILL );
     requestExit();
-    audioplay::destroy();
 }
 
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
@@ -158,10 +148,6 @@
     asset->close();
     delete asset;
 
-    // ensure we can call getPixels(). No need to call unlock, since the
-    // bitmap will go out of scope when we return from this method.
-    bitmap.lockPixels();
-
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -216,10 +202,6 @@
     // the packed resource can be released.
     delete map;
 
-    // ensure we can call getPixels(). No need to call unlock, since the
-    // bitmap will go out of scope when we return from this method.
-    bitmap.lockPixels();
-
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -712,7 +694,6 @@
         return false;
     }
 
-    Animation::Part* partWithAudio = NULL;
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
     while ((entry = zip->nextEntry(cookie)) != NULL) {
@@ -747,7 +728,6 @@
                                     // a part may have at most one audio file
                                     part.audioData = (uint8_t *)map->getDataPtr();
                                     part.audioLength = map->getDataLength();
-                                    partWithAudio = &part;
                                 } else if (leaf == "trim.txt") {
                                     part.trimData.setTo((char const*)map->getDataPtr(),
                                                         map->getDataLength());
@@ -797,13 +777,8 @@
         }
     }
 
-    // Create and initialize audioplay if there is a wav file in any of the animations.
-    // Do it on a separate thread so we don't hold up the animation intro.
-    if (partWithAudio != NULL) {
-        ALOGD("found audio.wav, creating playback engine");
-        mInitAudioThread = new InitAudioThread(partWithAudio->audioData,
-                                               partWithAudio->audioLength);
-        mInitAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL);
+    if (mInitCallback != nullptr) {
+        mInitCallback(animation.parts);
     }
 
     zip->endIteration(cookie);
@@ -876,11 +851,6 @@
         mTimeCheckThread = nullptr;
     }
 
-    // We should have joined mInitAudioThread thread in playAnimation
-    if (mInitAudioThread != nullptr) {
-        mInitAudioThread = nullptr;
-    }
-
     releaseAnimation(animation);
 
     if (clockFontInitialized) {
@@ -917,14 +887,8 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
-            // only play audio file the first time we animate the part
-            if (r == 0 && part.audioData && playSoundsAllowed()) {
-                ALOGD("playing clip for part%d, size=%d", (int) i, part.audioLength);
-                // Block until the audio engine is finished initializing.
-                if (mInitAudioThread != nullptr) {
-                    mInitAudioThread->join();
-                }
-                audioplay::playClip(part.audioData, part.audioLength);
+            if (mPlayPartCallback != nullptr) {
+                mPlayPartCallback(i, part, r);
             }
 
             glClearColor(
@@ -1013,10 +977,6 @@
         }
     }
 
-    // we've finally played everything we're going to play
-    audioplay::setPlaying(false);
-    audioplay::destroy();
-
     return true;
 }
 
@@ -1062,32 +1022,6 @@
     return animation;
 }
 
-bool BootAnimation::playSoundsAllowed() const {
-    // Only play sounds for system boots, not runtime restarts.
-    if (!mSystemBoot) {
-        return false;
-    }
-    if (mShuttingDown) { // no audio while shutting down
-        return false;
-    }
-    // Read the system property to see if we should play the sound.
-    // If it's not present, default to allowed.
-    if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) {
-        return false;
-    }
-
-    // Don't play sounds if this is a reboot due to an error.
-    char bootreason[PROPERTY_VALUE_MAX];
-    if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) {
-        for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) {
-            if (strcasecmp(str.c_str(), bootreason) == 0) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
 bool BootAnimation::updateIsTimeAccurate() {
     static constexpr long long MAX_TIME_IN_PAST =   60000LL * 60LL * 24LL * 30LL;  // 30 days
     static constexpr long long MAX_TIME_IN_FUTURE = 60000LL * 90LL;  // 90 minutes
@@ -1219,17 +1153,6 @@
     return NO_ERROR;
 }
 
-BootAnimation::InitAudioThread::InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength)
-    : Thread(false),
-      mExampleAudioData(exampleAudioData),
-      mExampleAudioLength(exampleAudioLength) {}
-
-bool BootAnimation::InitAudioThread::threadLoop() {
-    audioplay::create(mExampleAudioData, mExampleAudioLength);
-    // Exit immediately
-    return false;
-}
-
 // ---------------------------------------------------------------------------
 
 }
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 181ef1c..3ebe7d6 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -39,44 +39,6 @@
 class BootAnimation : public Thread, public IBinder::DeathRecipient
 {
 public:
-    BootAnimation();
-
-    sp<SurfaceComposerClient> session() const;
-
-private:
-    virtual bool        threadLoop();
-    virtual status_t    readyToRun();
-    virtual void        onFirstRef();
-    virtual void        binderDied(const wp<IBinder>& who);
-
-    bool                updateIsTimeAccurate();
-
-    class TimeCheckThread : public Thread {
-    public:
-        TimeCheckThread(BootAnimation* bootAnimation);
-        virtual ~TimeCheckThread();
-    private:
-        virtual status_t    readyToRun();
-        virtual bool        threadLoop();
-        bool                doThreadLoop();
-        void                addTimeDirWatch();
-
-        int mInotifyFd;
-        int mSystemWd;
-        int mTimeWd;
-        BootAnimation* mBootAnimation;
-    };
-
-    class InitAudioThread : public Thread {
-    public:
-        InitAudioThread(uint8_t* exampleAudioData, int mExampleAudioLength);
-    private:
-        virtual bool threadLoop();
-
-        uint8_t* mExampleAudioData;
-        int mExampleAudioLength;
-    };
-
     struct Texture {
         GLint   w;
         GLint   h;
@@ -131,6 +93,49 @@
         Font clockFont;
     };
 
+    // Callback will be called during initialization after we have loaded
+    // the animation and be provided with all parts in animation.
+    typedef std::function<void(const Vector<Animation::Part>& parts)> InitCallback;
+
+    // Callback will be called while animation is playing before each part is
+    // played. It will be provided with the part and play count for it.
+    // It will be provided with the partNumber for the part about to be played,
+    // as well as a reference to the part itself. It will also be provided with
+    // which play of that part is about to start, some parts are repeated
+    // multiple times.
+    typedef std::function<void(int partNumber, const Animation::Part& part, int playNumber)>
+            PlayPartCallback;
+
+    // Callbacks may be null and will be called from this class's internal
+    // thread.
+    BootAnimation(InitCallback initCallback, PlayPartCallback partCallback);
+
+    sp<SurfaceComposerClient> session() const;
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+    virtual void        binderDied(const wp<IBinder>& who);
+
+    bool                updateIsTimeAccurate();
+
+    class TimeCheckThread : public Thread {
+    public:
+        TimeCheckThread(BootAnimation* bootAnimation);
+        virtual ~TimeCheckThread();
+    private:
+        virtual status_t    readyToRun();
+        virtual bool        threadLoop();
+        bool                doThreadLoop();
+        void                addTimeDirWatch();
+
+        int mInotifyFd;
+        int mSystemWd;
+        int mTimeWd;
+        BootAnimation* mBootAnimation;
+    };
+
     status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
     status_t initTexture(FileMap* map, int* width, int* height);
     status_t initFont(Font* font, const char* fallback);
@@ -144,7 +149,6 @@
     void releaseAnimation(Animation*) const;
     bool parseAnimationDesc(Animation&);
     bool preloadZip(Animation &animation);
-    bool playSoundsAllowed() const;
 
     void checkExit();
 
@@ -162,12 +166,12 @@
     bool        mClockEnabled;
     bool        mTimeIsAccurate;
     bool        mTimeFormat12Hour;
-    bool        mSystemBoot;
     bool        mShuttingDown;
     String8     mZipFileName;
     SortedVector<String8> mLoadedFiles;
     sp<TimeCheckThread> mTimeCheckThread = nullptr;
-    sp<InitAudioThread> mInitAudioThread = nullptr;
+    InitCallback mInitCallback = nullptr;
+    PlayPartCallback mPlayPartCallback = nullptr;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index 3689d5e..c11d905 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -27,13 +27,77 @@
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 #include <utils/threads.h>
+#include <android-base/properties.h>
 
 #include "BootAnimation.h"
+#include "audioplay.h"
 
 using namespace android;
 
 // ---------------------------------------------------------------------------
 
+namespace {
+
+// Create a typedef for readability.
+typedef android::BootAnimation::Animation Animation;
+
+static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound";
+static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed";
+static const char POWER_CTL_PROP_NAME[] = "sys.powerctl";
+static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason";
+static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST {
+  "kernel_panic",
+  "Panic",
+  "Watchdog",
+};
+
+class InitAudioThread : public Thread {
+public:
+    InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength)
+        : Thread(false),
+          mExampleAudioData(exampleAudioData),
+          mExampleAudioLength(exampleAudioLength) {}
+private:
+    virtual bool threadLoop() {
+        audioplay::create(mExampleAudioData, mExampleAudioLength);
+        // Exit immediately
+        return false;
+    }
+
+    uint8_t* mExampleAudioData;
+    int mExampleAudioLength;
+};
+
+bool playSoundsAllowed() {
+    // Only play sounds for system boots, not runtime restarts.
+    if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) {
+        return false;
+    }
+    // no audio while shutting down
+    if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) {
+        return false;
+    }
+    // Read the system property to see if we should play the sound.
+    // If it's not present, default to allowed.
+    if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) {
+        return false;
+    }
+
+    // Don't play sounds if this is a reboot due to an error.
+    char bootreason[PROPERTY_VALUE_MAX];
+    if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) {
+        for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) {
+            if (strcasecmp(str.c_str(), bootreason) == 0) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+}  // namespace
+
+
 int main()
 {
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
@@ -71,10 +135,50 @@
             ALOGI("Waiting for SurfaceFlinger took %" PRId64 " ms", totalWaited);
         }
 
+        // TODO: Move audio code to a new class that just exports the callbacks.
+        sp<InitAudioThread> initAudioThread = nullptr;
+
+        auto initCallback = [&](const Vector<Animation::Part>& parts) {
+            const Animation::Part* partWithAudio = nullptr;
+            for (const Animation::Part& part : parts) {
+                if (part.audioData != nullptr) {
+                    partWithAudio = &part;
+                }
+            }
+
+            if (partWithAudio == nullptr) {
+                return;
+            }
+
+            ALOGD("found audio.wav, creating playback engine");
+            initAudioThread = new InitAudioThread(partWithAudio->audioData,
+                    partWithAudio->audioLength);
+            initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL);
+
+        };
+
+        auto partCallback = [&](int partNumber, const Animation::Part& part,
+                                int playNumber) {
+            // only play audio file the first time we animate the part
+            if (playNumber == 0 && part.audioData && playSoundsAllowed()) {
+                ALOGD("playing clip for part%d, size=%d",
+                      partNumber, part.audioLength);
+                // Block until the audio engine is finished initializing.
+                if (initAudioThread != nullptr) {
+                    initAudioThread->join();
+                }
+                audioplay::playClip(part.audioData, part.audioLength);
+            }
+        };
+
         // create the boot animation object
-        sp<BootAnimation> boot = new BootAnimation();
+        sp<BootAnimation> boot = new BootAnimation(initCallback, partCallback);
 
         IPCThreadState::self()->joinThreadPool();
+
+        // we've finally played everything we're going to play
+        audioplay::setPlaying(false);
+        audioplay::destroy();
     }
     return 0;
 }
diff --git a/cmds/hid/README.md b/cmds/hid/README.md
new file mode 100644
index 0000000..7e22d08
--- /dev/null
+++ b/cmds/hid/README.md
@@ -0,0 +1,145 @@
+# Usage
+##  Two options to use the hid command:
+### 1. Interactive through stdin:
+type `hid -` into the terminal, then type/paste commands to send to the binary.
+Use Ctrl+D to signal end of stream to the binary (EOF).
+
+This mode can be also used from an app to send HID events.
+For an example, see the cts test case at: [InputTestCase.java][2]
+
+When using another program to control hid in interactive mode, registering a
+new input device (for example, a bluetooth joystick) should be the first step.
+After the device is added, you need to wait for the _onInputDeviceAdded_
+(see [InputDeviceListener][1]) notification before issuing commands
+to the device.
+Failure to do so will cause missed events and inconsistent behaviour.
+In the current implementation of the hid command, the hid binary will wait
+for the file descriptor to the uhid node to send the UHID_START and UHID_OPEN
+signals before returning. However, this is not sufficient. These signals
+only notify the readiness of the kernel driver,
+but do not take into account the inputflinger framework.
+
+
+### 2. Using a file as an input:
+type `hid <filename>`, and the file will be used an an input to the binary.
+You must add a sufficient delay after a "register" command to ensure device
+is ready. The interactive mode is the recommended method of communicating
+with the hid binary.
+
+All of the input commands should be in pseudo-JSON format as documented below.
+See examples [here][3].
+
+The file can have multiple commands one after the other (which is not strictly
+legal JSON format, as this would imply multiple root elements).
+
+## Command description
+
+1. `register`
+Register a new uhid device
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:--------------------------|
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "register"  |
+| name          | string        | Device name                |
+| vid           | 16-bit integer| Vendor id                  |
+| pid           | 16-bit integer| Product id                 |
+| descriptor    | byte array    | USB HID report descriptor  |
+
+Device ID is used for matching the subsequent commands to a specific device
+to avoid ambiguity when multiple devices are registered.
+
+USB HID report descriptor should be generated according the the USB HID spec
+and can be checked by reverse parsing using a variety of tools, for example
+[usbdescreqparser][5].
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "register",
+  "name": "Odie (Test)",
+  "vid": 0x18d1,
+  "pid": 0x2c40,
+  "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x05, 0x09, 0x0a, 0x01, 0x00,
+    0x0a, 0x02, 0x00, 0x0a, 0x04, 0x00, 0x0a, 0x05, 0x00, 0x0a, 0x07, 0x00, 0x0a, 0x08, 0x00,
+    0x0a, 0x0e, 0x00, 0x0a, 0x0f, 0x00, 0x0a, 0x0d, 0x00, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x0a,
+    0x23, 0x02, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0b, 0x81, 0x02, 0x75, 0x01, 0x95,
+    0x01, 0x81, 0x03, 0x05, 0x01, 0x75, 0x04, 0x95, 0x01, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x66,
+    0x14, 0x00, 0x09, 0x39, 0x81, 0x42, 0x66, 0x00, 0x00, 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30,
+    0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x05, 0x02, 0x09, 0xc5, 0x09, 0xc4, 0x15, 0x00, 0x26,
+    0xff, 0x00, 0x35, 0x00, 0x46, 0xff, 0x00, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0x85,
+    0x02, 0x05, 0x08, 0x0a, 0x01, 0x00, 0x0a, 0x02, 0x00, 0x0a, 0x03, 0x00, 0x0a, 0x04, 0x00,
+    0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x91, 0x02, 0x75, 0x04, 0x95, 0x01, 0x91,
+    0x03, 0xc0, 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x03, 0x05, 0x01, 0x09, 0x06, 0xa1,
+    0x02, 0x05, 0x06, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
+    0x02, 0x06, 0xbc, 0xff, 0x0a, 0xad, 0xbd, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02, 0xc0, 0xc0]
+}
+```
+2. `delay`
+Add a delay to command processing
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:-------------------------- |
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "delay"     |
+| duration      | integer       | Delay in milliseconds      |
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "delay",
+  "duration": 10
+}
+```
+
+3. `report`
+Send a report to the HID device
+
+| Field         | Type          | Description                |
+|:-------------:|:-------------:|:-------------------------- |
+| id            | integer       | Device id                  |
+| command       | string        | Must be set to "report"    |
+| report        | byte array    | Report data to send        |
+
+Example:
+```json
+{
+  "id": 1,
+  "command": "report",
+  "report": [0x01, 0x01, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00]
+}
+```
+
+### Sending a joystick button press event
+To send a button press event on a joystick device:
+1. Register the joystick device
+2. Send button down event with coordinates ABS_X, ABS_Y, ABS_Z, and ABS_RZ
+at the center of the range. If the coordinates are not centered, this event
+will generate a motion event within the input framework, in addition to the
+button press event. The range can be determined from the uhid report descriptor.
+3. Send the button up event with the same coordinates as in 2.
+4. Check that the button press event was received.
+
+### Notes
+1. As soon as EOF is reached (either in interactive mode, or in file mode),
+the device that was created will be unregistered. There is no
+explicit command for unregistering a device.
+2. The linux input subsystem does not generate events for those values
+that remain unchanged. For example, if there are two events sent to the driver,
+and both events have the same value of ABS_X, then ABS_X coordinate
+will not be reported.
+3. The description of joystick actions is available [here][6].
+4. Joysticks are split axes. When an analog stick is in a resting state,
+the reported coordinates are at the center of the range.
+5. The `getevent` utility can used to print out the key events
+for debugging purposes.
+
+
+[1]: https://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
+[2]: ../../../../cts/tests/tests/hardware/src/android/hardware/input/cts/tests/InputTestCase.java
+[3]: ../../../../cts/tests/tests/hardware/res/raw/
+[4]: https://developer.android.com/training/game-controllers/controller-input.html#button
+[5]: http://eleccelerator.com/usbdescreqparser/
+[6]: https://developer.android.com/training/game-controllers/controller-input.html
\ No newline at end of file
diff --git a/cmds/hid/jni/Android.bp b/cmds/hid/jni/Android.bp
index 05c3099..095cfc6 100644
--- a/cmds/hid/jni/Android.bp
+++ b/cmds/hid/jni/Android.bp
@@ -4,10 +4,9 @@
     srcs: ["com_android_commands_hid_Device.cpp"],
 
     shared_libs: [
-        "libandroid_runtime",
+        "libandroid",
         "liblog",
         "libnativehelper",
-        "libutils",
     ],
 
     cflags: [
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 59953b8..5cc4fc4 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -26,17 +26,17 @@
 #include <memory>
 #include <unistd.h>
 
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/Log.h>
-#include <android_os_MessageQueue.h>
-#include <core_jni_helpers.h>
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
-#include <utils/Log.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
+#include <android/looper.h>
+#include <android/log.h>
+
+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
+#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
 
 namespace android {
 namespace uhid {
@@ -56,59 +56,67 @@
 
 static void checkAndClearException(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
-        ALOGE("An exception was thrown by callback '%s'.", methodName);
-        LOGE_EX(env);
+        LOGE("An exception was thrown by callback '%s'.", methodName);
         env->ExceptionClear();
     }
 }
 
 DeviceCallback::DeviceCallback(JNIEnv* env, jobject callback) :
-    mCallbackObject(env->NewGlobalRef(callback)) { }
+    mCallbackObject(env->NewGlobalRef(callback)) {
+    env->GetJavaVM(&mJavaVM);
+ }
 
 DeviceCallback::~DeviceCallback() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->DeleteGlobalRef(mCallbackObject);
 }
 
 void DeviceCallback::onDeviceError() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceError);
     checkAndClearException(env, "onDeviceError");
 }
 
 void DeviceCallback::onDeviceOpen() {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    JNIEnv* env = getJNIEnv();
     env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOpen);
     checkAndClearException(env, "onDeviceOpen");
 }
 
+JNIEnv* DeviceCallback::getJNIEnv() {
+    JNIEnv* env;
+    mJavaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+    return env;
+}
+
 Device* Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
         std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
-        std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) {
+        std::unique_ptr<DeviceCallback> callback) {
 
     int fd = ::open(UHID_PATH, O_RDWR | O_CLOEXEC);
     if (fd < 0) {
-        ALOGE("Failed to open uhid: %s", strerror(errno));
+        LOGE("Failed to open uhid: %s", strerror(errno));
         return nullptr;
     }
 
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
-    ev.type = UHID_CREATE;
-    strncpy((char*)ev.u.create.name, name, UHID_MAX_NAME_LENGTH);
-    ev.u.create.rd_data = descriptor.get();
-    ev.u.create.rd_size = descriptorSize;
-    ev.u.create.bus = BUS_BLUETOOTH;
-    ev.u.create.vendor = vid;
-    ev.u.create.product = pid;
-    ev.u.create.version = 0;
-    ev.u.create.country = 0;
+    ev.type = UHID_CREATE2;
+    strncpy((char*)ev.u.create2.name, name, UHID_MAX_NAME_LENGTH);
+    memcpy(&ev.u.create2.rd_data, descriptor.get(),
+            descriptorSize * sizeof(ev.u.create2.rd_data[0]));
+    ev.u.create2.rd_size = descriptorSize;
+    ev.u.create2.bus = BUS_BLUETOOTH;
+    ev.u.create2.vendor = vid;
+    ev.u.create2.product = pid;
+    ev.u.create2.version = 0;
+    ev.u.create2.country = 0;
 
     errno = 0;
     ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev)));
     if (ret < 0 || ret != sizeof(ev)) {
         ::close(fd);
-        ALOGE("Failed to create uhid node: %s", strerror(errno));
+        LOGE("Failed to create uhid node: %s", strerror(errno));
         return nullptr;
     }
 
@@ -116,20 +124,30 @@
     ret = TEMP_FAILURE_RETRY(::read(fd, &ev, sizeof(ev)));
     if (ret < 0 || ev.type != UHID_START) {
         ::close(fd);
-        ALOGE("uhid node failed to start: %s", strerror(errno));
+        LOGE("uhid node failed to start: %s", strerror(errno));
         return nullptr;
     }
-
-    return new Device(id, fd, std::move(callback), looper);
+    return new Device(id, fd, std::move(callback));
 }
 
-Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) :
-            mId(id), mFd(fd), mDeviceCallback(std::move(callback)), mLooper(looper) {
-    looper->addFd(fd, 0, Looper::EVENT_INPUT, handleLooperEvents, reinterpret_cast<void*>(this));
+Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback) :
+            mId(id), mFd(fd), mDeviceCallback(std::move(callback)) {
+    ALooper* aLooper = ALooper_forThread();
+    if (aLooper == NULL) {
+        LOGE("Could not get ALooper, ALooper_forThread returned NULL");
+        aLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+    }
+    ALooper_addFd(aLooper, fd, 0, ALOOPER_EVENT_INPUT, handleLooperEvents,
+                  reinterpret_cast<void*>(this));
 }
 
 Device::~Device() {
-    mLooper->removeFd(mFd);
+    ALooper* looper = ALooper_forThread();
+    if (looper != NULL) {
+        ALooper_removeFd(looper, mFd);
+    } else {
+        LOGE("Could not remove fd, ALooper_forThread() returned NULL!");
+    }
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
     ev.type = UHID_DESTROY;
@@ -141,25 +159,25 @@
 void Device::sendReport(uint8_t* report, size_t reportSize) {
     struct uhid_event ev;
     memset(&ev, 0, sizeof(ev));
-    ev.type = UHID_INPUT;
-    ev.u.input.size = reportSize;
-    memcpy(&ev.u.input.data, report, reportSize);
+    ev.type = UHID_INPUT2;
+    ev.u.input2.size = reportSize;
+    memcpy(&ev.u.input2.data, report, reportSize);
     ssize_t ret = TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev)));
     if (ret < 0 || ret != sizeof(ev)) {
-        ALOGE("Failed to send hid event: %s", strerror(errno));
+        LOGE("Failed to send hid event: %s", strerror(errno));
     }
 }
 
 int Device::handleEvents(int events) {
-    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
-        ALOGE("uhid node was closed or an error occurred. events=0x%x", events);
+    if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
+        LOGE("uhid node was closed or an error occurred. events=0x%x", events);
         mDeviceCallback->onDeviceError();
         return 0;
     }
     struct uhid_event ev;
     ssize_t ret = TEMP_FAILURE_RETRY(::read(mFd, &ev, sizeof(ev)));
     if (ret < 0) {
-        ALOGE("Failed to read from uhid node: %s", strerror(errno));
+        LOGE("Failed to read from uhid node: %s", strerror(errno));
         mDeviceCallback->onDeviceError();
         return 0;
     }
@@ -184,7 +202,7 @@
 }
 
 static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid, jint pid,
-        jbyteArray rawDescriptor, jobject queue, jobject callback) {
+        jbyteArray rawDescriptor, jobject callback) {
     ScopedUtfChars name(env, rawName);
     if (name.c_str() == nullptr) {
         return 0;
@@ -194,20 +212,21 @@
     std::unique_ptr<uint8_t[]> desc = getData(env, rawDescriptor, size);
 
     std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
-    sp<Looper> looper = android_os_MessageQueue_getMessageQueue(env, queue)->getLooper();
 
     uhid::Device* d = uhid::Device::open(
             id, reinterpret_cast<const char*>(name.c_str()), vid, pid,
-            std::move(desc), size, std::move(cb), std::move(looper));
+            std::move(desc), size, std::move(cb));
     return reinterpret_cast<jlong>(d);
 }
 
-static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr,jbyteArray rawReport) {
+static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr, jbyteArray rawReport) {
     size_t size;
     std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size);
     uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
     if (d) {
         d->sendReport(report.get(), size);
+    } else {
+        LOGE("Could not send report, Device* is null!");
     }
 }
 
@@ -220,7 +239,7 @@
 
 static JNINativeMethod sMethods[] = {
     { "nativeOpenDevice",
-            "(Ljava/lang/String;III[BLandroid/os/MessageQueue;"
+            "(Ljava/lang/String;III[B"
             "Lcom/android/commands/hid/Device$DeviceCallback;)J",
             reinterpret_cast<void*>(openDevice) },
     { "nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport) },
@@ -228,11 +247,21 @@
 };
 
 int register_com_android_commands_hid_Device(JNIEnv* env) {
-    jclass clazz = FindClassOrDie(env, "com/android/commands/hid/Device$DeviceCallback");
+    jclass clazz = env->FindClass("com/android/commands/hid/Device$DeviceCallback");
+    if (clazz == NULL) {
+        LOGE("Unable to find class 'DeviceCallback'");
+        return JNI_ERR;
+    }
     uhid::gDeviceCallbackClassInfo.onDeviceOpen =
-            GetMethodIDOrDie(env, clazz, "onDeviceOpen", "()V");
-    uhid::gDeviceCallbackClassInfo.onDeviceError=
-            GetMethodIDOrDie(env, clazz, "onDeviceError", "()V");
+            env->GetMethodID(clazz, "onDeviceOpen", "()V");
+    uhid::gDeviceCallbackClassInfo.onDeviceError =
+            env->GetMethodID(clazz, "onDeviceError", "()V");
+    if (uhid::gDeviceCallbackClassInfo.onDeviceOpen == NULL ||
+            uhid::gDeviceCallbackClassInfo.onDeviceError == NULL) {
+        LOGE("Unable to obtain onDeviceOpen or onDeviceError methods");
+        return JNI_ERR;
+    }
+
     return jniRegisterNativeMethods(env, "com/android/commands/hid/Device",
             sMethods, NELEM(sMethods));
 }
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 6c5899e..149456d 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -17,8 +17,6 @@
 #include <memory>
 
 #include <jni.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
 
 namespace android {
 namespace uhid {
@@ -32,16 +30,18 @@
     void onDeviceError();
 
 private:
+    JNIEnv* getJNIEnv();
     jobject mCallbackObject;
+    JavaVM* mJavaVM;
 };
 
 class Device {
 public:
     static Device* open(int32_t id, const char* name, int32_t vid, int32_t pid,
             std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
-            std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+            std::unique_ptr<DeviceCallback> callback);
 
-    Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper);
+    Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback);
     ~Device();
 
     void sendReport(uint8_t* report, size_t reportSize);
@@ -53,7 +53,6 @@
     int32_t mId;
     int mFd;
     std::unique_ptr<DeviceCallback> mDeviceCallback;
-    sp<Looper> mLooper;
 };
 
 
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index dbe883b..8c52a8e 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -29,22 +29,14 @@
 public class Device {
     private static final String TAG = "HidDevice";
 
-    // Minimum amount of time to wait before sending input events to a device. Even though we're
-    // guaranteed that the device has been created and opened by the input system, there's still a
-    // window in which the system hasn't started reading events out of it. If a stream of events
-    // begins in during this window (like a button down event) and *then* we start reading, we're
-    // liable to ignore the whole stream.
-    private static final int MIN_WAIT_FOR_FIRST_EVENT = 150;
-
     private static final int MSG_OPEN_DEVICE = 1;
     private static final int MSG_SEND_REPORT = 2;
     private static final int MSG_CLOSE_DEVICE = 3;
 
-
     private final int mId;
     private final HandlerThread mThread;
     private final DeviceHandler mHandler;
-    private long mEventTime;
+    private long mTimeToSend;
 
     private final Object mCond = new Object();
 
@@ -53,7 +45,7 @@
     }
 
     private static native long nativeOpenDevice(String name, int id, int vid, int pid,
-            byte[] descriptor, MessageQueue queue, DeviceCallback callback);
+            byte[] descriptor, DeviceCallback callback);
     private static native void nativeSendReport(long ptr, byte[] data);
     private static native void nativeCloseDevice(long ptr);
 
@@ -74,22 +66,22 @@
         args.arg2 = descriptor;
         args.arg3 = report;
         mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget();
-        mEventTime = SystemClock.uptimeMillis() + MIN_WAIT_FOR_FIRST_EVENT;
+        mTimeToSend = SystemClock.uptimeMillis();
     }
 
     public void sendReport(byte[] report) {
         Message msg = mHandler.obtainMessage(MSG_SEND_REPORT, report);
-        mHandler.sendMessageAtTime(msg, mEventTime);
+        // if two messages are sent at identical time, they will be processed in order received
+        mHandler.sendMessageAtTime(msg, mTimeToSend);
     }
 
     public void addDelay(int delay) {
-        mEventTime += delay;
+        mTimeToSend = Math.max(SystemClock.uptimeMillis(), mTimeToSend) + delay;
     }
 
     public void close() {
         Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
-        msg.setAsynchronous(true);
-        mHandler.sendMessageAtTime(msg, mEventTime + 1);
+        mHandler.sendMessageAtTime(msg, Math.max(SystemClock.uptimeMillis(), mTimeToSend) + 1);
         try {
             synchronized (mCond) {
                 mCond.wait();
@@ -111,8 +103,7 @@
                 case MSG_OPEN_DEVICE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3,
-                            (byte[]) args.arg2, getLooper().myQueue(), new DeviceCallback());
-                    nativeSendReport(mPtr, (byte[]) args.arg3);
+                            (byte[]) args.arg2, new DeviceCallback());
                     pauseEvents();
                     break;
                 case MSG_SEND_REPORT:
@@ -155,6 +146,7 @@
         }
 
         public void onDeviceError() {
+            Log.e(TAG, "Device error occurred, closing /dev/uhid");
             Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE);
             msg.setAsynchronous(true);
             msg.sendToTarget();
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
index 976a782..234e47f 100644
--- a/cmds/hid/src/com/android/commands/hid/Hid.java
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -16,7 +16,6 @@
 
 package com.android.commands.hid;
 
-import android.os.SystemClock;
 import android.util.JsonReader;
 import android.util.JsonToken;
 import android.util.Log;
@@ -91,7 +90,6 @@
         }
     }
 
-
     private void process(Event e) {
         final int index = mDevices.indexOfKey(e.getId());
         if (index >= 0) {
@@ -101,10 +99,16 @@
             } else if (Event.COMMAND_REPORT.equals(e.getCommand())) {
                 d.sendReport(e.getReport());
             } else {
-                error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
+                if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
+                    error("Device id=" + e.getId() + " is already registered. Ignoring event.");
+                } else {
+                    error("Unknown command \"" + e.getCommand() + "\". Ignoring event.");
+                }
             }
-        } else {
+        } else if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
             registerDevice(e);
+        } else {
+            Log.e(TAG, "Unknown device id specified. Ignoring event.");
         }
     }
 
@@ -124,7 +128,6 @@
     }
 
     private static void error(String msg, Exception e) {
-        System.out.println(msg);
         Log.e(TAG, msg);
         if (e != null) {
             Log.e(TAG, Log.getStackTraceString(e));
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d71573f..c4193f6 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1473,7 +1473,7 @@
         ClearDataObserver obs = new ClearDataObserver();
         try {
             mPm.freeStorageAndNotify(volumeUuid, sizeVal,
-                    StorageManager.FLAG_ALLOCATE_DEFY_RESERVED, obs);
+                    StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
             synchronized (obs) {
                 while (!obs.finished) {
                     try {
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 445665e..6ded246 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -33,17 +33,24 @@
 #include <ui/DisplayInfo.h>
 #include <ui/PixelFormat.h>
 
+#include <system/graphics.h>
+
 // TODO: Fix Skia.
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 #include <SkImageEncoder.h>
 #include <SkData.h>
+#include <SkColorSpace.h>
 #pragma GCC diagnostic pop
 
 using namespace android;
 
 static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
 
+#define COLORSPACE_UNKNOWN    0
+#define COLORSPACE_SRGB       1
+#define COLORSPACE_DISPLAY_P3 2
+
 static void usage(const char* pname)
 {
     fprintf(stderr,
@@ -67,6 +74,31 @@
     }
 }
 
+static sk_sp<SkColorSpace> dataSpaceToColorSpace(android_dataspace d)
+{
+    switch (d) {
+        case HAL_DATASPACE_V0_SRGB:
+            return SkColorSpace::MakeSRGB();
+        case HAL_DATASPACE_DISPLAY_P3:
+            return SkColorSpace::MakeRGB(
+                    SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+        default:
+            return nullptr;
+    }
+}
+
+static uint32_t dataSpaceToInt(android_dataspace d)
+{
+    switch (d) {
+        case HAL_DATASPACE_V0_SRGB:
+            return COLORSPACE_SRGB;
+        case HAL_DATASPACE_DISPLAY_P3:
+            return COLORSPACE_DISPLAY_P3;
+        default:
+            return COLORSPACE_UNKNOWN;
+    }
+}
+
 static status_t notifyMediaScanner(const char* fileName) {
     String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://");
     cmd.append(fileName);
@@ -81,13 +113,6 @@
 
 int main(int argc, char** argv)
 {
-    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
-    // not allowed to spawn any additional threads, but we still spawn
-    // a binder thread from userspace when we call startThreadPool().
-    // See b/36066697 for rationale
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-
     const char* pname = argv[0];
     bool png = false;
     int32_t displayId = DEFAULT_DISPLAY_ID;
@@ -136,6 +161,7 @@
 
     void const* base = NULL;
     uint32_t w, s, h, f;
+    android_dataspace d;
     size_t size = 0;
 
     // Maps orientations from DisplayInfo to ISurfaceComposer
@@ -146,11 +172,19 @@
         ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270
     };
 
+    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
+    // not allowed to spawn any additional threads, but we still spawn
+    // a binder thread from userspace when we call startThreadPool().
+    // See b/36066697 for rationale
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+
     ScreenshotClient screenshot;
     sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
     if (display == NULL) {
         fprintf(stderr, "Unable to get handle for display %d\n", displayId);
-        return 1;
+        // b/36066697: Avoid running static destructors.
+        _exit(1);
     }
 
     Vector<DisplayInfo> configs;
@@ -159,7 +193,8 @@
     if (static_cast<size_t>(activeConfig) >= configs.size()) {
         fprintf(stderr, "Active config %d not inside configs (size %zu)\n",
                 activeConfig, configs.size());
-        return 1;
+        // b/36066697: Avoid running static destructors.
+        _exit(1);
     }
     uint8_t displayOrientation = configs[activeConfig].orientation;
     uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
@@ -174,13 +209,15 @@
         h = screenshot.getHeight();
         s = screenshot.getStride();
         f = screenshot.getFormat();
+        d = screenshot.getDataSpace();
         size = screenshot.getSize();
     }
 
     if (base != NULL) {
         if (png) {
             const SkImageInfo info =
-                SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType);
+                SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
+                    dataSpaceToColorSpace(d));
             SkPixmap pixmap(info, base, s * bytesPerPixel(f));
             struct FDWStream final : public SkWStream {
               size_t fBytesWritten = 0;
@@ -197,9 +234,11 @@
                 notifyMediaScanner(fn);
             }
         } else {
+            uint32_t c = dataSpaceToInt(d);
             write(fd, &w, 4);
             write(fd, &h, 4);
             write(fd, &f, 4);
+            write(fd, &c, 4);
             size_t Bpp = bytesPerPixel(f);
             for (size_t y=0 ; y<h ; y++) {
                 write(fd, base, w*Bpp);
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index b765866..8fb1b7b 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -41,6 +41,7 @@
         "set-persistent-vr-mode-enabled";
     private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES =
         "set-display-props";
+    private static final String COMMAND_ENABLE_VD = "enable-virtual-display";
 
     private IVrManager mVrService;
 
@@ -49,7 +50,8 @@
         out.println(
                 "usage: vr [subcommand]\n" +
                 "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
-                "usage: vr set-display-props [width] [height] [dpi]\n"
+                "usage: vr set-display-props [width] [height] [dpi]\n" +
+                "usage: vr enable-virtual-display [true|false]\n"
                 );
     }
 
@@ -69,6 +71,9 @@
             case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
                 runSetPersistentVrModeEnabled();
                 break;
+            case COMMAND_ENABLE_VD:
+                runEnableVd();
+                break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
@@ -94,6 +99,23 @@
         }
     }
 
+    private void runEnableVd() throws RemoteException {
+        Vr2dDisplayProperties.Builder builder = new Vr2dDisplayProperties.Builder();
+
+        String value = nextArgRequired();
+        if ("true".equals(value)) {
+            builder.setEnabled(true);
+        } else if ("false".equals(value)) {
+            builder.setEnabled(false);
+        } // Don't do anything if not exactly true/false
+
+        try {
+            mVrService.setVr2dDisplayProperties(builder.build());
+        } catch (RemoteException re) {
+            System.err.println("Error: Can't enable (" + value +") virtual display" + re);
+        }
+    }
+
     private void runSetPersistentVrModeEnabled() throws RemoteException {
         String enableStr = nextArg();
         boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/config/compiled-classes-phone b/config/compiled-classes-phone
index 063276d..92c423a 100644
--- a/config/compiled-classes-phone
+++ b/config/compiled-classes-phone
@@ -441,7 +441,6 @@
 android.app.ResourcesManager$ActivityResources
 android.app.ResultInfo
 android.app.ResultInfo$1
-android.app.RetailDemoModeServiceInternal
 android.app.SearchableInfo
 android.app.SearchableInfo$1
 android.app.Service
@@ -3115,6 +3114,7 @@
 android.os.-$Lambda$-dncxFEc2F2bgG2fsIoC6FC6WNE$1
 android.os.-$Lambda$6x30vPJhBKUfNY8tswxuZo3DCe0
 android.os.AsyncResult
+android.os.AsyncTask
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 854e531..00d6657 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1667,6 +1667,8 @@
         int childrenSize = parent.mChildNodes.size();
         for (int i = 0; i < childrenSize; i++) {
             Node child = parent.mChildNodes.get(i);
+            child.mTotalDuration = child.mAnimation.getTotalDuration();  // Update cached duration.
+
             int index = visited.indexOf(child);
             if (index >= 0) {
                 // Child has been visited, cycle found. Mark all the nodes in the cycle.
@@ -1693,9 +1695,8 @@
                         child.mStartTime = parent.mEndTime;
                     }
 
-                    long duration = child.mAnimation.getTotalDuration();
-                    child.mEndTime = duration == DURATION_INFINITE ?
-                            DURATION_INFINITE : child.mStartTime + duration;
+                    child.mEndTime = child.mTotalDuration == DURATION_INFINITE
+                            ? DURATION_INFINITE : child.mStartTime + child.mTotalDuration;
                 }
             }
             updatePlayTime(child, visited);
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
index dd712a6..3f9064e 100644
--- a/core/java/android/annotation/IntDef.java
+++ b/core/java/android/annotation/IntDef.java
@@ -19,7 +19,7 @@
 import java.lang.annotation.Target;
 
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 /**
  * Denotes that the annotated element of integer type, represents
@@ -48,7 +48,7 @@
  *
  * @hide
  */
-@Retention(CLASS)
+@Retention(SOURCE)
 @Target({ANNOTATION_TYPE})
 public @interface IntDef {
     /** Defines the constant prefix for this element */
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
index 8c8d5d8..d5157c3 100644
--- a/core/java/android/annotation/StringDef.java
+++ b/core/java/android/annotation/StringDef.java
@@ -19,7 +19,7 @@
 import java.lang.annotation.Target;
 
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 /**
  * Denotes that the annotated String element, represents a logical
@@ -43,7 +43,7 @@
  *
  * @hide
  */
-@Retention(CLASS)
+@Retention(SOURCE)
 @Target({ANNOTATION_TYPE})
 public @interface StringDef {
     /** Defines the allowed constants for this element */
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bc6e9cd..0ff3215 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6416,17 +6416,7 @@
      */
     @Deprecated
     public boolean requestVisibleBehind(boolean visible) {
-        if (!mResumed) {
-            // Do not permit paused or stopped activities to do this.
-            visible = false;
-        }
-        try {
-            mVisibleBehind = ActivityManager.getService()
-                    .requestVisibleBehind(mToken, visible) && visible;
-        } catch (RemoteException e) {
-            mVisibleBehind = false;
-        }
-        return mVisibleBehind;
+        return false;
     }
 
     /**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f398c8d..06dbe82 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -360,6 +360,13 @@
             FIRST_START_NON_FATAL_ERROR_CODE + 1;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+     * externally.
+     * @hide
+     */
+    public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
@@ -649,6 +656,9 @@
      */
     public static final int COMPAT_MODE_TOGGLE = 2;
 
+    private static final boolean DEVELOPMENT_FORCE_LOW_RAM =
+            SystemProperties.getBoolean("debug.force_low_ram", false);
+
     /** @hide */
     public static class StackId {
         /** Invalid stack ID. */
@@ -1108,7 +1118,20 @@
 
     /** @hide */
     public static boolean isLowRamDeviceStatic() {
-        return RoSystemProperties.CONFIG_LOW_RAM;
+        return RoSystemProperties.CONFIG_LOW_RAM ||
+                (Build.IS_DEBUGGABLE && DEVELOPMENT_FORCE_LOW_RAM);
+    }
+
+    /**
+     * Returns true if this is a small battery device. Exactly whether a device is considered to be
+     * small battery is ultimately up to the device configuration, but currently it generally means
+     * something in the class of a device with 1000 mAh or less. This is mostly intended to be used
+     * to determine whether certain features should be altered to account for a drastically smaller
+     * battery.
+     * @hide
+     */
+    public static boolean isSmallBatteryDevice() {
+        return RoSystemProperties.CONFIG_SMALL_BATTERY;
     }
 
     /**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4aac830..14ac726 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -29,8 +29,8 @@
 import android.content.ContentProvider;
 import android.content.Context;
 import android.content.IContentProvider;
-import android.content.Intent;
 import android.content.IIntentReceiver;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -91,6 +91,7 @@
 import android.provider.Downloads;
 import android.provider.FontsContract;
 import android.provider.Settings;
+import android.renderscript.RenderScriptCacheDir;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
 import android.util.AndroidRuntimeException;
@@ -114,7 +115,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-import android.renderscript.RenderScriptCacheDir;
 import android.webkit.WebView;
 
 import com.android.internal.annotations.GuardedBy;
@@ -127,8 +127,21 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.TrustedCertificateStore;
+
+import dalvik.system.BaseDexClassLoader;
+import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
+
 import com.google.android.collect.Lists;
 
+import libcore.io.DropBox;
+import libcore.io.EventLogger;
+import libcore.io.IoUtils;
+import libcore.net.event.NetworkEventDispatcher;
+
+import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -145,16 +158,6 @@
 import java.util.Objects;
 import java.util.TimeZone;
 
-import libcore.io.DropBox;
-import libcore.io.EventLogger;
-import libcore.io.IoUtils;
-import libcore.net.event.NetworkEventDispatcher;
-import dalvik.system.BaseDexClassLoader;
-import dalvik.system.CloseGuard;
-import dalvik.system.VMDebug;
-import dalvik.system.VMRuntime;
-import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
-
 final class RemoteServiceException extends AndroidRuntimeException {
     public RemoteServiceException(String msg) {
         super(msg);
@@ -2358,13 +2361,13 @@
                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                         memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
+                        memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut,
                         nativeMax, nativeAllocated, nativeFree);
                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                         memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
-                        memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
+                        memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut,
                         dalvikMax, dalvikAllocated, dalvikFree);
             } else {
                 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
@@ -2675,8 +2678,14 @@
         Activity activity = null;
         try {
             java.lang.ClassLoader cl = appContext.getClassLoader();
-            activity = mInstrumentation.newActivity(
-                    cl, component.getClassName(), r.intent);
+            if (appContext.getApplicationContext() instanceof Application) {
+                activity = ((Application) appContext.getApplicationContext())
+                        .instantiateActivity(cl, component.getClassName(), r.intent);
+            }
+            if (activity == null) {
+                activity = mInstrumentation.newActivity(
+                        cl, component.getClassName(), r.intent);
+            }
             StrictMode.incrementExpectedActivityCount(activity.getClass());
             r.intent.setExtrasClassLoader(cl);
             r.intent.prepareToEnterProcess();
@@ -2857,6 +2866,9 @@
             TAG, "Handling launch of " + r);
 
         // Initialize before creating the activity
+        if (!ThreadedRenderer.sRendererDisabled) {
+            GraphicsEnvironment.earlyInitEGL();
+        }
         WindowManagerGlobal.initialize();
 
         Activity a = performLaunchActivity(r, customIntent);
@@ -3198,7 +3210,8 @@
             data.intent.setExtrasClassLoader(cl);
             data.intent.prepareToEnterProcess();
             data.setExtrasClassLoader(cl);
-            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
+            receiver = instantiate(cl, component, data.intent, app,
+                    Application::instantiateReceiver);
         } catch (Exception e) {
             if (DEBUG_BROADCAST) Slog.i(TAG,
                     "Finishing failed broadcast to " + data.intent.getComponent());
@@ -3286,12 +3299,13 @@
             } else {
                 try {
                     if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
+                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
 
                     java.lang.ClassLoader cl = packageInfo.getClassLoader();
-                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
+                    agent = instantiate(cl, classname, context,
+                            Application::instantiateBackupAgent);
 
                     // set up the agent's context
-                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
                     context.setOuterContext(agent);
                     agent.attach(context);
 
@@ -3351,9 +3365,12 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
         Service service = null;
+        Application app = null;
         try {
+            app = packageInfo.makeApplication(false, mInstrumentation);
             java.lang.ClassLoader cl = packageInfo.getClassLoader();
-            service = (Service) cl.loadClass(data.info.name).newInstance();
+            service = instantiate(cl, data.info.name, data.intent, app,
+                    Application::instantiateService);
         } catch (Exception e) {
             if (!mInstrumentation.onException(service, e)) {
                 throw new RuntimeException(
@@ -3368,7 +3385,6 @@
             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
             context.setOuterContext(service);
 
-            Application app = packageInfo.makeApplication(false, mInstrumentation);
             service.attach(context, this, data.info.name, data.token, app,
                     ActivityManager.getService());
             service.onCreate();
@@ -4908,7 +4924,8 @@
             // If the new config is the same as the config this Activity is already running with and
             // the override config also didn't change, then don't bother calling
             // onConfigurationChanged.
-            int diff = activity.mCurrentConfig.diff(newConfig);
+            final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
+
             if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken,
                     amOverrideConfig)) {
                 // Always send the task-level config changes. For system-level configuration, if
@@ -4996,6 +5013,14 @@
 
         int configDiff = 0;
 
+        // This flag tracks whether the new configuration is fundamentally equivalent to the
+        // existing configuration. This is necessary to determine whether non-activity
+        // callbacks should receive notice when the only changes are related to non-public fields.
+        // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag
+        // as that method uses the same check on the activity config override as well.
+        final boolean equivalent = config != null && mConfiguration != null
+                && (0 == mConfiguration.diffPublicOnly(config));
+
         synchronized (mResourcesManager) {
             if (mPendingConfiguration != null) {
                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
@@ -5052,7 +5077,7 @@
                     Activity a = (Activity) cb;
                     performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
                             config);
-                } else {
+                } else if (!equivalent) {
                     performConfigurationChanged(cb, config);
                 }
             }
@@ -5342,26 +5367,45 @@
         WindowManagerGlobal.getInstance().trimMemory(level);
     }
 
-    private void setupGraphicsSupport(Context context, File cacheDir) {
-        if (Process.isIsolated()) {
-            // Isolated processes aren't going to do UI.
-            return;
-        }
+    private void setupGraphicsSupport(Context context) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
-        try {
-            int uid = Process.myUid();
-            String[] packages = getPackageManager().getPackagesForUid(uid);
 
-            if (packages != null) {
-                ThreadedRenderer.setupDiskCache(cacheDir);
-                RenderScriptCacheDir.setupDiskCache(cacheDir);
-                GraphicsEnvironment.setupGraphicsEnvironment(context);
+        // The system package doesn't have real data directories, so don't set up cache paths.
+        if (!"android".equals(context.getPackageName())) {
+            // This cache location probably points at credential-encrypted
+            // storage which may not be accessible yet; assign it anyway instead
+            // of pointing at device-encrypted storage.
+            final File cacheDir = context.getCacheDir();
+            if (cacheDir != null) {
+                // Provide a usable directory for temporary files
+                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+            } else {
+                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
+                        + "due to missing cache directory");
             }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+            // Setup a location to store generated/compiled graphics code.
+            final Context deviceContext = context.createDeviceProtectedStorageContext();
+            final File codeCacheDir = deviceContext.getCodeCacheDir();
+            if (codeCacheDir != null) {
+                try {
+                    int uid = Process.myUid();
+                    String[] packages = getPackageManager().getPackagesForUid(uid);
+                    if (packages != null) {
+                        ThreadedRenderer.setupDiskCache(codeCacheDir);
+                        RenderScriptCacheDir.setupDiskCache(codeCacheDir);
+                    }
+                } catch (RemoteException e) {
+                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+                    throw e.rethrowFromSystemServer();
+                }
+            } else {
+                Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory");
+            }
         }
+
+        GraphicsEnvironment.chooseDriver(context);
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     private void updateDefaultDensity() {
@@ -5448,15 +5492,6 @@
         android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                 UserHandle.myUserId());
 
-        if (data.persistent) {
-            // Persistent processes on low-memory devices do not get to
-            // use hardware accelerated drawing, since this can add too much
-            // overhead to the process.
-            if (!ActivityManager.isHighEndGfx()) {
-                ThreadedRenderer.disable(false);
-            }
-        }
-
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
         }
@@ -5643,27 +5678,8 @@
         updateLocaleListFromAppContext(appContext,
                 mResourcesManager.getConfiguration().getLocales());
 
-        if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
-            // This cache location probably points at credential-encrypted
-            // storage which may not be accessible yet; assign it anyway instead
-            // of pointing at device-encrypted storage.
-            final File cacheDir = appContext.getCacheDir();
-            if (cacheDir != null) {
-                // Provide a usable directory for temporary files
-                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
-            } else {
-                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
-                        + "due to missing cache directory");
-            }
-
-            // Setup a location to store generated/compiled graphics code.
-            final Context deviceContext = appContext.createDeviceProtectedStorageContext();
-            final File codeCacheDir = deviceContext.getCodeCacheDir();
-            if (codeCacheDir != null) {
-                setupGraphicsSupport(appContext, codeCacheDir);
-            } else {
-                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
-            }
+        if (!Process.isIsolated()) {
+            setupGraphicsSupport(appContext);
         }
 
         // If we use profiles, setup the dex reporter to notify package manager
@@ -5694,8 +5710,8 @@
 
             try {
                 final ClassLoader cl = instrContext.getClassLoader();
-                mInstrumentation = (Instrumentation)
-                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
+                mInstrumentation = instantiate(cl, data.instrumentationName.getClassName(),
+                        instrContext, Application::instantiateInstrumentation);
             } catch (Exception e) {
                 throw new RuntimeException(
                     "Unable to instantiate instrumentation "
@@ -6240,8 +6256,8 @@
 
             try {
                 final java.lang.ClassLoader cl = c.getClassLoader();
-                localProvider = (ContentProvider)cl.
-                    loadClass(info.name).newInstance();
+                localProvider = instantiate(cl, info.name, context,
+                        Application::instantiateProvider);
                 provider = localProvider.getIContentProvider();
                 if (provider == null) {
                     Slog.e(TAG, "Failed to instantiate class " +
@@ -6440,6 +6456,49 @@
         }
     }
 
+    private <T> T instantiate(ClassLoader cl, String className, Context c,
+            Instantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        Application app = getApp(c);
+        if (app != null) {
+            T a = instantiator.instantiate(app, cl, className);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private <T> T instantiate(ClassLoader cl, String className, Intent intent, Context c,
+            IntentInstantiator<T> instantiator)
+            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        Application app = getApp(c);
+        if (app != null) {
+            T a = instantiator.instantiate(app, cl, className, intent);
+            if (a != null) return a;
+        }
+        return (T) cl.loadClass(className).newInstance();
+    }
+
+    private Application getApp(Context c) {
+        // We need this shortcut to avoid actually calling getApplicationContext() on an Application
+        // because the Application may not return itself for getApplicationContext() because the
+        // API doesn't enforce it.
+        if (c instanceof Application) return (Application) c;
+        if (c.getApplicationContext() instanceof Application) {
+            return (Application) c.getApplicationContext();
+        }
+        return null;
+    }
+
+    private interface Instantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
+    private interface IntentInstantiator<T> {
+        T instantiate(Application app, ClassLoader cl, String className, Intent intent)
+                throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+    }
+
     private static class EventLoggingReporter implements EventLogger.Reporter {
         @Override
         public void report (int code, Object... list) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e672ada..b331d84 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1947,4 +1947,13 @@
     public void finishOp(int op) {
         finishOp(op, Process.myUid(), mContext.getOpPackageName());
     }
+
+    /** @hide */
+    public boolean isOperationActive(int code, int uid, String packageName) {
+        try {
+            return mService.isOperationActive(code, uid, packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 156df36..7fb5e2e 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -16,17 +16,20 @@
 
 package android.app;
 
-import java.util.ArrayList;
-
 import android.annotation.CallSuper;
+import android.app.backup.BackupAgent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks;
 import android.content.ComponentCallbacks2;
+import android.content.ContentProvider;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
 
+import java.util.ArrayList;
+
 /**
  * Base class for maintaining global application state. You can provide your own
  * implementation by creating a subclass and specifying the fully-qualified name
@@ -289,4 +292,79 @@
             }
         }
     }
+
+    /**
+     * Allows application to override the creation of activities. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of receivers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of services. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @param intent Intent creating the class.
+     * @hide
+     */
+    public Service instantiateService(ClassLoader cl, String className, Intent intent) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of providers. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public ContentProvider instantiateProvider(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of backup agents. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public BackupAgent instantiateBackupAgent(ClassLoader cl, String className) {
+        return null;
+    }
+
+    /**
+     * Allows application to override the creation of instrumentation. This can be used to
+     * perform things such as dependency injection or class loader changes to these
+     * classes. Return null to use the default creation flow.
+     * @param cl The default classloader to use for instantiation.
+     * @param className The class to be instantiated.
+     * @hide
+     */
+    public Instrumentation instantiateInstrumentation(ClassLoader cl, String className) {
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e5c4208..7fc9a69 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -78,6 +78,10 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
 import android.util.ArrayMap;
 import android.util.IconDrawableFactory;
 import android.util.LauncherIcons;
@@ -281,7 +285,8 @@
     public PermissionInfo getPermissionInfo(String name, int flags)
             throws NameNotFoundException {
         try {
-            PermissionInfo pi = mPM.getPermissionInfo(name, flags);
+            PermissionInfo pi = mPM.getPermissionInfo(name,
+                    mContext.getOpPackageName(), flags);
             if (pi != null) {
                 return pi;
             }
@@ -2674,4 +2679,78 @@
             throw e.rethrowAsRuntimeException();
         }
     }
+
+    private static class DexModuleRegisterResult {
+        final String dexModulePath;
+        final boolean success;
+        final String message;
+
+        private DexModuleRegisterResult(String dexModulePath, boolean success, String message) {
+            this.dexModulePath = dexModulePath;
+            this.success = success;
+            this.message = message;
+        }
+    }
+
+    private static class DexModuleRegisterCallbackDelegate
+            extends android.content.pm.IDexModuleRegisterCallback.Stub
+            implements Handler.Callback {
+        private static final int MSG_DEX_MODULE_REGISTERED = 1;
+        private final DexModuleRegisterCallback callback;
+        private final Handler mHandler;
+
+        DexModuleRegisterCallbackDelegate(@NonNull DexModuleRegisterCallback callback) {
+            this.callback = callback;
+            mHandler = new Handler(Looper.getMainLooper(), this);
+        }
+
+        @Override
+        public void onDexModuleRegistered(@NonNull String dexModulePath, boolean success,
+                @Nullable String message)throws RemoteException {
+            mHandler.obtainMessage(MSG_DEX_MODULE_REGISTERED,
+                    new DexModuleRegisterResult(dexModulePath, success, message)).sendToTarget();
+        }
+
+        @Override
+        public boolean handleMessage(Message msg) {
+            if (msg.what != MSG_DEX_MODULE_REGISTERED) {
+                return false;
+            }
+            DexModuleRegisterResult result = (DexModuleRegisterResult)msg.obj;
+            callback.onDexModuleRegistered(result.dexModulePath, result.success, result.message);
+            return true;
+        }
+    }
+
+    @Override
+    public void registerDexModule(@NonNull String dexModule,
+            @Nullable DexModuleRegisterCallback callback) {
+        // Check if this is a shared module by looking if the others can read it.
+        boolean isSharedModule = false;
+        try {
+            StructStat stat = Os.stat(dexModule);
+            if ((OsConstants.S_IROTH & stat.st_mode) != 0) {
+                isSharedModule = true;
+            }
+        } catch (ErrnoException e) {
+            callback.onDexModuleRegistered(dexModule, false,
+                    "Could not get stat the module file: " + e.getMessage());
+            return;
+        }
+
+        // Module path is ok.
+        // Create the callback delegate to be passed to package manager service.
+        DexModuleRegisterCallbackDelegate callbackDelegate = null;
+        if (callback != null) {
+            callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
+        }
+
+        // Invoke the package manager service.
+        try {
+            mPM.registerDexModule(mContext.getPackageName(), dexModule,
+                    isSharedModule, callbackDelegate);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 3ea0c83..318c7ac 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,7 +63,6 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -90,6 +89,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteOrder;
+import java.util.ArrayList;
 import java.util.Objects;
 
 class ReceiverRestrictedContext extends ContextWrapper {
@@ -374,27 +374,26 @@
         // STOPSHIP: fix buggy apps
         if (SystemProperties.getBoolean("fw.ignore_buggy", false)) return false;
         if ("com.google.android.tts".equals(getApplicationInfo().packageName)) return true;
-        if ("com.breel.geswallpapers".equals(getApplicationInfo().packageName)) return true;
         return false;
     }
 
     @Override
     public SharedPreferences getSharedPreferences(File file, int mode) {
-        checkMode(mode);
-        if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
-            if (isCredentialProtectedStorage()
-                    && !getSystemService(StorageManager.class).isUserKeyUnlocked(
-                            UserHandle.myUserId())
-                    && !isBuggy()) {
-                throw new IllegalStateException("SharedPreferences in credential encrypted "
-                        + "storage are not available until after user is unlocked");
-            }
-        }
         SharedPreferencesImpl sp;
         synchronized (ContextImpl.class) {
             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
             sp = cache.get(file);
             if (sp == null) {
+                checkMode(mode);
+                if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
+                    if (isCredentialProtectedStorage()
+                            && !getSystemService(StorageManager.class).isUserKeyUnlocked(
+                            UserHandle.myUserId())
+                            && !isBuggy()) {
+                        throw new IllegalStateException("SharedPreferences in credential encrypted "
+                                + "storage are not available until after user is unlocked");
+                    }
+                }
                 sp = new SharedPreferencesImpl(file, mode);
                 cache.put(file, sp);
                 return sp;
@@ -425,6 +424,26 @@
         return packagePrefs;
     }
 
+    @Override
+    public void reloadSharedPreferences() {
+        // Build the list of all per-context impls (i.e. caches) we know about
+        ArrayList<SharedPreferencesImpl> spImpls = new ArrayList<>();
+        synchronized (ContextImpl.class) {
+            final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
+            for (int i = 0; i < cache.size(); i++) {
+                final SharedPreferencesImpl sp = cache.valueAt(i);
+                if (sp != null) {
+                    spImpls.add(sp);
+                }
+            }
+        }
+
+        // Issue the reload outside the cache lock
+        for (int i = 0; i < spImpls.size(); i++) {
+            spImpls.get(i).startReloadIfChangedUnexpectedly();
+        }
+    }
+
     /**
      * Try our best to migrate all files from source to target that match
      * requested prefix.
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index c2fd007..66dc6a1 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -60,114 +60,6 @@
 import java.io.PrintWriter;
 import java.lang.reflect.InvocationTargetException;
 
-final class FragmentState implements Parcelable {
-    final String mClassName;
-    final int mIndex;
-    final boolean mFromLayout;
-    final int mFragmentId;
-    final int mContainerId;
-    final String mTag;
-    final boolean mRetainInstance;
-    final boolean mDetached;
-    final Bundle mArguments;
-    final boolean mHidden;
-
-    Bundle mSavedFragmentState;
-
-    Fragment mInstance;
-
-    public FragmentState(Fragment frag) {
-        mClassName = frag.getClass().getName();
-        mIndex = frag.mIndex;
-        mFromLayout = frag.mFromLayout;
-        mFragmentId = frag.mFragmentId;
-        mContainerId = frag.mContainerId;
-        mTag = frag.mTag;
-        mRetainInstance = frag.mRetainInstance;
-        mDetached = frag.mDetached;
-        mArguments = frag.mArguments;
-        mHidden = frag.mHidden;
-    }
-
-    public FragmentState(Parcel in) {
-        mClassName = in.readString();
-        mIndex = in.readInt();
-        mFromLayout = in.readInt() != 0;
-        mFragmentId = in.readInt();
-        mContainerId = in.readInt();
-        mTag = in.readString();
-        mRetainInstance = in.readInt() != 0;
-        mDetached = in.readInt() != 0;
-        mArguments = in.readBundle();
-        mHidden = in.readInt() != 0;
-        mSavedFragmentState = in.readBundle();
-    }
-
-    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
-            Fragment parent, FragmentManagerNonConfig childNonConfig) {
-        if (mInstance == null) {
-            final Context context = host.getContext();
-            if (mArguments != null) {
-                mArguments.setClassLoader(context.getClassLoader());
-            }
-
-            if (container != null) {
-                mInstance = container.instantiate(context, mClassName, mArguments);
-            } else {
-                mInstance = Fragment.instantiate(context, mClassName, mArguments);
-            }
-
-            if (mSavedFragmentState != null) {
-                mSavedFragmentState.setClassLoader(context.getClassLoader());
-                mInstance.mSavedFragmentState = mSavedFragmentState;
-            }
-            mInstance.setIndex(mIndex, parent);
-            mInstance.mFromLayout = mFromLayout;
-            mInstance.mRestored = true;
-            mInstance.mFragmentId = mFragmentId;
-            mInstance.mContainerId = mContainerId;
-            mInstance.mTag = mTag;
-            mInstance.mRetainInstance = mRetainInstance;
-            mInstance.mDetached = mDetached;
-            mInstance.mHidden = mHidden;
-            mInstance.mFragmentManager = host.mFragmentManager;
-            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
-                    "Instantiated fragment " + mInstance);
-        }
-        mInstance.mChildNonConfig = childNonConfig;
-        return mInstance;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mClassName);
-        dest.writeInt(mIndex);
-        dest.writeInt(mFromLayout ? 1 : 0);
-        dest.writeInt(mFragmentId);
-        dest.writeInt(mContainerId);
-        dest.writeString(mTag);
-        dest.writeInt(mRetainInstance ? 1 : 0);
-        dest.writeInt(mDetached ? 1 : 0);
-        dest.writeBundle(mArguments);
-        dest.writeInt(mHidden ? 1 : 0);
-        dest.writeBundle(mSavedFragmentState);
-    }
-
-    public static final Parcelable.Creator<FragmentState> CREATOR
-            = new Parcelable.Creator<FragmentState>() {
-        public FragmentState createFromParcel(Parcel in) {
-            return new FragmentState(in);
-        }
-
-        public FragmentState[] newArray(int size) {
-            return new FragmentState[size];
-        }
-    };
-}
-
 /**
  * A Fragment is a piece of an application's user interface or behavior
  * that can be placed in an {@link Activity}.  Interaction with fragments
@@ -984,7 +876,7 @@
 
     /**
      * Return true if the fragment is currently visible to the user.  This means
-     * it: (1) has been added, (2) has its view attached to the window, and 
+     * it: (1) has been added, (2) has its view attached to the window, and
      * (3) is not hidden.
      */
     final public boolean isVisible() {
@@ -1463,7 +1355,7 @@
      * declaration for the styleable used here is:</p>
      *
      * {@sample development/samples/ApiDemos/res/values/attrs.xml fragment_arguments}
-     * 
+     *
      * <p>The fragment can then be declared within its activity's content layout
      * through a tag like this:</p>
      *
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 6af1f12..6cb987c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -670,7 +670,7 @@
 
     int mNextFragmentIndex = 0;
     SparseArray<Fragment> mActive;
-    ArrayList<Fragment> mAdded;
+    final ArrayList<Fragment> mAdded = new ArrayList<>();
     ArrayList<BackStackRecord> mBackStack;
     ArrayList<Fragment> mCreatedMenus;
     
@@ -925,7 +925,7 @@
 
     @Override
     public List<Fragment> getFragments() {
-        if (mAdded == null) {
+        if (mAdded.isEmpty()) {
             return Collections.EMPTY_LIST;
         }
         synchronized (mAdded) {
@@ -988,15 +988,17 @@
             }
         }
 
-        if (mAdded != null) {
-            N = mAdded.size();
-            if (N > 0) {
-                writer.print(prefix); writer.println("Added Fragments:");
-                for (int i=0; i<N; i++) {
-                    Fragment f = mAdded.get(i);
-                    writer.print(prefix); writer.print("  #"); writer.print(i);
-                            writer.print(": "); writer.println(f.toString());
-                }
+        N = mAdded.size();
+        if (N > 0) {
+            writer.print(prefix);
+            writer.println("Added Fragments:");
+            for (int i = 0; i < N; i++) {
+                Fragment f = mAdded.get(i);
+                writer.print(prefix);
+                writer.print("  #");
+                writer.print(i);
+                writer.print(": ");
+                writer.println(f.toString());
             }
         }
 
@@ -1604,14 +1606,12 @@
             boolean loadersRunning = false;
 
             // Must add them in the proper order. mActive fragments may be out of order
-            if (mAdded != null) {
-                final int numAdded = mAdded.size();
-                for (int i = 0; i < numAdded; i++) {
-                    Fragment f = mAdded.get(i);
-                    moveFragmentToExpectedState(f);
-                    if (f.mLoaderManager != null) {
-                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
-                    }
+            final int numAdded = mAdded.size();
+            for (int i = 0; i < numAdded; i++) {
+                Fragment f = mAdded.get(i);
+                moveFragmentToExpectedState(f);
+                if (f.mLoaderManager != null) {
+                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                 }
             }
 
@@ -1677,9 +1677,6 @@
     }
     
     public void addFragment(Fragment fragment, boolean moveToStateNow) {
-        if (mAdded == null) {
-            mAdded = new ArrayList<Fragment>();
-        }
         if (DEBUG) Log.v(TAG, "add: " + fragment);
         makeActive(fragment);
         if (!fragment.mDetached) {
@@ -1715,10 +1712,8 @@
                     throw new IllegalStateException("Fragment not added: " + fragment);
                 }
             }
-            if (mAdded != null) {
-                synchronized (mAdded) {
-                    mAdded.remove(fragment);
-                }
+            synchronized (mAdded) {
+                mAdded.remove(fragment);
             }
             if (fragment.mHasMenu && fragment.mMenuVisible) {
                 mNeedMenuInvalidate = true;
@@ -1766,11 +1761,9 @@
             fragment.mDetached = true;
             if (fragment.mAdded) {
                 // We are not already in back stack, so need to remove the fragment.
-                if (mAdded != null) {
-                    if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
-                    synchronized (mAdded) {
-                        mAdded.remove(fragment);
-                    }
+                if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
+                synchronized (mAdded) {
+                    mAdded.remove(fragment);
                 }
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
@@ -1785,9 +1778,6 @@
         if (fragment.mDetached) {
             fragment.mDetached = false;
             if (!fragment.mAdded) {
-                if (mAdded == null) {
-                    mAdded = new ArrayList<Fragment>();
-                }
                 if (mAdded.contains(fragment)) {
                     throw new IllegalStateException("Fragment already added: " + fragment);
                 }
@@ -1804,13 +1794,11 @@
     }
 
     public Fragment findFragmentById(int id) {
-        if (mAdded != null) {
-            // First look through added fragments.
-            for (int i=mAdded.size()-1; i>=0; i--) {
-                Fragment f = mAdded.get(i);
-                if (f != null && f.mFragmentId == id) {
-                    return f;
-                }
+        // First look through added fragments.
+        for (int i = mAdded.size() - 1; i >= 0; i--) {
+            Fragment f = mAdded.get(i);
+            if (f != null && f.mFragmentId == id) {
+                return f;
             }
         }
         if (mActive != null) {
@@ -1826,7 +1814,7 @@
     }
     
     public Fragment findFragmentByTag(String tag) {
-        if (mAdded != null && tag != null) {
+        if (tag != null) {
             // First look through added fragments.
             for (int i=mAdded.size()-1; i>=0; i--) {
                 Fragment f = mAdded.get(i);
@@ -1846,7 +1834,7 @@
         }
         return null;
     }
-    
+
     public Fragment findFragmentByWho(String who) {
         if (mActive != null && who != null) {
             for (int i=mActive.size()-1; i>=0; i--) {
@@ -2166,9 +2154,7 @@
         } else {
             mTmpAddedFragments.clear();
         }
-        if (mAdded != null) {
-            mTmpAddedFragments.addAll(mAdded);
-        }
+        mTmpAddedFragments.addAll(mAdded);
         Fragment oldPrimaryNav = getPrimaryNavigationFragment();
         for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
             final BackStackRecord record = records.get(recordNum);
@@ -2408,7 +2394,7 @@
         }
         // We want to leave the fragment in the started state
         final int state = Math.min(mCurState, Fragment.STARTED);
-        final int numAdded = mAdded == null ? 0 : mAdded.size();
+        final int numAdded = mAdded.size();
         for (int i = 0; i < numAdded; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment.mState < state) {
@@ -2756,23 +2742,21 @@
         BackStackState[] backStack = null;
         
         // Build list of currently added fragments.
-        if (mAdded != null) {
-            N = mAdded.size();
-            if (N > 0) {
-                added = new int[N];
-                for (int i=0; i<N; i++) {
-                    added[i] = mAdded.get(i).mIndex;
-                    if (added[i] < 0) {
-                        throwException(new IllegalStateException(
-                                "Failure saving state: active " + mAdded.get(i)
-                                + " has cleared index: " + added[i]));
-                    }
-                    if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
-                            + ": " + mAdded.get(i));
+        N = mAdded.size();
+        if (N > 0) {
+            added = new int[N];
+            for (int i=0; i<N; i++) {
+                added[i] = mAdded.get(i).mIndex;
+                if (added[i] < 0) {
+                    throwException(new IllegalStateException(
+                            "Failure saving state: active " + mAdded.get(i)
+                            + " has cleared index: " + added[i]));
                 }
+                if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
+                        + ": " + mAdded.get(i));
             }
         }
-        
+
         // Now save back stack.
         if (mBackStack != null) {
             N = mBackStack.size();
@@ -2878,8 +2862,8 @@
         }
 
         // Build the list of currently added fragments.
+        mAdded.clear();
         if (fms.mAdded != null) {
-            mAdded = new ArrayList<Fragment>(fms.mAdded.length);
             for (int i=0; i<fms.mAdded.length; i++) {
                 Fragment f = mActive.get(fms.mAdded[i]);
                 if (f == null) {
@@ -2895,8 +2879,6 @@
                     mAdded.add(f);
                 }
             }
-        } else {
-            mAdded = null;
         }
         
         // Build the back stack.
@@ -2972,7 +2954,7 @@
     public void noteStateNotSaved() {
         mSavedNonConfig = null;
         mStateSaved = false;
-        final int addedCount = mAdded == null ? 0 : mAdded.size();
+        final int addedCount = mAdded.size();
         for (int i = 0; i < addedCount; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment != null) {
@@ -3049,9 +3031,6 @@
      */
     @Deprecated
     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3062,9 +3041,6 @@
 
     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
             Configuration newConfig) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3078,9 +3054,6 @@
      */
     @Deprecated
     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3091,9 +3064,6 @@
 
     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
             Configuration newConfig) {
-        if (mAdded == null) {
-            return;
-        }
         for (int i = mAdded.size() - 1; i >= 0; --i) {
             final Fragment f = mAdded.get(i);
             if (f != null) {
@@ -3103,34 +3073,28 @@
     }
 
     public void dispatchConfigurationChanged(Configuration newConfig) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performConfigurationChanged(newConfig);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performConfigurationChanged(newConfig);
             }
         }
     }
 
     public void dispatchLowMemory() {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performLowMemory();
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performLowMemory();
             }
         }
     }
 
     public void dispatchTrimMemory(int level) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performTrimMemory(level);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performTrimMemory(level);
             }
         }
     }
@@ -3138,21 +3102,19 @@
     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         boolean show = false;
         ArrayList<Fragment> newMenus = null;
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performCreateOptionsMenu(menu, inflater)) {
-                        show = true;
-                        if (newMenus == null) {
-                            newMenus = new ArrayList<Fragment>();
-                        }
-                        newMenus.add(f);
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performCreateOptionsMenu(menu, inflater)) {
+                    show = true;
+                    if (newMenus == null) {
+                        newMenus = new ArrayList<Fragment>();
                     }
+                    newMenus.add(f);
                 }
             }
         }
-        
+
         if (mCreatedMenus != null) {
             for (int i=0; i<mCreatedMenus.size(); i++) {
                 Fragment f = mCreatedMenus.get(i);
@@ -3169,13 +3131,11 @@
     
     public boolean dispatchPrepareOptionsMenu(Menu menu) {
         boolean show = false;
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performPrepareOptionsMenu(menu)) {
-                        show = true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performPrepareOptionsMenu(menu)) {
+                    show = true;
                 }
             }
         }
@@ -3183,13 +3143,11 @@
     }
     
     public boolean dispatchOptionsItemSelected(MenuItem item) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performOptionsItemSelected(item)) {
-                        return true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performOptionsItemSelected(item)) {
+                    return true;
                 }
             }
         }
@@ -3197,13 +3155,11 @@
     }
     
     public boolean dispatchContextItemSelected(MenuItem item) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    if (f.performContextItemSelected(item)) {
-                        return true;
-                    }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                if (f.performContextItemSelected(item)) {
+                    return true;
                 }
             }
         }
@@ -3211,12 +3167,10 @@
     }
     
     public void dispatchOptionsMenuClosed(Menu menu) {
-        if (mAdded != null) {
-            for (int i=0; i<mAdded.size(); i++) {
-                Fragment f = mAdded.get(i);
-                if (f != null) {
-                    f.performOptionsMenuClosed(menu);
-                }
+        for (int i = 0; i < mAdded.size(); i++) {
+            Fragment f = mAdded.get(i);
+            if (f != null) {
+                f.performOptionsMenuClosed(menu);
             }
         }
     }
diff --git a/core/java/android/app/FragmentState.java b/core/java/android/app/FragmentState.java
new file mode 100644
index 0000000..a61da3bb
--- /dev/null
+++ b/core/java/android/app/FragmentState.java
@@ -0,0 +1,137 @@
+/*
+ * 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.content.Context;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+final class FragmentState implements Parcelable {
+    final String mClassName;
+    final int mIndex;
+    final boolean mFromLayout;
+    final int mFragmentId;
+    final int mContainerId;
+    final String mTag;
+    final boolean mRetainInstance;
+    final boolean mDetached;
+    final Bundle mArguments;
+    final boolean mHidden;
+
+    Bundle mSavedFragmentState;
+
+    Fragment mInstance;
+
+    FragmentState(Fragment frag) {
+        mClassName = frag.getClass().getName();
+        mIndex = frag.mIndex;
+        mFromLayout = frag.mFromLayout;
+        mFragmentId = frag.mFragmentId;
+        mContainerId = frag.mContainerId;
+        mTag = frag.mTag;
+        mRetainInstance = frag.mRetainInstance;
+        mDetached = frag.mDetached;
+        mArguments = frag.mArguments;
+        mHidden = frag.mHidden;
+    }
+
+    FragmentState(Parcel in) {
+        mClassName = in.readString();
+        mIndex = in.readInt();
+        mFromLayout = in.readInt() != 0;
+        mFragmentId = in.readInt();
+        mContainerId = in.readInt();
+        mTag = in.readString();
+        mRetainInstance = in.readInt() != 0;
+        mDetached = in.readInt() != 0;
+        mArguments = in.readBundle();
+        mHidden = in.readInt() != 0;
+        mSavedFragmentState = in.readBundle();
+    }
+
+    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
+            Fragment parent, FragmentManagerNonConfig childNonConfig) {
+        if (mInstance == null) {
+            final Context context = host.getContext();
+            if (mArguments != null) {
+                mArguments.setClassLoader(context.getClassLoader());
+            }
+
+            if (container != null) {
+                mInstance = container.instantiate(context, mClassName, mArguments);
+            } else {
+                mInstance = Fragment.instantiate(context, mClassName, mArguments);
+            }
+
+            if (mSavedFragmentState != null) {
+                mSavedFragmentState.setClassLoader(context.getClassLoader());
+                mInstance.mSavedFragmentState = mSavedFragmentState;
+            }
+            mInstance.setIndex(mIndex, parent);
+            mInstance.mFromLayout = mFromLayout;
+            mInstance.mRestored = true;
+            mInstance.mFragmentId = mFragmentId;
+            mInstance.mContainerId = mContainerId;
+            mInstance.mTag = mTag;
+            mInstance.mRetainInstance = mRetainInstance;
+            mInstance.mDetached = mDetached;
+            mInstance.mHidden = mHidden;
+            mInstance.mFragmentManager = host.mFragmentManager;
+
+            if (FragmentManagerImpl.DEBUG) {
+                Log.v(FragmentManagerImpl.TAG, "Instantiated fragment " + mInstance);
+            }
+        }
+        mInstance.mChildNonConfig = childNonConfig;
+        return mInstance;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mClassName);
+        dest.writeInt(mIndex);
+        dest.writeInt(mFromLayout ? 1 : 0);
+        dest.writeInt(mFragmentId);
+        dest.writeInt(mContainerId);
+        dest.writeString(mTag);
+        dest.writeInt(mRetainInstance ? 1 : 0);
+        dest.writeInt(mDetached ? 1 : 0);
+        dest.writeBundle(mArguments);
+        dest.writeInt(mHidden ? 1 : 0);
+        dest.writeBundle(mSavedFragmentState);
+    }
+
+    public static final Parcelable.Creator<FragmentState> CREATOR =
+            new Parcelable.Creator<FragmentState>() {
+                @Override
+                public FragmentState createFromParcel(Parcel in) {
+                    return new FragmentState(in);
+                }
+
+                @Override
+                public FragmentState[] newArray(int size) {
+                    return new FragmentState[size];
+                }
+            };
+}
\ No newline at end of file
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 7640e75..b26117d 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -42,7 +42,8 @@
     WindowContentFrameStats getWindowContentFrameStats(int windowId);
     void clearWindowAnimationFrameStats();
     WindowAnimationFrameStats getWindowAnimationFrameStats();
-    void executeShellCommand(String command, in ParcelFileDescriptor fd);
+    void executeShellCommand(String command, in ParcelFileDescriptor sink,
+            in ParcelFileDescriptor source);
     void grantRuntimePermission(String packageName, String permission, int userId);
     void revokeRuntimePermission(String packageName, String permission, int userId);
 
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 75a5bf7..7ac2223 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -22,6 +22,7 @@
 import android.app.IWallpaperManagerCallback;
 import android.app.WallpaperInfo;
 import android.content.ComponentName;
+import android.app.WallpaperColors;
 
 /** @hide */
 interface IWallpaperManager {
@@ -135,4 +136,23 @@
      * wallpaper content has changed.
      */
     boolean setLockWallpaperCallback(IWallpaperManagerCallback cb);
+
+    /**
+     * Returns the colors used by the lock screen or system wallpaper.
+     *
+     * @param which either {@link WallpaperManager#FLAG_LOCK}
+     * or {@link WallpaperManager#FLAG_SYSTEM}
+     * @return colors of chosen wallpaper
+     */
+    WallpaperColors getWallpaperColors(int which, int userId);
+
+    /**
+     * Register a callback to receive color updates
+     */
+    void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
+
+    /**
+     * Unregister a callback that was receiving color updates
+     */
+    void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId);
 }
diff --git a/core/java/android/app/IWallpaperManagerCallback.aidl b/core/java/android/app/IWallpaperManagerCallback.aidl
index 991b2bc..ea0ceab 100644
--- a/core/java/android/app/IWallpaperManagerCallback.aidl
+++ b/core/java/android/app/IWallpaperManagerCallback.aidl
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.app.WallpaperColors;
+
 /**
  * Callback interface used by IWallpaperManager to send asynchronous 
  * notifications back to its clients.  Note that this is a
@@ -28,4 +30,10 @@
      * Called when the wallpaper has changed
      */
     void onWallpaperChanged();
+
+    /**
+     * Called when wallpaper colors change
+     */
+    void onWallpaperColorsChanged(in WallpaperColors colors, int which, int userId);
+
 }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index dbea349..467fc95 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -816,7 +816,7 @@
      * returned.  If the timeout expires, a null object is returned. 
      *
      * @param monitor The ActivityMonitor to wait for.
-     * @param timeOut The timeout value in secs.
+     * @param timeOut The timeout value in milliseconds.
      *
      * @return The Activity object that matched the monitor.
      */
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index e4a22c4..95ec24c 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -43,6 +43,13 @@
  * long as necessary (and will not block the application's main loop), but
  * only one request will be processed at a time.
  *
+ * <p class="note"><b>Note:</b> IntentService is subject to all the
+ * <a href="/preview/features/background.html">background execution limits</a>
+ * imposed with Android 8.0 (API level 26). In most cases, you are better off
+ * using {@link android.support.v4.app.JobIntentService}, which uses jobs
+ * instead of services when running on Android 8.0 or higher.
+ * </p>
+ *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For a detailed discussion about how to create services, read the
@@ -50,6 +57,7 @@
  * guide.</p>
  * </div>
  *
+ * @see android.support.v4.app.JobIntentService
  * @see android.os.AsyncTask
  */
 public abstract class IntentService extends Service {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 2a29616..16b21f1 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -29,11 +29,12 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.persistentdata.IPersistentDataBlockService;
 import android.util.Log;
 import android.view.IOnKeyguardExitResult;
 import android.view.IWindowManager;
@@ -41,6 +42,7 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.widget.LockPatternUtils;
 
 import java.util.List;
 
@@ -74,6 +76,13 @@
             "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
 
     /**
+     * Intent used to prompt user for factory reset credentials.
+     * @hide
+     */
+    public static final String ACTION_CONFIRM_FRP_CREDENTIAL =
+            "android.app.action.CONFIRM_FRP_CREDENTIAL";
+
+    /**
      * A CharSequence dialog title to show to the user when used with a
      * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
      * @hide
@@ -88,6 +97,23 @@
     public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
 
     /**
+     * A CharSequence description to show to the user on the alternate button when used with
+     * {@link #ACTION_CONFIRM_FRP_CREDENTIAL}.
+     * @hide
+     */
+    public static final String EXTRA_ALTERNATE_BUTTON_LABEL =
+            "android.app.extra.ALTERNATE_BUTTON_LABEL";
+
+    /**
+     * Result code returned by the activity started by
+     * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
+     * alternate button.
+     *
+     * @hide
+     */
+    public static final int RESULT_ALTERNATE = 1;
+
+    /**
      * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
      * for the current user of the device. The caller is expected to launch this activity using
      * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
@@ -130,6 +156,63 @@
         return intent;
     }
 
+    /**
+     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
+     * for the previous owner of the device. The caller is expected to launch this activity using
+     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
+     * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
+     *
+     * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
+     *                             clicking this button, the activity returns
+     *                             {@link #RESULT_ALTERNATE}
+     *
+     * @return  the intent for launching the activity or null if the credential of the previous
+     * owner can not be verified (e.g. because there was none, or the device does not support
+     * verifying credentials after a factory reset, or device setup has already been completed).
+     *
+     * @hide
+     */
+    public Intent createConfirmFactoryResetCredentialIntent(
+            CharSequence title, CharSequence description, CharSequence alternateButtonLabel) {
+        if (!LockPatternUtils.frpCredentialEnabled()) {
+            Log.w(TAG, "Factory reset credentials not supported.");
+            return null;
+        }
+
+        // Cannot verify credential if the device is provisioned
+        if (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            Log.e(TAG, "Factory reset credential cannot be verified after provisioning.");
+            return null;
+        }
+
+        // Make sure we have a credential
+        try {
+            IPersistentDataBlockService pdb = IPersistentDataBlockService.Stub.asInterface(
+                    ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));
+            if (pdb == null) {
+                Log.e(TAG, "No persistent data block service");
+                return null;
+            }
+            if (!pdb.hasFrpCredentialHandle()) {
+                Log.i(TAG, "The persistent data block does not have a factory reset credential.");
+                return null;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        Intent intent = new Intent(ACTION_CONFIRM_FRP_CREDENTIAL);
+        intent.putExtra(EXTRA_TITLE, title);
+        intent.putExtra(EXTRA_DESCRIPTION, description);
+        intent.putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
+
+        // explicitly set the package for security
+        intent.setPackage(getSettingsPackageForIntent(intent));
+
+        return intent;
+    }
+
     private String getSettingsPackageForIntent(Intent intent) {
         List<ResolveInfo> resolveInfos = mContext.getPackageManager()
                 .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 393909b..79e5407 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -448,10 +448,13 @@
             }
         }
 
+        // Prepend the shared libraries, maintaining their original order where possible.
         if (sharedLibraries != null) {
+            int index = 0;
             for (String lib : sharedLibraries) {
                 if (!outZipPaths.contains(lib)) {
-                    outZipPaths.add(0, lib);
+                    outZipPaths.add(index, lib);
+                    index++;
                     appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
                 }
             }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4dd71b4..531afa4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -33,6 +33,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ShortcutInfo;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -559,6 +560,11 @@
     @SystemApi
     public static final int FLAG_AUTOGROUP_SUMMARY  = 0x00000400;
 
+    /**
+     * @hide
+     */
+    public static final int FLAG_CAN_COLORIZE = 0x00000800;
+
     public int flags;
 
     /** @hide */
@@ -1085,6 +1091,11 @@
     public static final String EXTRA_CONTAINS_CUSTOM_VIEW = "android.contains.customView";
 
     /**
+     * @hide
+     */
+    public static final String EXTRA_REDUCED_IMAGES = "android.reduced.images";
+
+    /**
      * {@link #extras} key: the audio contents of this notification.
      *
      * This is for use when rendering the notification on an audio-focused interface;
@@ -2536,6 +2547,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() {
@@ -2745,6 +2772,11 @@
         private int mBackgroundColor = COLOR_INVALID;
         private int mForegroundColor = COLOR_INVALID;
         private int mBackgroundColorHint = COLOR_INVALID;
+        /**
+         * A temporary location where actions are stored. If != null the view originally has action
+         * but doesn't have any for this inflation.
+         */
+        private ArrayList<Action> mOriginalActions;
         private boolean mRebuildStyledRemoteViews;
 
         /**
@@ -4057,7 +4089,53 @@
                 contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin);
                 contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin);
                 contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin);
+                // Bind the reply action
+                Action action = findReplyAction();
+                contentView.setViewVisibility(R.id.reply_icon_action, action != null
+                        ? View.VISIBLE
+                        : View.GONE);
+
+                if (action != null) {
+                    int contrastColor = resolveContrastColor();
+                    contentView.setDrawableParameters(R.id.reply_icon_action,
+                            true /* targetBackground */,
+                            -1,
+                            contrastColor,
+                            PorterDuff.Mode.SRC_ATOP, -1);
+                    int iconColor = NotificationColorUtil.isColorLight(contrastColor)
+                            ? Color.BLACK : Color.WHITE;
+                    contentView.setDrawableParameters(R.id.reply_icon_action,
+                            false /* targetBackground */,
+                            -1,
+                            iconColor,
+                            PorterDuff.Mode.SRC_ATOP, -1);
+                    contentView.setOnClickPendingIntent(R.id.right_icon,
+                            action.actionIntent);
+                    contentView.setOnClickPendingIntent(R.id.reply_icon_action,
+                            action.actionIntent);
+                    contentView.setRemoteInputs(R.id.right_icon, action.mRemoteInputs);
+                    contentView.setRemoteInputs(R.id.reply_icon_action, action.mRemoteInputs);
+
+                }
             }
+            contentView.setViewVisibility(R.id.right_icon_container, mN.mLargeIcon != null
+                    ? View.VISIBLE
+                    : View.GONE);
+        }
+
+        private Action findReplyAction() {
+            ArrayList<Action> actions = mActions;
+            if (mOriginalActions != null) {
+                actions = mOriginalActions;
+            }
+            int numActions = actions.size();
+            for (int i = 0; i < numActions; i++) {
+                Action action = actions.get(i);
+                if (hasValidRemoteInput(action)) {
+                    return action;
+                }
+            }
+            return null;
         }
 
         private void bindNotificationHeader(RemoteViews contentView, boolean ambient) {
@@ -4473,11 +4551,16 @@
                     savedBundle.getBoolean(EXTRA_SHOW_CHRONOMETER));
             publicExtras.putBoolean(EXTRA_CHRONOMETER_COUNT_DOWN,
                     savedBundle.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN));
-            publicExtras.putCharSequence(EXTRA_TITLE,
-                    mContext.getString(com.android.internal.R.string.notification_hidden_text));
             mN.extras = publicExtras;
-            final RemoteViews view = ambient ? makeAmbientNotification()
-                    : applyStandardTemplate(getBaseLayoutResource());
+            RemoteViews view;
+            if (ambient) {
+                publicExtras.putCharSequence(EXTRA_TITLE,
+                        mContext.getString(com.android.internal.R.string.notification_hidden_text));
+                view = makeAmbientNotification();
+            } else{
+                view = makeNotificationHeader(false /* ambient */);
+                view.setBoolean(R.id.notification_header, "setExpandOnlyOnButton", true);
+            }
             mN.extras = savedBundle;
             mN.mLargeIcon = largeIcon;
             mN.largeIcon = largeIconLegacy;
@@ -4871,9 +4954,13 @@
             buildUnstyled();
 
             if (mStyle != null) {
+                mStyle.reduceImageSizes(mContext);
+                mStyle.purgeResources();
                 mStyle.buildStyled(mN);
             }
 
+            mN.reduceImageSizes(mContext);
+
             if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
                     && (useExistingRemoteView())) {
                 if (mN.contentView == null) {
@@ -5063,6 +5150,52 @@
     }
 
     /**
+     * Reduces the image sizes to conform to a maximum allowed size. This also processes all custom
+     * remote views.
+     *
+     * @hide
+     */
+    void reduceImageSizes(Context context) {
+        if (extras.getBoolean(EXTRA_REDUCED_IMAGES)) {
+            return;
+        }
+        if (mLargeIcon != null || largeIcon != null) {
+            Resources resources = context.getResources();
+            Class<? extends Style> style = getNotificationStyle();
+            int maxWidth = resources.getDimensionPixelSize(R.dimen.notification_right_icon_size);
+            int maxHeight = maxWidth;
+            if (MediaStyle.class.equals(style)
+                    || DecoratedMediaCustomViewStyle.class.equals(style)) {
+                maxHeight = resources.getDimensionPixelSize(
+                        R.dimen.notification_media_image_max_height);
+                maxWidth = resources.getDimensionPixelSize(
+                        R.dimen.notification_media_image_max_width);
+            }
+            if (mLargeIcon != null) {
+                mLargeIcon.scaleDownIfNecessary(maxWidth, maxHeight);
+            }
+            if (largeIcon != null) {
+                largeIcon = Icon.scaleDownIfNecessary(largeIcon, maxWidth, maxHeight);
+            }
+        }
+        reduceImageSizesForRemoteView(contentView, context);
+        reduceImageSizesForRemoteView(headsUpContentView, context);
+        reduceImageSizesForRemoteView(bigContentView, context);
+        extras.putBoolean(EXTRA_REDUCED_IMAGES, true);
+    }
+
+    private void reduceImageSizesForRemoteView(RemoteViews remoteView, Context context) {
+        if (remoteView != null) {
+            Resources resources = context.getResources();
+            int maxWidth = resources.getDimensionPixelSize(
+                    R.dimen.notification_custom_view_max_image_width);
+            int maxHeight = resources.getDimensionPixelSize(
+                    R.dimen.notification_custom_view_max_image_height);
+            remoteView.reduceImageSizes(maxWidth, maxHeight);
+        }
+    }
+
+    /**
      * @return whether this notification is a foreground service notification
      */
     private boolean isForegroundService() {
@@ -5099,7 +5232,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;
     }
 
     /**
@@ -5354,6 +5496,14 @@
         public boolean displayCustomViewInline() {
             return false;
         }
+
+        /**
+         * Reduces the image sizes contained in this style.
+         *
+         * @hide
+         */
+        public void reduceImageSizes(Context context) {
+        }
     }
 
     /**
@@ -5452,6 +5602,27 @@
         /**
          * @hide
          */
+        @Override
+        public void reduceImageSizes(Context context) {
+            super.reduceImageSizes(context);
+            Resources resources = context.getResources();
+            if (mPicture != null) {
+                int maxPictureWidth = resources.getDimensionPixelSize(
+                        R.dimen.notification_big_picture_max_height);
+                int maxPictureHeight = resources.getDimensionPixelSize(
+                        R.dimen.notification_big_picture_max_width);
+                mPicture = Icon.scaleDownIfNecessary(mPicture, maxPictureWidth, maxPictureHeight);
+            }
+            if (mBigLargeIcon != null) {
+                int rightIconSize = resources.getDimensionPixelSize(
+                        R.dimen.notification_right_icon_size);
+                mBigLargeIcon.scaleDownIfNecessary(rightIconSize, rightIconSize);
+            }
+        }
+
+        /**
+         * @hide
+         */
         public RemoteViews makeBigContentView() {
             // Replace mN.mLargeIcon with mBigLargeIcon if mBigLargeIconSet
             // This covers the following cases:
@@ -5607,10 +5778,11 @@
         @Override
         public RemoteViews makeContentView(boolean increasedHeight) {
             if (increasedHeight) {
-                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mOriginalActions = mBuilder.mActions;
                 mBuilder.mActions = new ArrayList<>();
                 RemoteViews remoteViews = makeBigContentView();
-                mBuilder.mActions = actions;
+                mBuilder.mActions = mBuilder.mOriginalActions;
+                mBuilder.mOriginalActions = null;
                 return remoteViews;
             }
             return super.makeContentView(increasedHeight);
@@ -5894,10 +6066,11 @@
                 return mBuilder.applyStandardTemplate(mBuilder.getBaseLayoutResource(),
                         mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
             } else {
-                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mOriginalActions = mBuilder.mActions;
                 mBuilder.mActions = new ArrayList<>();
                 RemoteViews remoteViews = makeBigContentView();
-                mBuilder.mActions = actions;
+                mBuilder.mActions = mBuilder.mOriginalActions;
+                mBuilder.mOriginalActions = null;
                 return remoteViews;
             }
         }
@@ -6727,8 +6900,8 @@
                 // Need to clone customContent before adding, because otherwise it can no longer be
                 // parceled independently of remoteViews.
                 customContent = customContent.clone();
-                remoteViews.removeAllViews(R.id.notification_main_column);
-                remoteViews.addView(R.id.notification_main_column, customContent);
+                remoteViews.removeAllViewsExceptId(R.id.notification_main_column, R.id.progress);
+                remoteViews.addView(R.id.notification_main_column, customContent, 0 /* index */);
             }
             // also update the end margin if there is an image
             int endMargin = R.dimen.notification_content_margin_end;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 143d147..d6e3691 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -15,11 +15,6 @@
  */
 package android.app;
 
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.annotation.SystemApi;
 import android.app.NotificationManager.Importance;
 import android.content.Intent;
@@ -31,6 +26,11 @@
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.IOException;
 import java.util.Arrays;
 
@@ -743,7 +743,7 @@
 
     private static String longArrayToString(long[] values) {
         StringBuffer sb = new StringBuffer();
-        if (values != null) {
+        if (values != null && values.length > 0) {
             for (int i = 0; i < values.length - 1; i++) {
                 sb.append(values[i]).append(DELIMITER);
             }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 235b8d4..9d7e4a2 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -18,14 +18,12 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.app.Notification.Builder;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.ParceledListSlice;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
@@ -33,7 +31,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -41,7 +38,6 @@
 import android.os.StrictMode;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
-import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.util.ArraySet;
@@ -312,6 +308,7 @@
             }
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
+        notification.reduceImageSizes(mContext);
         final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index f83f39f..b7d3f57 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -102,6 +102,7 @@
                     FLAG_NO_CREATE,
                     FLAG_CANCEL_CURRENT,
                     FLAG_UPDATE_CURRENT,
+                    FLAG_IMMUTABLE,
 
                     Intent.FILL_IN_ACTION,
                     Intent.FILL_IN_DATA,
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/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 80554ff..fb11272 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -44,8 +44,6 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Objects;
 import java.util.WeakHashMap;
 import java.util.function.Predicate;
@@ -417,7 +415,12 @@
             if (activityResources == null) {
                 return overrideConfig == null;
             } else {
-                return Objects.equals(activityResources.overrideConfig, overrideConfig);
+                // The two configurations must either be equal or publicly equivalent to be
+                // considered the same.
+                return Objects.equals(activityResources.overrideConfig, overrideConfig)
+                        || (overrideConfig != null && activityResources.overrideConfig != null
+                                && 0 == overrideConfig.diffPublicOnly(
+                                        activityResources.overrideConfig));
             }
         }
     }
@@ -984,8 +987,6 @@
                 }
             }
 
-            invalidatePath("/");
-
             redirectResourcesToNewImplLocked(updatedResourceKeys);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
diff --git a/core/java/android/app/RetailDemoModeServiceInternal.java b/core/java/android/app/RetailDemoModeServiceInternal.java
deleted file mode 100644
index 7ca214a..0000000
--- a/core/java/android/app/RetailDemoModeServiceInternal.java
+++ /dev/null
@@ -1,29 +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 android.app;
-
-/**
- * Retail Demo Mode Service interface to be used locally inside system server
- *
- * @hide Only for use inside system server
- */
-public interface RetailDemoModeServiceInternal {
-    /**
-     * Used to notify RetailDemoModeService of any user activity.
-     */
-    public void onUserActivity();
-}
\ No newline at end of file
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index fb8bd39..4a09214 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -94,6 +94,7 @@
 
     public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
     public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
+    public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
 
     private Context mContext;
     private IStatusBarService mService;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index a13c69d7..9a019b8 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -127,6 +127,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
@@ -493,6 +494,13 @@
                 return new TelecomManager(ctx.getOuterContext());
             }});
 
+        registerService(Context.EUICC_SERVICE, EuiccManager.class,
+                new CachedServiceFetcher<EuiccManager>() {
+            @Override
+            public EuiccManager createService(ContextImpl ctx) {
+                return new EuiccManager(ctx.getOuterContext());
+            }});
+
         registerService(Context.UI_MODE_SERVICE, UiModeManager.class,
                 new CachedServiceFetcher<UiModeManager>() {
             @Override
@@ -794,7 +802,7 @@
         registerService(Context.RADIO_SERVICE, RadioManager.class,
                 new CachedServiceFetcher<RadioManager>() {
             @Override
-            public RadioManager createService(ContextImpl ctx) {
+            public RadioManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                 return new RadioManager(ctx);
             }});
 
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 18e7599..c99de5d 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -975,11 +975,11 @@
     }
 
     /**
-     * Executes a shell command. This method returs a file descriptor that points
+     * Executes a shell command. This method returns a file descriptor that points
      * to the standard output stream. The command execution is similar to running
      * "adb shell <command>" from a host connected to the device.
      * <p>
-     * <strong>Note:</strong> It is your responsibility to close the retunred file
+     * <strong>Note:</strong> It is your responsibility to close the returned file
      * descriptor once you are done reading.
      * </p>
      *
@@ -1000,7 +1000,7 @@
             sink = pipe[1];
 
             // Calling out without a lock held.
-            mUiAutomationConnection.executeShellCommand(command, sink);
+            mUiAutomationConnection.executeShellCommand(command, sink, null);
         } catch (IOException ioe) {
             Log.e(LOG_TAG, "Error executing shell command!", ioe);
         } catch (RemoteException re) {
@@ -1012,6 +1012,59 @@
         return source;
     }
 
+    /**
+     * Executes a shell command. This method returns two file descriptors,
+     * one that points to the standard output stream (element at index 0), and one that points
+     * to the standard input stream (element at index 1). The command execution is similar
+     * to running "adb shell <command>" from a host connected to the device.
+     * <p>
+     * <strong>Note:</strong> It is your responsibility to close the returned file
+     * descriptors once you are done reading/writing.
+     * </p>
+     *
+     * @param command The command to execute.
+     * @return File descriptors (out, in) to the standard output/input streams.
+     *
+     * @hide
+     */
+    @TestApi
+    public ParcelFileDescriptor[] executeShellCommandRw(String command) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+
+        ParcelFileDescriptor source_read = null;
+        ParcelFileDescriptor sink_read = null;
+
+        ParcelFileDescriptor source_write = null;
+        ParcelFileDescriptor sink_write = null;
+
+        try {
+            ParcelFileDescriptor[] pipe_read = ParcelFileDescriptor.createPipe();
+            source_read = pipe_read[0];
+            sink_read = pipe_read[1];
+
+            ParcelFileDescriptor[] pipe_write = ParcelFileDescriptor.createPipe();
+            source_write = pipe_write[0];
+            sink_write = pipe_write[1];
+
+            // Calling out without a lock held.
+            mUiAutomationConnection.executeShellCommand(command, sink_read, source_write);
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Error executing shell command!", ioe);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error executing shell command!", re);
+        } finally {
+            IoUtils.closeQuietly(sink_read);
+            IoUtils.closeQuietly(source_write);
+        }
+
+        ParcelFileDescriptor[] result = new ParcelFileDescriptor[2];
+        result[0] = source_read;
+        result[1] = sink_write;
+        return result;
+    }
+
     private static float getDegreesForRotation(int value) {
         switch (value) {
             case Surface.ROTATION_90: {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 9960df6..5e414b8 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -36,9 +36,11 @@
 import android.view.WindowContentFrameStats;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.IAccessibilityManager;
+import android.util.Log;
 
 import libcore.io.IoUtils;
 
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -55,6 +57,8 @@
  */
 public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
 
+    private static final String TAG = "UiAutomationConnection";
+
     private static final int INITIAL_FROZEN_ROTATION_UNSPECIFIED = -1;
 
     private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
@@ -267,47 +271,95 @@
         }
     }
 
+    public class Repeater implements Runnable {
+        // Continuously read readFrom and write back to writeTo until EOF is encountered
+        private final InputStream readFrom;
+        private final OutputStream writeTo;
+        public Repeater (InputStream readFrom, OutputStream writeTo) {
+            this.readFrom = readFrom;
+            this.writeTo = writeTo;
+        }
+        @Override
+        public void run() {
+            try {
+                final byte[] buffer = new byte[8192];
+                int readByteCount;
+                while (true) {
+                    readByteCount = readFrom.read(buffer);
+                    if (readByteCount < 0) {
+                        break;
+                    }
+                    writeTo.write(buffer, 0, readByteCount);
+                    writeTo.flush();
+                }
+            } catch (IOException ioe) {
+                throw new RuntimeException("Error while reading/writing ", ioe);
+            } finally {
+                IoUtils.closeQuietly(readFrom);
+                IoUtils.closeQuietly(writeTo);
+            }
+        }
+    }
+
     @Override
-    public void executeShellCommand(final String command, final ParcelFileDescriptor sink)
-            throws RemoteException {
+    public void executeShellCommand(final String command, final ParcelFileDescriptor sink,
+            final ParcelFileDescriptor source) throws RemoteException {
         synchronized (mLock) {
             throwIfCalledByNotTrustedUidLocked();
             throwIfShutdownLocked();
             throwIfNotConnectedLocked();
         }
+        final java.lang.Process process;
 
-        Thread streamReader = new Thread() {
+        try {
+            process = Runtime.getRuntime().exec(command);
+        } catch (IOException exc) {
+            throw new RuntimeException("Error running shell command '" + command + "'", exc);
+        }
+
+        // Read from process and write to pipe
+        final Thread readFromProcess;
+        if (sink != null) {
+            InputStream sink_in = process.getInputStream();;
+            OutputStream sink_out = new FileOutputStream(sink.getFileDescriptor());
+
+            readFromProcess = new Thread(new Repeater(sink_in, sink_out));
+            readFromProcess.start();
+        } else {
+            readFromProcess = null;
+        }
+
+        // Read from pipe and write to process
+        final Thread writeToProcess;
+        if (source != null) {
+            OutputStream source_out = process.getOutputStream();
+            InputStream source_in = new FileInputStream(source.getFileDescriptor());
+
+            writeToProcess = new Thread(new Repeater(source_in, source_out));
+            writeToProcess.start();
+        } else {
+            writeToProcess = null;
+        }
+
+        Thread cleanup = new Thread(new Runnable() {
+            @Override
             public void run() {
-                InputStream in = null;
-                OutputStream out = null;
-                java.lang.Process process = null;
-
                 try {
-                    process = Runtime.getRuntime().exec(command);
-
-                    in = process.getInputStream();
-                    out = new FileOutputStream(sink.getFileDescriptor());
-
-                    final byte[] buffer = new byte[8192];
-                    while (true) {
-                        final int readByteCount = in.read(buffer);
-                        if (readByteCount < 0) {
-                            break;
-                        }
-                        out.write(buffer, 0, readByteCount);
+                    if (writeToProcess != null) {
+                        writeToProcess.join();
                     }
-                } catch (IOException ioe) {
-                    throw new RuntimeException("Error running shell command", ioe);
-                } finally {
-                    if (process != null) {
-                        process.destroy();
+                    if (readFromProcess != null) {
+                        readFromProcess.join();
                     }
-                    IoUtils.closeQuietly(out);
-                    IoUtils.closeQuietly(sink);
+                } catch (InterruptedException exc) {
+                    Log.e(TAG, "At least one of the threads was interrupted");
                 }
-            };
-        };
-        streamReader.start();
+                IoUtils.closeQuietly(sink);
+                IoUtils.closeQuietly(source);
+                process.destroy();
+                }
+            });
+        cleanup.start();
     }
 
     @Override
diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
index a608bb0..0eb2af3 100644
--- a/core/java/android/app/Vr2dDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,19 +26,31 @@
  *
  * @hide
  */
-public class Vr2dDisplayProperties implements Parcelable {
+public final class Vr2dDisplayProperties implements Parcelable {
 
-   /**
-    * The actual width, height and dpi.
-    */
+    public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1;
+
+    /**
+     * The actual width, height and dpi.
+     */
     private final int mWidth;
     private final int mHeight;
     private final int mDpi;
 
+    // Flags describing the virtual display behavior.
+    private final int mAddedFlags;
+    private final int mRemovedFlags;
+
     public Vr2dDisplayProperties(int width, int height, int dpi) {
+        this(width, height, dpi, 0, 0);
+    }
+
+    private Vr2dDisplayProperties(int width, int height, int dpi, int flags, int removedFlags) {
         mWidth = width;
         mHeight = height;
         mDpi = dpi;
+        mAddedFlags = flags;
+        mRemovedFlags = removedFlags;
     }
 
     @Override
@@ -52,11 +63,13 @@
 
     @Override
     public String toString() {
-        return "Vr2dDisplayProperties{" +
-                "mWidth=" + mWidth +
-                ", mHeight=" + mHeight +
-                ", mDpi=" + mDpi +
-                "}";
+        return "Vr2dDisplayProperties{"
+                + "mWidth=" + mWidth
+                + ", mHeight=" + mHeight
+                + ", mDpi=" + mDpi
+                + ", flags=" + toReadableFlags(mAddedFlags)
+                + ", removed_flags=" + toReadableFlags(mRemovedFlags)
+                + "}";
     }
 
     @Override
@@ -66,6 +79,8 @@
 
         Vr2dDisplayProperties that = (Vr2dDisplayProperties) o;
 
+        if (getFlags() != that.getFlags()) return false;
+        if (getRemovedFlags() != that.getRemovedFlags()) return false;
         if (getWidth() != that.getWidth()) return false;
         if (getHeight() != that.getHeight()) return false;
         return getDpi() == that.getDpi();
@@ -81,6 +96,8 @@
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
         dest.writeInt(mDpi);
+        dest.writeInt(mAddedFlags);
+        dest.writeInt(mRemovedFlags);
     }
 
     public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR
@@ -100,13 +117,12 @@
         mWidth = source.readInt();
         mHeight = source.readInt();
         mDpi = source.readInt();
+        mAddedFlags = source.readInt();
+        mRemovedFlags = source.readInt();
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.println(prefix + "Vr2dDisplayProperties:");
-        pw.println(prefix + "  width=" + mWidth);
-        pw.println(prefix + "  height=" + mHeight);
-        pw.println(prefix + "  dpi=" + mDpi);
+        pw.println(prefix + toString());
     }
 
     public int getWidth() {
@@ -120,4 +136,83 @@
     public int getDpi() {
         return mDpi;
     }
+
+    public int getFlags() {
+        return mAddedFlags;
+    }
+
+    public int getRemovedFlags() {
+        return mRemovedFlags;
+    }
+
+    private static String toReadableFlags(int flags) {
+        String retval = "{";
+        if ((flags & FLAG_VIRTUAL_DISPLAY_ENABLED) == FLAG_VIRTUAL_DISPLAY_ENABLED) {
+            retval += "enabled";
+        }
+        return retval + "}";
+    }
+
+    /**
+     * Convenience class for creating Vr2dDisplayProperties.
+     */
+    public static class Builder {
+        private int mAddedFlags = 0;
+        private int mRemovedFlags = 0;
+
+        // Negative values are translated as an "ignore" to VrManagerService.
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private int mDpi = -1;
+
+        public Builder() {
+        }
+
+        /**
+         * Sets the dimensions to use for the virtual display.
+         */
+        public Builder setDimensions(int width, int height, int dpi) {
+            mWidth = width;
+            mHeight = height;
+            mDpi = dpi;
+            return this;
+        }
+
+        /**
+         * Toggles the virtual display functionality for 2D activities in VR.
+         */
+        public Builder setEnabled(boolean enabled) {
+            if (enabled) {
+                addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            } else {
+                removeFlags(FLAG_VIRTUAL_DISPLAY_ENABLED);
+            }
+            return this;
+        }
+
+        /**
+         * Adds property flags.
+         */
+        public Builder addFlags(int flags) {
+            mAddedFlags |= flags;
+            mRemovedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Removes property flags.
+         */
+        public Builder removeFlags(int flags) {
+            mRemovedFlags |= flags;
+            mAddedFlags &= ~flags;
+            return this;
+        }
+
+        /**
+         * Builds the Vr2dDisplayProperty instance.
+         */
+        public Vr2dDisplayProperties build() {
+            return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags);
+        }
+    }
 }
diff --git a/core/java/android/app/WallpaperColors.aidl b/core/java/android/app/WallpaperColors.aidl
new file mode 100644
index 0000000..f5edff2
--- /dev/null
+++ b/core/java/android/app/WallpaperColors.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable WallpaperColors;
\ No newline at end of file
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
new file mode 100644
index 0000000..2a8130f
--- /dev/null
+++ b/core/java/android/app/WallpaperColors.java
@@ -0,0 +1,420 @@
+/*
+ * 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Provides information about the colors of a wallpaper.
+ * <p>
+ * Exposes the 3 most visually representative colors of a wallpaper. Can be either
+ * {@link WallpaperColors#getPrimaryColor()}, {@link WallpaperColors#getSecondaryColor()}
+ * or {@link WallpaperColors#getTertiaryColor()}.
+ */
+public final class WallpaperColors implements Parcelable {
+
+    /**
+     * 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;
+
+    // Even though we have a maximum size, we'll mainly match bitmap sizes
+    // using the area instead. This way our comparisons are aspect ratio independent.
+    private static final int MAX_WALLPAPER_EXTRACTION_AREA = MAX_BITMAP_SIZE * MAX_BITMAP_SIZE;
+
+    // When extracting the main colors, only consider colors
+    // 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.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;
+    private static final float MAX_DARK_AREA = 0.05f;
+
+    private final ArrayList<Color> mMainColors;
+    private int mColorHints;
+
+    public WallpaperColors(Parcel parcel) {
+        mMainColors = new ArrayList<>();
+        final int count = parcel.readInt();
+        for (int i = 0; i < count; i++) {
+            final int colorInt = parcel.readInt();
+            Color color = Color.valueOf(colorInt);
+            mMainColors.add(color);
+        }
+        mColorHints = parcel.readInt();
+    }
+
+    /**
+     * Constructs {@link WallpaperColors} from a drawable.
+     * <p>
+     * Main colors will be extracted from the drawable.
+     *
+     * @param drawable Source where to extract from.
+     */
+    public static WallpaperColors fromDrawable(Drawable drawable) {
+        int width = drawable.getIntrinsicWidth();
+        int height = drawable.getIntrinsicHeight();
+
+        // Some drawables do not have intrinsic dimensions
+        if (width <= 0 || height <= 0) {
+            width = MAX_BITMAP_SIZE;
+            height = MAX_BITMAP_SIZE;
+        }
+
+        Size optimalSize = calculateOptimalSize(width, height);
+        Bitmap bitmap = Bitmap.createBitmap(optimalSize.getWidth(), optimalSize.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        final Canvas bmpCanvas = new Canvas(bitmap);
+        drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+        drawable.draw(bmpCanvas);
+
+        final WallpaperColors colors = WallpaperColors.fromBitmap(bitmap);
+        bitmap.recycle();
+
+        return colors;
+    }
+
+    /**
+     * Constructs {@link WallpaperColors} from a bitmap.
+     * <p>
+     * Main colors will be extracted from the bitmap.
+     *
+     * @param bitmap Source where to extract from.
+     */
+    public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap) {
+        if (bitmap == null) {
+            throw new IllegalArgumentException("Bitmap can't be null");
+        }
+
+        final int bitmapArea = bitmap.getWidth() * bitmap.getHeight();
+        boolean shouldRecycle = false;
+        if (bitmapArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+            shouldRecycle = true;
+            Size optimalSize = calculateOptimalSize(bitmap.getWidth(), bitmap.getHeight());
+            bitmap = Bitmap.createScaledBitmap(bitmap, optimalSize.getWidth(),
+                    optimalSize.getHeight(), true /* filter */);
+        }
+
+        final Palette palette = Palette
+                .from(bitmap)
+                .setQuantizer(new VariationalKMeansQuantizer())
+                .maximumColorCount(5)
+                .clearFilters()
+                .resizeBitmapArea(MAX_WALLPAPER_EXTRACTION_AREA)
+                .generate();
+
+        // Remove insignificant colors and sort swatches by population
+        final ArrayList<Palette.Swatch> swatches = new ArrayList<>(palette.getSwatches());
+        final float minColorArea = bitmap.getWidth() * bitmap.getHeight() * MIN_COLOR_OCCURRENCE;
+        swatches.removeIf(s -> s.getPopulation() < minColorArea);
+        swatches.sort((a, b) -> b.getPopulation() - a.getPopulation());
+
+        final int swatchesSize = swatches.size();
+        Color primary = null, secondary = null, tertiary = null;
+
+        swatchLoop:
+        for (int i = 0; i < swatchesSize; i++) {
+            Color color = Color.valueOf(swatches.get(i).getRgb());
+            switch (i) {
+                case 0:
+                    primary = color;
+                    break;
+                case 1:
+                    secondary = color;
+                    break;
+                case 2:
+                    tertiary = color;
+                    break;
+                default:
+                    // out of bounds
+                    break swatchLoop;
+            }
+        }
+
+        int hints = calculateHints(bitmap);
+
+        if (shouldRecycle) {
+            bitmap.recycle();
+        }
+
+        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.
+     * @param secondaryColor Secondary color.
+     * @param tertiaryColor Tertiary color.
+     * @param colorHints A combination of WallpaperColor hints.
+     * @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) {
+
+        if (primaryColor == null) {
+            throw new IllegalArgumentException("Primary color should never be null.");
+        }
+
+        mMainColors = new ArrayList<>(3);
+        mMainColors.add(primaryColor);
+        if (secondaryColor != null) {
+            mMainColors.add(secondaryColor);
+        }
+        if (tertiaryColor != null) {
+            if (secondaryColor == null) {
+                throw new IllegalArgumentException("tertiaryColor can't be specified when "
+                        + "secondaryColor is null");
+            }
+            mMainColors.add(tertiaryColor);
+        }
+
+        mColorHints = colorHints;
+    }
+
+    public static final Creator<WallpaperColors> CREATOR = new Creator<WallpaperColors>() {
+        @Override
+        public WallpaperColors createFromParcel(Parcel in) {
+            return new WallpaperColors(in);
+        }
+
+        @Override
+        public WallpaperColors[] newArray(int size) {
+            return new WallpaperColors[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        List<Color> mainColors = getMainColors();
+        int count = mainColors.size();
+        dest.writeInt(count);
+        for (int i = 0; i < count; i++) {
+            Color color = mainColors.get(i);
+            dest.writeInt(color.toArgb());
+        }
+        dest.writeInt(mColorHints);
+    }
+
+    /**
+     * Gets the most visually representative color of the wallpaper.
+     * "Visually representative" means easily noticeable in the image,
+     * probably happening at high frequency.
+     *
+     * @return A color.
+     */
+    public @NonNull Color getPrimaryColor() {
+        return mMainColors.get(0);
+    }
+
+    /**
+     * Gets the second most preeminent color of the wallpaper. Can be null.
+     *
+     * @return A color, may be null.
+     */
+    public @Nullable Color getSecondaryColor() {
+        return mMainColors.size() < 2 ? null : mMainColors.get(1);
+    }
+
+    /**
+     * Gets the third most preeminent color of the wallpaper. Can be null.
+     *
+     * @return A color, may be null.
+     */
+    public @Nullable Color getTertiaryColor() {
+        return mMainColors.size() < 3 ? null : mMainColors.get(2);
+    }
+
+    /**
+     * List of most preeminent colors, sorted by importance.
+     *
+     * @return List of colors.
+     * @hide
+     */
+    public @NonNull List<Color> getMainColors() {
+        return Collections.unmodifiableList(mMainColors);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        WallpaperColors other = (WallpaperColors) o;
+        return mMainColors.equals(other.mMainColors)
+                && mColorHints == other.mColorHints;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * mMainColors.hashCode() + mColorHints;
+    }
+
+    /**
+     * Combination of WallpaperColor hints.
+     *
+     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
+     * @return True if dark text is supported.
+     * @hide
+     */
+    public int getColorHints() {
+        return mColorHints;
+    }
+
+    /**
+     * @param colorHints Combination of WallpaperColors hints.
+     * @see WallpaperColors#HINT_SUPPORTS_DARK_TEXT
+     * @hide
+     */
+    public void setColorHints(int colorHints) {
+        mColorHints = colorHints;
+    }
+
+    /**
+     * Checks if image is bright and clean enough to support light text.
+     *
+     * @param source What to read.
+     * @return Whether image supports dark text or not.
+     */
+    private static int calculateHints(Bitmap source) {
+        if (source == null) {
+            return 0;
+        }
+
+        int[] pixels = new int[source.getWidth() * source.getHeight()];
+        double totalLuminance = 0;
+        final int maxDarkPixels = (int) (pixels.length * MAX_DARK_AREA);
+        int darkPixels = 0;
+        source.getPixels(pixels, 0 /* offset */, source.getWidth(), 0 /* x */, 0 /* y */,
+                source.getWidth(), source.getHeight());
+
+        // 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++) {
+            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++;
+            }
+            totalLuminance += 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) {
+        // Calculate how big the bitmap needs to be.
+        // This avoids unnecessary processing and allocation inside Palette.
+        final int requestedArea = width * height;
+        double scale = 1;
+        if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+            scale = Math.sqrt(MAX_WALLPAPER_EXTRACTION_AREA / (double) requestedArea);
+        }
+        int newWidth = (int) (width * scale);
+        int newHeight = (int) (height * scale);
+        // Dealing with edge cases of the drawable being too wide or too tall.
+        // Width or height would end up being 0, in this case we'll set it to 1.
+        if (newWidth == 0) {
+            newWidth = 1;
+        }
+        if (newHeight == 0) {
+            newHeight = 1;
+        }
+
+        return new Size(newWidth, newHeight);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder colors = new StringBuilder();
+        for (int i = 0; i < mMainColors.size(); i++) {
+            colors.append(Integer.toHexString(mMainColors.get(i).toArgb())).append(" ");
+        }
+        return "[WallpaperColors: " + colors.toString() + "h: " + mColorHints + "]";
+    }
+}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a850423..84839bf 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -17,12 +17,14 @@
 package android.app;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RawRes;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -52,13 +54,13 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 import android.view.WindowManagerGlobal;
 
 import libcore.io.IoUtils;
@@ -71,6 +73,7 @@
 import java.io.InputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -271,15 +274,20 @@
         }
     }
 
-    static class Globals extends IWallpaperManagerCallback.Stub {
+    private static class Globals extends IWallpaperManagerCallback.Stub {
         private final IWallpaperManager mService;
+        private boolean mColorCallbackRegistered;
+        private final ArrayList<Pair<OnColorsChangedListener, Handler>> mColorListeners =
+                new ArrayList<>();
         private Bitmap mCachedWallpaper;
         private int mCachedWallpaperUserId;
         private Bitmap mDefaultWallpaper;
+        private Handler mMainLooperHandler;
 
         Globals(Looper looper) {
             IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
             mService = IWallpaperManager.Stub.asInterface(b);
+            mMainLooperHandler = new Handler(looper);
             forgetLoadedWallpaper();
         }
 
@@ -292,6 +300,90 @@
             forgetLoadedWallpaper();
         }
 
+        /**
+         * Start listening to wallpaper color events.
+         * Will be called whenever someone changes their wallpaper or if a live wallpaper
+         * changes its colors.
+         * @param callback Listener
+         * @param handler Thread to call it from. Main thread if null.
+         * @param userId Owner of the wallpaper or UserHandle.USER_ALL
+         */
+        public void addOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+                @Nullable Handler handler, int userId) {
+            synchronized (this) {
+                if (!mColorCallbackRegistered) {
+                    try {
+                        mService.registerWallpaperColorsCallback(this, userId);
+                        mColorCallbackRegistered = true;
+                    } catch (RemoteException e) {
+                        // Failed, service is gone
+                        Log.w(TAG, "Can't register for color updates", e);
+                    }
+                }
+                mColorListeners.add(new Pair<>(callback, handler));
+            }
+        }
+
+        /**
+         * Stop listening to wallpaper color events.
+         *
+         * @param callback listener
+         * @param userId Owner of the wallpaper or UserHandle.USER_ALL
+         */
+        public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+                int userId) {
+            synchronized (this) {
+                mColorListeners.removeIf(pair -> pair.first == callback);
+
+                if (mColorListeners.size() == 0 && mColorCallbackRegistered) {
+                    mColorCallbackRegistered = false;
+                    try {
+                        mService.unregisterWallpaperColorsCallback(this, userId);
+                    } catch (RemoteException e) {
+                        // Failed, service is gone
+                        Log.w(TAG, "Can't unregister color updates", e);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
+            synchronized (this) {
+                for (Pair<OnColorsChangedListener, Handler> listener : mColorListeners) {
+                    Handler handler = listener.second;
+                    if (listener.second == null) {
+                        handler = mMainLooperHandler;
+                    }
+                    handler.post(() -> {
+                        // Dealing with race conditions between posting a callback and
+                        // removeOnColorsChangedListener being called.
+                        boolean stillExists;
+                        synchronized (sGlobals) {
+                            stillExists = mColorListeners.contains(listener);
+                        }
+                        if (stillExists) {
+                            listener.first.onColorsChanged(colors, which, userId);
+                        }
+                    });
+                }
+            }
+        }
+
+        WallpaperColors getWallpaperColors(int which, int userId) {
+            if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
+                throw new IllegalArgumentException(
+                        "Must request colors for exactly one kind of wallpaper");
+            }
+
+            try {
+                return mService.getWallpaperColors(which, userId);
+            } catch (RemoteException e) {
+                // Can't get colors, connection lost.
+            }
+            return null;
+        }
+
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
                 @SetWallpaperFlags int which) {
             return peekWallpaperBitmap(context, returnDefault, which, context.getUserId());
@@ -747,6 +839,81 @@
     }
 
     /**
+     * Registers a listener to get notified when the wallpaper colors change.
+     * Callback might be called from an arbitrary background thread.
+     *
+     * @param listener A listener to register
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        addOnColorsChangedListener(listener, null);
+    }
+
+    /**
+     * Registers a listener to get notified when the wallpaper colors change
+     * @param listener A listener to register
+     * @param handler Where to call it from. Will be called from the main thread
+     *                if null.
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+            @NonNull Handler handler) {
+        addOnColorsChangedListener(listener, handler, mContext.getUserId());
+    }
+
+    /**
+     * Registers a listener to get notified when the wallpaper colors change
+     * @param listener A listener to register
+     * @param handler Where to call it from. Will be called from the main thread
+     *                if null.
+     * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+     * @hide
+     */
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener,
+            @NonNull Handler handler, int userId) {
+        sGlobals.addOnColorsChangedListener(listener, handler, userId);
+    }
+
+    /**
+     * Stop listening to color updates.
+     * @param callback A callback to unsubscribe.
+     */
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback) {
+        removeOnColorsChangedListener(callback, mContext.getUserId());
+    }
+
+    /**
+     * Stop listening to color updates.
+     * @param callback A callback to unsubscribe.
+     * @param userId Owner of the wallpaper or UserHandle.USER_ALL.
+     * @hide
+     */
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener callback,
+            int userId) {
+        sGlobals.removeOnColorsChangedListener(callback, userId);
+    }
+
+    /**
+     * Get the primary colors of a wallpaper
+     * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
+     *     {@link #FLAG_LOCK}
+     * @return {@link WallpaperColors} or null if colors are unknown.
+     */
+    public @Nullable WallpaperColors getWallpaperColors(int which) {
+        return getWallpaperColors(which, mContext.getUserId());
+    }
+
+    /**
+     * Get the primary colors of a wallpaper
+     * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
+     *     {@link #FLAG_LOCK}
+     * @param userId Owner of the wallpaper.
+     * @return {@link WallpaperColors} or null if colors are unknown.
+     * @hide
+     */
+    public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
+        return sGlobals.getWallpaperColors(which, userId);
+    }
+
+    /**
      * Version of {@link #getWallpaperFile(int)} that can access the wallpaper data
      * for a given user.  The caller must hold the INTERACT_ACROSS_USERS_FULL
      * permission to access another user's wallpaper data.
@@ -1737,5 +1904,40 @@
         public void onWallpaperChanged() throws RemoteException {
             mLatch.countDown();
         }
+
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId)
+            throws RemoteException {
+            sGlobals.onWallpaperColorsChanged(colors, which, userId);
+        }
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when colors change on a wallpaper.
+     */
+    public interface OnColorsChangedListener {
+        /**
+         * Called when colors change.
+         * A {@link android.app.WallpaperColors} object containing a simplified
+         * color histogram will be given.
+         *
+         * @param colors Wallpaper color info
+         * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
+         */
+        void onColorsChanged(WallpaperColors colors, int which);
+
+        /**
+         * Called when colors change.
+         * A {@link android.app.WallpaperColors} object containing a simplified
+         * color histogram will be given.
+         *
+         * @param colors Wallpaper color info
+         * @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
+         * @param userId Owner of the wallpaper
+         * @hide
+         */
+        default void onColorsChanged(WallpaperColors colors, int which, int userId) {
+            onColorsChanged(colors, which);
+        }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 2931467..f8aa948 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -263,6 +263,25 @@
         = "android.app.action.PROVISION_MANAGED_DEVICE";
 
     /**
+     * Activity action: launch when user provisioning completed, i.e.
+     * {@link #getUserProvisioningState()} returns one of the complete state.
+     *
+     * <p> Please note that the API behavior is not necessarily consistent across various releases,
+     * and devices, as it's contract between SetupWizard and ManagedProvisioning. The default
+     * implementation is that ManagedProvisioning launches SetupWizard in NFC provisioning only.
+     *
+     * <p> The activity must be protected by permission
+     * {@link android.Manifest.permission#BIND_DEVICE_ADMIN}, and the process must hold
+     * {@link android.Manifest.permission#DISPATCH_PROVISIONING_MESSAGE} to be launched.
+     * Only one {@link ComponentName} in the entire system should be enabled, and the rest of the
+     * components are not started by this intent.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_STATE_USER_SETUP_COMPLETE =
+            "android.app.action.STATE_USER_SETUP_COMPLETE";
+
+    /**
      * Activity action: Starts the provisioning flow which sets up a managed device.
      *
      * <p>During device owner provisioning, a device admin app is downloaded and set as the owner of
@@ -3114,6 +3133,14 @@
     public static final int WIPE_RESET_PROTECTION_DATA = 0x0002;
 
     /**
+     * Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
+     *
+     * TODO(b/35851809): make this public.
+     * @hide
+     */
+    public static final int WIPE_EUICC = 0x0004;
+
+    /**
      * Ask that all user data be wiped. If called as a secondary user, the user will be removed and
      * other users will remain unaffected. Calling from the primary user will cause the device to
      * reboot, erasing all device data - including all the secondary users and their data - while
@@ -5947,6 +5974,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/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 5f92af9..42e6147 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -942,6 +942,11 @@
             long ident = Binder.clearCallingIdentity();
 
             if (DEBUG) Log.v(TAG, "doRestore() invoked");
+
+            // Ensure that any side-effect SharedPreferences writes have landed *before*
+            // we may be about to rewrite the file out from underneath
+            waitForSharedPrefs();
+
             BackupDataInput input = new BackupDataInput(data.getFileDescriptor());
             try {
                 BackupAgent.this.onRestore(input, appVersionCode, newState);
@@ -952,8 +957,8 @@
                 Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
                 throw ex;
             } finally {
-                // Ensure that any side-effect SharedPreferences writes have landed
-                waitForSharedPrefs();
+                // And bring live SharedPreferences instances up to date
+                reloadSharedPreferences();
 
                 Binder.restoreCallingIdentity(ident);
                 try {
@@ -1053,6 +1058,8 @@
             } finally {
                 // Ensure that any side-effect SharedPreferences writes have landed
                 waitForSharedPrefs();
+                // And bring live SharedPreferences instances up to date
+                reloadSharedPreferences();
 
                 Binder.restoreCallingIdentity(ident);
                 try {
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index a10de45..6d65e3e 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -34,4 +34,6 @@
     boolean isDeviceLocked(int userId);
     boolean isDeviceSecure(int userId);
     boolean isTrustUsuallyManaged(int userId);
+    void unlockedByFingerprintForUser(int userId);
+    void clearAllFingerprints();
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 54a7e5c..852cb8e 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -27,8 +27,6 @@
 import android.os.RemoteException;
 import android.util.ArrayMap;
 
-import com.android.internal.widget.LockPatternUtils;
-
 /**
  * See {@link com.android.server.trust.TrustManagerService}
  * @hide
@@ -187,6 +185,32 @@
         }
     }
 
+    /**
+     * Updates the trust state for the user due to the user unlocking via fingerprint.
+     * Should only be called if user authenticated via fingerprint and bouncer can be skipped.
+     * @param userId
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void unlockedByFingerprintForUser(int userId) {
+        try {
+            mService.unlockedByFingerprintForUser(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears authenticated fingerprints for all users.
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void clearAllFingerprints() {
+        try {
+            mService.clearAllFingerprints();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index dd1a61c..7fc79d7 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -211,7 +211,8 @@
         }
         synchronized (mLeScanClients) {
             if (callback != null && mLeScanClients.containsKey(callback)) {
-                postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+                return postCallbackErrorOrReturn(callback,
+                            ScanCallback.SCAN_FAILED_ALREADY_STARTED);
             }
             IBluetoothGatt gatt;
             try {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 86a30cf..076deab 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -280,12 +280,24 @@
 
         @Override
         public void onSuccess(PendingIntent launcher) {
-            mHandler.post(() -> mCallback.onDeviceFound(launcher.getIntentSender()));
+            Handler handler = mHandler;
+            if (handler == null) return;
+            handler.post(() -> {
+                Callback callback = mCallback;
+                if (callback == null) return;
+                callback.onDeviceFound(launcher.getIntentSender());
+            });
         }
 
         @Override
         public void onFailure(CharSequence reason) {
-            mHandler.post(() -> mCallback.onFailure(reason));
+            Handler handler = mHandler;
+            if (handler == null) return;
+            handler.post(() -> {
+                Callback callback = mCallback;
+                if (callback == null) return;
+                callback.onFailure(reason);
+            });
         }
 
         @Override
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 58bd5cd..2629929 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -17,11 +17,12 @@
 package android.content;
 
 import android.accounts.Account;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.Trace;
+import android.util.Log;
 
 import java.util.HashMap;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -95,6 +96,8 @@
  * </ul>
  */
 public abstract class AbstractThreadedSyncAdapter {
+    private static final String TAG = "SyncAdapter";
+
     /**
      * Kernel event log tag.  Also listed in data/etc/event-log-tags.
      * @deprecated Private constant.  May go away in the next release.
@@ -102,6 +105,8 @@
     @Deprecated
     public static final int LOG_SYNC_DETAILS = 2743;
 
+    private static final boolean ENABLE_LOG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG);
+
     private final Context mContext;
     private final AtomicInteger mNumSyncStarts;
     private final ISyncAdapterImpl mISyncAdapterImpl;
@@ -163,71 +168,104 @@
         @Override
         public void startSync(ISyncContext syncContext, String authority, Account account,
                 Bundle extras) {
-            final SyncContext syncContextClient = new SyncContext(syncContext);
-
-            boolean alreadyInProgress;
-            // synchronize to make sure that mSyncThreads doesn't change between when we
-            // check it and when we use it
-            final Account threadsKey = toSyncKey(account);
-            synchronized (mSyncThreadLock) {
-                if (!mSyncThreads.containsKey(threadsKey)) {
-                    if (mAutoInitialize
-                            && extras != null
-                            && extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
-                        try {
-                            if (ContentResolver.getIsSyncable(account, authority) < 0) {
-                                ContentResolver.setIsSyncable(account, authority, 1);
-                            }
-                        } finally {
-                            syncContextClient.onFinished(new SyncResult());
-                        }
-                        return;
-                    }
-                    SyncThread syncThread = new SyncThread(
-                            "SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
-                            syncContextClient, authority, account, extras);
-                    mSyncThreads.put(threadsKey, syncThread);
-                    syncThread.start();
-                    alreadyInProgress = false;
-                } else {
-                    alreadyInProgress = true;
+            if (ENABLE_LOG) {
+                if (extras != null) {
+                    extras.size(); // Unparcel so its toString() will show the contents.
                 }
+                Log.d(TAG, "startSync() start " + authority + " " + account + " " + extras);
             }
+            try {
+                final SyncContext syncContextClient = new SyncContext(syncContext);
 
-            // do this outside since we don't want to call back into the syncContext while
-            // holding the synchronization lock
-            if (alreadyInProgress) {
-                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+                boolean alreadyInProgress;
+                // synchronize to make sure that mSyncThreads doesn't change between when we
+                // check it and when we use it
+                final Account threadsKey = toSyncKey(account);
+                synchronized (mSyncThreadLock) {
+                    if (!mSyncThreads.containsKey(threadsKey)) {
+                        if (mAutoInitialize
+                                && extras != null
+                                && extras.getBoolean(
+                                        ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
+                            try {
+                                if (ContentResolver.getIsSyncable(account, authority) < 0) {
+                                    ContentResolver.setIsSyncable(account, authority, 1);
+                                }
+                            } finally {
+                                syncContextClient.onFinished(new SyncResult());
+                            }
+                            return;
+                        }
+                        SyncThread syncThread = new SyncThread(
+                                "SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
+                                syncContextClient, authority, account, extras);
+                        mSyncThreads.put(threadsKey, syncThread);
+                        syncThread.start();
+                        alreadyInProgress = false;
+                    } else {
+                        if (ENABLE_LOG) {
+                            Log.d(TAG, "  alreadyInProgress");
+                        }
+                        alreadyInProgress = true;
+                    }
+                }
+
+                // do this outside since we don't want to call back into the syncContext while
+                // holding the synchronization lock
+                if (alreadyInProgress) {
+                    syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+                }
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "startSync() caught exception", th);
+                }
+                throw th;
+            } finally {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "startSync() finishing");
+                }
             }
         }
 
         @Override
         public void cancelSync(ISyncContext syncContext) {
-            // synchronize to make sure that mSyncThreads doesn't change between when we
-            // check it and when we use it
-            SyncThread info = null;
-            synchronized (mSyncThreadLock) {
-                for (SyncThread current : mSyncThreads.values()) {
-                    if (current.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
-                        info = current;
-                        break;
+            try {
+                // synchronize to make sure that mSyncThreads doesn't change between when we
+                // check it and when we use it
+                SyncThread info = null;
+                synchronized (mSyncThreadLock) {
+                    for (SyncThread current : mSyncThreads.values()) {
+                        if (current.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
+                            info = current;
+                            break;
+                        }
                     }
                 }
-            }
-            if (info != null) {
-                if (mAllowParallelSyncs) {
-                    onSyncCanceled(info);
+                if (info != null) {
+                    if (ENABLE_LOG) {
+                        Log.d(TAG, "cancelSync() " + info.mAuthority + " " + info.mAccount);
+                    }
+                    if (mAllowParallelSyncs) {
+                        onSyncCanceled(info);
+                    } else {
+                        onSyncCanceled();
+                    }
                 } else {
-                    onSyncCanceled();
+                    if (ENABLE_LOG) {
+                        Log.w(TAG, "cancelSync() unknown context");
+                    }
+                }
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "cancelSync() caught exception", th);
+                }
+                throw th;
+            } finally {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "cancelSync() finishing");
                 }
             }
         }
-
-        public void initialize(Account account, String authority) throws RemoteException {
-            Bundle extras = new Bundle();
-            extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
-            startSync(null, authority, account, extras);
-        }
     }
 
     /**
@@ -256,6 +294,10 @@
         public void run() {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
+            if (ENABLE_LOG) {
+                Log.d(TAG, "Thread started");
+            }
+
             // Trace this sync instance.  Note, conceptually this should be in
             // SyncStorageEngine.insertStartSyncEvent(), but the trace functions require unique
             // threads in order to track overlapping operations, so we'll do it here for now.
@@ -265,8 +307,15 @@
             ContentProviderClient provider = null;
             try {
                 if (isCanceled()) {
+                    if (ENABLE_LOG) {
+                        Log.d(TAG, "Already canceled");
+                    }
                     return;
                 }
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "Calling onPerformSync...");
+                }
+
                 provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
                 if (provider != null) {
                     AbstractThreadedSyncAdapter.this.onPerformSync(mAccount, mExtras,
@@ -274,10 +323,23 @@
                 } else {
                     syncResult.databaseError = true;
                 }
+
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "onPerformSync done");
+                }
+
             } catch (SecurityException e) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "SecurityException", e);
+                }
                 AbstractThreadedSyncAdapter.this.onSecurityException(mAccount, mExtras,
                         mAuthority, syncResult);
                 syncResult.databaseError = true;
+            } catch (RuntimeException | Error th) {
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "caught exception", th);
+                }
+                throw th;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
 
@@ -292,6 +354,10 @@
                 synchronized (mSyncThreadLock) {
                     mSyncThreads.remove(mThreadsKey);
                 }
+
+                if (ENABLE_LOG) {
+                    Log.d(TAG, "Thread finished");
+                }
             }
         }
 
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 5bc1f18..9323261 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -43,6 +43,7 @@
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
+import libcore.io.IoUtils;
 
 /**
  * Representation of a clipped data on the clipboard.
@@ -335,46 +336,46 @@
             // If this Item has a URI value, try using that.
             Uri uri = getUri();
             if (uri != null) {
-
                 // First see if the URI can be opened as a plain text stream
                 // (of any sub-type).  If so, this is the best textual
                 // representation for it.
+                final ContentResolver resolver = context.getContentResolver();
+                AssetFileDescriptor descr = null;
                 FileInputStream stream = null;
+                InputStreamReader reader = null;
                 try {
-                    // Ask for a stream of the desired type.
-                    AssetFileDescriptor descr = context.getContentResolver()
-                            .openTypedAssetFileDescriptor(uri, "text/*", null);
-                    stream = descr.createInputStream();
-                    InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
-
-                    // Got it...  copy the stream into a local string and return it.
-                    StringBuilder builder = new StringBuilder(128);
-                    char[] buffer = new char[8192];
-                    int len;
-                    while ((len=reader.read(buffer)) > 0) {
-                        builder.append(buffer, 0, len);
+                    try {
+                        // Ask for a stream of the desired type.
+                        descr = resolver.openTypedAssetFileDescriptor(uri, "text/*", null);
+                    } catch (SecurityException e) {
+                        Log.w("ClipData", "Failure opening stream", e);
+                    } catch (FileNotFoundException|RuntimeException e) {
+                        // Unable to open content URI as text...  not really an
+                        // error, just something to ignore.
                     }
-                    return builder.toString();
-
-                } catch (SecurityException e) {
-                    Log.w("ClipData", "Failure opening stream", e);
-
-                } catch (FileNotFoundException e) {
-                    // Unable to open content URI as text...  not really an
-                    // error, just something to ignore.
-
-                } catch (IOException e) {
-                    // Something bad has happened.
-                    Log.w("ClipData", "Failure loading text", e);
-                    return e.toString();
-
-                } finally {
-                    if (stream != null) {
+                    if (descr != null) {
                         try {
-                            stream.close();
+                            stream = descr.createInputStream();
+                            reader = new InputStreamReader(stream, "UTF-8");
+
+                            // Got it...  copy the stream into a local string and return it.
+                            final StringBuilder builder = new StringBuilder(128);
+                            char[] buffer = new char[8192];
+                            int len;
+                            while ((len=reader.read(buffer)) > 0) {
+                                builder.append(buffer, 0, len);
+                            }
+                            return builder.toString();
                         } catch (IOException e) {
+                            // Something bad has happened.
+                            Log.w("ClipData", "Failure loading text", e);
+                            return e.toString();
                         }
                     }
+                } finally {
+                    IoUtils.closeQuietly(descr);
+                    IoUtils.closeQuietly(stream);
+                    IoUtils.closeQuietly(reader);
                 }
 
                 // If we couldn't open the URI as a stream, use the URI itself as a textual
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index a04a7b2..f8c139f 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -524,7 +524,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
@@ -579,7 +582,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 309827c..9ccc552 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2938,7 +2938,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 32e7d48..654b8da 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -34,7 +34,6 @@
 import android.annotation.UserIdInt;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
-import android.app.Notification;
 import android.app.VrManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -127,8 +126,8 @@
      * File creation mode: allow all other applications to have read access to
      * the created file.
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
-     * mode will throw a {@link SecurityException}.
+     * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
+     * mode throws a {@link SecurityException}.
      *
      * @deprecated Creating world-readable files is very dangerous, and likely
      *             to cause security holes in applications. It is strongly
@@ -147,7 +146,7 @@
      * File creation mode: allow all other applications to have write access to
      * the created file.
      * <p>
-     * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
+     * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
      * mode will throw a {@link SecurityException}.
      *
      * @deprecated Creating world-writable files is very dangerous, and likely
@@ -814,6 +813,9 @@
      */
     public abstract boolean deleteSharedPreferences(String name);
 
+    /** @hide */
+    public abstract void reloadSharedPreferences();
+
     /**
      * Open a private file associated with this Context's application package
      * for reading.
@@ -1127,13 +1129,47 @@
      * </ul>
      * <p>
      * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
-     * are required to read or write to the returned path; it's always
-     * accessible to the calling app. This only applies to paths generated for
-     * package name of the calling application. To access paths belonging to
-     * other packages,
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
-     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+     * are required to read or write to the path that this method returns.
+     * However, starting from {@link android.os.Build.VERSION_CODES#M},
+     * to read the OBB expansion files, you must declare the
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission in the app manifest and ask for
+     * permission at runtime as follows:
+     * </p>
      * <p>
+     * {@code <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+     * android:maxSdkVersion="23" />}
+     * </p>
+     * <p>
+     * Starting from {@link android.os.Build.VERSION_CODES#N},
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
+     * permission is not required, so don’t ask for this
+     * permission at runtime. To handle both cases, your app must first try to read the OBB file,
+     * and if it fails, you must request
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission at runtime.
+     * </p>
+     *
+     * <p>
+     * The following code snippet shows how to do this:
+     * </p>
+     *
+     * <pre>
+     * File obb = new File(obb_filename);
+     * boolean open_failed = false;
+     *
+     * try {
+     *     BufferedReader br = new BufferedReader(new FileReader(obb));
+     *     open_failed = false;
+     *     ReadObbFile(br);
+     * } catch (IOException e) {
+     *     open_failed = true;
+     * }
+     *
+     * if (open_failed) {
+     *     // request READ_EXTERNAL_STORAGE permission before reading OBB file
+     *     ReadObbFileWithPermission();
+     * }
+     * </pre>
+     *
      * On devices with multiple users (as described by {@link UserManager}),
      * multiple users may share the same OBB storage location. Applications
      * should ensure that multiple instances running under different users don't
@@ -2675,8 +2711,8 @@
 
     /**
      * Similar to {@link #startService(Intent)}, but with an implicit promise that the
-     * Service will call {@link android.app.Service#startForeground(int, Notification)
-     * startForeground(int, Notification)} once it begins running.  The service is given
+     * Service will call {@link android.app.Service#startForeground(int, android.app.Notification)
+     * startForeground(int, android.app.Notification)} once it begins running.  The service is given
      * an amount of time comparable to the ANR interval to do this, otherwise the system
      * will automatically stop the service and declare the app ANR.
      *
@@ -2697,7 +2733,7 @@
      * or the service can not be found.
      *
      * @see #stopService
-     * @see android.app.Service#startForeground(int, Notification)
+     * @see android.app.Service#startForeground(int, android.app.Notification)
      */
     @Nullable
     public abstract ComponentName startForegroundService(Intent service);
@@ -3528,6 +3564,17 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.telephony.euicc.EuiccManager} to manage the device eUICC (embedded SIM).
+     *
+     * @see #getSystemService
+     * @see android.telephony.euicc.EuiccManager
+     * TODO(b/35851809): Unhide this API.
+     * @hide
+     */
+    public static final String EUICC_SERVICE = "euicc_service";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.text.ClipboardManager} for accessing and modifying
      * {@link android.content.ClipboardManager} for accessing and modifying
      * the contents of the global clipboard.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index df59f0e..a9fd58b 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -19,7 +19,6 @@
 import android.annotation.SystemApi;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
-import android.app.Notification;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -173,6 +172,12 @@
         return mBase.getSharedPreferences(file, mode);
     }
 
+    /** @hide */
+    @Override
+    public void reloadSharedPreferences() {
+        mBase.reloadSharedPreferences();
+    }
+
     @Override
     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
         return mBase.moveSharedPreferencesFrom(sourceContext, name);
diff --git a/core/java/android/content/ISyncAdapter.aidl b/core/java/android/content/ISyncAdapter.aidl
index dd9d14e..4660527 100644
--- a/core/java/android/content/ISyncAdapter.aidl
+++ b/core/java/android/content/ISyncAdapter.aidl
@@ -44,12 +44,4 @@
      * @param syncContext the ISyncContext that was passed to {@link #startSync}
      */
     void cancelSync(ISyncContext syncContext);
-
-    /**
-     * Initialize the SyncAdapter for this account and authority.
-     *
-     * @param account the account that should be synced
-     * @param authority the authority that should be synced
-     */
-    void initialize(in Account account, String authority);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 970b362..6ed1fb7 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import static android.content.ContentProvider.maybeAddUserId;
+
 import android.annotation.AnyRes;
 import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
@@ -43,7 +45,7 @@
 import android.os.ShellCommand;
 import android.os.StrictMode;
 import android.os.UserHandle;
-import android.os.storage.StorageManager;
+import android.provider.ContactsContract.QuickContact;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
@@ -51,7 +53,9 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+
 import com.android.internal.util.XmlUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -69,8 +73,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static android.content.ContentProvider.maybeAddUserId;
-
 /**
  * An intent is an abstract description of an operation to be performed.  It
  * can be used with {@link Context#startActivity(Intent) startActivity} to
@@ -3442,11 +3444,13 @@
             "android.intent.extra.FORCE_FACTORY_RESET";
 
     /**
-     * Broadcast action: report that a settings element is being restored from backup.  The intent
-     * contains three extras: EXTRA_SETTING_NAME is a string naming the restored setting,
-     * EXTRA_SETTING_NEW_VALUE is the value being restored, and EXTRA_SETTING_PREVIOUS_VALUE
-     * is the value of that settings entry prior to the restore operation.  All of these values are
-     * represented as strings.
+     * Broadcast action: report that a settings element is being restored from backup. The intent
+     * contains four extras: EXTRA_SETTING_NAME is a string naming the restored setting,
+     * EXTRA_SETTING_NEW_VALUE is the value being restored, EXTRA_SETTING_PREVIOUS_VALUE
+     * is the value of that settings entry prior to the restore operation, and
+     * EXTRA_SETTING_RESTORED_FROM_SDK_INT is the version of the SDK that the setting has been
+     * restored from (corresponds to {@link android.os.Build.VERSION#SDK_INT}). The first three
+     * values are represented as strings, the fourth one as int.
      *
      * <p>This broadcast is sent only for settings provider entries known to require special handling
      * around restore time.  These entries are found in the BROADCAST_ON_RESTORE table within
@@ -3455,6 +3459,7 @@
      * @see #EXTRA_SETTING_NAME
      * @see #EXTRA_SETTING_PREVIOUS_VALUE
      * @see #EXTRA_SETTING_NEW_VALUE
+     * @see #EXTRA_SETTING_RESTORED_FROM_SDK_INT
      * {@hide}
      */
     public static final String ACTION_SETTING_RESTORED = "android.os.action.SETTING_RESTORED";
@@ -3465,6 +3470,8 @@
     public static final String EXTRA_SETTING_PREVIOUS_VALUE = "previous_value";
     /** {@hide} */
     public static final String EXTRA_SETTING_NEW_VALUE = "new_value";
+    /** {@hide} */
+    public static final String EXTRA_SETTING_RESTORED_FROM_SDK_INT = "restored_from_sdk_int";
 
     /**
      * Activity Action: Process a piece of text.
@@ -4765,10 +4772,21 @@
     /** {@hide} */
     public static final String EXTRA_REASON = "android.intent.extra.REASON";
 
-    /** {@hide} */
+    /**
+     * {@hide}
+     * This extra will be send together with {@link #ACTION_FACTORY_RESET}
+     */
     public static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
 
     /**
+     * {@hide}
+     * This extra will be set to true when the user choose to wipe the data on eSIM during factory
+     * reset for the device with eSIM. This extra will be sent together with
+     * {@link #ACTION_FACTORY_RESET}
+     */
+    public static final String EXTRA_WIPE_ESIMS = "com.android.internal.intent.extra.WIPE_ESIMS";
+
+    /**
      * Optional {@link android.app.PendingIntent} extra used to deliver the result of the SIM
      * activation request.
      * TODO: Add information about the structure and response data used with the pending intent.
@@ -9771,6 +9789,7 @@
                 && leavingPackage) {
             switch (mAction) {
                 case ACTION_PROVIDER_CHANGED:
+                case QuickContact.ACTION_QUICK_CONTACT:
                     // Ignore actions that don't need to grant
                     break;
                 default:
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index ddbdb8a..ccd7994 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -20,6 +20,7 @@
 import android.content.pm.XmlSerializerAndParser;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.SparseArray;
@@ -63,7 +64,7 @@
                     sa.getString(com.android.internal.R.styleable.SyncAdapter_contentAuthority);
             final String accountType =
                     sa.getString(com.android.internal.R.styleable.SyncAdapter_accountType);
-            if (authority == null || accountType == null) {
+            if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(accountType)) {
                 return null;
             }
             final boolean userVisible =
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index bb24ccd..abf9cc9 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -24,7 +24,11 @@
 
 /** @hide */
 public class SyncStatusInfo implements Parcelable {
-    static final int VERSION = 2;
+    private static final String TAG = "Sync";
+
+    static final int VERSION = 4;
+
+    private static final int MAX_EVENT_COUNT = 10;
 
     public final int authorityId;
     public long totalElapsedTime;
@@ -47,7 +51,8 @@
   // no race conditions when accessing this list
   private ArrayList<Long> periodicSyncTimes;
 
-    private static final String TAG = "Sync";
+    private final ArrayList<Long> mLastEventTimes = new ArrayList<>();
+    private final ArrayList<String> mLastEvents = new ArrayList<>();
 
     public SyncStatusInfo(int authorityId) {
         this.authorityId = authorityId;
@@ -92,6 +97,12 @@
         } else {
             parcel.writeInt(-1);
         }
+        parcel.writeInt(mLastEventTimes.size());
+        for (int i = 0; i < mLastEventTimes.size(); i++) {
+            parcel.writeLong(mLastEventTimes.get(i));
+            parcel.writeString(mLastEvents.get(i));
+        }
+        parcel.writeInt(numSourcePeriodic);
     }
 
     public SyncStatusInfo(Parcel parcel) {
@@ -117,15 +128,34 @@
         if (version == 1) {
             periodicSyncTimes = null;
         } else {
-            int N = parcel.readInt();
-            if (N < 0) {
+            final int count = parcel.readInt();
+            if (count < 0) {
                 periodicSyncTimes = null;
             } else {
                 periodicSyncTimes = new ArrayList<Long>();
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < count; i++) {
                     periodicSyncTimes.add(parcel.readLong());
                 }
             }
+            if (version >= 3) {
+                mLastEventTimes.clear();
+                mLastEvents.clear();
+                final int nEvents = parcel.readInt();
+                for (int i = 0; i < nEvents; i++) {
+                    mLastEventTimes.add(parcel.readLong());
+                    mLastEvents.add(parcel.readString());
+                }
+            }
+        }
+        if (version < 4) {
+            // Before version 4, numSourcePeriodic wasn't persisted.
+            numSourcePeriodic = numSyncs - numSourceLocal - numSourcePoll - numSourceServer
+                    - numSourceUser;
+            if (numSourcePeriodic < 0) { // Sanity check.
+                numSourcePeriodic = 0;
+            }
+        } else {
+            numSourcePeriodic = parcel.readInt();
         }
     }
 
@@ -149,6 +179,8 @@
         if (other.periodicSyncTimes != null) {
             periodicSyncTimes = new ArrayList<Long>(other.periodicSyncTimes);
         }
+        mLastEventTimes.addAll(other.mLastEventTimes);
+        mLastEvents.addAll(other.mLastEvents);
     }
 
     public void setPeriodicSyncTime(int index, long when) {
@@ -172,6 +204,31 @@
         }
     }
 
+    /** */
+    public void addEvent(String message) {
+        if (mLastEventTimes.size() >= MAX_EVENT_COUNT) {
+            mLastEventTimes.remove(MAX_EVENT_COUNT - 1);
+            mLastEvents.remove(MAX_EVENT_COUNT - 1);
+        }
+        mLastEventTimes.add(0, System.currentTimeMillis());
+        mLastEvents.add(0, message);
+    }
+
+    /** */
+    public int getEventCount() {
+        return mLastEventTimes.size();
+    }
+
+    /** */
+    public long getEventTime(int i) {
+        return mLastEventTimes.get(i);
+    }
+
+    /** */
+    public String getEvent(int i) {
+        return mLastEvents.get(i);
+    }
+
     public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
         public SyncStatusInfo createFromParcel(Parcel in) {
             return new SyncStatusInfo(in);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 9a01476..18f9e53 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -28,8 +28,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
-
 /**
  * Information you can retrieve about a particular application
  * activity or receiver. This corresponds to information collected
diff --git a/core/java/android/content/pm/IDexModuleRegisterCallback.aidl b/core/java/android/content/pm/IDexModuleRegisterCallback.aidl
new file mode 100644
index 0000000..4af6999
--- /dev/null
+++ b/core/java/android/content/pm/IDexModuleRegisterCallback.aidl
@@ -0,0 +1,28 @@
+/*
+** Copyright 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.content.pm;
+
+import android.os.Bundle;
+
+/**
+ * Callback for registering a dex module with the Package Manager.
+ *
+ * @hide
+ */
+oneway interface IDexModuleRegisterCallback {
+    void onDexModuleRegistered(in String dexModulePath, in boolean success, in String message);
+}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e8e0eb3..4b44a17 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -25,6 +25,7 @@
 import android.content.pm.ChangedPackages;
 import android.content.pm.InstantAppInfo;
 import android.content.pm.FeatureInfo;
+import android.content.pm.IDexModuleRegisterCallback;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageDeleteObserver;
@@ -71,7 +72,7 @@
     String[] currentToCanonicalPackageNames(in String[] names);
     String[] canonicalToCurrentPackageNames(in String[] names);
 
-    PermissionInfo getPermissionInfo(String name, int flags);
+    PermissionInfo getPermissionInfo(String name, String packageName, int flags);
 
     ParceledListSlice queryPermissionsByGroup(String group, int flags);
 
@@ -475,6 +476,38 @@
             String loaderIsa);
 
     /**
+     * Register an application dex module with the package manager.
+     * The package manager will keep track of the given module for future optimizations.
+     *
+     * Dex module optimizations will disable the classpath checking at runtime. The client bares
+     * the responsibility to ensure that the static assumptions on classes in the optimized code
+     * hold at runtime (e.g. there's no duplicate classes in the classpath).
+     *
+     * Note that the package manager already keeps track of dex modules loaded with
+     * {@link dalvik.system.DexClassLoader} and {@link dalvik.system.PathClassLoader}.
+     * This can be called for an eager registration.
+     *
+     * The call might take a while and the results will be posted on the main thread, using
+     * the given callback.
+     *
+     * If the module is intended to be shared with other apps, make sure that the file
+     * permissions allow for it.
+     * If at registration time the permissions allow for others to read it, the module would
+     * be marked as a shared module which might undergo a different optimization strategy.
+     * (usually shared modules will generated larger optimizations artifacts,
+     * taking more disk space).
+     *
+     * @param packageName the package name to which the dex module belongs
+     * @param dexModulePath the absolute path of the dex module.
+     * @param isSharedModule whether or not the module is intended to be used by other apps.
+     * @param callback if not null,
+     *   {@link android.content.pm.IDexModuleRegisterCallback.IDexModuleRegisterCallback#onDexModuleRegistered}
+     *   will be called once the registration finishes.
+     */
+     oneway void registerDexModule(in String packageName, in String dexModulePath,
+             in boolean isSharedModule, IDexModuleRegisterCallback callback);
+
+    /**
      * Ask the package manager to perform a dex-opt for the given reason. The package
      * manager will map the reason to a compiler filter according to the current system
      * configuration.
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 358787e..e9c9588 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -20,12 +20,10 @@
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 /**
  * A representation of an activity that can belong to this user or a managed
@@ -173,12 +171,6 @@
     public Drawable getBadgedIcon(int density) {
         Drawable originalIcon = getIcon(density);
 
-        if (originalIcon instanceof BitmapDrawable) {
-            // TODO: Go through LauncherAppsService
-            return mPm.getUserBadgedIcon(originalIcon, mUser);
-        } else {
-            Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
-        }
-        return originalIcon;
+        return mPm.getUserBadgedIcon(originalIcon, mUser);
     }
 }
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index ed41e79..aa9562f 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -608,15 +608,15 @@
     }
 
     /**
-     * Get {@link ApplicationInfo} for a profile
+     * Returns {@link ApplicationInfo} about an application installed for a specific user profile.
      *
      * @param packageName The package name of the application
      * @param flags Additional option flags {@link PackageManager#getApplicationInfo}
      * @param user The UserHandle of the profile.
      *
-     * @return An {@link ApplicationInfo} containing information about the package or
-     *         null if the package isn't installed for the given user, or the target user
-     *         is not enabled.
+     * @return {@link ApplicationInfo} containing information about the package. Returns
+     *         {@code null} if the package isn't installed for the given profile, or the profile
+     *         isn't enabled.
      */
     public ApplicationInfo getApplicationInfo(@NonNull String packageName,
             @ApplicationInfoFlags int flags, @NonNull UserHandle user)
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 7f3f35f..2add9a3 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -24,6 +24,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.app.ActivityManager;
+import android.app.AppGlobals;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager.InstallReason;
@@ -1355,6 +1356,17 @@
          * if unavailable.
          */
         public @Nullable Bitmap getAppIcon() {
+            if (appIcon == null) {
+                // Icon may have been omitted for calls that return bulk session
+                // lists, so try fetching the specific icon.
+                try {
+                    final SessionInfo info = AppGlobals.getPackageManager().getPackageInstaller()
+                            .getSessionInfo(sessionId);
+                    appIcon = (info != null) ? info.appIcon : null;
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
             return appIcon;
         }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index be2cd10..06dbc0b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1898,6 +1898,14 @@
     public static final String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
 
     /**
+     * The device includes broadcast radio tuner.
+     *
+     * @hide FutureFeature
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_RADIO = "android.hardware.radio";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device includes an accelerometer.
      */
@@ -2031,6 +2039,15 @@
             "android.hardware.telephony.carrierlock";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
+     * supports embedded subscriptions on eUICCs.
+     * TODO(b/35851809): Make this public.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports connecting to USB devices
      * as the USB host.
@@ -2267,6 +2284,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports Wi-Fi Passpoint.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint";
+
+    /**
+     * 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
@@ -2312,6 +2337,18 @@
     public static final String FEATURE_EMBEDDED = "android.hardware.type.embedded";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: This is a device dedicated to be primarily used
+     * with keyboard, mouse or touchpad. This includes traditional desktop
+     * computers, laptops and variants such as convertibles or detachables.
+     * Due to the larger screen, the device will most likely use the
+     * {@link #FEATURE_FREEFORM_WINDOW_MANAGEMENT} feature as well.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_PC = "android.hardware.type.pc";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
      * The device supports printing.
      */
@@ -5731,4 +5768,46 @@
      * @hide
      */
     public abstract String getInstantAppAndroidId(String packageName, @NonNull UserHandle user);
+
+    /**
+     * Callback use to notify the callers of module registration that the operation
+     * has finished.
+     *
+     * @hide
+     */
+    public static abstract class DexModuleRegisterCallback {
+        public abstract void onDexModuleRegistered(String dexModulePath, boolean success,
+                String message);
+    }
+
+    /**
+     * Register an application dex module with the package manager.
+     * The package manager will keep track of the given module for future optimizations.
+     *
+     * Dex module optimizations will disable the classpath checking at runtime. The client bares
+     * the responsibility to ensure that the static assumptions on classes in the optimized code
+     * hold at runtime (e.g. there's no duplicate classes in the classpath).
+     *
+     * Note that the package manager already keeps track of dex modules loaded with
+     * {@link dalvik.system.DexClassLoader} and {@link dalvik.system.PathClassLoader}.
+     * This can be called for an eager registration.
+     *
+     * The call might take a while and the results will be posted on the main thread, using
+     * the given callback.
+     *
+     * If the module is intended to be shared with other apps, make sure that the file
+     * permissions allow for it.
+     * If at registration time the permissions allow for others to read it, the module would
+     * be marked as a shared module which might undergo a different optimization strategy.
+     * (usually shared modules will generated larger optimizations artifacts,
+     * taking more disk space).
+     *
+     * @param dexModulePath the absolute path of the dex module.
+     * @param callback if not null, {@link DexModuleRegisterCallback#onDexModuleRegistered} will
+     *                 be called once the registration finishes.
+     *
+     * @hide
+     */
+    public abstract void registerDexModule(String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c67376c..bcba938e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -40,7 +40,7 @@
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
 
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -200,6 +200,8 @@
     // Temporary workaround; allow meta-data to expose components to instant apps
     private static final String META_DATA_INSTANT_APPS = "instantapps.clients.allowed";
 
+    private static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
+
     /**
      * Bit mask of all the valid bits that can be set in recreateOnConfigChanges.
      * @hide
@@ -3639,6 +3641,7 @@
 
         final int innerDepth = parser.getDepth();
         int type;
+
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                 && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -3815,6 +3818,10 @@
             }
         }
 
+        // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
+        // every activity info has had a chance to set it from its attributes.
+        setMaxAspectRatio(owner);
+
         modifySharedLibrariesForBackwardCompatibility(owner);
 
         if (hasDomainURLs(owner)) {
@@ -4258,7 +4265,12 @@
                 a.info.flags |= FLAG_ALWAYS_FOCUSABLE;
             }
 
-            setActivityMaxAspectRatio(a.info, sa, owner);
+            if (sa.hasValue(R.styleable.AndroidManifestActivity_maxAspectRatio)
+                    && sa.getType(R.styleable.AndroidManifestActivity_maxAspectRatio)
+                    == TypedValue.TYPE_FLOAT) {
+                a.setMaxAspectRatio(sa.getFloat(R.styleable.AndroidManifestActivity_maxAspectRatio,
+                        0 /*default*/));
+            }
 
             a.info.lockTaskLaunchMode =
                     sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
@@ -4271,7 +4283,7 @@
                 sa.getString(R.styleable.AndroidManifestActivity_enableVrMode);
 
             a.info.rotationAnimation =
-                sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, ROTATION_ANIMATION_ROTATE);
+                sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation, ROTATION_ANIMATION_UNSPECIFIED);
 
             a.info.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
                     ActivityInfo.COLOR_MODE_DEFAULT);
@@ -4496,28 +4508,40 @@
         }
     }
 
-    private void setActivityMaxAspectRatio(ActivityInfo aInfo, TypedArray sa, Package owner) {
-        if (aInfo.resizeMode == RESIZE_MODE_RESIZEABLE
-                || aInfo.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
-            // Resizeable activities can be put in any aspect ratio.
-            aInfo.maxAspectRatio = 0;
-            return;
-        }
-
+    /**
+     * Sets every the max aspect ratio of every child activity that doesn't already have an aspect
+     * ratio set.
+     */
+    private void setMaxAspectRatio(Package owner) {
         // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater.
         // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD.
-        float defaultMaxAspectRatio = owner.applicationInfo.targetSdkVersion < O
+        float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O
                 ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;
-        if (owner.applicationInfo.maxAspectRatio != 0 ) {
+
+        if (owner.applicationInfo.maxAspectRatio != 0) {
             // Use the application max aspect ration as default if set.
-            defaultMaxAspectRatio = owner.applicationInfo.maxAspectRatio;
+            maxAspectRatio = owner.applicationInfo.maxAspectRatio;
+        } else if (owner.mAppMetaData != null
+                && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) {
+            maxAspectRatio = owner.mAppMetaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio);
         }
 
-        aInfo.maxAspectRatio = sa.getFloat(
-                R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio);
-        if (aInfo.maxAspectRatio < 1.0f && aInfo.maxAspectRatio != 0) {
-            // Ignore any value lesser than 1.0.
-            aInfo.maxAspectRatio = 0;
+        for (Activity activity : owner.activities) {
+            // If the max aspect ratio for the activity has already been set, skip.
+            if (activity.hasMaxAspectRatio()) {
+                continue;
+            }
+
+            // By default we prefer to use a values defined on the activity directly than values
+            // defined on the application. We do not check the styled attributes on the activity
+            // as it would have already been set when we processed the activity. We wait to process
+            // the meta data here since this method is called at the end of processing the
+            // application and all meta data is guaranteed.
+            final float activityAspectRatio = activity.metaData != null
+                    ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio)
+                    : maxAspectRatio;
+
+            activity.setMaxAspectRatio(activityAspectRatio);
         }
     }
 
@@ -4658,6 +4682,7 @@
         info.windowLayout = target.info.windowLayout;
         info.resizeMode = target.info.resizeMode;
         info.maxAspectRatio = target.info.maxAspectRatio;
+
         info.encryptionAware = info.directBootAware = target.info.directBootAware;
 
         Activity a = new Activity(mParseActivityAliasArgs, info);
@@ -6940,6 +6965,11 @@
 
     public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable {
         public final ActivityInfo info;
+        private boolean mHasMaxAspectRatio;
+
+        private boolean hasMaxAspectRatio() {
+            return mHasMaxAspectRatio;
+        }
 
         public Activity(final ParseComponentArgs args, final ActivityInfo _info) {
             super(args, _info);
@@ -6952,6 +6982,23 @@
             info.packageName = packageName;
         }
 
+
+        private void setMaxAspectRatio(float maxAspectRatio) {
+            if (info.resizeMode == RESIZE_MODE_RESIZEABLE
+                    || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
+                // Resizeable activities can be put in any aspect ratio.
+                return;
+            }
+
+            if (maxAspectRatio < 1.0f && maxAspectRatio != 0) {
+                // Ignore any value lesser than 1.0.
+                return;
+            }
+
+            info.maxAspectRatio = maxAspectRatio;
+            mHasMaxAspectRatio = true;
+        }
+
         public String toString() {
             StringBuilder sb = new StringBuilder(128);
             sb.append("Activity{");
@@ -6971,11 +7018,13 @@
         public void writeToParcel(Parcel dest, int flags) {
             super.writeToParcel(dest, flags);
             dest.writeParcelable(info, flags | Parcelable.PARCELABLE_ELIDE_DUPLICATES);
+            dest.writeBoolean(mHasMaxAspectRatio);
         }
 
         private Activity(Parcel in) {
             super(in);
             info = in.readParcelable(Object.class.getClassLoader());
+            mHasMaxAspectRatio = in.readBoolean();
 
             for (ActivityIntentInfo aii : intents) {
                 aii.activity = this;
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index c0b82b4..61b0eb0 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -36,161 +36,72 @@
 import java.util.List;
 
 /**
- * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users
- * with quick access to activities other than an app's main activity in the currently-active
- * launcher.  For example,
- * an email app may publish the "compose new email" action, which will directly open the
- * compose activity.  The {@link ShortcutInfo} class contains information about each of the
- * shortcuts themselves.
+ * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users with quick
+ * access to activities other than an app's main activity in the currently-active launcher, provided
+ * that the launcher supports app shortcuts.  For example, an email app may publish the "compose new
+ * email" action, which will directly open the compose activity.  The {@link ShortcutInfo} class
+ * contains information about each of the shortcuts themselves.
  *
- * <h3>Static Shortcuts and Dynamic Shortcuts</h3>
+ * <p>This page discusses the implementation details of the <code>ShortcutManager</code> class. For
+ * guidance on performing operations on app shortcuts within your app, see the
+ * <a href="/guide/topics/ui/shortcuts.html">App Shortcuts</a> feature guide.
  *
- * <p>
- * There are several different types of shortcuts:
+ * <h3>Shortcut characteristics</h3>
  *
- * <ul>
- * <li><p>Static shortcuts are declared in a resource XML file, which is referenced in the publisher
- * app's <code>AndroidManifest.xml</code> file. These shortcuts are visually associated with an
- * app's launcher icon.
- * <p>Static shortcuts are published when an app is installed, and the details of these shortcuts
- * change when an app is upgraded with an updated XML file. Static shortcuts are immutable, and
- * their definitions, such as icons and labels, cannot be changed dynamically without upgrading the
- * publisher app.</li>
+ * This section describes in-depth details about each shortcut type's usage and availability.
  *
- * <li>Dynamic shortcuts are published at runtime using this class's APIs. These shortcuts are
- * visually associated with an app's launcher icon. Apps can publish, update, and remove dynamic
- * shortcuts at runtime.
- * </ul>
+ * <p class="note"><b>Important security note:</b> All shortcut information is stored in
+ * <a href="/training/articles/direct-boot.html">credential encrypted storage</a>, so your app
+ * cannot access a user's shortcuts until after they've unlocked the device.
  *
- * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
- * {@code LAUNCHER} category&mdash;can have shortcuts.
- * If an app has multiple main activities, these activities have different sets
- * of shortcuts.
+ * <h4>Static and dynamic shortcuts</h4>
  *
  * <p>Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user
- * long-presses on an app's launcher icon. Note that the actual gesture may be different
- * depending on the launcher app.
+ * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the
+ * app's launcher icon, but the actual gesture may be different on other launcher apps.
  *
- * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
- * static and dynamic shortcuts combined.
+ * <p>The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
  *
+ * <h4>Pinned shortcuts</h4>
  *
- * <h3>Pinning Shortcuts</h3>
+ * <p>Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned
+ * shortcut is removed from the launcher only in the following situations:
+ * <ul>
+ *     <li>The user removes it.
+ *     <li>The publisher app associated with the shortcut is uninstalled.
+ *     <li>The user performs the clear data action on the publisher app from the device's
+ *     <b>Settings</b> app.
+ * </ul>
  *
- * <p>Apps running in the foreground can also <em>pin</em> shortcuts at runtime, subject to user
- * permission, using this class's APIs. Each pinned shortcut is a copy of a static shortcut or a
- * dynamic shortcut. Although users can pin a shortcut multiple times, the system calls the pinning
- * API only once to complete the pinning process. Unlike static and dynamic shortcuts, pinned
- * shortcuts appear as separate icons, visually distinct from the app's launcher icon, in the
- * launcher. There is no limit to the number of pinned shortcuts that an app can create.
+ * <p>Because the system performs
+ * <a href="/guide/topics/ui/shortcuts.html#backup-and-restore">backup and restore</a> on pinned
+ * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or
+ * server-side identifiers, rather than identifiers generated locally that might not make sense on
+ * other devices.
  *
- * <p>Pinned shortcuts <strong>cannot</strong> be removed by publisher apps. They're removed only
- * when the user removes them, when the publisher app is uninstalled, or when the user performs the
- * clear data action on the publisher app from the device's <b>Settings</b> app.
+ * <h3>Shortcut display order</h3>
  *
- * <p>However, the publisher app can <em>disable</em> pinned shortcuts so they cannot be started.
- * See the following sections for details.
+ * <p>When the launcher displays an app's shortcuts, they should appear in the following order:
  *
- * <h3>Updating and Disabling Shortcuts</h3>
+ * <ul>
+ *   <li>Static shortcuts (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
+ *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
+ *   <li>Within each shortcut type (static and dynamic), sort the shortcuts in order of increasing
+ *   rank according to {@link ShortcutInfo#getRank()}.
+ * </ul>
  *
- * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
- * the pinned shortcut will still be visible and launchable.  This allows an app to have
- * more than {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
+ * <p>Shortcut ranks are non-negative, sequential integers that determine the order in which
+ * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks
+ * of existing shortcuts when you call {@link #updateShortcuts(List)},
+ * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}.
  *
- * <p>For example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
- * <ol>
- *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
- *     conversations (c1, c2, ..., c5).
+ * <p class="note"><b>Note:</b> Ranks are auto-adjusted so that they're unique for each type of
+ * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and
+ * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut
+ * at the second position. In response, the third and fourth shortcuts move closer to the bottom of
+ * the shortcut list, with their ranks changing to 2 and 3, respectively.
  *
- *     <li>The user pins all 5 of the shortcuts.
- *
- *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
- *     so the publisher app
- *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
- *     c4, c5, ..., c8.
- *     The publisher app has to remove c1, c2, and c3 because it can't have more than
- *     5 dynamic shortcuts.
- *
- *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
- *     shortcuts for these conversations are still available and launchable.
- *
- *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
- *     the publisher app, including the 3 pinned
- *     shortcuts, even though an app can have at most 5 dynamic shortcuts.
- *
- *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
- *     8 shortcuts, when, for example, the chat peers' icons have changed.
- * </ol>
- * The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
- * can also be used
- * to update existing shortcuts with the same IDs, but they <b>cannot</b> be used
- * for updating non-dynamic, pinned shortcuts because these two methods try to convert the given
- * lists of shortcuts to dynamic shortcuts.
- *
- *
- * <h4>Disabling Static Shortcuts</h4>
- * <p>When an app is upgraded and the new version
- * no longer uses a static shortcut that appeared in the previous version, this deprecated
- * shortcut isn't published as a static shortcut.
- *
- * <p>If the deprecated shortcut is pinned, then the pinned shortcut will remain on the launcher,
- * but it's disabled automatically. When a pinned shortcut is disabled, this class's APIs cannot
- * update it.
- *
- * <h4>Disabling Dynamic Shortcuts</h4>
- * Sometimes pinned shortcuts become obsolete and may not be usable.  For example, a pinned shortcut
- * to a group chat becomes unusable when the associated group chat is deleted.  In cases like this,
- * apps should use {@link #disableShortcuts(List)}, which removes the specified dynamic
- * shortcuts and also makes any specified pinned shortcuts un-launchable.
- * The {@link #disableShortcuts(List, CharSequence)} method can also be used to disable shortcuts
- * and show users a custom error message when they attempt to launch the disabled shortcuts.
- *
- *
- * <h3>Publishing Static Shortcuts</h3>
- *
- * <p>
- * In order to add static shortcuts to your app, first add
- * {@code <meta-data android:name="android.app.shortcuts" />} to your main activity in
- * AndroidManifest.xml:
- * <pre>
- *&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- *             package="com.example.myapplication"&gt;
- *  &lt;application ... &gt;
- *    &lt;activity android:name="Main"&gt;
- *      &lt;intent-filter&gt;
- *        &lt;action android:name="android.intent.action.MAIN" /&gt;
- *        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
- *      &lt;/intent-filter&gt;
- *      <strong>&lt;meta-data android:name="android.app.shortcuts"
- *                 android:resource="@xml/shortcuts" /&gt;</strong>
- *    &lt;/activity&gt;
- *  &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * Then, define your app's static shortcuts in the <code>res/xml/shortcuts.xml</code>
- * file:
- * <pre>
- *&lt;shortcuts xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- *  &lt;shortcut
- *    android:shortcutId="compose"
- *    android:enabled="true"
- *    android:icon="@drawable/compose_icon"
- *    android:shortcutShortLabel="@string/compose_shortcut_short_label1"
- *    android:shortcutLongLabel="@string/compose_shortcut_long_label1"
- *    android:shortcutDisabledMessage="@string/compose_disabled_message1"&gt;
- *    &lt;intent
- *      android:action="android.intent.action.VIEW"
- *      android:targetPackage="com.example.myapplication"
- *      android:targetClass="com.example.myapplication.ComposeActivity" /&gt;
- *    &lt;!-- If your shortcut is associated with multiple intents, include them
- *         here. The last intent in the list is what the user sees when they
- *         launch this shortcut. --&gt;
- *    &lt;categories android:name="android.shortcut.conversation" /&gt;
- *  &lt;/shortcut&gt;
- *  &lt;!-- Specify more shortcuts here. --&gt;
- *&lt;/shortcuts&gt;
- * </pre>
+ * <h3>Options for static shortcuts</h3>
  *
  * The following list includes descriptions for the different attributes within a static shortcut:
  * <dl>
@@ -236,9 +147,10 @@
  *   {@code android:action} is mandatory.
  *   See <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a> for the
  *   other supported tags.
- *   You can provide multiple intents for a single shortcut so that the last defined activity is launched
- *   with the other activities in the <a href="/guide/components/tasks-and-back-stack.html">back stack</a>.
- *   See {@link android.app.TaskStackBuilder} for details.
+ *   <p>You can provide multiple intents for a single shortcut so that the last defined activity is
+ *   launched with the other activities in the
+ *   <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See
+ *   {@link android.app.TaskStackBuilder} for details.
  *   <p><b>Note:</b> String resources may not be used within an {@code <intent>} element.
  *   </dd>
  *   <dt>{@code categories}</dt>
@@ -247,337 +159,92 @@
  *   </dd>
  * </dl>
  *
- * <h3>Publishing Dynamic Shortcuts</h3>
+ * <h3>Updating shortcuts</h3>
  *
- * <p>
- * Apps can publish dynamic shortcuts with {@link #setDynamicShortcuts(List)}
- * or {@link #addDynamicShortcuts(List)}.  The {@link #updateShortcuts(List)} method can also be
- * used to update existing, mutable shortcuts.
- * Use {@link #removeDynamicShortcuts(List)} or {@link #removeAllDynamicShortcuts()} to remove
- * dynamic shortcuts.
- *
- * <p>The following code snippet shows how to create a single dynamic shortcut:
- * <pre>
- *ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
- *
- *ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
- *    .setShortLabel("Web site")
- *    .setLongLabel("Open the web site")
- *    .setIcon(Icon.createWithResource(context, R.drawable.icon_website))
- *    .setIntent(new Intent(Intent.ACTION_VIEW,
- *                   Uri.parse("https://www.mysite.example.com/")))
- *    .build();
- *
- *shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
- * </pre>
- *
- * <h3>Publishing Pinned Shortcuts</h3>
- *
- * <p>Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a
- * supported launcher programatically using {@link #requestPinShortcut(ShortcutInfo, IntentSender)}.
- * You pass two arguments into this method:
- *
- * <ul>
- *   <li>A {@link ShortcutInfo} object &ndash; If the shortcut already exists, this object should
- *   contain only the shortcut's ID. Otherwise, the new {@link ShortcutInfo} object must contain an
- *   ID, an intent, and a short label for the new shortcut.
- *   <li><p>A {@link android.app.PendingIntent} object &ndash; This intent represents the callback
- *   that your app receives if the shortcut is successfully pinned to the device's launcher.
- *   <p><b>Note:</b> If the user doesn't allow the shortcut to be pinned to the launcher, the
- *   pinning process fails, and the {@link Intent} object that is passed into this
- *   {@link android.app.PendingIntent} object isn't executed.
- *   <div class="note"><p><b>Note:</b> Due to background execution limits introduced in Android
- *   {@link VERSION_CODES#O}, it's best to use a
- *   <a href="{@docRoot}guide/components/broadcasts.html#manifest-declared_receivers">
- *   manifest-declared receiver</a> to receive a callback.
- *   <p>Also, to prevent other apps from invoking the receiver, add the attribute assignment
- *   <code>android:exported="false"</code> to the receiver's manifest entry.</p></div>
- * </ul>
- *
- * The following code snippet shows how to pin a single shortcut that already exists and is enabled:
- *
- * <pre>
- *ShortcutManager mShortcutManager =
- *        context.getSystemService(ShortcutManager.class);
- *
- *if (mShortcutManager.isRequestPinShortcutSupported()) {
- *
- *    // This example defines a new shortcut; that is, this shortcut hasn't
- *    // been published before.
- *    ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder()
- *            .setIcon(myIcon)
- *            .setShortLabel("My awesome shortcut")
- *            .setIntent(myIntent)
- *            .build();
- *
- *    PendingIntent resultPendingIntent = null;
- *
- *    // Create the following Intent and PendingIntent objects only if your app
- *    // needs to be notified that the user allowed the shortcut to be pinned.
- *    // Use a boolean value, such as "appNeedsNotifying", to define this behavior.
- *    if (appNeedsNotifying) {
- *        // We assume here the app has a manifest-declared receiver "MyReceiver".
- *        Intent pinnedShortcutCallbackIntent = new Intent(context, MyReceiver.class);
- *
- *        // Configure the intent so that your app's broadcast receiver gets
- *        // the callback successfully.
- *        PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,
- *                pinnedShortcutCallbackIntent);
- *
- *        resultPendingIntent = successCallback.getIntentSender();
- *    }
- *
- *    mShortcutManager.requestPinShortcut(pinShortcutInfo, resultPendingIntent);
- *}
- * </pre>
- *
- * <p class="note"><strong>Note:</strong> As you add logic in your app to make requests to pin
- * shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether
- * your app can complete this process on a particular device, check the return value of
- * {@link #isRequestPinShortcutSupported()}. Based on this return value, you might decide to hide
- * the option in your app that allows users to pin a shortcut.
- *
- * <p class="note"><strong>Note:</strong> See also the support library APIs
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#isRequestPinShortcutSupported(
- * Context)} and
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#requestPinShortcut(
- * Context, ShortcutInfoCompat, IntentSender)}, which works on Android versions lower than
- * {@link VERSION_CODES#O} by falling back to the deprecated private intent
- * {@code com.android.launcher.action.INSTALL_SHORTCUT}.
- *
- * <h4>Custom Activity for Pinning Shortcuts</h4>
- *
- * <p>You can also create a specialized activity that helps users create shortcuts, complete with
- * custom options and a confirmation button. In your app's manifest file, add
- * {@link Intent#ACTION_CREATE_SHORTCUT} to the activity's <code>&lt;intent-filter&gt;</code>
- * element, as shown in the following snippet:
- *
- * <pre>
- *&lt;manifest&gt;
- *    ...
- *    &lt;application&gt;
- *        &lt;activity android:name="com.example.MyCustomPromptToPinShortcut" ... &gt;
- *            &lt;intent-filter
- *                    action android:name="android.intent.action.ACTION_CREATE_SHORTCUT"&gt;
- *            ...
- *            &lt;/intent-filter&gt;
- *        &lt;/activity&gt;
- *        ...
- *    &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * <p>When you use this specialized activity in your app, the following sequence of steps takes
- * place:</p>
- *
+ * <p>As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
  * <ol>
- *   <li>The user attempts to create a shortcut, triggering the system to start the specialized
- *   activity.</li>
- *   <li>The user sets options for the shortcut.</li>
- *   <li>The user selects the confirmation button, allowing your app to create the shortcut using
- *   the {@link #createShortcutResultIntent(ShortcutInfo)} method. This method returns an
- *   {@link Intent}, which your app relays back to the previously-executing activity using
- *   {@link Activity#setResult(int)}.</li>
- *   <li>Your app calls {@link Activity#finish()} on the activity used for creating the customized
- *   shortcut.</li>
+ *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
+ *     conversations (c1, c2, ..., c5).
+ *
+ *     <li>The user pins all 5 of the shortcuts.
+ *
+ *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
+ *     so the publisher app
+ *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
+ *     c4, c5, ..., c8.
+ *     The publisher app has to remove c1, c2, and c3 because it can't have more than
+ *     5 dynamic shortcuts.
+ *
+ *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
+ *     shortcuts for these conversations are still available and launchable.
+ *
+ *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
+ *     the publisher app, including the 3 pinned shortcuts, even though an app can have at most 5
+ *     dynamic shortcuts.
+ *
+ *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
+ *     8 shortcuts, when, for example, the chat peers' icons have changed.
+ *     <p>The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
+ *     can also be used to update existing shortcuts with the same IDs, but they <b>cannot</b> be
+ *     used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the
+ *     given lists of shortcuts to dynamic shortcuts.
  * </ol>
  *
- * <h3>Shortcut Intents</h3>
+ * <h3>Shortcut intents</h3>
+ *
  * <p>
  * Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags.
  * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other
  * flags; otherwise, if the app is already running, the app is simply brought to
  * the foreground, and the target activity may not appear.
  *
- * <p>The {@link ShortcutInfo.Builder#setIntents(Intent[])} method can be used instead of
- * {@link ShortcutInfo.Builder#setIntent(Intent)} with {@link android.app.TaskStackBuilder}
- * in order to launch an activity with other activities in the back stack.
- * When the user selects a shortcut to load an activity with a back stack,
- * then presses the back key, a parent activity from the same app will be shown
- * instead of the user being navigated back to the launcher.
- *
- * <p>Static shortcuts can also have multiple intents to achieve the same effect.
- * In order to associate multiple {@link Intent} objects with a shortcut, simply list multiple
- * <code>&lt;intent&gt;</code> elements within a single <code>&lt;shortcut&gt;</code> element.
- * The last intent specifies what the user sees when they launch a shortcut.
- *
  * <p>Static shortcuts <b>cannot</b> have custom intent flags.
  * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK}
- * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set.
- * This means, when the app is already running, all the existing activities will be
- * destroyed when a static shortcut is launched.
- * If this behavior is not desirable, you can use a <em>trampoline activity</em>,
- * or an invisible activity that starts another activity in {@link Activity#onCreate},
- * then calls {@link Activity#finish()}.
- * The first activity should include an attribute setting
- * of {@code android:taskAffinity=""} in the app's <code>AndroidManifest.xml</code>
- * file, and the intent within the static shortcut should point at this first activity.
+ * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all
+ * the existing activities in your app will be destroyed when a static shortcut is launched.
+ * If this behavior is not desirable, you can use a <em>trampoline activity</em>, or an invisible
+ * activity that starts another activity in {@link Activity#onCreate}, then calls
+ * {@link Activity#finish()}:
+ * <ol>
+ *     <li>In the <code>AndroidManifest.xml</code> file, the trampoline activity should include the
+ *     attribute assignment {@code android:taskAffinity=""}.
+ *     <li>In the shortcuts resource file, the intent within the static shortcut should point at
+ *     the trampoline activity.
+ * </ol>
  *
+ * <h3>Handling system locale changes</h3>
  *
- * <h3>Showing New Information in a Shortcut</h3>
- * <p>
- * In order to avoid confusion, you should not use {@link #updateShortcuts(List)} to update
- * a shortcut so that it contains conceptually different information.
+ * <p>Apps should update dynamic and pinned shortcuts when the system locale changes using the
+ * {@link Intent#ACTION_LOCALE_CHANGED} broadcast. When the system locale changes,
+ * <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is reset, so even
+ * background apps can add and update dynamic shortcuts until the rate limit is reached again.
  *
- * <p>For example, a phone app may publish the most frequently called contact as a dynamic
- * shortcut.  Over time, this contact may change. When it does, the app should
- * represent the changed contact with a new shortcut that contains a different ID, using either
- * {@link #setDynamicShortcuts(List)} or {@link #addDynamicShortcuts(List)}, rather than updating
- * the existing shortcut with {@link #updateShortcuts(List)}.
- * This is because when the shortcut is pinned, changing
- * it to reference a different contact will likely confuse the user.
+ * <h3>Shortcut limits</h3>
  *
- * <p>On the other hand, when the
- * contact's information has changed, such as the name or picture, the app should
- * use {@link #updateShortcuts(List)} so that the pinned shortcut is updated too.
+ * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
+ * {@code LAUNCHER} category&mdash;can have shortcuts. If an app has multiple main activities, you
+ * need to define the set of shortcuts for <em>each</em> activity.
  *
+ * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
+ * static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts that
+ * an app can create.
  *
- * <h3>Shortcut Display Order</h3>
- * When the launcher displays the shortcuts that are associated with a particular launcher icon,
- * the shortcuts should appear in the following order:
- * <ul>
- *   <li>First show static shortcuts
- *   (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
- *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
- *   <li>Within each category of shortcuts (static and dynamic), sort the shortcuts in order
- *   of increasing rank according to {@link ShortcutInfo#getRank()}.
- * </ul>
- * <p>Shortcut ranks are non-negative, sequential integers
- * that determine the order in which shortcuts appear, assuming that the shortcuts are all in
- * the same category.
- * Ranks of existing shortcuts can be updated with
- * {@link #updateShortcuts(List)}. You can also use {@link #addDynamicShortcuts(List)} and
- * {@link #setDynamicShortcuts(List)}.
+ * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
+ * the pinned shortcut is still visible and launchable.  This allows an app to have more than
+ * {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
  *
- * <p>Ranks are auto-adjusted so that they're unique for each target activity in each category
- * (static or dynamic).  For example, if there are 3 dynamic shortcuts with ranks 0, 1 and 2,
- * adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut at
- * the second position.
- * In response, the third and fourth shortcuts move closer to the bottom of the shortcut list,
- * with their ranks changing to 2 and 3, respectively.
+ * <h4>Rate limiting</h4>
  *
- * <h3>Rate Limiting</h3>
+ * <p>When <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is active,
+ * {@link #isRateLimitingActive()} returns {@code true}.
  *
- * <p>
- * Calls to {@link #setDynamicShortcuts(List)}, {@link #addDynamicShortcuts(List)}, and
- * {@link #updateShortcuts(List)} may be rate-limited when called by <em>background apps</em>, or
- * apps with no foreground activity or service.  When you attempt to call these methods
- * from a background app after exceeding the rate limit, these APIs return {@code false}.
- *
- * <p>Apps with a foreground activity or service are not rate-limited.
- *
- * <p>Rate-limiting is reset upon certain events, so that even background apps
- * can call these APIs until the rate limit is reached again.
- * These events include the following:
+ * <p>Rate limiting is reset upon certain events, so even background apps can call these APIs until
+ * the rate limit is reached again. These events include the following:
  * <ul>
  *   <li>An app comes to the foreground.
  *   <li>The system locale changes.
  *   <li>The user performs the <strong>inline reply</strong> action on a notification.
  * </ul>
- *
- * <p>When rate-limiting is active, {@link #isRateLimitingActive()} returns {@code true}.
- *
- * <h4>Resetting rate-limiting for testing</h4>
- *
- * <p>
- * If your app is rate-limited during development or testing, you can use the
- * <strong>Reset ShortcutManager rate-limiting</strong> development option or
- * the following {@code adb} command to reset it:
- * <pre class="no-pretty-print">
- *$ adb shell cmd shortcut reset-throttling [ --user USER-ID ]
- * </pre>
- *
- * <h3>Handling System Locale Changes</h3>
- *
- * <p>
- * Apps should update dynamic and pinned shortcuts when the system locale changes
- * using the {@link Intent#ACTION_LOCALE_CHANGED} broadcast.
- *
- * <p>When the system locale changes, rate-limiting is reset, so even background apps
- * can add and update dynamic shortcuts until the rate limit is reached again.
- *
- *
- * <h3>Backup and Restore</h3>
- *
- * <p>
- * When an app has the {@code android:allowBackup="true"} attribute assignment included
- * in its <code>AndroidManifest.xml</code> file, pinned shortcuts are
- * backed up automatically and are restored when the user sets up a new device.
- *
- * <h4>Categories of shortcuts that are backed up</h4>
- *
- * <ul>
- *  <li>Pinned shortcuts are backed up.  Bitmap icons are not backed up by the system,
- *  so launcher apps should back them up and restore them so that the user still sees icons
- *  for pinned shortcuts on the launcher.  Apps can always use
- *  {@link #updateShortcuts(List)} to re-publish icons.
- *
- *  <li>Static shortcuts aren't backed up, but when an app is re-installed on a new
- *  device, they are re-published from the <code>AndroidManifest.xml</code> file.
- *
- *  <li>Dynamic shortcuts <b>aren't</b> backed up.
- * </ul>
- *
- * <p>Because dynamic shortcuts are not restored, it is recommended that apps check
- * currently-published dynamic shortcuts using {@link #getDynamicShortcuts()}
- * each time they are launched, and they should re-publish
- * dynamic shortcuts when necessary.
- *
- * <pre>
- *public class MainActivity extends Activity {
- *    public void onCreate(Bundle savedInstanceState) {
- *        super.onCreate(savedInstanceState);
- *        ShortcutManager shortcutManager =
- *                getSystemService(ShortcutManager.class);
- *
- *        if (shortcutManager.getDynamicShortcuts().size() == 0) {
- *            // Application restored. Need to re-publish dynamic shortcuts.
- *            if (shortcutManager.getPinnedShortcuts().size() > 0) {
- *                // Pinned shortcuts have been restored. Use
- *                // updateShortcuts() to make sure they contain
- *                // up-to-date information.
- *            }
- *        }
- *    }
- *    // ...
- *}
- * </pre>
- *
- *
- * <h4>Backup/restore and shortcut IDs</h4>
- * <p>
- * Because pinned shortcuts are backed up and restored on new devices, shortcut IDs
- * should contain either stable, constant strings or server-side identifiers,
- * rather than identifiers generated locally that might not make sense on other devices.
- *
- *
- * <h3>Report Shortcut Usage and Prediction</h3>
- * <p>
- * Launcher apps may be capable of predicting which shortcuts will most likely be
- * used at a given time by examining the shortcut usage history data.
- *
- * <p>In order to provide launchers with such data, publisher apps should
- * report the shortcuts that are used with {@link #reportShortcutUsed(String)}
- * when a shortcut is selected,
- * <b>or when an action equivalent to a shortcut is taken by the user even if it wasn't started
- * with the shortcut</b>.
- *
- * <p>For example, suppose a navigation app supports "navigate to work" as a shortcut.
- * It should then report when the user selects this shortcut <b>and</b> when the user chooses
- * to navigate to work within the app itself.
- * This helps the launcher app
- * learn that the user wants to navigate to work at a certain time every
- * weekday, and it can then show this shortcut in a suggestion list at the right time.
- *
- * <h3>Launcher API</h3>
- *
- * The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
- *
- *
- * <h3>Direct Boot and Shortcuts</h3>
- *
- * All shortcut information is stored in credential encrypted storage, so no shortcuts can be
- * accessed when the user is locked.
  */
 @SystemService(Context.SHORTCUT_SERVICE)
 public class ShortcutManager {
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 3c3b84d..9490e27 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,4 +25,5 @@
  */
 oneway interface IRuntimePermissionPresenter {
     void getAppPermissions(String packageName, in RemoteCallback callback);
+    void revokeRuntimePermission(String packageName, String permissionName);
 }
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 6d55d2f..02d0a6d 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -31,6 +30,7 @@
 import android.os.RemoteException;
 import android.permissionpresenterservice.RuntimePermissionPresenterService;
 import android.util.Log;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
@@ -118,6 +118,22 @@
         mRemoteService.processMessage(message);
     }
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     */
+    public void revokeRuntimePermission(String packageName, String permissionName) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = packageName;
+        args.arg2 = permissionName;
+
+        Message message = mRemoteService.obtainMessage(
+                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
+        mRemoteService.processMessage(message);
+    }
+
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -125,6 +141,7 @@
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
         public static final int MSG_UNBIND = 3;
+        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
 
         private final Object mLock = new Object();
 
@@ -231,6 +248,25 @@
                         mRemoteInstance = null;
                     }
                 } break;
+
+                case MSG_REVOKE_APP_PERMISSIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    final String packageName = (String) args.arg1;
+                    final String permissionName = (String) args.arg2;
+                    args.recycle();
+                    final IRuntimePermissionPresenter remoteInstance;
+                    synchronized (mLock) {
+                        remoteInstance = mRemoteInstance;
+                    }
+                    if (remoteInstance == null) {
+                        return;
+                    }
+                    try {
+                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error getting app permissions", re);
+                    }
+                } break;
             }
 
             synchronized (mLock) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 88c1627..f7cccd5 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,35 +16,33 @@
 
 package android.content.res;
 
-import android.graphics.Point;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.Config;
 import android.graphics.Rect;
-import android.util.DisplayMetrics;
-import android.view.Display;
+import android.os.Build;
+import android.os.LocaleList;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
 import android.view.DisplayInfo;
+import android.view.View;
+
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ActivityInfo.Config;
-import android.os.Build;
-import android.os.LocaleList;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.view.View;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Locale;
 
+
 /**
  * This class describes all device configuration information that can
  * impact the resources the application retrieves.  This includes both
@@ -1277,7 +1275,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;
         }
@@ -1320,7 +1318,19 @@
      * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
      */
     public int diff(Configuration delta) {
-        return diff(delta, false /* compareUndefined */);
+        return diff(delta, false /* compareUndefined */, false /* publicOnly */);
+    }
+
+    /**
+     * Returns the diff against the provided {@link Configuration} excluding values that would
+     * publicly be equivalent, such as appBounds.
+     * @param delta {@link Configuration} to compare to.
+     *
+     * TODO(b/36812336): Remove once appBounds has been moved out of Configuration.
+     * {@hide}
+     */
+    public int diffPublicOnly(Configuration delta) {
+        return diff(delta, false /* compareUndefined */, true /* publicOnly */);
     }
 
     /**
@@ -1328,7 +1338,7 @@
      *
      * @hide
      */
-    public int diff(Configuration delta, boolean compareUndefined) {
+    public int diff(Configuration delta, boolean compareUndefined, boolean publicOnly) {
         int changed = 0;
         if ((compareUndefined || delta.fontScale > 0) && fontScale != delta.fontScale) {
             changed |= ActivityInfo.CONFIG_FONT_SCALE;
@@ -1426,7 +1436,9 @@
         // Make sure that one of the values is not null and that they are not equal.
         if ((compareUndefined || delta.appBounds != null)
                 && appBounds != delta.appBounds
-                && (appBounds == null || !appBounds.equals(delta.appBounds))) {
+                && (appBounds == null || (!publicOnly && !appBounds.equals(delta.appBounds))
+                        || (publicOnly && (appBounds.width() != delta.appBounds.width()
+                                || appBounds.height() != delta.appBounds.height())))) {
             changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
         }
 
@@ -1650,7 +1662,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;
     }
 
@@ -1818,9 +1847,11 @@
     }
 
     /**
-     * Return whether the screen has a wide color gamut.
+     * Return whether the screen has a wide color gamut and wide color gamut rendering
+     * is supported by this device.
      *
-     * @return true if the screen has a wide color gamut, false otherwise
+     * @return true if the screen has a wide color gamut and wide color gamut rendering
+     * is supported, false otherwise
      */
     public boolean isScreenWideColorGamut() {
         return (colorMode & COLOR_MODE_WIDE_COLOR_GAMUT_MASK) == COLOR_MODE_WIDE_COLOR_GAMUT_YES;
@@ -2265,6 +2296,7 @@
     private static final String XML_ATTR_NAVIGATION = "nav";
     private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
     private static final String XML_ATTR_ORIENTATION = "ori";
+    private static final String XML_ATTR_ROTATION = "rot";
     private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
     private static final String XML_ATTR_COLOR_MODE = "clrMod";
     private static final String XML_ATTR_UI_MODE = "ui";
diff --git a/core/java/android/hardware/SensorDirectChannel.java b/core/java/android/hardware/SensorDirectChannel.java
index bd7f9cf..36607c9 100644
--- a/core/java/android/hardware/SensorDirectChannel.java
+++ b/core/java/android/hardware/SensorDirectChannel.java
@@ -212,7 +212,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 63eedf5..55343a2 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -73,8 +73,10 @@
      * Create a request suitable for still image capture. Specifically, this
      * means prioritizing image quality over frame rate. These requests would
      * commonly be used with the {@link CameraCaptureSession#capture} method.
-     * This template is guaranteed to be supported on all camera devices.
-     *
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      * @see #createCaptureRequest
      */
     public static final int TEMPLATE_STILL_CAPTURE = 2;
@@ -84,7 +86,10 @@
      * that a stable frame rate is used, and post-processing is set for
      * recording quality. These requests would commonly be used with the
      * {@link CameraCaptureSession#setRepeatingRequest} method.
-     * This template is guaranteed to be supported on all camera devices.
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
@@ -98,7 +103,10 @@
      * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
      * This template is guaranteed to be supported on all camera devices except
      * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
-     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) and
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 1b150bf..90bf896 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -16,28 +16,29 @@
 
 package android.hardware.camera2;
 
-import android.annotation.RequiresPermission;
-import android.annotation.SystemService;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemService;
 import android.content.Context;
-import android.hardware.ICameraService;
-import android.hardware.ICameraServiceListener;
 import android.hardware.CameraInfo;
 import android.hardware.CameraStatus;
+import android.hardware.ICameraService;
+import android.hardware.ICameraServiceListener;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.legacy.CameraDeviceUserShim;
 import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.os.IBinder;
 import android.os.Binder;
 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.os.ServiceSpecificException;
-import android.util.Log;
+import android.os.SystemProperties;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import java.util.ArrayList;
 
@@ -210,7 +211,9 @@
     public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
             throws CameraAccessException {
         CameraCharacteristics characteristics = null;
-
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
         synchronized (mLock) {
             /*
              * Get the camera characteristics from the camera service directly if it supports it,
@@ -462,6 +465,9 @@
                         "Handler argument is null, but no looper exists in the calling thread");
             }
         }
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
 
         openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
     }
@@ -507,6 +513,9 @@
      */
     public void setTorchMode(@NonNull String cameraId, boolean enabled)
             throws CameraAccessException {
+        if (CameraManagerGlobal.sCameraServiceDisabled) {
+            throw new IllegalArgumentException("No cameras available on device");
+        }
         CameraManagerGlobal.get().setTorchMode(cameraId, enabled);
     }
 
@@ -745,6 +754,9 @@
         private CameraManagerGlobal() {
         }
 
+        public static final boolean sCameraServiceDisabled =
+                SystemProperties.getBoolean("config.disable_cameraservice", false);
+
         public static CameraManagerGlobal get() {
             return gCameraManager;
         }
@@ -764,7 +776,7 @@
         public ICameraService getCameraService() {
             synchronized(mLock) {
                 connectCameraServiceLocked();
-                if (mCameraService == null) {
+                if (mCameraService == null && !sCameraServiceDisabled) {
                     Log.e(TAG, "Camera service is unavailable");
                 }
                 return mCameraService;
@@ -779,7 +791,7 @@
          */
         private void connectCameraServiceLocked() {
             // Only reconnect if necessary
-            if (mCameraService != null) return;
+            if (mCameraService != null || sCameraServiceDisabled) return;
 
             Log.i(TAG, "Connecting to camera service");
 
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index b3938cb..c7654c9 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -158,7 +158,7 @@
     }
 
     @Override
-    public synchronized int capture(CaptureRequest request, CaptureCallback callback,
+    public int capture(CaptureRequest request, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (request == null) {
             throw new IllegalArgumentException("request must not be null");
@@ -169,21 +169,23 @@
             throw new IllegalArgumentException("capture request was created for another session");
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
-                    " handler " + handler);
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
+                        " handler " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.capture(request,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.capture(request,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
+    public int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (requests == null) {
             throw new IllegalArgumentException("Requests must not be null");
@@ -203,22 +205,24 @@
             }
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
-            Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) +
-                    ", callback " + callback + " handler " + handler);
+            if (DEBUG) {
+                CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+                Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) +
+                        ", callback " + callback + " handler " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.captureBurst(requests,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.captureBurst(requests,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
+    public int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
             Handler handler) throws CameraAccessException {
         if (request == null) {
             throw new IllegalArgumentException("request must not be null");
@@ -226,21 +230,23 @@
             throw new IllegalArgumentException("repeating reprocess requests are not supported");
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
-                    callback + " handler" + " " + handler);
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "setRepeatingRequest - request " + request + ", callback " +
+                        callback + " handler" + " " + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.setRepeatingRequest(request,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized int setRepeatingBurst(List<CaptureRequest> requests,
+    public int setRepeatingBurst(List<CaptureRequest> requests,
             CaptureCallback callback, Handler handler) throws CameraAccessException {
         if (requests == null) {
             throw new IllegalArgumentException("requests must not be null");
@@ -255,34 +261,39 @@
             }
         }
 
-        checkNotClosed();
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        handler = checkHandler(handler, callback);
+            handler = checkHandler(handler, callback);
 
-        if (DEBUG) {
-            CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
-            Log.v(TAG, mIdString + "setRepeatingBurst - requests " + Arrays.toString(requestArray) +
-                    ", callback " + callback + " handler" + "" + handler);
+            if (DEBUG) {
+                CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
+                Log.v(TAG, mIdString + "setRepeatingBurst - requests " +
+                        Arrays.toString(requestArray) + ", callback " + callback +
+                        " handler" + "" + handler);
+            }
+
+            return addPendingSequence(mDeviceImpl.setRepeatingBurst(requests,
+                    createCaptureCallbackProxy(handler, callback), mDeviceHandler));
         }
-
-        return addPendingSequence(mDeviceImpl.setRepeatingBurst(requests,
-                createCaptureCallbackProxy(handler, callback), mDeviceHandler));
     }
 
     @Override
-    public synchronized void stopRepeating() throws CameraAccessException {
-        checkNotClosed();
+    public void stopRepeating() throws CameraAccessException {
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
 
-        if (DEBUG) {
-            Log.v(TAG, mIdString + "stopRepeating");
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "stopRepeating");
+            }
+
+            mDeviceImpl.stopRepeating();
         }
-
-        mDeviceImpl.stopRepeating();
     }
 
     @Override
     public void abortCaptures() throws CameraAccessException {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             checkNotClosed();
 
             if (DEBUG) {
@@ -296,13 +307,9 @@
 
             mAborting = true;
             mAbortDrainer.taskStarted();
-        }
 
-        synchronized (mDeviceImpl.mInterfaceLock) {
-            synchronized (this) {
-                mDeviceImpl.flush();
-                // The next BUSY -> IDLE set of transitions will mark the end of the abort.
-            }
+            mDeviceImpl.flush();
+            // The next BUSY -> IDLE set of transitions will mark the end of the abort.
         }
     }
 
@@ -332,7 +339,7 @@
      */
     @Override
     public void replaceSessionClose() {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             /*
              * In order for creating new sessions to be fast, the new session should be created
              * before the old session is closed.
@@ -357,13 +364,13 @@
             // configuration for the new session. If it was already called, then we don't care,
             // since it won't get called again.
             mSkipUnconfigure = true;
+            close();
         }
-        close();
     }
 
     @Override
     public void close() {
-        synchronized (this) {
+        synchronized (mDeviceImpl.mInterfaceLock) {
             if (mClosed) {
                 if (DEBUG) Log.v(TAG, mIdString + "close - reentering");
                 return;
@@ -372,45 +379,42 @@
             if (DEBUG) Log.v(TAG, mIdString + "close - first time");
 
             mClosed = true;
-        }
 
-        synchronized (mDeviceImpl.mInterfaceLock) {
-            synchronized (this) {
-                /*
-                 * Flush out any repeating request. Since camera is closed, no new requests
-                 * can be queued, and eventually the entire request queue will be drained.
-                 *
-                 * If the camera device was already closed, short circuit and do nothing; since
-                 * no more internal device callbacks will fire anyway.
-                 *
-                 * Otherwise, once stopRepeating is done, wait for camera to idle, then unconfigure
-                 * the camera. Once that's done, fire #onClosed.
-                 */
-                try {
-                    mDeviceImpl.stopRepeating();
-                } catch (IllegalStateException e) {
-                    // OK: Camera device may already be closed, nothing else to do
+            /*
+             * Flush out any repeating request. Since camera is closed, no new requests
+             * can be queued, and eventually the entire request queue will be drained.
+             *
+             * If the camera device was already closed, short circuit and do nothing; since
+             * no more internal device callbacks will fire anyway.
+             *
+             * Otherwise, once stopRepeating is done, wait for camera to idle, then unconfigure
+             * the camera. Once that's done, fire #onClosed.
+             */
+            try {
+                mDeviceImpl.stopRepeating();
+            } catch (IllegalStateException e) {
+                // OK: Camera device may already be closed, nothing else to do
 
-                    // TODO: Fire onClosed anytime we get the device onClosed or the ISE?
-                    // or just suppress the ISE only and rely onClosed.
-                    // Also skip any of the draining work if this is already closed.
+                // TODO: Fire onClosed anytime we get the device onClosed or the ISE?
+                // or just suppress the ISE only and rely onClosed.
+                // Also skip any of the draining work if this is already closed.
 
-                    // Short-circuit; queue callback immediately and return
-                    mStateCallback.onClosed(this);
-                    return;
-                } catch (CameraAccessException e) {
-                    // OK: close does not throw checked exceptions.
-                    Log.e(TAG, mIdString + "Exception while stopping repeating: ", e);
+                // Short-circuit; queue callback immediately and return
+                mStateCallback.onClosed(this);
+                return;
+            } catch (CameraAccessException e) {
+                // OK: close does not throw checked exceptions.
+                Log.e(TAG, mIdString + "Exception while stopping repeating: ", e);
 
-                    // TODO: call onError instead of onClosed if this happens
-                }
+                // TODO: call onError instead of onClosed if this happens
             }
-        }
 
-        synchronized (this) {
             // If no sequences are pending, fire #onClosed immediately
             mSequenceDrainer.beginDrain();
         }
+        if (mInput != null) {
+            mInput.release();
+        }
     }
 
     /**
@@ -552,6 +556,8 @@
     @Override
     public CameraDeviceImpl.StateCallbackKK getDeviceStateCallback() {
         final CameraCaptureSession session = this;
+        final Object interfaceLock = mDeviceImpl.mInterfaceLock;
+
 
         return new CameraDeviceImpl.StateCallbackKK() {
             private boolean mBusy = false;
@@ -588,7 +594,7 @@
                 boolean isAborting;
                 if (DEBUG) Log.v(TAG, mIdString + "onIdle");
 
-                synchronized (session) {
+                synchronized (interfaceLock) {
                     isAborting = mAborting;
                 }
 
@@ -606,7 +612,7 @@
                 if (mBusy && isAborting) {
                     mAbortDrainer.taskFinished();
 
-                    synchronized (session) {
+                    synchronized (interfaceLock) {
                         mAborting = false;
                     }
                 }
@@ -729,7 +735,7 @@
         @Override
         public void onDrained() {
             if (DEBUG) Log.v(TAG, mIdString + "onAbortDrained");
-            synchronized (CameraCaptureSessionImpl.this) {
+            synchronized (mDeviceImpl.mInterfaceLock) {
                 /*
                  * Any queued aborts have now completed.
                  *
@@ -757,7 +763,6 @@
             // Take device lock before session lock so that we can call back into device
             // without causing a deadlock
             synchronized (mDeviceImpl.mInterfaceLock) {
-                synchronized (CameraCaptureSessionImpl.this) {
                 /*
                  * The device is now IDLE, and has settled. It will not transition to
                  * ACTIVE or BUSY again by itself.
@@ -766,33 +771,31 @@
                  *
                  * This operation is idempotent; a session will not be closed twice.
                  */
-                    if (DEBUG)
-                        Log.v(TAG, mIdString + "Session drain complete, skip unconfigure: " +
-                                mSkipUnconfigure);
+                if (DEBUG)
+                    Log.v(TAG, mIdString + "Session drain complete, skip unconfigure: " +
+                            mSkipUnconfigure);
 
-                    // Fast path: A new capture session has replaced this one; don't wait for idle
-                    // as we won't get state updates any more anyway.
-                    if (mSkipUnconfigure) {
-                        return;
-                    }
+                // Fast path: A new capture session has replaced this one; don't wait for idle
+                // as we won't get state updates any more anyway.
+                if (mSkipUnconfigure) {
+                    return;
+                }
 
-                    // Final slow path: unconfigure the camera, no session has replaced us and
-                    // everything is idle.
-                    try {
-                        // begin transition to unconfigured
-                        mDeviceImpl.configureStreamsChecked(/*inputConfig*/null, /*outputs*/null,
-                                /*operatingMode*/ ICameraDeviceUser.NORMAL_MODE);
-                    } catch (CameraAccessException e) {
-                        // OK: do not throw checked exceptions.
-                        Log.e(TAG, mIdString + "Exception while unconfiguring outputs: ", e);
+                // Final slow path: unconfigure the camera, no session has replaced us and
+                // everything is idle.
+                try {
+                    // begin transition to unconfigured
+                    mDeviceImpl.configureStreamsChecked(/*inputConfig*/null, /*outputs*/null,
+                            /*operatingMode*/ ICameraDeviceUser.NORMAL_MODE);
+                } catch (CameraAccessException e) {
+                    // OK: do not throw checked exceptions.
+                    Log.e(TAG, mIdString + "Exception while unconfiguring outputs: ", e);
 
-                        // TODO: call onError instead of onClosed if this happens
-                    } catch (IllegalStateException e) {
-                        // Camera is already closed, so nothing left to do
-                        if (DEBUG) Log.v(TAG, mIdString +
-                                "Camera was already closed or busy, skipping unconfigure");
-                    }
-
+                    // TODO: call onError instead of onClosed if this happens
+                } catch (IllegalStateException e) {
+                    // Camera is already closed, so nothing left to do
+                    if (DEBUG) Log.v(TAG, mIdString +
+                            "Camera was already closed or busy, skipping unconfigure");
                 }
             }
         }
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 15dbf26..fec7fd9 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -96,6 +96,9 @@
         CaptureRequest.Builder singleTargetRequestBuilder = new CaptureRequest.Builder(
                 requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
 
+        // Carry over userTag, as native metadata doesn't have this field.
+        singleTargetRequestBuilder.setTag(request.getTag());
+
         // Overwrite the capture intent to make sure a good value is set.
         Iterator<Surface> iterator = outputSurfaces.iterator();
         Surface firstSurface = iterator.next();
@@ -118,6 +121,7 @@
             requestMetadata = new CameraMetadataNative(request.getNativeCopy());
             doubleTargetRequestBuilder = new CaptureRequest.Builder(
                     requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
+            doubleTargetRequestBuilder.setTag(request.getTag());
             doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
                     CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
             doubleTargetRequestBuilder.addTarget(firstSurface);
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index dbe1394..00e047d 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1112,6 +1112,8 @@
                 return ImageFormat.DEPTH_POINT_CLOUD;
             case HAL_PIXEL_FORMAT_Y16:
                 return ImageFormat.DEPTH16;
+            case HAL_PIXEL_FORMAT_RAW16:
+                return ImageFormat.RAW_DEPTH;
             case ImageFormat.JPEG:
                 throw new IllegalArgumentException(
                         "ImageFormat.JPEG is an unknown internal format");
@@ -1179,6 +1181,8 @@
                 return HAL_PIXEL_FORMAT_BLOB;
             case ImageFormat.DEPTH16:
                 return HAL_PIXEL_FORMAT_Y16;
+            case ImageFormat.RAW_DEPTH:
+                return HAL_PIXEL_FORMAT_RAW16;
             default:
                 return format;
         }
@@ -1220,6 +1224,7 @@
                 return HAL_DATASPACE_V0_JFIF;
             case ImageFormat.DEPTH_POINT_CLOUD:
             case ImageFormat.DEPTH16:
+            case ImageFormat.RAW_DEPTH:
                 return HAL_DATASPACE_DEPTH;
             default:
                 return HAL_DATASPACE_UNKNOWN;
@@ -1609,6 +1614,8 @@
                 return "DEPTH16";
             case ImageFormat.DEPTH_POINT_CLOUD:
                 return "DEPTH_POINT_CLOUD";
+            case ImageFormat.RAW_DEPTH:
+                return "RAW_DEPTH";
             case ImageFormat.PRIVATE:
                 return "PRIVATE";
             default:
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6a02b6b..bda8039 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -256,6 +256,15 @@
      */
     public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
 
+    /**
+     * Virtual display flag: Indicates that the orientation of this display device is coupled to
+     * the rotation of its associated logical display.
+     *
+     * @see #createVirtualDisplay
+     * @hide
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index bdb278b..4586316 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -34,6 +34,11 @@
     InputDevice getInputDevice(int deviceId);
     int[] getInputDeviceIds();
 
+    // Enable/disable input device.
+    boolean isInputDeviceEnabled(int deviceId);
+    void enableInputDevice(int deviceId);
+    void disableInputDevice(int deviceId);
+
     // Reports whether the hardware supports the given keys; returns true if successful
     boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);
 
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 5149e93..4898c1a 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,8 +16,6 @@
 
 package android.hardware.input;
 
-import com.android.internal.os.SomeArgs;
-
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -32,10 +30,10 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.Vibrator;
-import android.os.VibrationEffect;
 import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemClock;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
@@ -47,6 +45,8 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
+import com.android.internal.os.SomeArgs;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -319,6 +319,62 @@
     }
 
     /**
+     * Returns true if an input device is enabled. Should return true for most
+     * situations. Some system apps may disable an input device, for
+     * example to prevent unwanted touch events.
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public boolean isInputDeviceEnabled(int id) {
+        try {
+            return mIm.isInputDeviceEnabled(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not check enabled status of input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Enables an InputDevice.
+     * <p>
+     * Requires {@link android.Manifest.permissions.DISABLE_INPUT_DEVICE}.
+     * </p>
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public void enableInputDevice(int id) {
+        try {
+            mIm.enableInputDevice(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not enable input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Disables an InputDevice.
+     * <p>
+     * Requires {@link android.Manifest.permissions.DISABLE_INPUT_DEVICE}.
+     * </p>
+     *
+     * @param id The input device Id.
+     *
+     * @hide
+     */
+    public void disableInputDevice(int id) {
+        try {
+            mIm.disableInputDevice(id);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not disable input device with id = " + id);
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Registers an input device listener to receive notifications about when
      * input devices are added, removed or changed.
      *
diff --git a/core/java/android/hardware/radio/IRadioService.aidl b/core/java/android/hardware/radio/IRadioService.aidl
new file mode 100644
index 0000000..9a157d1
--- /dev/null
+++ b/core/java/android/hardware/radio/IRadioService.aidl
@@ -0,0 +1,31 @@
+/**
+ * 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.hardware.radio;
+
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+
+/**
+ * API to the broadcast radio service.
+ *
+ * {@hide}
+ */
+interface IRadioService {
+    ITuner openTuner(int moduleId, in RadioManager.BandConfig bandConfig, boolean withAudio,
+            in ITunerCallback callback);
+}
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
new file mode 100644
index 0000000..1fc71e0
--- /dev/null
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -0,0 +1,89 @@
+/**
+ * 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.hardware.radio;
+
+import android.hardware.radio.RadioManager;
+
+/** {@hide} */
+interface ITuner {
+    void close();
+
+    /**
+     * @throws IllegalArgumentException if config is not valid or null
+     */
+    void setConfiguration(in RadioManager.BandConfig config);
+
+    RadioManager.BandConfig getConfiguration();
+
+    /**
+     * @throws IllegalStateException if tuner was opened without audio
+     */
+    void setMuted(boolean mute);
+
+    boolean isMuted();
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void step(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void scan(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if called out of sequence
+     */
+    void tune(int channel, int subChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void cancel();
+
+    RadioManager.ProgramInfo getProgramInformation();
+
+    /**
+     * @returns {@code true} if the scan was properly scheduled,
+     *          {@code false} if the scan feature is unavailable
+     */
+    boolean startBackgroundScan();
+
+    /**
+     * @returns the list, or null if scan is in progress
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if the scan has not been started, client may
+     *         call startBackgroundScan to fix this.
+     */
+    List<RadioManager.ProgramInfo> getProgramList(String filter);
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    boolean isAnalogForced();
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    void setAnalogForced(boolean isForced);
+
+    boolean isAntennaConnected();
+}
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
new file mode 100644
index 0000000..b32c683
--- /dev/null
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -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 android.hardware.radio;
+
+import android.hardware.radio.RadioManager;
+
+/** {@hide} */
+oneway interface ITunerCallback {
+    void onError(int status);
+    void onConfigurationChanged(in RadioManager.BandConfig config);
+    void onProgramInfoChanged(in RadioManager.ProgramInfo info);
+}
diff --git a/core/java/android/hardware/radio/RadioManager.aidl b/core/java/android/hardware/radio/RadioManager.aidl
new file mode 100644
index 0000000..0f0ec84
--- /dev/null
+++ b/core/java/android/hardware/radio/RadioManager.aidl
@@ -0,0 +1,23 @@
+/**
+ * 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.hardware.radio;
+
+/** @hide */
+parcelable RadioManager.ProgramInfo;
+
+/** @hide */
+parcelable RadioManager.BandConfig;
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 24bb524..20292f7 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -16,12 +16,21 @@
 
 package android.hardware.radio;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
 import java.util.List;
 import java.util.Arrays;
 
@@ -35,6 +44,7 @@
 @SystemApi
 @SystemService(Context.RADIO_SERVICE)
 public class RadioManager {
+    private static final String TAG = "RadioManager";
 
     /** Method return status: successful operation */
     public static final int STATUS_OK = 0;
@@ -110,10 +120,12 @@
         private final int mNumAudioSources;
         private final boolean mIsCaptureSupported;
         private final BandDescriptor[] mBands;
+        private final boolean mIsBgScanSupported;
+        private final String mVendorExension;
 
         ModuleProperties(int id, int classId, String implementor, String product, String version,
                 String serial, int numTuners, int numAudioSources, boolean isCaptureSupported,
-                BandDescriptor[] bands) {
+                BandDescriptor[] bands, boolean isBgScanSupported, String vendorExension) {
             mId = id;
             mClassId = classId;
             mImplementor = implementor;
@@ -124,6 +136,8 @@
             mNumAudioSources = numAudioSources;
             mIsCaptureSupported = isCaptureSupported;
             mBands = bands;
+            mIsBgScanSupported = isBgScanSupported;
+            mVendorExension = vendorExension;
         }
 
 
@@ -198,6 +212,35 @@
             return mIsCaptureSupported;
         }
 
+        /**
+         * {@code true} if the module supports background scanning. At the given time it may not
+         * be available though, see {@link RadioTuner#startBackgroundScan()}.
+         *
+         * @return {@code true} if background scanning is supported (not necessary available
+         * at a given time), {@code false} otherwise.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isBackgroundScanningSupported() {
+            return mIsBgScanSupported;
+        }
+
+        /**
+         * Opaque vendor-specific string, passed from HAL without changes.
+         * Format of this string can vary across vendors.
+         *
+         * It may be used for extra features, that's not supported by a platform,
+         * for example: "preset-slots=6;ultra-hd-capable=false".
+         *
+         * Client application MUST verify vendor/product name from the
+         * ModuleProperties class before doing any interpretation of this value.
+         *
+         * @hide FutureFeature
+         */
+        public @NonNull String getVendorExension() {
+            return mVendorExension == null ? "" : mVendorExension;
+        }
+
         /** List of descriptors for all bands supported by this module.
          * @return an array of {@link BandDescriptor}.
          */
@@ -220,6 +263,8 @@
             for (int i = 0; i < tmp.length; i++) {
                 mBands[i] = (BandDescriptor) tmp[i];
             }
+            mIsBgScanSupported = in.readInt() == 1;
+            mVendorExension = in.readString();
         }
 
         public static final Parcelable.Creator<ModuleProperties> CREATOR
@@ -245,6 +290,8 @@
             dest.writeInt(mNumAudioSources);
             dest.writeInt(mIsCaptureSupported ? 1 : 0);
             dest.writeParcelableArray(mBands, flags);
+            dest.writeInt(mIsBgScanSupported ? 1 : 0);
+            dest.writeString(mVendorExension);
         }
 
         @Override
@@ -260,6 +307,7 @@
                     + ", mNumTuners=" + mNumTuners
                     + ", mNumAudioSources=" + mNumAudioSources
                     + ", mIsCaptureSupported=" + mIsCaptureSupported
+                    + ", mIsBgScanSupported=" + mIsBgScanSupported
                     + ", mBands=" + Arrays.toString(mBands) + "]";
         }
 
@@ -277,6 +325,8 @@
             result = prime * result + mNumAudioSources;
             result = prime * result + (mIsCaptureSupported ? 1 : 0);
             result = prime * result + Arrays.hashCode(mBands);
+            result = prime * result + (mIsBgScanSupported ? 1 : 0);
+            result = prime * result + ((mVendorExension == null) ? 0 : mVendorExension.hashCode());
             return result;
         }
 
@@ -319,6 +369,10 @@
                 return false;
             if (!Arrays.equals(mBands, other.getBands()))
                 return false;
+            if (mIsBgScanSupported != other.isBackgroundScanningSupported())
+                return false;
+            if (!TextUtils.equals(mVendorExension, other.mVendorExension))
+                return false;
             return true;
         }
     }
@@ -334,6 +388,9 @@
         private final int mSpacing;
 
         BandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing) {
+            if (type != BAND_AM && type != BAND_FM && type != BAND_FM_HD && type != BAND_AM_HD) {
+                throw new IllegalArgumentException("Unsupported band: " + type);
+            }
             mRegion = region;
             mType = type;
             mLowerLimit = lowerLimit;
@@ -387,10 +444,28 @@
             mSpacing = in.readInt();
         }
 
+        private static int lookupTypeFromParcel(Parcel in) {
+            int pos = in.dataPosition();
+            in.readInt();  // skip region
+            int type = in.readInt();
+            in.setDataPosition(pos);
+            return type;
+        }
+
         public static final Parcelable.Creator<BandDescriptor> CREATOR
                 = new Parcelable.Creator<BandDescriptor>() {
             public BandDescriptor createFromParcel(Parcel in) {
-                return new BandDescriptor(in);
+                int type = lookupTypeFromParcel(in);
+                switch (type) {
+                    case BAND_FM:
+                    case BAND_FM_HD:
+                        return new FmBandDescriptor(in);
+                    case BAND_AM:
+                    case BAND_AM_HD:
+                        return new AmBandDescriptor(in);
+                    default:
+                        throw new IllegalArgumentException("Unsupported band: " + type);
+                }
             }
 
             public BandDescriptor[] newArray(int size) {
@@ -719,7 +794,17 @@
         public static final Parcelable.Creator<BandConfig> CREATOR
                 = new Parcelable.Creator<BandConfig>() {
             public BandConfig createFromParcel(Parcel in) {
-                return new BandConfig(in);
+                int type = BandDescriptor.lookupTypeFromParcel(in);
+                switch (type) {
+                    case BAND_FM:
+                    case BAND_FM_HD:
+                        return new FmBandConfig(in);
+                    case BAND_AM:
+                    case BAND_AM_HD:
+                        return new AmBandConfig(in);
+                    default:
+                        throw new IllegalArgumentException("Unsupported band: " + type);
+                }
             }
 
             public BandConfig[] newArray(int size) {
@@ -1139,23 +1224,32 @@
      * {@link RadioTuner#getProgramInformation(RadioManager.ProgramInfo[])} */
     public static class ProgramInfo implements Parcelable {
 
+        // sourced from hardware/interfaces/broadcastradio/1.1/types.hal
+        private final static int FLAG_LIVE = 1 << 0;
+        private final static int FLAG_MUTED = 1 << 1;
+
         private final int mChannel;
         private final int mSubChannel;
         private final boolean mTuned;
         private final boolean mStereo;
         private final boolean mDigital;
+        private final int mFlags;
         private final int mSignalStrength;
         private final RadioMetadata mMetadata;
+        private final String mVendorExension;
 
         ProgramInfo(int channel, int subChannel, boolean tuned, boolean stereo,
-                boolean digital, int signalStrength, RadioMetadata metadata) {
+                boolean digital, int signalStrength, RadioMetadata metadata, int flags,
+                String vendorExension) {
             mChannel = channel;
             mSubChannel = subChannel;
             mTuned = tuned;
             mStereo = stereo;
             mDigital = digital;
+            mFlags = flags;
             mSignalStrength = signalStrength;
             mMetadata = metadata;
+            mVendorExension = vendorExension;
         }
 
         /** Main channel expressed in units according to band type.
@@ -1189,6 +1283,30 @@
         public boolean isDigital() {
             return mDigital;
         }
+
+        /**
+         * {@code true} if the program is currently playing live stream.
+         * This may result in a slightly altered reception parameters,
+         * usually targetted at reduced latency.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isLive() {
+            return (mFlags & FLAG_LIVE) != 0;
+        }
+
+        /**
+         * {@code true} if radio stream is not playing, ie. due to bad reception
+         * conditions or buffering. In this state volume knob MAY be disabled to
+         * prevent user increasing volume too much.
+         * It does NOT mean the user has muted audio.
+         *
+         * @hide FutureFeature
+         */
+        public boolean isMuted() {
+            return (mFlags & FLAG_MUTED) != 0;
+        }
+
         /** Signal strength indicator from 0 (no signal) to 100 (excellent)
          * @return the signal strength indication.
          */
@@ -1203,6 +1321,22 @@
             return mMetadata;
         }
 
+        /**
+         * Opaque vendor-specific string, passed from HAL without changes.
+         * Format of this string can vary across vendors.
+         *
+         * It may be used for extra features, that's not supported by a platform,
+         * for example: "paid-service=true;bitrate=320kbps".
+         *
+         * Client application MUST verify vendor/product name from the
+         * ModuleProperties class before doing any interpretation of this value.
+         *
+         * @hide FutureFeature
+         */
+        public @NonNull String getVendorExension() {
+            return mVendorExension == null ? "" : mVendorExension;
+        }
+
         private ProgramInfo(Parcel in) {
             mChannel = in.readInt();
             mSubChannel = in.readInt();
@@ -1215,6 +1349,8 @@
             } else {
                 mMetadata = null;
             }
+            mFlags = in.readInt();
+            mVendorExension = in.readString();
         }
 
         public static final Parcelable.Creator<ProgramInfo> CREATOR
@@ -1242,6 +1378,8 @@
                 dest.writeByte((byte)1);
                 mMetadata.writeToParcel(dest, flags);
             }
+            dest.writeInt(mFlags);
+            dest.writeString(mVendorExension);
         }
 
         @Override
@@ -1253,7 +1391,7 @@
         public String toString() {
             return "ProgramInfo [mChannel=" + mChannel + ", mSubChannel=" + mSubChannel
                     + ", mTuned=" + mTuned + ", mStereo=" + mStereo + ", mDigital=" + mDigital
-                    + ", mSignalStrength=" + mSignalStrength
+                    + ", mFlags=" + mFlags + ", mSignalStrength=" + mSignalStrength
                     + ((mMetadata == null) ? "" : (", mMetadata=" + mMetadata.toString()))
                     + "]";
         }
@@ -1267,8 +1405,10 @@
             result = prime * result + (mTuned ? 1 : 0);
             result = prime * result + (mStereo ? 1 : 0);
             result = prime * result + (mDigital ? 1 : 0);
+            result = prime * result + mFlags;
             result = prime * result + mSignalStrength;
             result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode());
+            result = prime * result + ((mVendorExension == null) ? 0 : mVendorExension.hashCode());
             return result;
         }
 
@@ -1289,6 +1429,8 @@
                 return false;
             if (mDigital != other.isDigital())
                 return false;
+            if (mFlags != other.mFlags)
+                return false;
             if (mSignalStrength != other.getSignalStrength())
                 return false;
             if (mMetadata == null) {
@@ -1296,6 +1438,8 @@
                     return false;
             } else if (!mMetadata.equals(other.getMetadata()))
                 return false;
+            if (!TextUtils.equals(mVendorExension, other.mVendorExension))
+                return false;
             return true;
         }
     }
@@ -1332,23 +1476,47 @@
     public RadioTuner openTuner(int moduleId, BandConfig config, boolean withAudio,
             RadioTuner.Callback callback, Handler handler) {
         if (callback == null) {
-            return null;
+            throw new IllegalArgumentException("callback must not be empty");
         }
-        RadioModule module = new RadioModule(moduleId, config, withAudio, callback, handler);
-        if (module != null) {
-            if (!module.initCheck()) {
-                module = null;
+
+        if (mService != null) {
+            Log.d(TAG, "Opening tuner...");
+
+            ITuner tuner;
+            ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
+            try {
+                tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
+            if (tuner == null) {
+                Log.e(TAG, "Failed to open tuner");
+                return null;
+            }
+            return new TunerAdapter(tuner);
         }
+
+        RadioModule module = new RadioModule(moduleId, config, withAudio, callback, handler);
+        if (!module.initCheck()) {
+            Log.e(TAG, "Failed to open tuner");
+            module = null;
+        }
+
         return (RadioTuner)module;
     }
 
-    private final Context mContext;
+    @NonNull private final Context mContext;
+    // TODO(b/36863239): NonNull when transitioned from native service
+    @Nullable private final IRadioService mService;
 
     /**
      * @hide
      */
-    public RadioManager(Context context) {
+    public RadioManager(@NonNull Context context) throws ServiceNotFoundException {
         mContext = context;
+
+        boolean isServiceJava = SystemProperties.getBoolean("config.enable_java_radio", false);
+        mService = isServiceJava ? IRadioService.Stub.asInterface(
+                ServiceManager.getServiceOrThrow(Context.RADIO_SERVICE)) : null;
     }
 }
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
index 8964893..c0df0f3 100644
--- a/core/java/android/hardware/radio/RadioModule.java
+++ b/core/java/android/hardware/radio/RadioModule.java
@@ -79,8 +79,14 @@
 
     public native int getProgramInformation(RadioManager.ProgramInfo[] info);
 
+    public native boolean startBackgroundScan();
+
     public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
 
+    public native boolean isAnalogForced();
+
+    public native void setAnalogForced(boolean isForced);
+
     public native boolean isAntennaConnected();
 
     public native boolean hasControl();
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index c8034eb..6e1232d 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -212,6 +212,23 @@
     public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
 
     /**
+     * Initiates a background scan to update internally cached program list.
+     *
+     * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot.
+     *
+     * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will
+     * be called if the return value of this call was {@code true}. As result of this call
+     * programListChanged may be triggered (if the scanned list differs).
+     *
+     * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature
+     * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device
+     * or permanently if the feature is not supported
+     * (see ModuleProperties#isBackgroundScanningSupported()).
+     * @hide FutureFeature
+     */
+    public abstract boolean startBackgroundScan();
+
+    /**
      * Get the list of discovered radio stations.
      *
      * To get the full list, set filter to null or empty string. Otherwise, client application
@@ -219,13 +236,40 @@
      *
      * @param filter vendor-specific selector for radio stations.
      * @return a list of radio stations.
-     * @throws IllegalStateException if the scan is in progress or has not been started.
+     * @throws IllegalStateException if the scan is in progress or has not been started,
+     *         startBackgroundScan() call may fix it.
      * @throws IllegalArgumentException if the filter argument is not valid.
      * @hide FutureFeature
      */
     public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
 
     /**
+     * Checks, if the analog playback is forced, see setAnalogForced.
+     *
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     * @return {@code true} if analog is forced, {@code false} otherwise.
+     * @hide FutureFeature
+     */
+    public abstract boolean isAnalogForced();
+
+    /**
+     * Forces the analog playback for the supporting radio technology.
+     *
+     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+     * this option. This is purely user choice, ie. does not reflect digital-
+     * analog handover managed from the HAL implementation side.
+     *
+     * Some radio technologies may not support this, ie. DAB.
+     *
+     * @param isForced {@code true} to force analog, {@code false} for a default behaviour.
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     * @hide FutureFeature
+     */
+    public abstract void setAnalogForced(boolean isForced);
+
+    /**
      * Get current antenna connection state for current configuration.
      * Only valid if a configuration has been applied.
      * @return {@code true} if the antenna is connected, {@code false} otherwise.
@@ -317,6 +361,32 @@
          * with control set to {@code true}.
          */
         public void onControlChanged(boolean control) {}
+
+        /**
+         * onBackgroundScanAvailabilityChange() is called when background scan
+         * feature becomes available or not.
+         *
+         * @param isAvailable true, if the tuner turned temporarily background-
+         *                    capable, false in the other case.
+         * @hide FutureFeature
+         */
+        public void onBackgroundScanAvailabilityChange(boolean isAvailable) {}
+
+        /**
+         * Called when a background scan completes successfully.
+         *
+         * @hide FutureFeature
+         */
+        public void onBackgroundScanComplete() {}
+
+        /**
+         * Called when available program list changed.
+         *
+         * Use getProgramList() to get the actual list.
+         *
+         * @hide FutureFeature
+         */
+        public void onProgramListChanged() {}
     }
 
 }
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
new file mode 100644
index 0000000..a457494
--- /dev/null
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -0,0 +1,233 @@
+/**
+ * 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.hardware.radio;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Implements the RadioTuner interface by forwarding calls to radio service.
+ */
+class TunerAdapter extends RadioTuner {
+    private static final String TAG = "radio.TunerAdapter";
+
+    @NonNull private final ITuner mTuner;
+    private boolean mIsClosed = false;
+
+    TunerAdapter(ITuner tuner) {
+        if (tuner == null) {
+            throw new NullPointerException();
+        }
+        mTuner = tuner;
+    }
+
+    @Override
+    public void close() {
+        synchronized (mTuner) {
+            if (mIsClosed) {
+                Log.d(TAG, "Tuner is already closed");
+                return;
+            }
+            mIsClosed = true;
+        }
+        try {
+            mTuner.close();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception trying to close tuner", e);
+        }
+    }
+
+    @Override
+    public int setConfiguration(RadioManager.BandConfig config) {
+        try {
+            mTuner.setConfiguration(config);
+            return RadioManager.STATUS_OK;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Can't set configuration", e);
+            return RadioManager.STATUS_BAD_VALUE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public int getConfiguration(RadioManager.BandConfig[] config) {
+        if (config == null || config.length != 1) {
+            throw new IllegalArgumentException("The argument must be an array of length 1");
+        }
+        try {
+            config[0] = mTuner.getConfiguration();
+            return RadioManager.STATUS_OK;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public int setMute(boolean mute) {
+        try {
+            mTuner.setMuted(mute);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't set muted", e);
+            return RadioManager.STATUS_ERROR;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public boolean getMute() {
+        try {
+            return mTuner.isMuted();
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return true;
+        }
+    }
+
+    @Override
+    public int step(int direction, boolean skipSubChannel) {
+        try {
+            mTuner.step(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't step", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int scan(int direction, boolean skipSubChannel) {
+        try {
+            mTuner.scan(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't scan", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int tune(int channel, int subChannel) {
+        try {
+            mTuner.tune(channel, subChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_BAD_VALUE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int cancel() {
+        try {
+            mTuner.cancel();
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't cancel", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
+    }
+
+    @Override
+    public int getProgramInformation(RadioManager.ProgramInfo[] info) {
+        if (info == null || info.length != 1) {
+            throw new IllegalArgumentException("The argument must be an array of length 1");
+        }
+        try {
+            info[0] = mTuner.getProgramInformation();
+            return RadioManager.STATUS_OK;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+    }
+
+    @Override
+    public boolean startBackgroundScan() {
+        try {
+            return mTuner.startBackgroundScan();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) {
+        try {
+            return mTuner.getProgramList(filter);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean isAnalogForced() {
+        try {
+            return mTuner.isAnalogForced();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public void setAnalogForced(boolean isForced) {
+        try {
+            mTuner.setAnalogForced(isForced);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean isAntennaConnected() {
+        try {
+            return mTuner.isAntennaConnected();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
+    }
+
+    @Override
+    public boolean hasControl() {
+        // TODO(b/36863239): forward to mTuner
+        throw new RuntimeException("Not implemented");
+    }
+}
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
new file mode 100644
index 0000000..ba85017
--- /dev/null
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -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.
+ */
+
+package android.hardware.radio;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Implements the ITunerCallback interface by forwarding calls to RadioTuner.Callback.
+ */
+class TunerCallbackAdapter extends ITunerCallback.Stub {
+    @NonNull private final RadioTuner.Callback mCallback;
+    @NonNull private final Handler mHandler;
+
+    TunerCallbackAdapter(@NonNull RadioTuner.Callback callback, @Nullable Handler handler) {
+        mCallback = callback;
+        if (handler == null) {
+            mHandler = new Handler(Looper.getMainLooper());
+        } else {
+            mHandler = handler;
+        }
+    }
+
+    @Override
+    public void onError(int status) {
+        mHandler.post(() -> mCallback.onError(status));
+    }
+
+    @Override
+    public void onConfigurationChanged(RadioManager.BandConfig config) {
+        mHandler.post(() -> mCallback.onConfigurationChanged(config));
+    }
+
+    @Override
+    public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
+        mHandler.post(() -> mCallback.onProgramInfoChanged(info));
+    }
+}
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index ad20ce5..160376b 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -341,7 +341,8 @@
               }
           }
         }
-        Slog.w(TAG, "No Enrollment application supports the given keyphrase/locale");
+        Slog.w(TAG, "No enrollment application supports the given keyphrase/locale: '"
+                + keyphrase + "'/" + locale);
         return null;
     }
 
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 7a0272d..9b5d0d3 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -349,7 +349,9 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
         } finally {
             super.finalize();
         }
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 33a92fd..d73d3d8 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -316,10 +316,13 @@
      * @return HashMap containing all connected USB devices.
      */
     public HashMap<String,UsbDevice> getDeviceList() {
+        HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
+        if (mService == null) {
+            return result;
+        }
         Bundle bundle = new Bundle();
         try {
             mService.getDeviceList(bundle);
-            HashMap<String,UsbDevice> result = new HashMap<String,UsbDevice>();
             for (String name : bundle.keySet()) {
                 result.put(name, (UsbDevice)bundle.get(name));
             }
@@ -361,6 +364,9 @@
      * @return list of USB accessories, or null if none are attached.
      */
     public UsbAccessory[] getAccessoryList() {
+        if (mService == null) {
+            return null;
+        }
         try {
             UsbAccessory accessory = mService.getCurrentAccessory();
             if (accessory == null) {
@@ -397,6 +403,9 @@
      * @return true if caller has permission
      */
     public boolean hasPermission(UsbDevice device) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.hasDevicePermission(device);
         } catch (RemoteException e) {
@@ -414,6 +423,9 @@
      * @return true if caller has permission
      */
     public boolean hasPermission(UsbAccessory accessory) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.hasAccessoryPermission(accessory);
         } catch (RemoteException e) {
@@ -531,6 +543,9 @@
      * {@hide}
      */
     public boolean isFunctionEnabled(String function) {
+        if (mService == null) {
+            return false;
+        }
         try {
             return mService.isFunctionEnabled(function);
         } catch (RemoteException e) {
@@ -588,6 +603,9 @@
      * @hide
      */
     public UsbPort[] getPorts() {
+        if (mService == null) {
+            return null;
+        }
         try {
             return mService.getPorts();
         } catch (RemoteException e) {
@@ -636,6 +654,7 @@
         Preconditions.checkNotNull(port, "port must not be null");
         UsbPort.checkRoles(powerRole, dataRole);
 
+        Log.d(TAG, "setPortRoles Package:" + mContext.getPackageName());
         try {
             mService.setPortRoles(port.getId(), powerRole, dataRole);
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index fea730e..afdb202 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -65,6 +65,18 @@
     public static final int MODE_DUAL = Constants.PortMode.DRP;
 
     /**
+     * Mode bit: This USB port can support USB Type-C Audio accessory.
+     */
+    public static final int MODE_AUDIO_ACCESSORY =
+            android.hardware.usb.V1_1.Constants.PortMode_1_1.AUDIO_ACCESSORY;
+
+    /**
+     * Mode bit: This USB port can support USB Type-C debug accessory.
+     */
+    public static final int MODE_DEBUG_ACCESSORY =
+            android.hardware.usb.V1_1.Constants.PortMode_1_1.DEBUG_ACCESSORY;
+
+    /**
      * Power role: This USB port does not have a power role.
      */
     public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE;
@@ -135,9 +147,9 @@
      * in a bit-field.
      *
      * @param powerRole The desired power role: {@link UsbPort#POWER_ROLE_SOURCE}
-     * or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
-     * @param dataRole The desired data role: {@link UsbPort#DATA_ROLE_HOST}
-     * or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
+     *                  or {@link UsbPort#POWER_ROLE_SINK}, or 0 if no power role.
+     * @param dataRole  The desired data role: {@link UsbPort#DATA_ROLE_HOST}
+     *                  or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
      * @hide
      */
     public static int combineRolesAsBit(int powerRole, int dataRole) {
@@ -148,18 +160,31 @@
 
     /** @hide */
     public static String modeToString(int mode) {
-        switch (mode) {
-            case MODE_NONE:
-                return "none";
-            case MODE_DFP:
-                return "dfp";
-            case MODE_UFP:
-                return "ufp";
-            case MODE_DUAL:
-                return "dual";
-            default:
-                return Integer.toString(mode);
+        StringBuilder modeString = new StringBuilder();
+        if (mode == MODE_NONE) {
+            return "none";
         }
+
+        if ((mode & MODE_DUAL) == MODE_DUAL) {
+            modeString.append("dual, ");
+        } else {
+            if ((mode & MODE_DFP) == MODE_DFP) {
+                modeString.append("dfp, ");
+            } else if ((mode & MODE_UFP) == MODE_UFP) {
+                modeString.append("ufp, ");
+            }
+        }
+        if ((mode & MODE_AUDIO_ACCESSORY) == MODE_AUDIO_ACCESSORY) {
+            modeString.append("audio_acc, ");
+        }
+        if ((mode & MODE_DEBUG_ACCESSORY) == MODE_DEBUG_ACCESSORY) {
+            modeString.append("debug_acc, ");
+        }
+
+        if (modeString.length() == 0) {
+            return Integer.toString(mode);
+        }
+        return modeString.substring(0, modeString.length() - 2);
     }
 
     /** @hide */
@@ -240,6 +265,13 @@
         Preconditions.checkArgumentInRange(dataRole, DATA_ROLE_NONE, DATA_ROLE_DEVICE, "dataRole");
     }
 
+    /** @hide */
+    public boolean isModeSupported(int mode) {
+        if ((mSupportedModes & mode) == mode) return true;
+        return false;
+    }
+
+
     @Override
     public String toString() {
         return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes) + "}";
@@ -258,16 +290,16 @@
 
     public static final Parcelable.Creator<UsbPort> CREATOR =
             new Parcelable.Creator<UsbPort>() {
-        @Override
-        public UsbPort createFromParcel(Parcel in) {
-            String id = in.readString();
-            int supportedModes = in.readInt();
-            return new UsbPort(id, supportedModes);
-        }
+                @Override
+                public UsbPort createFromParcel(Parcel in) {
+                    String id = in.readString();
+                    int supportedModes = in.readInt();
+                    return new UsbPort(id, supportedModes);
+                }
 
-        @Override
-        public UsbPort[] newArray(int size) {
-            return new UsbPort[size];
-        }
-    };
+                @Override
+                public UsbPort[] newArray(int size) {
+                    return new UsbPort[size];
+                }
+            };
 }
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 90990b7..2e8f8e1 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -118,7 +118,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index ed223d1..d2e3510 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -16,10 +16,6 @@
 
 package android.inputmethodservice;
 
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.view.IInputMethodSession;
-
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -34,9 +30,13 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.InputMethodSession;
-import android.view.inputmethod.CursorAnchorInfo;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.view.IInputMethodSession;
 
 class IInputMethodSessionWrapper extends IInputMethodSession.Stub
         implements HandlerCaller.Callback {
@@ -218,7 +218,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (mInputMethodSession == null) {
                 // The session has been finished.
                 finishInputEvent(event, false);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index caf7982..0d2fcd0 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,8 +18,8 @@
 
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
@@ -34,8 +34,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.BackupUtils;
+import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
 import java.io.ByteArrayOutputStream;
@@ -52,14 +52,18 @@
  * @hide
  */
 public class NetworkTemplate implements Parcelable {
+    private static final String TAG = "NetworkTemplate";
+
     /**
      * Current Version of the Backup Serializer.
      */
     private static final int BACKUP_VERSION = 1;
 
     public static final int MATCH_MOBILE_ALL = 1;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_3G_LOWER = 2;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_4G = 3;
     public static final int MATCH_WIFI = 4;
@@ -69,9 +73,26 @@
     public static final int MATCH_BLUETOOTH = 8;
     public static final int MATCH_PROXY = 9;
 
+    private static boolean isKnownMatchRule(final int rule) {
+        switch (rule) {
+            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE_3G_LOWER:
+            case MATCH_MOBILE_4G:
+            case MATCH_WIFI:
+            case MATCH_ETHERNET:
+            case MATCH_MOBILE_WILDCARD:
+            case MATCH_WIFI_WILDCARD:
+            case MATCH_BLUETOOTH:
+            case MATCH_PROXY:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
     private static boolean sForceAllNetworkTypes = false;
 
-    @VisibleForTesting
     public static void forceAllNetworkTypes() {
         sForceAllNetworkTypes = true;
     }
@@ -180,6 +201,11 @@
         mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
         mNetworkId = networkId;
+
+        if (!isKnownMatchRule(matchRule)) {
+            Log.e(TAG, "Unknown network template rule " + matchRule
+                    + " will not match any identity.");
+        }
     }
 
     private NetworkTemplate(Parcel in) {
@@ -294,7 +320,9 @@
             case MATCH_PROXY:
                 return matchesProxy(ident);
             default:
-                throw new IllegalArgumentException("unknown network template");
+                // We have no idea what kind of network template we are, so we
+                // just claim not to match anything.
+                return false;
         }
     }
 
@@ -428,7 +456,7 @@
             case MATCH_PROXY:
                 return "PROXY";
             default:
-                return "UNKNOWN";
+                return "UNKNOWN(" + matchRule + ")";
         }
     }
 
@@ -496,6 +524,11 @@
         String subscriberId = BackupUtils.readString(in);
         String networkId = BackupUtils.readString(in);
 
+        if (!isKnownMatchRule(matchRule)) {
+            throw new BackupUtils.BadVersionException(
+                    "Restored network template contains unknown match rule " + matchRule);
+        }
+
         return new NetworkTemplate(matchRule, subscriberId, networkId);
     }
 }
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 3cc52a6..185b181 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -97,7 +97,7 @@
  *       shut down the tunnel gracefully.</li>
  * </ol>
  *
- * <p>Services extended this class need to be declared with appropriate
+ * <p>Services extending this class need to be declared with an appropriate
  * permission and intent filter. Their access must be secured by
  * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
  * their intent filter must match {@link #SERVICE_INTERFACE} action. Here
@@ -110,6 +110,13 @@
  *     &lt;/intent-filter&gt;
  * &lt;/service&gt;</pre>
  *
+ * <p> The Android system starts a VPN in the background by calling
+ * {@link android.content.Context#startService startService()}. In Android 8.0
+ * (API level 26) and higher, the system places VPN apps on the temporary
+ * whitelist for a short period so the app can start in the background. The VPN
+ * app must promote itself to the foreground after it's launched or the system
+ * will shut down the app.
+ *
  * @see Builder
  */
 public class VpnService extends Service {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index c5b0d2b..4160ed7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -201,7 +201,7 @@
      * New in version 22:
      *   - BLE scan result background count, BLE unoptimized scan time
      */
-    static final String CHECKIN_VERSION = "23";
+    static final String CHECKIN_VERSION = "24";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -1219,6 +1219,7 @@
 
         // Platform-level low power state stats
         public String statPlatformIdleState;
+        public String statSubsystemPowerState;
 
         public HistoryStepDetails() {
             clear();
@@ -1250,6 +1251,7 @@
             out.writeInt(statSoftIrqTime);
             out.writeInt(statIdlTime);
             out.writeString(statPlatformIdleState);
+            out.writeString(statSubsystemPowerState);
         }
 
         public void readFromParcel(Parcel in) {
@@ -1271,6 +1273,7 @@
             statSoftIrqTime = in.readInt();
             statIdlTime = in.readInt();
             statPlatformIdleState = in.readString();
+            statSubsystemPowerState = in.readString();
         }
     }
 
@@ -5564,6 +5567,10 @@
                         pw.print(", PlatformIdleStat ");
                         pw.print(rec.stepDetails.statPlatformIdleState);
                         pw.println();
+
+                        pw.print(", SubsystemPowerState ");
+                        pw.print(rec.stepDetails.statSubsystemPowerState);
+                        pw.println();
                     } else {
                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                         pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
@@ -5599,6 +5606,13 @@
                         pw.print(',');
                         if (rec.stepDetails.statPlatformIdleState != null) {
                             pw.print(rec.stepDetails.statPlatformIdleState);
+                            if (rec.stepDetails.statSubsystemPowerState != null) {
+                                pw.print(',');
+                            }
+                        }
+
+                        if (rec.stepDetails.statSubsystemPowerState != null) {
+                            pw.print(rec.stepDetails.statSubsystemPowerState);
                         }
                         pw.println();
                     }
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 9b5ff29..ec01364 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -260,6 +260,19 @@
     }
 
     /**
+     * Return the size of {@link #mParcelledData} in bytes if available, otherwise {@code 0}.
+     *
+     * @hide
+     */
+    public int getSize() {
+        if (mParcelledData != null) {
+            return mParcelledData.dataSize();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
      * Reports whether the bundle contains any parcelled file descriptors.
      */
     public boolean hasFileDescriptors() {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 55b6dc8..75fea52 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -16,13 +16,20 @@
 
 package android.os;
 
-import com.android.internal.util.FastPrintWriter;
-import com.android.internal.util.TypedProperties;
-
 import android.app.AppGlobals;
 import android.content.Context;
 import android.util.Log;
 
+import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.TypedProperties;
+
+import dalvik.bytecode.OpcodeInfo;
+import dalvik.system.VMDebug;
+
+import org.apache.harmony.dalvik.ddmc.Chunk;
+import org.apache.harmony.dalvik.ddmc.ChunkHandler;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
@@ -31,21 +38,16 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Reader;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.harmony.dalvik.ddmc.Chunk;
-import org.apache.harmony.dalvik.ddmc.ChunkHandler;
-import org.apache.harmony.dalvik.ddmc.DdmServer;
 
-import dalvik.bytecode.OpcodeInfo;
-import dalvik.system.VMDebug;
 
 
 /**
@@ -744,6 +746,7 @@
             dest.writeInt(dalvikPrivateClean);
             dest.writeInt(dalvikSharedClean);
             dest.writeInt(dalvikSwappedOut);
+            dest.writeInt(dalvikSwappedOutPss);
             dest.writeInt(nativePss);
             dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
@@ -751,6 +754,7 @@
             dest.writeInt(nativePrivateClean);
             dest.writeInt(nativeSharedClean);
             dest.writeInt(nativeSwappedOut);
+            dest.writeInt(nativeSwappedOutPss);
             dest.writeInt(otherPss);
             dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
@@ -771,6 +775,7 @@
             dalvikPrivateClean = source.readInt();
             dalvikSharedClean = source.readInt();
             dalvikSwappedOut = source.readInt();
+            dalvikSwappedOutPss = source.readInt();
             nativePss = source.readInt();
             nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
@@ -778,6 +783,7 @@
             nativePrivateClean = source.readInt();
             nativeSharedClean = source.readInt();
             nativeSwappedOut = source.readInt();
+            nativeSwappedOutPss = source.readInt();
             otherPss = source.readInt();
             otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
@@ -2266,13 +2272,26 @@
     }
 
     /**
-     * Append the stack traces of a given native process to a specified file.
+     * Append the Java stack traces of a given native process to a specified file.
+     *
      * @param pid pid to dump.
      * @param file path of file to append dump to.
      * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
      * @hide
      */
-    public static native void dumpNativeBacktraceToFileTimeout(int pid, String file, int timeoutSecs);
+    public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file,
+                                                                int timeoutSecs);
+
+    /**
+     * Append the native stack traces of a given process to a specified file.
+     *
+     * @param pid pid to dump.
+     * @param file path of file to append dump to.
+     * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
+     * @hide
+     */
+    public static native boolean dumpNativeBacktraceToFileTimeout(int pid, String file,
+                                                                  int timeoutSecs);
 
     /**
      * Get description of unreachable native memory.
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 50b4f8c..56d6e0a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -369,11 +369,11 @@
      * constraints remain.
      *
      * @param minCount Always keep at least this many files.
-     * @param minAge Always keep files younger than this age.
+     * @param minAgeMs Always keep files younger than this age, in milliseconds.
      * @return if any files were deleted.
      */
-    public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
-        if (minCount < 0 || minAge < 0) {
+    public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
+        if (minCount < 0 || minAgeMs < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
         }
 
@@ -393,9 +393,9 @@
         for (int i = minCount; i < files.length; i++) {
             final File file = files[i];
 
-            // Keep files newer than minAge
+            // Keep files newer than minAgeMs
             final long age = System.currentTimeMillis() - file.lastModified();
-            if (age > minAge) {
+            if (age > minAgeMs) {
                 if (file.delete()) {
                     Log.d(TAG, "Deleted old file " + file);
                     deleted = true;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index f9eaba9..07c6055 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -35,23 +35,12 @@
     private static final String TAG = "GraphicsEnvironment";
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
 
-    public static void setupGraphicsEnvironment(Context context) {
-        chooseDriver(context);
-
-        // Now that we've figured out which driver to use for this process, load and initialize it.
-        // This can take multiple frame periods, and it would otherwise happen as part of the first
-        // frame, increasing first-frame latency. Starting it here, as a low-priority background
-        // thread, means that it's usually done long before we start drawing the first frame,
-        // without significantly disrupting other activity launch work.
-        Thread eglInitThread = new Thread(
-                () -> {
-                    EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
-                },
-                "EGL Init");
-        eglInitThread.start();
-    }
-
-    private static void chooseDriver(Context context) {
+    /**
+     * Choose whether the current process should use the builtin or an updated driver.
+     *
+     * @hide
+     */
+    public static void chooseDriver(Context context) {
         String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
         if (driverPackageName == null || driverPackageName.isEmpty()) {
             return;
@@ -101,6 +90,27 @@
         setDriverPath(paths);
     }
 
+    /**
+     * Start a background thread to initialize EGL.
+     *
+     * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
+     * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
+     * its first frame adds directly to user-visible app launch latency. By starting it earlier
+     * on a separate thread, it can usually be finished well before the UI is ready to be drawn.
+     *
+     * Should only be called after chooseDriver().
+     *
+     * @hide
+     */
+    public static void earlyInitEGL() {
+        Thread eglInitThread = new Thread(
+                () -> {
+                    EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+                },
+                "EGL Init");
+        eglInitThread.start();
+    }
+
     private static String chooseAbi(ApplicationInfo ai) {
         String isa = VMRuntime.getCurrentInstructionSet();
         if (ai.primaryCpuAbi != null &&
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e20113e..571fbcd 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -295,6 +295,7 @@
     private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
 
     private static native byte[] nativeCreateByteArray(long nativePtr);
+    private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen);
     private static native byte[] nativeReadBlob(long nativePtr);
     @FastNative
     private static native int nativeReadInt(long nativePtr);
@@ -2211,11 +2212,8 @@
      * given byte array.
      */
     public final void readByteArray(byte[] val) {
-        // TODO: make this a native method to avoid the extra copy.
-        byte[] ba = createByteArray();
-        if (ba.length == val.length) {
-           System.arraycopy(ba, 0, val, 0, ba.length);
-        } else {
+        boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
+        if (!valid) {
             throw new RuntimeException("bad array lengths");
         }
     }
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index c45eb2e..b5d62e5 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -386,6 +386,12 @@
      **/
     public static final int THREAD_GROUP_TOP_APP = 5;
 
+    /**
+     * Thread group for RT app.
+     * @hide
+     **/
+    public static final int THREAD_GROUP_RT_APP = 6;
+
     public static final int SIGNAL_QUIT = 3;
     public static final int SIGNAL_KILL = 9;
     public static final int SIGNAL_USR1 = 10;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index db9f28b..673a8ba 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -22,20 +22,26 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.logging.MetricsLogger;
+
 import libcore.io.Streams;
 
-import java.io.ByteArrayInputStream;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -46,22 +52,19 @@
 import java.io.RandomAccessFile;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
-import java.security.Signature;
 import java.security.SignatureException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 
-import com.android.internal.logging.MetricsLogger;
-
 import sun.security.pkcs.PKCS7;
 import sun.security.pkcs.SignerInfo;
 
@@ -84,11 +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_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
+
+    private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 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_EUICC_FACTORY_RESET =
+            "com.android.internal.action.EUICC_FACTORY_RESET";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -673,18 +684,26 @@
      */
     public static void rebootWipeUserData(Context context) throws IOException {
         rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
-                false /* force */);
+                false /* force */, false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, String reason) throws IOException {
-        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
+        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */,
+                false /* wipeEuicc */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, boolean shutdown)
             throws IOException {
-        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
+        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */,
+                false /* wipeEuicc */);
+    }
+
+    /** {@hide} */
+    public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+            boolean force) throws IOException {
+        rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */);
     }
 
     /**
@@ -701,6 +720,7 @@
      * @param reason    the reason for the wipe that is visible in the logs
      * @param force     whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
      *                  should be ignored
+     * @param wipeEuicc whether wipe the euicc data
      *
      * @throws IOException  if writing the recovery command file
      * fails, or if the reboot itself fails.
@@ -709,7 +729,7 @@
      * @hide
      */
     public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
-            boolean force) throws IOException {
+            boolean force, boolean wipeEuicc) throws IOException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
             throw new SecurityException("Wiping data is not allowed for this user.");
@@ -731,6 +751,8 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
+        wipeEuiccData(context, wipeEuicc);
+
         String shutdownArg = null;
         if (shutdown) {
             shutdownArg = "--shutdown_after";
@@ -745,6 +767,91 @@
         bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);
     }
 
+    private static void wipeEuiccData(Context context, final boolean isWipeEuicc) {
+        ContentResolver cr = context.getContentResolver();
+        if (Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) == 0) {
+            // If the eUICC isn't provisioned, there's no reason to either wipe or retain profiles,
+            // as there's nothing to wipe nor retain.
+            Log.d(TAG, "Skipping eUICC wipe/retain as it is not provisioned");
+            return;
+        }
+
+        EuiccManager euiccManager = (EuiccManager) context.getSystemService(
+                Context.EUICC_SERVICE);
+        if (euiccManager != null && euiccManager.isEnabled()) {
+            CountDownLatch euiccFactoryResetLatch = new CountDownLatch(1);
+
+            BroadcastReceiver euiccWipeFinishReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    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);
+                            if (isWipeEuicc) {
+                                Log.e(TAG, "Error wiping euicc data, Detailed code = "
+                                        + detailedCode);
+                            } else {
+                                Log.e(TAG, "Error retaining euicc data, Detailed code = "
+                                        + detailedCode);
+                            }
+                        } else {
+                            if (isWipeEuicc) {
+                                Log.d(TAG, "Successfully wiped euicc data.");
+                            } else {
+                                Log.d(TAG, "Successfully retained euicc data.");
+                            }
+                        }
+                        euiccFactoryResetLatch.countDown();
+                    }
+                }
+            };
+
+            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_EUICC_FACTORY_RESET);
+            HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread");
+            euiccHandlerThread.start();
+            Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+            context.getApplicationContext()
+                    .registerReceiver(euiccWipeFinishReceiver, filterConsent, null, euiccHandler);
+            if (isWipeEuicc) {
+                euiccManager.eraseSubscriptions(callbackIntent);
+            } else {
+                euiccManager.retainSubscriptionsForFactoryReset(callbackIntent);
+            }
+            try {
+                long waitingTimeMillis = Settings.Global.getLong(
+                        context.getContentResolver(),
+                        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)) {
+                    if (isWipeEuicc) {
+                        Log.e(TAG, "Timeout wiping eUICC data.");
+                    } else {
+                        Log.e(TAG, "Timeout retaining eUICC data.");
+                    }
+                }
+                context.getApplicationContext().unregisterReceiver(euiccWipeFinishReceiver);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                if (isWipeEuicc) {
+                    Log.e(TAG, "Wiping eUICC data interrupted", e);
+                } else {
+                    Log.e(TAG, "Retaining eUICC data interrupted", e);
+                }
+            }
+        }
+    }
+
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 6c01b36..fa96dd3 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import com.android.internal.os.Zygote;
+
 import dalvik.annotation.optimization.FastNative;
 
 /**
@@ -94,6 +96,8 @@
     // Must be volatile to avoid word tearing.
     private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
 
+    private static int sZygoteDebugFlags = 0;
+
     private static native long nativeGetEnabledTags();
     private static native void nativeSetAppTracingAllowed(boolean allowed);
     private static native void nativeSetTracingEnabled(boolean allowed);
@@ -118,9 +122,10 @@
         // The system provides ordering through a priority level.  Callbacks made through
         // SystemProperties.addChangeCallback currently have a negative priority, while
         // our native code is using a priority of zero.
-        SystemProperties.addChangeCallback(new Runnable() {
-            @Override public void run() {
-                cacheEnabledTags();
+        SystemProperties.addChangeCallback(() -> {
+            cacheEnabledTags();
+            if ((sZygoteDebugFlags & Zygote.DEBUG_JAVA_DEBUGGABLE) != 0) {
+                traceCounter(TRACE_TAG_ALWAYS, "java_debuggable", 1);
             }
         });
     }
@@ -201,8 +206,9 @@
      *
      * @hide
      */
-    public static void setTracingEnabled(boolean enabled) {
+    public static void setTracingEnabled(boolean enabled, int debugFlags) {
         nativeSetTracingEnabled(enabled);
+        sZygoteDebugFlags = debugFlags;
 
         // Setting whether tracing is enabled may change the tags, so we update the cached tags
         // here.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a7fc2e7..794b3ba 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -303,10 +303,12 @@
     public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
 
     /**
-     * Specifies if a user is disallowed from configuring VPN.
-     * The default value is <code>false</code>.
-     * This restriction has an effect in a managed profile only from
-     * {@link android.os.Build.VERSION_CODES#M}
+     * Specifies if a user is disallowed from configuring a VPN. The default value is
+     * <code>false</code>. This restriction has an effect when set by device owners and, in Android
+     * 6.0 ({@linkplain android.os.Build.VERSION_CODES#M API level 23}) or higher, profile owners.
+     * <p>This restriction also prevents VPNs from starting. However, in Android 7.0
+     * ({@linkplain android.os.Build.VERSION_CODES#N API level 24}) or higher, the system does
+     * start always-on VPNs created by the device or profile owner.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -389,10 +391,13 @@
     public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
 
     /**
-     * Specifies if a user is disallowed from disabling application verification.
-     * Starting from {@link android.os.Build.VERSION_CODES#O}, application verification
-     * is enforced across all users on the device if a profile owner or device owner sets
-     * this restriction to <code>true</code>. The default value is <code>false</code>.
+     * Specifies if a user is disallowed from disabling application verification. The default
+     * value is <code>false</code>.
+     *
+     * <p>In Android 8.0 ({@linkplain android.os.Build.VERSION_CODES#O API level 26}) and higher,
+     * this is a global user restriction. If a device owner or profile owner sets this restriction,
+     * the system enforces app verification across all users on the device. Running in earlier
+     * Android versions, this restriction affects only the profile that sets it.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -901,11 +906,8 @@
      * @return the user name
      */
     public String getUserName() {
-        try {
-            return mService.getUserInfo(getUserHandle()).name;
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
+        UserInfo user = getUserInfo(getUserHandle());
+        return user == null ? "" : user.name;
     }
 
     /**
@@ -1458,7 +1460,7 @@
             user = mService.createUser(name, flags);
             // TODO: Keep this in sync with
             // UserManagerService.LocalService.createUserEvenWhenDisallowed
-            if (user != null && !user.isAdmin()) {
+            if (user != null && !user.isAdmin() && !user.isDemo()) {
                 mService.setUserRestriction(DISALLOW_SMS, true, user.id);
                 mService.setUserRestriction(DISALLOW_OUTGOING_CALLS, true, user.id);
             }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 6aa601a..fe9e8c6 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import android.hardware.vibrator.V1_0.Constants.Effect;
+import android.hardware.vibrator.V1_1.Constants.Effect_1_1;
 
 import java.util.Arrays;
 
@@ -41,7 +41,7 @@
      * @see #get(int)
      * @hide
      */
-    public static final int EFFECT_CLICK = Effect.CLICK;
+    public static final int EFFECT_CLICK = Effect_1_1.CLICK;
 
     /**
      * A double click effect.
@@ -49,7 +49,14 @@
      * @see #get(int)
      * @hide
      */
-    public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
+    public static final int EFFECT_DOUBLE_CLICK = Effect_1_1.DOUBLE_CLICK;
+
+    /**
+     * A tick effect.
+     * @see #get(int)
+     * @hide
+     */
+    public static final int EFFECT_TICK = Effect_1_1.TICK;
 
     /** @hide to prevent subclassing from outside of the framework */
     public VibrationEffect() { }
@@ -382,9 +389,14 @@
 
         @Override
         public void validate() {
-            if (mEffectId != EFFECT_CLICK) {
-                throw new IllegalArgumentException(
-                        "Unknown prebaked effect type (value=" + mEffectId + ")");
+            switch (mEffectId) {
+                case EFFECT_CLICK:
+                case EFFECT_DOUBLE_CLICK:
+                case EFFECT_TICK:
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unknown prebaked effect type (value=" + mEffectId + ")");
             }
         }
 
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 93826d80..670f794 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -19,6 +19,7 @@
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.Zygote;
@@ -507,4 +508,27 @@
             return (state.inputStream.readInt() == 0);
         }
     }
+
+    /**
+     * Try connecting to the Zygote over and over again until we hit a time-out.
+     * @param socketName The name of the socket to connect to.
+     */
+    public static void waitForConnectionToZygote(String socketName) {
+        for (int n = 20; n >= 0; n--) {
+            try {
+                final ZygoteState zs = ZygoteState.connect(socketName);
+                zs.close();
+                return;
+            } catch (IOException ioe) {
+                Log.w(LOG_TAG,
+                        "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+        }
+        Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + socketName);
+    }
 }
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 92f7f31..50855bb 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -293,7 +293,7 @@
     ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode) = 74;
     long getCacheQuotaBytes(String volumeUuid, int uid) = 75;
     long getCacheSizeBytes(String volumeUuid, int uid) = 76;
-    long getAllocatableBytes(String volumeUuid, int flags) = 77;
-    void allocateBytes(String volumeUuid, long bytes, int flags) = 78;
+    long getAllocatableBytes(String volumeUuid, int flags, String callingPackage) = 77;
+    void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) = 78;
     void secdiscard(in String path) = 79;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f42edcd..f2aa113 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1181,7 +1181,7 @@
      *
      * @hide
      */
-    public long getStorageCacheBytes(File path) {
+    public long getStorageCacheBytes(File path, @AllocateFlags int flags) {
         final long cachePercent = Settings.Global.getInt(mResolver,
                 Settings.Global.SYS_STORAGE_CACHE_PERCENTAGE, DEFAULT_CACHE_PERCENTAGE);
         final long cacheBytes = (path.getTotalSpace() * cachePercent) / 100;
@@ -1189,7 +1189,16 @@
         final long maxCacheBytes = Settings.Global.getLong(mResolver,
                 Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES, DEFAULT_CACHE_MAX_BYTES);
 
-        return Math.min(cacheBytes, maxCacheBytes);
+        final long result = Math.min(cacheBytes, maxCacheBytes);
+        if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+            return 0;
+        } else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED) != 0) {
+            return 0;
+        } else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED) != 0) {
+            return result / 2;
+        } else {
+            return result;
+        }
     }
 
     /**
@@ -1645,17 +1654,26 @@
     public static final int FLAG_ALLOCATE_AGGRESSIVE = 1 << 0;
 
     /**
-     * Flag indicating that a disk space allocation request should defy any
-     * reserved disk space.
+     * Flag indicating that a disk space allocation request should be allowed to
+     * clear up to all reserved disk space.
      *
      * @hide
      */
-    public static final int FLAG_ALLOCATE_DEFY_RESERVED = 1 << 1;
+    public static final int FLAG_ALLOCATE_DEFY_ALL_RESERVED = 1 << 1;
+
+    /**
+     * Flag indicating that a disk space allocation request should be allowed to
+     * clear up to half of all reserved disk space.
+     *
+     * @hide
+     */
+    public static final int FLAG_ALLOCATE_DEFY_HALF_RESERVED = 1 << 2;
 
     /** @hide */
     @IntDef(flag = true, value = {
             FLAG_ALLOCATE_AGGRESSIVE,
-            FLAG_ALLOCATE_DEFY_RESERVED,
+            FLAG_ALLOCATE_DEFY_ALL_RESERVED,
+            FLAG_ALLOCATE_DEFY_HALF_RESERVED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AllocateFlags {}
@@ -1711,7 +1729,8 @@
     public long getAllocatableBytes(@NonNull UUID storageUuid,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
         try {
-            return mStorageManager.getAllocatableBytes(convert(storageUuid), flags);
+            return mStorageManager.getAllocatableBytes(convert(storageUuid), flags,
+                    mContext.getOpPackageName());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -1768,7 +1787,8 @@
     public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
         try {
-            mStorageManager.allocateBytes(convert(storageUuid), bytes, flags);
+            mStorageManager.allocateBytes(convert(storageUuid), bytes, flags,
+                    mContext.getOpPackageName());
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
         } catch (RemoteException e) {
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 344d947..2931627f 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -20,7 +20,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.permission.IRuntimePermissionPresenter;
 import android.content.pm.permission.RuntimePermissionPresentationInfo;
 import android.content.pm.permission.RuntimePermissionPresenter;
@@ -30,6 +29,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
+
 import com.android.internal.os.SomeArgs;
 
 import java.util.List;
@@ -72,6 +72,16 @@
      */
     public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
 
+    /**
+     * Revoke the permission {@code permissionName} for app {@code packageName}
+     *
+     * @param packageName The package for which to revoke
+     * @param permissionName The permission to revoke
+     *
+     * @hide
+     */
+    public abstract void onRevokeRuntimePermission(String packageName, String permissionName);
+
     @Override
     public final IBinder onBind(Intent intent) {
         return new IRuntimePermissionPresenter.Stub() {
@@ -83,12 +93,22 @@
                 mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
                         args).sendToTarget();
             }
+
+            @Override
+            public void revokeRuntimePermission(String packageName, String permissionName) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = packageName;
+                args.arg2 = permissionName;
+                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
+                        args).sendToTarget();
+            }
         };
     }
 
     private final class MyHandler extends Handler {
         public static final int MSG_GET_APP_PERMISSIONS = 1;
         public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
+        public static final int MSG_REVOKE_APP_PERMISSION = 3;
 
         public MyHandler(Looper looper) {
             super(looper, null, false);
@@ -113,6 +133,14 @@
                         callback.sendResult(null);
                     }
                 } break;
+                case MSG_REVOKE_APP_PERMISSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String packageName = (String) args.arg1;
+                    String permissionName = (String) args.arg2;
+                    args.recycle();
+
+                    onRevokeRuntimePermission(packageName, permissionName);
+                } break;
             }
         }
     }
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 2179bd4..4306bc4 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -934,6 +934,7 @@
      * @param singleLineTitle set {@code true} if the title should be constrained to one line
      */
     public void setSingleLineTitle(boolean singleLineTitle) {
+        mHasSingleLineTitleAttr = true;
         mSingleLineTitle = singleLineTitle;
         notifyChanged();
     }
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index d921ed4..f903012 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -82,7 +82,8 @@
      * If neither of the above are given then:
      * <ul>
      * <li>If exactly one active alarm exists, it is dismissed.
-     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to dismiss.
+     * <li>If more than one active alarm exists, the user is prompted to choose the alarm to
+     * dismiss.
      * </ul>
      * </p><p>
      * If the extra {@link #EXTRA_ALARM_SEARCH_MODE} is used, and the search results contain two or
@@ -104,8 +105,7 @@
      * @see #EXTRA_ALARM_SEARCH_MODE
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_DISMISS_ALARM =
-            "android.intent.action.DISMISS_ALARM";
+    public static final String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
 
     /**
      * Activity Action: Snooze a currently ringing alarm.
@@ -124,8 +124,7 @@
      * @see #EXTRA_ALARM_SNOOZE_DURATION
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_SNOOZE_ALARM =
-            "android.intent.action.SNOOZE_ALARM";
+    public static final String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
 
     /**
      * Activity Action: Set a timer.
@@ -155,6 +154,16 @@
     public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
 
     /**
+     * Activity Action: Dismiss timers.
+     * <p>
+     * Dismiss all currently expired timers. If there are no expired timers, then this is a no-op.
+     * </p>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_DISMISS_TIMER = "android.intent.action.DISMISS_TIMER";
+
+    /**
      * Activity Action: Show the timers.
      * <p>
      * This action opens the timers page.
@@ -200,8 +209,7 @@
      * @see #ALARM_SEARCH_MODE_LABEL
      * @see #ACTION_DISMISS_ALARM
      */
-    public static final String EXTRA_ALARM_SEARCH_MODE =
-        "android.intent.extra.alarm.SEARCH_MODE";
+    public static final String EXTRA_ALARM_SEARCH_MODE = "android.intent.extra.alarm.SEARCH_MODE";
 
     /**
      * Search for the alarm that is most closely matched by the search parameters
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c3b84b7..06e76fe 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -410,6 +410,21 @@
             "android.settings.BLUETOOTH_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow configuration of Assist Gesture.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ASSIST_GESTURE_SETTINGS =
+            "android.settings.ASSIST_GESTURE_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of cast endpoints.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -1422,10 +1437,10 @@
      * to the caller package.
      *
      * <p>
-     * <b>NOTE: </b> applications should call
+     * <b>NOTE: </b> Applications should call
      * {@link android.view.autofill.AutofillManager#hasEnabledAutofillServices()} and
-     * {@link android.view.autofill.AutofillManager#isAutofillSupported()} first, and only
-     * broadcast this intent if they return {@code false} and {@code true} respectively.
+     * {@link android.view.autofill.AutofillManager#isAutofillSupported()}, and only use this action
+     * to start an activity if they return {@code false} and {@code true} respectively.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE =
@@ -1783,6 +1798,12 @@
                 return mContentProvider;
             }
         }
+
+        public void clearProviderForTest() {
+            synchronized (mLock) {
+                mContentProvider = null;
+            }
+        }
     }
 
     // Thread-safe.
@@ -2008,6 +2029,16 @@
                 if (c != null) c.close();
             }
         }
+
+        public void clearGenerationTrackerForTest() {
+            synchronized (NameValueCache.this) {
+                if (mGenerationTracker != null) {
+                    mGenerationTracker.destroy();
+                }
+                mValues.clear();
+                mGenerationTracker = null;
+            }
+        }
     }
 
     /**
@@ -2196,6 +2227,12 @@
             outKeySet.addAll(MOVED_TO_GLOBAL);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -4609,6 +4646,12 @@
             outKeySet.addAll(MOVED_TO_GLOBAL);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -6486,6 +6529,12 @@
         public static final String DOZE_PULSE_ON_PICK_UP = "doze_pulse_on_pick_up";
 
         /**
+         * Whether the device should pulse on long press gesture.
+         * @hide
+         */
+        public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press";
+
+        /**
          * Whether the device should pulse on double tap gesture.
          * @hide
          */
@@ -6769,6 +6818,21 @@
                 "camera_double_twist_to_flip_enabled";
 
         /**
+         * Whether or not the smart camera lift trigger that launches the camera when the user moves
+         * the phone into a position for taking photos should be enabled.
+         *
+         * @hide
+         */
+        public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled";
+
+        /**
+         * The default enable state of the camera lift trigger.
+         *
+         * @hide
+         */
+        public static final int CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT = 1;
+
+        /**
          * Whether the assist gesture should be enabled.
          *
          * @hide
@@ -6783,6 +6847,29 @@
         public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
 
         /**
+         * Whether the assist gesture should silence alerts.
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED =
+                "assist_gesture_silence_alerts_enabled";
+
+        /**
+         * Whether the assist gesture should wake the phone.
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_WAKE_ENABLED =
+                "assist_gesture_wake_enabled";
+
+        /**
+         * Whether Assist Gesture Deferred Setup has been completed
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
+
+        /**
          * Control whether Night display is currently activated.
          * @hide
          */
@@ -6922,6 +7009,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
          */
@@ -6977,6 +7074,12 @@
         public static final String NOTIFICATION_BADGING = "notification_badging";
 
         /**
+         * Comma separated list of QS tiles that have been auto-added already.
+         * @hide
+         */
+        public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -7057,8 +7160,6 @@
             NIGHT_DISPLAY_CUSTOM_END_TIME,
             NIGHT_DISPLAY_COLOR_TEMPERATURE,
             NIGHT_DISPLAY_AUTO_MODE,
-            NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
-            NIGHT_DISPLAY_ACTIVATED,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
@@ -7071,8 +7172,16 @@
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             ASSIST_GESTURE_ENABLED,
             ASSIST_GESTURE_SENSITIVITY,
+            ASSIST_GESTURE_SETUP_COMPLETE,
+            ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
+            ASSIST_GESTURE_WAKE_ENABLED,
             VR_DISPLAY_MODE,
-            NOTIFICATION_BADGING
+            NOTIFICATION_BADGING,
+            QS_AUTO_ADDED_TILES,
+            SCREENSAVER_ENABLED,
+            SCREENSAVER_COMPONENTS,
+            SCREENSAVER_ACTIVATE_ON_DOCK,
+            SCREENSAVER_ACTIVATE_ON_SLEEP,
         };
 
         /**
@@ -7654,6 +7763,31 @@
        public static final String FORCE_ALLOW_ON_EXTERNAL = "force_allow_on_external";
 
         /**
+         * The default SM-DP+ configured for this device.
+         *
+         * <p>An SM-DP+ is used by an LPA (see {@link android.service.euicc.EuiccService}) to
+         * download profiles. If this value is set, the LPA will query this server for any profiles
+         * available to this device. If any are available, they may be downloaded during device
+         * provisioning or in settings without needing the user to enter an activation code.
+         *
+         * @see android.service.euicc.EuiccService
+         * @hide
+         *
+         * TODO(b/35851809): Make this a SystemApi.
+         */
+        public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
+
+        /**
+         * Whether any profile has ever been downloaded onto a eUICC on the device.
+         *
+         * <p>Used to hide eUICC UI from users who have never made use of it and would only be
+         * confused by seeing references to it in settings.
+         * (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String EUICC_PROVISIONED = "euicc_provisioned";
+
+        /**
          * Whether any activity can be resized. When this is true, any
          * activity, regardless of manifest values, can be resized for multi-window.
          * (0 = false, 1 = true)
@@ -9156,6 +9290,23 @@
         public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
 
         /**
+         * Battery anomaly detection specific settings
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * "anomaly_detection_enabled=true,wakelock_threshold=2000"
+         *
+         * The following keys are supported:
+         *
+         * <pre>
+         * anomaly_detection_enabled       (boolean)
+         * wakelock_enabled                (boolean)
+         * wakelock_threshold              (long)
+         * </pre>
+         * @hide
+         */
+        public static final String ANOMALY_DETECTION_CONSTANTS = "anomaly_detection_constants";
+
+        /**
          * App standby (app idle) specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
@@ -9943,22 +10094,6 @@
         public static final String DEVICE_DEMO_MODE = "device_demo_mode";
 
         /**
-         * Retail mode specific settings. This is encoded as a key=value list, separated by commas.
-         * Ex: "user_inactivity_timeout_ms=30000,warning_dialog_timeout_ms=10000". The following
-         * keys are supported:
-         *
-         * <pre>
-         * user_inactivity_timeout_ms  (long)
-         * warning_dialog_timeout_ms   (long)
-         * </pre>
-         * <p>
-         * Type: string
-         *
-         * @hide
-         */
-        public static final String RETAIL_DEMO_MODE_CONSTANTS = "retail_demo_mode_constants";
-
-        /**
          * Indicates the maximum time that an app is blocked for the network rules to get updated.
          *
          * Type: long
@@ -10004,6 +10139,23 @@
                 "location_settings_link_to_permissions_enabled";
 
         /**
+         * Flag to enable use of RefactoredBackupManagerService.
+         *
+         * @hide
+         */
+        public static final String BACKUP_REFACTORED_SERVICE_DISABLED =
+            "backup_refactored_service_disabled";
+
+        /**
+         * Flag to set the waiting time for euicc factory reset inside System > Settings
+         * Type: long
+         *
+         * @hide
+         */
+        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
          * keys and easy to update.
          *
@@ -10063,6 +10215,12 @@
             outKeySet.addAll(MOVED_TO_SECURE);
         }
 
+        /** @hide */
+        public static void clearProviderForTest() {
+            sProviderHolder.clearProviderForTest();
+            sNameValueCache.clearGenerationTrackerForTest();
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -10520,7 +10678,7 @@
         /**
          * The maximum allowed notification enqueue rate in Hertz.
          *
-         * Should be a float, and includes both posts and updates.
+         * Should be a float, and includes updates only.
          * @hide
          */
         public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
@@ -10583,6 +10741,13 @@
          */
         public static final String ENABLE_CACHE_QUOTA_CALCULATION =
                 "enable_cache_quota_calculation";
+
+        /**
+         * Whether the Deletion Helper no threshold toggle is available.
+         * @hide
+         */
+        public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE =
+                "enable_deletion_helper_no_threshold_toggle";
     }
 
     /**
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index bfc8636c..42282ac 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -48,7 +48,7 @@
     byte[] sign(String name, in byte[] data);
     int verify(String name, in byte[] data, in byte[] signature);
     byte[] get_pubkey(String name);
-    int grant(String name, int granteeUid);
+    String grant(String name, int granteeUid);
     int ungrant(String name, int granteeUid);
     long getmtime(String name, int uid);
     int duplicate(String srcKey, int srcUid, String destKey, int destUid);
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index a80ef03..53b49f0 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -179,11 +179,18 @@
  * should not contain fields for username, password, and credit card information. The reason for
  * this rule is that a malicious app could draft a view structure where the credit card fields
  * are not visible, so when the user selects a dataset from the username UI, the credit card info is
- * released to the application without the user knowledge. Similar, it's recommended to always
+ * released to the application without the user knowledge. Similarly, it's recommended to always
  * protect a dataset that contains sensitive information by requiring dataset authentication
- * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}).
+ * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include
+ * info about the "primary" field of the partition in the custom presentation for "secondary"
+ * fields &mdash; that would prevent a malicious app from getting the "primary" fields without the
+ * user realizing they're being released (for example, a malicious app could have fields for a
+ * credit card number, verification code, and expiration date crafted in a way that just the latter
+ * is visible; by explicitly indicating the expiration date is related to a given credit card
+ * number, the service would be providing a visual clue for the users to check what would be
+ * released upon selecting that field).
  *
- * <p>When the service detects that a screen have multiple partitions, it should return a
+ * <p>When the service detects that a screen has multiple partitions, it should return a
  * {@link FillResponse} with just the datasets for the partition that originated the request (i.e.,
  * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose
  * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if
@@ -236,6 +243,36 @@
  * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous;
  * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions.
  *
+ * <h3>Package verification</h3>
+ *
+ * <p>When autofilling app-specific data (like username and password), the service must verify
+ * the authenticity of the request by obtaining all signing certificates of the app being
+ * autofilled, and only fulfilling the request when they match the values that were
+ * obtained when the data was first saved &mdash; such verification is necessary to avoid phishing
+ * attempts by apps that were sideloaded in the device with the same package name of another app.
+ * Here's an example on how to achieve that by hashing the signing certificates:
+ *
+ * <pre class="prettyprint">
+ * private String getCertificatesHash(String packageName) throws Exception {
+ *   PackageManager pm = mContext.getPackageManager();
+ *   PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ *   ArrayList<String> hashes = new ArrayList<>(info.signatures.length);
+ *   for (Signature sig : info.signatures) {
+ *     byte[] cert = sig.toByteArray();
+ *     MessageDigest md = MessageDigest.getInstance("SHA-256");
+ *     md.update(cert);
+ *     hashes.add(toHexString(md.digest()));
+ *   }
+ *   Collections.sort(hashes);
+ *   StringBuilder hash = new StringBuilder();
+ *   for (int i = 0; i < hashes.size(); i++) {
+ *     hash.append(hashes.get(i));
+ *   }
+ *   return hash.toString();
+ * }
+ *
+ * </pre>
+ *
  * <h3>Ignoring views</h3>
  *
  * <p>If the service find views that cannot be autofilled (for example, a text field representing
@@ -243,6 +280,76 @@
  * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
  * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
  * focused.
+ *
+ * <h3>Web security</h3>
+ *
+ * <p>When handling autofill requests that represent web pages (typically
+ * view structures whose root's {@link android.app.assist.AssistStructure.ViewNode#getClassName()}
+ * is a {@link android.webkit.WebView}), the service should take the following steps to verify if
+ * the structure can be autofilled with the data associated with the app requesting it:
+ *
+ * <ol>
+ *   <li>Use the {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()} to get the
+ *       source of the document.
+ *   <li>Get the canonical domain using the
+ *       <a href="https://publicsuffix.org/>Public Suffix List</a> (see example below).
+ *   <li>Use <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a>
+ *       to obtain the package name and certificate fingerprint of the package corresponding to
+ *       the canonical domain.
+ *   <li>Make sure the certificate fingerprint matches the value returned by Package Manager
+ *       (see "Package verification" section above).
+ * </ol>
+ *
+ * <p>Here's an example on how to get the canonical domain using
+ * <a href="https://github.com/google/guava">Guava</a>:
+ *
+ * <pre class="prettyprint">
+ * private static String getCanonicalDomain(String domain) {
+ *   InternetDomainName idn = InternetDomainName.from(domain);
+ *   while (!idn.isTopPrivateDomain() && idn != null) {
+ *     idn = idn.parent();
+ *   }
+ *   return idn == null ? null : idn.toString();
+ * }
+ * </pre>
+ *
+ * <p>If the association between the web domain and app package cannot be verified through the steps
+ * above, the service can still autofill the app, but it should warn the user about the potential
+ * data leakage first, and askfor the user to confirm. For example, the service could:
+ *
+ * <ol>
+ *   <li>Create a dataset that requires
+ *       {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authentication} to
+ *       unlock.
+ *   <li>Include the web domain in the custom presentation for the
+ *       {@link Dataset.Builder#setValue(AutofillId, AutofillValue, android.widget.RemoteViews)
+ *       dataset value}.
+ *   <li>When the user select that dataset, show a disclaimer dialog explaining that the app is
+ *       requesting credentials for a web domain, but the service could not verify if the app owns
+ *       that domain. If the user agrees, then the service can unlock the dataset.
+ *   <li>Similarly, when adding a {@link SaveInfo} object for the request, the service should
+ *       include the above disclaimer in the {@link SaveInfo.Builder#setDescription(CharSequence)}.
+ * </ol>
+ *
+ * <p>This same procedure could also be used when the autofillable data is contained inside an
+ * {@code IFRAME}, in which case the WebView generates a new autofill context when a node inside
+ * the {@code IFRAME} is focused, which the root node containing the {@code IFRAME}'s {@code src}
+ * attribute on {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()}. A typical and
+ * legitimate use case for this scenario is a financial app that allows the user
+ * to login on different bank accounts. For example, a financial app {@code my_financial_app} could
+ * use a WebView that loads contents from {@code banklogin.my_financial_app.com}, which contains an
+ * {@code IFRAME} node whose {@code src} attribute is {@code login.some_bank.com}. When fulfilling
+ * that request, the service could add an
+ * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authenticated dataset}
+ * whose presentation displays "Username for some_bank.com" and
+ * "Password for some_bank.com". Then when the user taps one of these options, the service
+ * shows the disclaimer dialog explaining that selecting that option would release the
+ * {@code login.some_bank.com} credentials to the {@code my_financial_app}; if the user agrees,
+ * then the service returns an unlocked dataset with the {@code some_bank.com} credentials.
+ *
+ * <p><b>Note:</b> The autofill service could also whitelist well-known browser apps and skip the
+ * verifications above, as long as the service can verify the authenticity of the browser app by
+ * checking its signing certificate.
  */
 public abstract class AutofillService extends Service {
     private static final String TAG = "AutofillService";
@@ -387,7 +494,7 @@
      * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
      * to notify the result of the request.
      *
-     * <p><b>NOTE: </b>to retrieve the actual value of the field, the service should call
+     * <p><b>Note:</b> To retrieve the actual value of the field, the service should call
      * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls
      * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no
      * guarantee such method will return the most recent value of the field.
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index e13fdf6..80ef3aa 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -205,6 +205,13 @@
         /**
          * Adds a new {@link Dataset} to this response.
          *
+         * <p><b>Note: </b> the total number of datasets is limited by the Binder transaction size,
+         * so it's recommended to keep it small (in the range of 10-20 at most) and use pagination
+         * by adding a fake
+         * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated dataset}
+         * at the end with a presentation string like "Next 10" that would return a new
+         * {@link FillResponse} with the next 10 datasets, and so on.
+         *
          * @return This builder.
          */
         public @NonNull Builder addDataset(@Nullable Dataset dataset) {
diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/core/java/android/service/euicc/EuiccProfileInfo.java
new file mode 100644
index 0000000..ba6c9a2
--- /dev/null
+++ b/core/java/android/service/euicc/EuiccProfileInfo.java
@@ -0,0 +1,84 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.UiccAccessRule;
+import android.text.TextUtils;
+
+/**
+ * Information about an embedded profile (subscription) on an eUICC.
+ *
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class EuiccProfileInfo implements Parcelable {
+
+    /** The iccid of the subscription. */
+    public final String iccid;
+
+    /**
+     * Optional access rules defining which apps can manage this subscription. If unset, only the
+     * platform can manage it.
+     */
+    public final @Nullable UiccAccessRule[] accessRules;
+
+    /** An optional nickname for the subscription. */
+    public final @Nullable String nickname;
+
+    public static final Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() {
+        @Override
+        public EuiccProfileInfo createFromParcel(Parcel in) {
+            return new EuiccProfileInfo(in);
+        }
+
+        @Override
+        public EuiccProfileInfo[] newArray(int size) {
+            return new EuiccProfileInfo[size];
+        }
+    };
+
+    public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules,
+            @Nullable String nickname) {
+        if (!TextUtils.isDigitsOnly(iccid)) {
+            throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
+        }
+        this.iccid = iccid;
+        this.accessRules = accessRules;
+        this.nickname = nickname;
+    }
+
+    private EuiccProfileInfo(Parcel in) {
+        iccid = in.readString();
+        accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+        nickname = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(iccid);
+        dest.writeTypedArray(accessRules, flags);
+        dest.writeString(nickname);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
new file mode 100644
index 0000000..0c2e4b7
--- /dev/null
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -0,0 +1,523 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.CallSuper;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.euicc.DownloadableSubscription;
+import android.telephony.euicc.EuiccInfo;
+import android.util.ArraySet;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Service interface linking the system with an eUICC local profile assistant (LPA) application.
+ *
+ * <p>An LPA consists of two separate components (which may both be implemented in the same APK):
+ * the LPA backend, and the LPA UI or LUI.
+ *
+ * <p>To implement the LPA backend, you must extend this class and declare this service in your
+ * manifest file. The service must require the
+ * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission and include an intent filter
+ * with the {@link #EUICC_SERVICE_INTERFACE} action. The priority of the intent filter must be set
+ * to a non-zero value in case multiple implementations are present on the device. For example:
+ *
+ * <pre>{@code
+ * <service android:name=".MyEuiccService"
+ *          android:permission="android.permission.BIND_EUICC_SERVICE">
+ *     <intent-filter android:priority="100">
+ *         <action android:name="android.service.euicc.EuiccService" />
+ *     </intent-filter>
+ * </service>
+ * }</pre>
+ *
+ * <p>To implement the LUI, you must provide an activity for the following actions:
+ *
+ * <ul>
+ * <li>{@link #ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS}
+ * <li>{@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION}
+ * </ul>
+ *
+ * <p>As with the service, each activity must require the
+ * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission. Each should have an intent
+ * filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero
+ * priority.
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ * @hide
+ */
+public abstract class EuiccService extends Service {
+    /** Action which must be included in this service's intent filter. */
+    public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
+
+    /** Category which must be defined to all UI actions, for efficient lookup. */
+    public static final String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI";
+
+    // LUI actions. These are passthroughs of the corresponding EuiccManager actions.
+
+    /** @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS */
+    public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
+            "android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+    /** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */
+    public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
+            "android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+
+    // LUI resolution actions. These are called by the platform to resolve errors in situations that
+    // require user interaction.
+    // TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
+    // more scoped out.
+    /** Alert the user that this action will result in an active SIM being deactivated. */
+    public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
+            "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
+    /**
+     * Alert the user about a download/switch being done for an app that doesn't currently have
+     * carrier privileges.
+     */
+    public static final String ACTION_RESOLVE_NO_PRIVILEGES =
+            "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
+
+    /** Intent extra set for resolution requests containing the package name of the calling app. */
+    public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
+            "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+
+    /** Result code for a successful operation. */
+    public static final int RESULT_OK = 0;
+    /** Result code indicating that an active SIM must be deactivated to perform the operation. */
+    public static final int RESULT_MUST_DEACTIVATE_SIM = -1;
+    // New predefined codes should have negative values.
+
+    /** Start of implementation-specific error results. */
+    public static final int RESULT_FIRST_USER = 1;
+
+    /**
+     * List of all valid resolution actions for validation purposes.
+     * @hide
+     */
+    public static final ArraySet<String> RESOLUTION_ACTIONS;
+    static {
+        RESOLUTION_ACTIONS = new ArraySet<>();
+        RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM);
+        RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES);
+    }
+
+    /** Boolean extra for resolution actions indicating whether the user granted consent. */
+    public static final String RESOLUTION_EXTRA_CONSENT = "consent";
+
+    private final IEuiccService.Stub mStubWrapper;
+
+    private ThreadPoolExecutor mExecutor;
+
+    public EuiccService() {
+        mStubWrapper = new IEuiccServiceWrapper();
+    }
+
+    @Override
+    @CallSuper
+    public void onCreate() {
+        super.onCreate();
+        // We use a oneway AIDL interface to avoid blocking phone process binder threads on IPCs to
+        // an external process, but doing so means the requests are serialized by binder, which is
+        // not desired. Spin up a background thread pool to allow requests to be parallelized.
+        // TODO(b/38206971): Consider removing this if basic card-level functions like listing
+        // profiles are moved to the platform.
+        mExecutor = new ThreadPoolExecutor(
+                4 /* corePoolSize */,
+                4 /* maxPoolSize */,
+                30, TimeUnit.SECONDS, /* keepAliveTime */
+                new LinkedBlockingQueue<>(), /* workQueue */
+                new ThreadFactory() {
+                    private final AtomicInteger mCount = new AtomicInteger(1);
+
+                    @Override
+                    public Thread newThread(Runnable r) {
+                        return new Thread(r, "EuiccService #" + mCount.getAndIncrement());
+                    }
+                }
+        );
+        mExecutor.allowCoreThreadTimeOut(true);
+    }
+
+    @Override
+    @CallSuper
+    public void onDestroy() {
+        mExecutor.shutdownNow();
+        super.onDestroy();
+    }
+
+    /**
+     * If overriding this method, call through to the super method for any unknown actions.
+     * {@inheritDoc}
+     */
+    @Override
+    @CallSuper
+    public IBinder onBind(Intent intent) {
+        return mStubWrapper;
+    }
+
+    /**
+     * Return the EID of the eUICC.
+     *
+     * @param slotId ID of the SIM slot being queried. This is currently not populated but is here
+     *     to future-proof the APIs.
+     * @return the EID.
+     * @see android.telephony.euicc.EuiccManager#getEid
+     */
+    // TODO(b/36260308): Update doc when we have multi-SIM support.
+    public abstract String onGetEid(int slotId);
+
+    /**
+     * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param subscription A subscription whose metadata needs to be populated.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return The result of the operation.
+     * @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata
+     */
+    public abstract GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(
+            int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim);
+
+    /**
+     * Return metadata for subscriptions which are available for download for this device.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return The result of the list operation.
+     * @see android.telephony.euicc.EuiccManager#getDefaultDownloadableSubscriptionList
+     */
+    public abstract GetDefaultDownloadableSubscriptionListResult
+            onGetDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim);
+
+    /**
+     * Download the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param subscription The subscription to download.
+     * @param switchAfterDownload If true, the subscription should be enabled upon successful
+     *     download.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return the result of the download operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#downloadSubscription
+     */
+    public abstract int onDownloadSubscription(int slotId,
+            DownloadableSubscription subscription, boolean switchAfterDownload,
+            boolean forceDeactivateSim);
+
+    /**
+     * Return a list of all @link EuiccProfileInfo}s.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return The result of the operation.
+     * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
+     * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
+     */
+    public abstract GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId);
+
+    /**
+     * Return info about the eUICC chip/device.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the {@link EuiccInfo} for the eUICC chip/device.
+     * @see android.telephony.euicc.EuiccManager#getEuiccInfo
+     */
+    public abstract EuiccInfo onGetEuiccInfo(int slotId);
+
+    /**
+     * Delete the given subscription.
+     *
+     * <p>If the subscription is currently active, it should be deactivated first (equivalent to a
+     * physical SIM being ejected).
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to delete.
+     * @return the result of the delete operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#deleteSubscription
+     */
+    public abstract int onDeleteSubscription(int slotId, String iccid);
+
+    /**
+     * Switch to the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to enable. May be null, in which case the current
+     *     profile should be deactivated and no profile should be activated to replace it - this is
+     *     equivalent to a physical SIM being ejected.
+     * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+     *     eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+     *     should be returned to allow the user to consent to this operation first.
+     * @return the result of the switch operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#switchToSubscription
+     */
+    public abstract int onSwitchToSubscription(int slotId, @Nullable String iccid,
+            boolean forceDeactivateSim);
+
+    /**
+     * Update the nickname of the given subscription.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @param iccid the ICCID of the subscription to update.
+     * @param nickname the new nickname to apply.
+     * @return the result of the update operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#updateSubscriptionNickname
+     */
+    public abstract int onUpdateSubscriptionNickname(int slotId, String iccid,
+            String nickname);
+
+    /**
+     * Erase all of the subscriptions on the device.
+     *
+     * <p>This is intended to be used for device resets. As such, the reset should be performed even
+     * if an active SIM must be deactivated in order to access the eUICC.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the erase operation. May be one of the predefined {@code RESULT_}
+     *     constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     * @see android.telephony.euicc.EuiccManager#eraseSubscriptions
+     */
+    public abstract int onEraseSubscriptions(int slotId);
+
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>Called directly before a factory reset. Assumes that a normal factory reset will lead to
+     * profiles being erased on first boot (to cover fastboot/recovery wipes), so the implementation
+     * should persist some bit that will remain accessible after the factory reset to bypass this
+     * flow when this method is called.
+     *
+     * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
+     *     but is here to future-proof the APIs.
+     * @return the result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
+     */
+    public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
+
+    /**
+     * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
+     */
+    private class IEuiccServiceWrapper extends IEuiccService.Stub {
+        @Override
+        public void downloadSubscription(int slotId, DownloadableSubscription subscription,
+                boolean switchAfterDownload, boolean forceDeactivateSim,
+                IDownloadSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onDownloadSubscription(
+                            slotId, subscription, switchAfterDownload, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEid(int slotId, IGetEidCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    String eid = EuiccService.this.onGetEid(slotId);
+                    try {
+                        callback.onSuccess(eid);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getDownloadableSubscriptionMetadata(int slotId,
+                DownloadableSubscription subscription,
+                boolean forceDeactivateSim,
+                IGetDownloadableSubscriptionMetadataCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetDownloadableSubscriptionMetadataResult result =
+                            EuiccService.this.onGetDownloadableSubscriptionMetadata(
+                                    slotId, subscription, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim,
+                IGetDefaultDownloadableSubscriptionListCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetDefaultDownloadableSubscriptionListResult result =
+                            EuiccService.this.onGetDefaultDownloadableSubscriptionList(
+                                    slotId, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEuiccProfileInfoList(int slotId, IGetEuiccProfileInfoListCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    GetEuiccProfileInfoListResult result =
+                            EuiccService.this.onGetEuiccProfileInfoList(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void getEuiccInfo(int slotId, IGetEuiccInfoCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    EuiccInfo euiccInfo = EuiccService.this.onGetEuiccInfo(slotId);
+                    try {
+                        callback.onSuccess(euiccInfo);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+
+        }
+
+        @Override
+        public void deleteSubscription(int slotId, String iccid,
+                IDeleteSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onDeleteSubscription(slotId, iccid);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
+                ISwitchToSubscriptionCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result =
+                            EuiccService.this.onSwitchToSubscription(
+                                    slotId, iccid, forceDeactivateSim);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void updateSubscriptionNickname(int slotId, String iccid, String nickname,
+                IUpdateSubscriptionNicknameCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result =
+                            EuiccService.this.onUpdateSubscriptionNickname(slotId, iccid, nickname);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void eraseSubscriptions(int slotId, IEraseSubscriptionsCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onEraseSubscriptions(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void retainSubscriptionsForFactoryReset(int slotId,
+                IRetainSubscriptionsForFactoryResetCallback callback) {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    int result = EuiccService.this.onRetainSubscriptionsForFactoryReset(slotId);
+                    try {
+                        callback.onComplete(result);
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl
new file mode 100644
index 0000000..c2636a1
--- /dev/null
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetDefaultDownloadableSubscriptionListResult;
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
new file mode 100644
index 0000000..5a24492
--- /dev/null
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.euicc.DownloadableSubscription;
+
+/**
+ * Result of a {@link EuiccService#onGetDefaultDownloadableSubscriptionList} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetDefaultDownloadableSubscriptionListResult implements Parcelable {
+
+    public static final Creator<GetDefaultDownloadableSubscriptionListResult> CREATOR =
+            new Creator<GetDefaultDownloadableSubscriptionListResult>() {
+        @Override
+        public GetDefaultDownloadableSubscriptionListResult createFromParcel(Parcel in) {
+            return new GetDefaultDownloadableSubscriptionListResult(in);
+        }
+
+        @Override
+        public GetDefaultDownloadableSubscriptionListResult[] newArray(int size) {
+            return new GetDefaultDownloadableSubscriptionListResult[size];
+        }
+    };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /**
+     * The available {@link DownloadableSubscription}s (with filled-in metadata).
+     *
+     * <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
+     */
+    @Nullable
+    public final DownloadableSubscription[] subscriptions;
+
+    /**
+     * Construct a new {@link GetDefaultDownloadableSubscriptionListResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param subscriptions The available subscriptions. Should only be provided if the result is
+     *     {@link EuiccService#RESULT_OK}.
+     */
+    public GetDefaultDownloadableSubscriptionListResult(int result,
+            @Nullable DownloadableSubscription[] subscriptions) {
+        this.result = result;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.subscriptions = subscriptions;
+        } else {
+            if (subscriptions != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null subscriptions: " + result);
+            }
+            this.subscriptions = null;
+        }
+    }
+
+    private GetDefaultDownloadableSubscriptionListResult(Parcel in) {
+        this.result = in.readInt();
+        this.subscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedArray(subscriptions, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl
new file mode 100644
index 0000000..791ad9b
--- /dev/null
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetDownloadableSubscriptionMetadataResult;
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
new file mode 100644
index 0000000..de8a307
--- /dev/null
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.euicc.DownloadableSubscription;
+
+/**
+ * Result of a {@link EuiccService#onGetDownloadableSubscriptionMetadata} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetDownloadableSubscriptionMetadataResult implements Parcelable {
+
+    public static final Creator<GetDownloadableSubscriptionMetadataResult> CREATOR =
+            new Creator<GetDownloadableSubscriptionMetadataResult>() {
+        @Override
+        public GetDownloadableSubscriptionMetadataResult createFromParcel(Parcel in) {
+            return new GetDownloadableSubscriptionMetadataResult(in);
+        }
+
+        @Override
+        public GetDownloadableSubscriptionMetadataResult[] newArray(int size) {
+            return new GetDownloadableSubscriptionMetadataResult[size];
+        }
+    };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /**
+     * The {@link DownloadableSubscription} with filled-in metadata.
+     *
+     * <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
+     */
+    @Nullable
+    public final DownloadableSubscription subscription;
+
+    /**
+     * Construct a new {@link GetDownloadableSubscriptionMetadataResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param subscription The subscription with filled-in metadata. Should only be provided if the
+     *     result is {@link EuiccService#RESULT_OK}.
+     */
+    public GetDownloadableSubscriptionMetadataResult(int result,
+            @Nullable DownloadableSubscription subscription) {
+        this.result = result;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.subscription = subscription;
+        } else {
+            if (subscription != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null subscription: " + result);
+            }
+            this.subscription = null;
+        }
+    }
+
+    private GetDownloadableSubscriptionMetadataResult(Parcel in) {
+        this.result = in.readInt();
+        this.subscription = in.readTypedObject(DownloadableSubscription.CREATOR);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedObject(this.subscription, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl
new file mode 100644
index 0000000..6003b79
--- /dev/null
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.euicc;
+
+parcelable GetEuiccProfileInfoListResult;
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
new file mode 100644
index 0000000..7ad8488
--- /dev/null
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
@@ -0,0 +1,104 @@
+/*
+ * 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.service.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Result of a {@link EuiccService#onGetEuiccProfileInfoList} operation.
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class GetEuiccProfileInfoListResult implements Parcelable {
+
+    public static final Creator<GetEuiccProfileInfoListResult> CREATOR =
+            new Creator<GetEuiccProfileInfoListResult>() {
+                @Override
+                public GetEuiccProfileInfoListResult createFromParcel(Parcel in) {
+                    return new GetEuiccProfileInfoListResult(in);
+                }
+
+                @Override
+                public GetEuiccProfileInfoListResult[] newArray(int size) {
+                    return new GetEuiccProfileInfoListResult[size];
+                }
+            };
+
+    /**
+     * Result of the operation.
+     *
+     * <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
+     * implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
+     */
+    public final int result;
+
+    /** The profile list (only upon success). */
+    @Nullable
+    public final EuiccProfileInfo[] profiles;
+
+    /** Whether the eUICC is removable. */
+    public final boolean isRemovable;
+
+    /**
+     * Construct a new {@link GetEuiccProfileInfoListResult}.
+     *
+     * @param result Result of the operation. May be one of the predefined {@code RESULT_} constants
+     *     in EuiccService or any implementation-specific code starting with
+     *     {@link EuiccService#RESULT_FIRST_USER}.
+     * @param profiles the list of profiles. Should only be provided if the result is
+     *     {@link EuiccService#RESULT_OK}.
+     * @param isRemovable whether the eUICC in this slot is removable. If true, the profiles
+     *     returned here will only be considered accessible as long as this eUICC is present.
+     *     Otherwise, they will remain accessible until the next time a response with isRemovable
+     *     set to false is returned.
+     */
+    public GetEuiccProfileInfoListResult(
+            int result, @Nullable EuiccProfileInfo[] profiles, boolean isRemovable) {
+        this.result = result;
+        this.isRemovable = isRemovable;
+        if (this.result == EuiccService.RESULT_OK) {
+            this.profiles = profiles;
+        } else {
+            if (profiles != null) {
+                throw new IllegalArgumentException(
+                        "Error result with non-null profiles: " + result);
+            }
+            this.profiles = null;
+        }
+
+    }
+
+    private GetEuiccProfileInfoListResult(Parcel in) {
+        this.result = in.readInt();
+        this.profiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
+        this.isRemovable = in.readBoolean();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeTypedArray(profiles, flags);
+        dest.writeBoolean(isRemovable);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl b/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl
new file mode 100644
index 0000000..4667066
--- /dev/null
+++ b/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IDeleteSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
new file mode 100644
index 0000000..6893c85
--- /dev/null
+++ b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IDownloadSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl b/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl
new file mode 100644
index 0000000..c975f18
--- /dev/null
+++ b/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IEraseSubscriptionsCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
new file mode 100644
index 0000000..e10dd8c
--- /dev/null
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.service.euicc;
+
+import android.service.euicc.IDeleteSubscriptionCallback;
+import android.service.euicc.IDownloadSubscriptionCallback;
+import android.service.euicc.IEraseSubscriptionsCallback;
+import android.service.euicc.IGetDefaultDownloadableSubscriptionListCallback;
+import android.service.euicc.IGetDownloadableSubscriptionMetadataCallback;
+import android.service.euicc.IGetEidCallback;
+import android.service.euicc.IGetEuiccInfoCallback;
+import android.service.euicc.IGetEuiccProfileInfoListCallback;
+import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
+import android.service.euicc.ISwitchToSubscriptionCallback;
+import android.service.euicc.IUpdateSubscriptionNicknameCallback;
+import android.telephony.euicc.DownloadableSubscription;
+
+/** @hide */
+oneway interface IEuiccService {
+    void downloadSubscription(int slotId, in DownloadableSubscription subscription,
+            boolean switchAfterDownload, boolean forceDeactivateSim,
+            in IDownloadSubscriptionCallback callback);
+    void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
+            boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
+    void getEid(int slotId, in IGetEidCallback callback);
+    void getEuiccProfileInfoList(int slotId, in IGetEuiccProfileInfoListCallback callback);
+    void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim,
+            in IGetDefaultDownloadableSubscriptionListCallback callback);
+    void getEuiccInfo(int slotId, in IGetEuiccInfoCallback callback);
+    void deleteSubscription(int slotId, String iccid, in IDeleteSubscriptionCallback callback);
+    void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim,
+            in ISwitchToSubscriptionCallback callback);
+    void updateSubscriptionNickname(int slotId, String iccid, String nickname,
+            in IUpdateSubscriptionNicknameCallback callback);
+    void eraseSubscriptions(int slotId, in IEraseSubscriptionsCallback callback);
+    void retainSubscriptionsForFactoryReset(
+            int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl b/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl
new file mode 100644
index 0000000..0c5a0c6
--- /dev/null
+++ b/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.service.euicc;
+
+import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
+
+/** @hide */
+oneway interface IGetDefaultDownloadableSubscriptionListCallback {
+    void onComplete(in GetDefaultDownloadableSubscriptionListResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl b/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl
new file mode 100644
index 0000000..3353061
--- /dev/null
+++ b/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.service.euicc;
+
+import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
+
+/** @hide */
+oneway interface IGetDownloadableSubscriptionMetadataCallback {
+    void onComplete(in GetDownloadableSubscriptionMetadataResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEidCallback.aidl b/core/java/android/service/euicc/IGetEidCallback.aidl
new file mode 100644
index 0000000..35ee9c2
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEidCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IGetEidCallback {
+    void onSuccess(String eid);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl b/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl
new file mode 100644
index 0000000..6d28148
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.service.euicc;
+
+import android.telephony.euicc.EuiccInfo;
+
+/** @hide */
+oneway interface IGetEuiccInfoCallback {
+    void onSuccess(in EuiccInfo euiccInfo);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl b/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl
new file mode 100644
index 0000000..761ec1f
--- /dev/null
+++ b/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.service.euicc;
+
+import android.service.euicc.GetEuiccProfileInfoListResult;
+
+/** @hide */
+oneway interface IGetEuiccProfileInfoListCallback {
+    void onComplete(in GetEuiccProfileInfoListResult result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
new file mode 100644
index 0000000..1276830
--- /dev/null
+++ b/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IRetainSubscriptionsForFactoryResetCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl b/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl
new file mode 100644
index 0000000..0f91a6b
--- /dev/null
+++ b/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface ISwitchToSubscriptionCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl b/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl
new file mode 100644
index 0000000..6666933
--- /dev/null
+++ b/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.euicc;
+
+/** @hide */
+oneway interface IUpdateSubscriptionNicknameCallback {
+    void onComplete(int result);
+}
\ No newline at end of file
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
index 287dc76..9b52934 100644
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.java
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
@@ -106,6 +106,8 @@
             if (mPayload != null) {
                 dest.writeInt(mPayload.length);
                 dest.writeByteArray(mPayload);
+            } else {
+                dest.writeInt(0);
             }
         }
     }
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
index 6db2110..abc6466 100644
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
@@ -78,4 +78,10 @@
      * @param uid the Android user id.
      */
     void clearSecureUserId(int uid);
+
+    /**
+     * Notifies gatekeeper that device setup has been completed and any potentially still existing
+     * state from before a factory reset can be cleaned up (if it has not been already).
+     */
+    void reportDeviceSetupComplete();
 }
diff --git a/core/java/android/service/oemlock/IOemLockService.aidl b/core/java/android/service/oemlock/IOemLockService.aidl
index 2c606f9..682e7ee 100644
--- a/core/java/android/service/oemlock/IOemLockService.aidl
+++ b/core/java/android/service/oemlock/IOemLockService.aidl
@@ -27,4 +27,8 @@
 
     void setOemUnlockAllowedByUser(boolean allowed);
     boolean isOemUnlockAllowedByUser();
+
+    boolean canUserAllowOemUnlock();
+    boolean isOemUnlockAllowed();
+    boolean isDeviceOemUnlocked();
 }
diff --git a/core/java/android/service/oemlock/OemLockManager.java b/core/java/android/service/oemlock/OemLockManager.java
index e2ade87..3a56d9f 100644
--- a/core/java/android/service/oemlock/OemLockManager.java
+++ b/core/java/android/service/oemlock/OemLockManager.java
@@ -88,7 +88,8 @@
      *
      * All actors involved must agree for OEM unlock to be possible.
      *
-     * @param unlocked Whether the device should be made OEM unlocked.
+     * @param allowed Whether the device should be allowed to be unlocked.
+     * @throws SecurityException if the user is not allowed to unlock the device.
      *
      * @see #isOemUnlockAllowedByUser()
      */
@@ -115,4 +116,48 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Returns whether all parties other than the user allow OEM unlock meaning the user can
+     * directly control whether or not the device can be OEM unlocked.
+     *
+     * If this is true, {@link #isOemUnlockAllowedByUser} is the same as {@link #isOemUnlockAllowed}
+     *
+     * @return Whether the user can directly control whether the device can be OEM unlocked.
+     *
+     * @hide
+     */
+    public boolean canUserAllowOemUnlock() {
+        try {
+            return mService.canUserAllowOemUnlock();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @return Whether the bootloader is able to OEM unlock the device.
+     *
+     * @hide
+     */
+    public boolean isOemUnlockAllowed() {
+        try {
+            return mService.isOemUnlockAllowed();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @return Whether the device has been OEM unlocked by the bootloader.
+     *
+     * @hide
+     */
+    public boolean isDeviceOemUnlocked() {
+        try {
+            return mService.isDeviceOemUnlocked();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
index 626b408..31352f1 100644
--- a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
+++ b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl
@@ -36,5 +36,6 @@
     void setOemUnlockEnabled(boolean enabled);
     boolean getOemUnlockEnabled();
     int getFlashLockState();
+    boolean hasFrpCredentialHandle();
 }
 
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 479c9e2..fbc6fc6 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -262,7 +262,8 @@
      * @param keyphrase The keyphrase that's being used, for example "Hello Android".
      * @param locale The locale for which the enrollment needs to be performed.
      * @param callback The callback to notify of detection events.
-     * @return An always-on hotword detector for the given keyphrase and locale.
+     * @return An always-on hotword detector for the given keyphrase and locale. Is null if the
+     * keyphrase and locale is not supported.
      */
     public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
             String keyphrase, Locale locale, AlwaysOnHotwordDetector.Callback callback) {
@@ -272,8 +273,10 @@
         synchronized (mLock) {
             // Allow only one concurrent recognition via the APIs.
             safelyShutdownHotwordDetector();
-            mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
-                    mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            if (isKeyphraseAndLocaleSupportedForHotword(keyphrase, locale)) {
+                mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
+                        mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            }
         }
         return mHotwordDetector;
     }
@@ -287,6 +290,20 @@
         return mKeyphraseEnrollmentInfo;
     }
 
+    /**
+      * Checks if a given keyphrase and locale are supported to create an
+      * {@link AlwaysOnHotwordDetector}.
+      *
+      * @return true if the keyphrase and locale combination is supported, false otherwise.
+      * @hide
+      */
+    public final boolean isKeyphraseAndLocaleSupportedForHotword(String keyphrase, Locale locale) {
+        if (mKeyphraseEnrollmentInfo == null) {
+            return false;
+        }
+        return mKeyphraseEnrollmentInfo.getKeyphraseMetadata(keyphrase, locale) != null;
+    }
+
     private void safelyShutdownHotwordDetector() {
         try {
             synchronized (mLock) {
diff --git a/core/java/android/service/vr/IVrListener.aidl b/core/java/android/service/vr/IVrListener.aidl
index afb13d3..acca3fa 100644
--- a/core/java/android/service/vr/IVrListener.aidl
+++ b/core/java/android/service/vr/IVrListener.aidl
@@ -20,5 +20,5 @@
 
 /** @hide */
 oneway interface IVrListener {
-    void focusedActivityChanged(in ComponentName component);
+    void focusedActivityChanged(in ComponentName component, boolean running2dInVr, int pid);
 }
diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java
index 5da4560..fa3d065 100644
--- a/core/java/android/service/vr/VrListenerService.java
+++ b/core/java/android/service/vr/VrListenerService.java
@@ -70,8 +70,10 @@
 
     private final IVrListener.Stub mBinder = new IVrListener.Stub() {
         @Override
-        public void focusedActivityChanged(ComponentName component) {
-            mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget();
+        public void focusedActivityChanged(
+                ComponentName component, boolean running2dInVr, int pid) {
+            mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, running2dInVr ? 1 : 0,
+                    pid, component).sendToTarget();
         }
     };
 
@@ -84,7 +86,8 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: {
-                    VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj);
+                    VrListenerService.this.onCurrentVrActivityChanged(
+                            (ComponentName) msg.obj, msg.arg1 == 1, msg.arg2);
                 } break;
             }
         }
@@ -120,6 +123,29 @@
     }
 
     /**
+     * An extended version of onCurrentVrActivityChanged
+     *
+     * <p>This will be called when this service is initially bound, but is not
+     * guaranteed to be called before onUnbind.  In general, this is intended to be used to
+     * determine when user focus has transitioned between two VR activities, or between a
+     * VR activity and a 2D activity. This should be overridden instead of the above
+     * onCurrentVrActivityChanged as that version is deprecated.</p>
+     *
+     * @param component the {@link ComponentName} of the VR activity or the 2D intent.
+     * @param running2dInVr true if the component is a 2D component.
+     * @param pid the process the component is running in.
+     *
+     * @see android.app.Activity#setVrModeEnabled
+     * @see android.R.attr#enableVrMode
+     * @hide
+     */
+    public void onCurrentVrActivityChanged(
+            ComponentName component, boolean running2dInVr, int pid) {
+        // Override to implement. Default to old behaviour of sending null for 2D.
+        onCurrentVrActivityChanged(running2dInVr ? null : component);
+    }
+
+    /**
      * Checks if the given component is enabled in user settings.
      *
      * <p>If this component is not enabled in the user's settings, it will not be started when
diff --git a/core/java/android/service/wallpaper/IWallpaperConnection.aidl b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
index f9c5aaa..3c3ef0c 100644
--- a/core/java/android/service/wallpaper/IWallpaperConnection.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperConnection.aidl
@@ -18,6 +18,7 @@
 
 import android.os.ParcelFileDescriptor;
 import android.service.wallpaper.IWallpaperEngine;
+import android.app.WallpaperColors;
 
 /**
  * @hide
@@ -26,4 +27,5 @@
 	void attachEngine(IWallpaperEngine engine);
 	void engineShown(IWallpaperEngine engine);
     ParcelFileDescriptor setWallpaper(String name);
+    void onWallpaperColorsChanged(in WallpaperColors colors);
 }
diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
index de527e9..fb6f637 100644
--- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl
@@ -30,5 +30,6 @@
     void dispatchPointer(in MotionEvent event);
     void dispatchWallpaperCommand(String action, int x, int y,
             int z, in Bundle extras);
-	void destroy();
+    void requestWallpaperColors();
+    void destroy();
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 6bbb0ff..5ef60a5 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,24 +16,20 @@
 
 package android.service.wallpaper;
 
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.util.MergedConfiguration;
-import android.view.WindowInsets;
-
-import com.android.internal.R;
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.view.BaseIWindow;
-import com.android.internal.view.BaseSurfaceHolder;
-
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Service;
+import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Bundle;
@@ -42,6 +38,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.MergedConfiguration;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.IWindowSession;
@@ -53,9 +50,14 @@
 import android.view.SurfaceHolder;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.view.BaseIWindow;
+import com.android.internal.view.BaseSurfaceHolder;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -103,6 +105,7 @@
     private static final int MSG_WINDOW_RESIZED = 10030;
     private static final int MSG_WINDOW_MOVED = 10035;
     private static final int MSG_TOUCH_EVENT = 10040;
+    private static final int MSG_REQUEST_WALLPAPER_COLORS = 10050;
     
     private final ArrayList<Engine> mActiveEngines
             = new ArrayList<Engine>();
@@ -266,7 +269,7 @@
             }
 
             @Override
-            public void onInputEvent(InputEvent event) {
+            public void onInputEvent(InputEvent event, int displayId) {
                 boolean handled = false;
                 try {
                     if (event instanceof MotionEvent
@@ -542,7 +545,38 @@
          */
         public void onSurfaceDestroyed(SurfaceHolder holder) {
         }
-        
+
+        /**
+         * Notifies the engine that wallpaper colors changed significantly.
+         * This will trigger a {@link #onComputeWallpaperColors()} call.
+         * @hide
+         */
+        public void invalidateColors() {
+            try {
+                mConnection.onWallpaperColorsChanged(onComputeWallpaperColors());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't invalidate wallpaper colors because " +
+                        "wallpaper connection was lost", e);
+            }
+        }
+
+        /**
+         * Notifies the system about what colors the wallpaper is using.
+         * You might return null if no color information is available at the moment. In that case
+         * you might want to call {@link #invalidateColors()} in a near future.
+         * <p>
+         * The simplest way of creating A {@link android.app.WallpaperColors} object is by using
+         * {@link android.app.WallpaperColors#fromBitmap(Bitmap)} or
+         * {@link android.app.WallpaperColors#fromDrawable(Drawable)}, but you can also specify
+         * your main colors and dark text support explicitly using one of the constructors.
+         *
+         * @return Wallpaper colors.
+         * @hide
+         */
+        public @Nullable WallpaperColors onComputeWallpaperColors() {
+            return null;
+        }
+
         protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
             out.print(prefix); out.print("mInitializing="); out.print(mInitializing);
                     out.print(" mDestroyed="); out.println(mDestroyed);
@@ -1161,6 +1195,11 @@
             }
         }
 
+        public void requestWallpaperColors() {
+            Message msg = mCaller.obtainMessage(MSG_REQUEST_WALLPAPER_COLORS);
+            mCaller.sendMessage(msg);
+        }
+
         public void destroy() {
             Message msg = mCaller.obtainMessage(DO_DETACH);
             mCaller.sendMessage(msg);
@@ -1236,6 +1275,16 @@
                     }
                     ev.recycle();
                 } break;
+                case MSG_REQUEST_WALLPAPER_COLORS: {
+                    if (mConnection == null) {
+                        break;
+                    }
+                    try {
+                        mConnection.onWallpaperColorsChanged(mEngine.onComputeWallpaperColors());
+                    } catch (RemoteException e) {
+                        // Connection went away, nothing to do in here.
+                    }
+                } break;
                 default :
                     Log.w(TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 6208c53..c7a5fce 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -491,8 +491,6 @@
      * An index is associated to each block (which will be used by display lists),
      * this class simply invalidates the index of blocks overlapping a modification.
      *
-     * This method is package private and not private so that it can be tested.
-     *
      * @param startLine the first line of the range of modified lines
      * @param endLine the last line of the range, possibly equal to startLine, lower
      * than getLineCount()
@@ -613,16 +611,20 @@
     }
 
     /**
-     * This package private method is used for test purposes only
+     * This method is used for test purposes only.
      * @hide
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks) {
+    public void setBlocksDataForTest(int[] blockEndLines, int[] blockIndices, int numberOfBlocks,
+            int totalLines) {
         mBlockEndLines = new int[blockEndLines.length];
         mBlockIndices = new int[blockIndices.length];
         System.arraycopy(blockEndLines, 0, mBlockEndLines, 0, blockEndLines.length);
         System.arraycopy(blockIndices, 0, mBlockIndices, 0, blockIndices.length);
         mNumberOfBlocks = numberOfBlocks;
+        while (mInts.size() < totalLines) {
+            mInts.insertAt(mInts.size(), new int[COLUMNS_NORMAL]);
+        }
     }
 
     /**
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 756e9a0..e4ed62a 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -16,6 +16,8 @@
 
 package android.text;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Paint.FontMetricsInt;
@@ -28,6 +30,8 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.ArrayList;
+
 /**
  * Represents a line of styled text, for measuring in visual order and
  * for rendering.
@@ -58,7 +62,9 @@
     // Additional width of whitespace for justification. This value is per whitespace, thus
     // the line width will increase by mAddedWidth x (number of stretchable whitespaces).
     private float mAddedWidth;
+
     private final TextPaint mWorkPaint = new TextPaint();
+    private final TextPaint mActivePaint = new TextPaint();
     private final SpanSet<MetricAffectingSpan> mMetricAffectingSpanSpanSet =
             new SpanSet<MetricAffectingSpan>(MetricAffectingSpan.class);
     private final SpanSet<CharacterStyle> mCharacterStyleSpanSet =
@@ -66,6 +72,9 @@
     private final SpanSet<ReplacementSpan> mReplacementSpanSpanSet =
             new SpanSet<ReplacementSpan>(ReplacementSpan.class);
 
+    private final UnderlineInfo mUnderlineInfo = new UnderlineInfo();
+    private final ArrayList<UnderlineInfo> mUnderlines = new ArrayList();
+
     private static final TextLine[] sCached = new TextLine[3];
 
     /**
@@ -695,6 +704,36 @@
         fmi.leading = Math.max(fmi.leading, previousLeading);
     }
 
+    private static void drawUnderline(TextPaint wp, Canvas c, int color, float thickness,
+            float xleft, float xright, float baseline) {
+        final float underlineTop = baseline + wp.baselineShift + wp.getUnderlinePosition();
+
+        final int previousColor = wp.getColor();
+        final Paint.Style previousStyle = wp.getStyle();
+        final boolean previousAntiAlias = wp.isAntiAlias();
+
+        wp.setStyle(Paint.Style.FILL);
+        wp.setAntiAlias(true);
+
+        wp.setColor(color);
+        c.drawRect(xleft, underlineTop, xright, underlineTop + thickness, wp);
+
+        wp.setStyle(previousStyle);
+        wp.setColor(previousColor);
+        wp.setAntiAlias(previousAntiAlias);
+    }
+
+    private float getRunAdvance(TextPaint wp, int start, int end, int contextStart, int contextEnd,
+            boolean runIsRtl, int offset) {
+        if (mCharsValid) {
+            return wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, offset);
+        } else {
+            final int delta = mStart;
+            return wp.getRunAdvance(mText, delta + start, delta + end,
+                    delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
+        }
+    }
+
     /**
      * Utility function for measuring and rendering text.  The text must
      * not include a tab.
@@ -711,13 +750,15 @@
      * @param fmi receives metrics information, can be null
      * @param needWidth true if the width of the run is needed
      * @param offset the offset for the purpose of measuring
+     * @param underlines the list of locations and paremeters for drawing underlines
      * @return the signed width of the run based on the run direction; only
      * valid if needWidth is true
      */
     private float handleText(TextPaint wp, int start, int end,
             int contextStart, int contextEnd, boolean runIsRtl,
             Canvas c, float x, int top, int y, int bottom,
-            FontMetricsInt fmi, boolean needWidth, int offset) {
+            FontMetricsInt fmi, boolean needWidth, int offset,
+            @Nullable ArrayList<UnderlineInfo> underlines) {
 
         wp.setWordSpacing(mAddedWidth);
         // Get metrics first (even for empty strings or "0" width runs)
@@ -725,28 +766,26 @@
             expandMetricsFromPaint(fmi, wp);
         }
 
-        int runLen = end - start;
         // No need to do anything if the run width is "0"
-        if (runLen == 0) {
+        if (end == start) {
             return 0f;
         }
 
-        float ret = 0;
+        float totalWidth = 0;
 
-        if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
-            if (mCharsValid) {
-                ret = wp.getRunAdvance(mChars, start, end, contextStart, contextEnd,
-                        runIsRtl, offset);
-            } else {
-                int delta = mStart;
-                ret = wp.getRunAdvance(mText, delta + start, delta + end,
-                        delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
-            }
+        final int numUnderlines = underlines == null ? 0 : underlines.size();
+        if (needWidth || (c != null && (wp.bgColor != 0 || numUnderlines != 0 || runIsRtl))) {
+            totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset);
         }
 
         if (c != null) {
+            final float leftX, rightX;
             if (runIsRtl) {
-                x -= ret;
+                leftX = x - totalWidth;
+                rightX = x;
+            } else {
+                leftX = x;
+                rightX = x + totalWidth;
             }
 
             if (wp.bgColor != 0) {
@@ -755,36 +794,50 @@
 
                 wp.setColor(wp.bgColor);
                 wp.setStyle(Paint.Style.FILL);
-                c.drawRect(x, top, x + ret, bottom, wp);
+                c.drawRect(leftX, top, rightX, bottom, wp);
 
                 wp.setStyle(previousStyle);
                 wp.setColor(previousColor);
             }
 
-            if (wp.underlineColor != 0) {
-                // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
-                float underlineTop = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();
+            if (numUnderlines != 0) {
+                for (int i = 0; i < numUnderlines; i++) {
+                    final UnderlineInfo info = underlines.get(i);
 
-                int previousColor = wp.getColor();
-                Paint.Style previousStyle = wp.getStyle();
-                boolean previousAntiAlias = wp.isAntiAlias();
+                    final int underlineStart = Math.max(info.start, start);
+                    final int underlineEnd = Math.min(info.end, offset);
+                    float underlineStartAdvance = getRunAdvance(
+                            wp, start, end, contextStart, contextEnd, runIsRtl, underlineStart);
+                    float underlineEndAdvance = getRunAdvance(
+                            wp, start, end, contextStart, contextEnd, runIsRtl, underlineEnd);
+                    final float underlineXLeft, underlineXRight;
+                    if (runIsRtl) {
+                        underlineXLeft = rightX - underlineEndAdvance;
+                        underlineXRight = rightX - underlineStartAdvance;
+                    } else {
+                        underlineXLeft = leftX + underlineStartAdvance;
+                        underlineXRight = leftX + underlineEndAdvance;
+                    }
 
-                wp.setStyle(Paint.Style.FILL);
-                wp.setAntiAlias(true);
-
-                wp.setColor(wp.underlineColor);
-                c.drawRect(x, underlineTop, x + ret, underlineTop + wp.underlineThickness, wp);
-
-                wp.setStyle(previousStyle);
-                wp.setColor(previousColor);
-                wp.setAntiAlias(previousAntiAlias);
+                    // Theoretically, there could be cases where both Paint's and TextPaint's
+                    // setUnderLineText() are called. For backward compatibility, we need to draw
+                    // both underlines, the one with custom color first.
+                    if (info.underlineColor != 0) {
+                        drawUnderline(wp, c, info.underlineColor, info.underlineThickness,
+                                underlineXLeft, underlineXRight, y);
+                    }
+                    if (info.isUnderlineText) {
+                        drawUnderline(wp, c, wp.getColor(), ((Paint) wp).getUnderlineThickness(),
+                                underlineXLeft, underlineXRight, y);
+                    }
+                }
             }
 
             drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl,
-                    x, y + wp.baselineShift);
+                    leftX, y + wp.baselineShift);
         }
 
-        return runIsRtl ? -ret : ret;
+        return runIsRtl ? -totalWidth : totalWidth;
     }
 
     /**
@@ -864,6 +917,37 @@
         return result;
     }
 
+    private static final class UnderlineInfo {
+        public boolean isUnderlineText;
+        public int underlineColor;
+        public float underlineThickness;
+        public int start = -1;
+        public int end = -1;
+
+        public boolean hasUnderline() {
+            return isUnderlineText || underlineColor != 0;
+        }
+
+        // Copies the info, but not the start and end range.
+        public UnderlineInfo copyInfo() {
+            final UnderlineInfo copy = new UnderlineInfo();
+            copy.isUnderlineText = isUnderlineText;
+            copy.underlineColor = underlineColor;
+            copy.underlineThickness = underlineThickness;
+            return copy;
+        }
+    }
+
+    private void extractUnderlineInfo(@NonNull TextPaint paint, @NonNull UnderlineInfo info) {
+        info.isUnderlineText = paint.isUnderlineText();
+        if (info.isUnderlineText) {
+            paint.setUnderlineText(false);
+        }
+        info.underlineColor = paint.underlineColor;
+        info.underlineThickness = paint.underlineThickness;
+        paint.setUnderlineText(0, 0.0f);
+    }
+
     /**
      * Utility function for handling a unidirectional run.  The run must not
      * contain tabs but can contain styles.
@@ -894,7 +978,7 @@
 
         // Case of an empty line, make sure we update fmi according to mPaint
         if (start == measureLimit) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
             if (fmi != null) {
                 expandMetricsFromPaint(fmi, wp);
@@ -903,11 +987,11 @@
         }
 
         if (mSpanned == null) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
             wp.setHyphenEdit(adjustHyphenEdit(start, limit, wp.getHyphenEdit()));
             return handleText(wp, start, limit, start, limit, runIsRtl, c, x, top,
-                    y, bottom, fmi, needWidth, measureLimit);
+                    y, bottom, fmi, needWidth, measureLimit, null);
         }
 
         mMetricAffectingSpanSpanSet.init(mSpanned, mStart + start, mStart + limit);
@@ -920,7 +1004,7 @@
         // for the run bounds.
         final float originalX = x;
         for (int i = start, inext; i < measureLimit; i = inext) {
-            TextPaint wp = mWorkPaint;
+            final TextPaint wp = mWorkPaint;
             wp.set(mPaint);
 
             inext = mMetricAffectingSpanSpanSet.getNextTransition(mStart + i, mStart + limit) -
@@ -934,7 +1018,7 @@
                 // empty by construction. This special case in getSpans() explains the >= & <= tests
                 if ((mMetricAffectingSpanSpanSet.spanStarts[j] >= mStart + mlimit) ||
                         (mMetricAffectingSpanSpanSet.spanEnds[j] <= mStart + i)) continue;
-                MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
+                final MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
                 if (span instanceof ReplacementSpan) {
                     replacement = (ReplacementSpan)span;
                 } else {
@@ -950,26 +1034,68 @@
                 continue;
             }
 
+            final TextPaint activePaint = mActivePaint;
+            activePaint.set(mPaint);
+            int activeStart = i;
+            int activeEnd = mlimit;
+            final UnderlineInfo underlineInfo = mUnderlineInfo;
+            mUnderlines.clear();
             for (int j = i, jnext; j < mlimit; j = jnext) {
                 jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + inext) -
                         mStart;
-                int offset = Math.min(jnext, mlimit);
 
+                final int offset = Math.min(jnext, mlimit);
                 wp.set(mPaint);
                 for (int k = 0; k < mCharacterStyleSpanSet.numberOfSpans; k++) {
                     // Intentionally using >= and <= as explained above
                     if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + offset) ||
                             (mCharacterStyleSpanSet.spanEnds[k] <= mStart + j)) continue;
 
-                    CharacterStyle span = mCharacterStyleSpanSet.spans[k];
+                    final CharacterStyle span = mCharacterStyleSpanSet.spans[k];
                     span.updateDrawState(wp);
                 }
 
-                wp.setHyphenEdit(adjustHyphenEdit(j, jnext, wp.getHyphenEdit()));
+                extractUnderlineInfo(wp, underlineInfo);
 
-                x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x,
-                        top, y, bottom, fmi, needWidth || jnext < measureLimit, offset);
+                if (j == i) {
+                    // First chunk of text. We can't handle it yet, since we may need to merge it
+                    // with the next chunk. So we just save the TextPaint for future comparisons
+                    // and use.
+                    activePaint.set(wp);
+                } else if (!wp.hasEqualAttributes(activePaint)) {
+                    // The style of the present chunk of text is substantially different from the
+                    // style of the previous chunk. We need to handle the active piece of text
+                    // and restart with the present chunk.
+                    activePaint.setHyphenEdit(adjustHyphenEdit(
+                            activeStart, activeEnd, mPaint.getHyphenEdit()));
+                    x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, x,
+                            top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
+                            Math.min(activeEnd, mlimit), mUnderlines);
+
+                    activeStart = j;
+                    activePaint.set(wp);
+                    mUnderlines.clear();
+                } else {
+                    // The present TextPaint is substantially equal to the last TextPaint except
+                    // perhaps for underlines. We just need to expand the active piece of text to
+                    // include the present chunk, which we always do anyway. We don't need to save
+                    // wp to activePaint, since they are already equal.
+                }
+
+                activeEnd = jnext;
+                if (underlineInfo.hasUnderline()) {
+                    final UnderlineInfo copy = underlineInfo.copyInfo();
+                    copy.start = j;
+                    copy.end = jnext;
+                    mUnderlines.add(copy);
+                }
             }
+            // Handle the final piece of text.
+            activePaint.setHyphenEdit(adjustHyphenEdit(
+                    activeStart, activeEnd, mPaint.getHyphenEdit()));
+            x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, x,
+                    top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
+                    Math.min(activeEnd, mlimit), mUnderlines);
         }
 
         return x - originalX;
diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java
index 4f8cff0..5234fa9 100644
--- a/core/java/android/text/TextPaint.java
+++ b/core/java/android/text/TextPaint.java
@@ -17,6 +17,7 @@
 package android.text;
 
 import android.annotation.ColorInt;
+import android.annotation.NonNull;
 import android.graphics.Paint;
 
 /**
@@ -40,7 +41,7 @@
     @ColorInt
     public int underlineColor = 0;
     /**
-     * Defined as a multiplier of the default underline thickness. Use 1.0f for default thickness.
+     * Thickness of the underline, in pixels.
      * @hide
      */
     public float underlineThickness;
@@ -74,6 +75,24 @@
     }
 
     /**
+     * Returns true if all attributes, including the attributes inherited from Paint, are equal.
+     *
+     * The caller is expected to have checked the trivial cases, like the pointers being equal,
+     * the objects having different classes, or the parameter being null.
+     * @hide
+     */
+    public boolean hasEqualAttributes(@NonNull TextPaint other) {
+        return bgColor == other.bgColor
+                && baselineShift == other.baselineShift
+                && linkColor == other.linkColor
+                && drawableState == other.drawableState
+                && density == other.density
+                && underlineColor == other.underlineColor
+                && underlineThickness == other.underlineThickness
+                && super.hasEqualAttributes((Paint) other);
+    }
+
+    /**
      * Defines a custom underline for this Paint.
      * @param color underline solid color
      * @param thickness underline thickness
@@ -83,4 +102,16 @@
         underlineColor = color;
         underlineThickness = thickness;
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public float getUnderlineThickness() {
+        if (underlineColor != 0) { // Return custom thickness only if underline color is set.
+            return underlineThickness;
+        } else {
+            return super.getUnderlineThickness();
+        }
+    }
 }
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 585f882..3baadd4 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1943,6 +1943,16 @@
         return charSequence;
     }
 
+    /**
+     * Prepends {@code start} and appends {@code end} to a given {@link StringBuilder}
+     *
+     * @hide
+     */
+    public static void wrap(StringBuilder builder, String start, String end) {
+        builder.insert(0, start);
+        builder.append(end);
+    }
+
     private static Object sLock = new Object();
 
     private static char[] sTemp = null;
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index 2f1abe9..0122e49 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -202,6 +202,15 @@
     }
 
     /**
+     * @hide
+     * Checks if the original or backup file exists.
+     * @return whether the original or backup file exists.
+     */
+    public boolean exists() {
+        return mBaseName.exists() || mBackupName.exists();
+    }
+
+    /**
      * Gets the last modified time of the atomic file.
      * {@hide}
      *
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index e01a1a6..0299865 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -30,8 +30,9 @@
 /**
  * API for sending log output.
  *
- * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
- * methods.
+ * <p>Generally, you should use the {@link #v Log.v()}, {@link #d Log.d()},
+ * {@link #i Log.i()}, {@link #w Log.w()}, and {@link #e Log.e()} methods to write logs.
+ * You can then <a href="{@docRoot}studio/debug/am-logcat.html">view the logs in logcat</a>.
  *
  * <p>The order in terms of verbosity, from least to most is
  * ERROR, WARN, INFO, DEBUG, VERBOSE.  Verbose should never be compiled
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
index 5c718f1..e865b6e 100644
--- a/core/java/android/util/MathUtils.java
+++ b/core/java/android/util/MathUtils.java
@@ -16,8 +16,6 @@
 
 package android.util;
 
-import java.util.Random;
-
 /**
  * A class that contains utility methods related to numbers.
  *
@@ -181,7 +179,7 @@
     }
 
     public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
-        return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
+        return maxStart + (maxStop - maxStart) * ((value - minStart) / (minStop - minStart));
     }
 
     /**
diff --git a/core/java/android/util/MemoryIntArray.java b/core/java/android/util/MemoryIntArray.java
index 589edbc..bf33519 100644
--- a/core/java/android/util/MemoryIntArray.java
+++ b/core/java/android/util/MemoryIntArray.java
@@ -158,7 +158,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             IoUtils.closeQuietly(this);
         } finally {
             super.finalize();
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
index 68d0309..ae66050 100644
--- a/core/java/android/util/MergedConfiguration.java
+++ b/core/java/android/util/MergedConfiguration.java
@@ -161,6 +161,21 @@
         return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}";
     }
 
+    @Override
+    public int hashCode() {
+        return mMergedConfig.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (!(that instanceof MergedConfiguration)) {
+            return false;
+        }
+
+        if (that == this) return true;
+        return mMergedConfig.equals(((MergedConfiguration) that).mMergedConfig);
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "mGlobalConfig=" + mGlobalConfig);
         pw.println(prefix + "mOverrideConfig=" + mOverrideConfig);
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 480abc1..9afa56d 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -24,7 +24,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.List;
 
 /**
  * Class to write to a protobuf stream.
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 1b74c13..45fa561 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN;
+import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY;
 import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
 
 import android.graphics.Point;
@@ -34,13 +35,17 @@
 import android.text.style.AccessibilityClickableSpan;
 import android.text.style.ClickableSpan;
 import android.util.LongSparseArray;
+import android.util.Slog;
 import android.view.View.AttachInfo;
 import android.view.accessibility.AccessibilityInteractionClient;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityRequestPreparer;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
@@ -61,11 +66,24 @@
  */
 final class AccessibilityInteractionController {
 
+    private static final String LOG_TAG = "AccessibilityInteractionController";
+
+    // Debugging flag
     private static final boolean ENFORCE_NODE_TREE_CONSISTENT = false;
 
+    // Constants for readability
+    private static final boolean IGNORE_REQUEST_PREPARERS = true;
+    private static final boolean CONSIDER_REQUEST_PREPARERS = false;
+
+    // If an app holds off accessibility for longer than this, the hold-off is canceled to prevent
+    // accessibility from hanging
+    private static final long REQUEST_PREPARER_TIMEOUT_MS = 500;
+
     private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
         new ArrayList<AccessibilityNodeInfo>();
 
+    private final Object mLock = new Object();
+
     private final Handler mHandler;
 
     private final ViewRootImpl mViewRootImpl;
@@ -76,6 +94,8 @@
 
     private final int mMyProcessId;
 
+    private final AccessibilityManager mA11yManager;
+
     private final ArrayList<View> mTempArrayList = new ArrayList<View>();
 
     private final Point mTempPoint = new Point();
@@ -85,6 +105,13 @@
 
     private AddNodeInfosForViewId mAddNodeInfosForViewId;
 
+    @GuardedBy("mLock")
+    private int mNumActiveRequestPreparers;
+    @GuardedBy("mLock")
+    private List<MessageHolder> mMessagesWaitingForRequestPreparer;
+    @GuardedBy("mLock")
+    private int mActiveRequestPreparerId;
+
     public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
         Looper looper =  viewRootImpl.mHandler.getLooper();
         mMyLooperThreadId = looper.getThread().getId();
@@ -92,18 +119,23 @@
         mHandler = new PrivateHandler(looper);
         mViewRootImpl = viewRootImpl;
         mPrefetcher = new AccessibilityNodePrefetcher();
+        mA11yManager = mViewRootImpl.mContext.getSystemService(AccessibilityManager.class);
     }
 
-    private void scheduleMessage(Message message, int interrogatingPid, long interrogatingTid) {
-        // If the interrogation is performed by the same thread as the main UI
-        // thread in this process, set the message as a static reference so
-        // after this call completes the same thread but in the interrogating
-        // client can handle the message to generate the result.
-        if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
-            AccessibilityInteractionClient.getInstanceForThread(
-                    interrogatingTid).setSameThreadMessage(message);
-        } else {
-            mHandler.sendMessage(message);
+    private void scheduleMessage(Message message, int interrogatingPid, long interrogatingTid,
+            boolean ignoreRequestPreparers) {
+        if (ignoreRequestPreparers
+                || !holdOffMessageIfNeeded(message, interrogatingPid, interrogatingTid)) {
+            // If the interrogation is performed by the same thread as the main UI
+            // thread in this process, set the message as a static reference so
+            // after this call completes the same thread but in the interrogating
+            // client can handle the message to generate the result.
+            if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) {
+                AccessibilityInteractionClient.getInstanceForThread(
+                        interrogatingTid).setSameThreadMessage(message);
+            } else {
+                mHandler.sendMessage(message);
+            }
         }
     }
 
@@ -121,11 +153,11 @@
             long accessibilityNodeId, Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
             long interrogatingTid, MagnificationSpec spec, Bundle arguments) {
-        Message message = mHandler.obtainMessage();
+        final Message message = mHandler.obtainMessage();
         message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID;
         message.arg1 = flags;
 
-        SomeArgs args = SomeArgs.obtain();
+        final SomeArgs args = SomeArgs.obtain();
         args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
         args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
         args.argi3 = interactionId;
@@ -135,7 +167,141 @@
         args.arg4 = arguments;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
+    }
+
+    /**
+     * Check if this message needs to be held off while the app prepares to meet either this
+     * request, or a request ahead of it.
+     *
+     * @param originalMessage The message to be processed
+     * @param callingPid The calling process id
+     * @param callingTid The calling thread id
+     *
+     * @return {@code true} if the message is held off and will be processed later, {@code false} if
+     *         the message should be posted.
+     */
+    private boolean holdOffMessageIfNeeded(
+            Message originalMessage, int callingPid, long callingTid) {
+        synchronized (mLock) {
+            // If a request is already pending, queue this request for when it's finished
+            if (mNumActiveRequestPreparers != 0) {
+                queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
+                return true;
+            }
+
+            // Currently the only message that can hold things off is findByA11yId with extra data.
+            if (originalMessage.what
+                    != PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID) {
+                return false;
+            }
+            SomeArgs originalMessageArgs = (SomeArgs) originalMessage.obj;
+            Bundle requestArguments = (Bundle) originalMessageArgs.arg4;
+            if (requestArguments == null) {
+                return false;
+            }
+
+            // If nothing it registered for this view, nothing to do
+            int accessibilityViewId = originalMessageArgs.argi1;
+            final List<AccessibilityRequestPreparer> preparers =
+                    mA11yManager.getRequestPreparersForAccessibilityId(accessibilityViewId);
+            if (preparers == null) {
+                return false;
+            }
+
+            // If the bundle doesn't request the extra data, nothing to do
+            final String extraDataKey = requestArguments.getString(EXTRA_DATA_REQUESTED_KEY);
+            if (extraDataKey == null) {
+                return false;
+            }
+
+            // Send the request to the AccessibilityRequestPreparers on the UI thread
+            mNumActiveRequestPreparers = preparers.size();
+            for (int i = 0; i < preparers.size(); i++) {
+                final Message requestPreparerMessage = mHandler.obtainMessage(
+                        PrivateHandler.MSG_PREPARE_FOR_EXTRA_DATA_REQUEST);
+                final SomeArgs requestPreparerArgs = SomeArgs.obtain();
+                // virtualDescendentId
+                requestPreparerArgs.argi1 =
+                        (originalMessageArgs.argi2 == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
+                        ? AccessibilityNodeProvider.HOST_VIEW_ID : originalMessageArgs.argi2;
+                requestPreparerArgs.arg1 = preparers.get(i);
+                requestPreparerArgs.arg2 = extraDataKey;
+                requestPreparerArgs.arg3 = requestArguments;
+                Message preparationFinishedMessage = mHandler.obtainMessage(
+                        PrivateHandler.MSG_APP_PREPARATION_FINISHED);
+                preparationFinishedMessage.arg1 = ++mActiveRequestPreparerId;
+                requestPreparerArgs.arg4 = preparationFinishedMessage;
+
+                requestPreparerMessage.obj = requestPreparerArgs;
+                scheduleMessage(requestPreparerMessage, callingPid, callingTid,
+                        IGNORE_REQUEST_PREPARERS);
+                mHandler.obtainMessage(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT);
+                mHandler.sendEmptyMessageDelayed(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT,
+                        REQUEST_PREPARER_TIMEOUT_MS);
+            }
+
+            // Set the initial request aside
+            queueMessageToHandleOncePrepared(originalMessage, callingPid, callingTid);
+            return true;
+        }
+    }
+
+    private void prepareForExtraDataRequestUiThread(Message message) {
+        SomeArgs args = (SomeArgs) message.obj;
+        final int virtualDescendantId = args.argi1;
+        final AccessibilityRequestPreparer preparer = (AccessibilityRequestPreparer) args.arg1;
+        final String extraDataKey = (String) args.arg2;
+        final Bundle requestArguments = (Bundle) args.arg3;
+        final Message preparationFinishedMessage = (Message) args.arg4;
+
+        preparer.onPrepareExtraData(virtualDescendantId, extraDataKey,
+                requestArguments, preparationFinishedMessage);
+    }
+
+    private void queueMessageToHandleOncePrepared(Message message, int interrogatingPid,
+            long interrogatingTid) {
+        if (mMessagesWaitingForRequestPreparer == null) {
+            mMessagesWaitingForRequestPreparer = new ArrayList<>(1);
+        }
+        MessageHolder messageHolder =
+                new MessageHolder(message, interrogatingPid, interrogatingTid);
+        mMessagesWaitingForRequestPreparer.add(messageHolder);
+    }
+
+    private void requestPreparerDoneUiThread(Message message) {
+        synchronized (mLock) {
+            if (message.arg1 != mActiveRequestPreparerId) {
+                Slog.e(LOG_TAG, "Surprising AccessibilityRequestPreparer callback (likely late)");
+                return;
+            }
+            mNumActiveRequestPreparers--;
+            if (mNumActiveRequestPreparers <= 0) {
+                mHandler.removeMessages(PrivateHandler.MSG_APP_PREPARATION_TIMEOUT);
+                scheduleAllMessagesWaitingForRequestPreparerLocked();
+            }
+        }
+    }
+
+    private void requestPreparerTimeoutUiThread() {
+        synchronized (mLock) {
+            Slog.e(LOG_TAG, "AccessibilityRequestPreparer timed out");
+            scheduleAllMessagesWaitingForRequestPreparerLocked();
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void scheduleAllMessagesWaitingForRequestPreparerLocked() {
+        int numMessages = mMessagesWaitingForRequestPreparer.size();
+        for (int i = 0; i < numMessages; i++) {
+            MessageHolder request = mMessagesWaitingForRequestPreparer.get(i);
+            scheduleMessage(request.mMessage, request.mInterrogatingPid,
+                    request.mInterrogatingTid,
+                    (i == 0) /* the app is ready for the first request */);
+        }
+        mMessagesWaitingForRequestPreparer.clear();
+        mNumActiveRequestPreparers = 0; // Just to be safe - should be unnecessary
+        mActiveRequestPreparerId = -1;
     }
 
     private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
@@ -193,7 +359,7 @@
         args.arg4 = interactiveRegion;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findAccessibilityNodeInfosByViewIdUiThread(Message message) {
@@ -259,7 +425,7 @@
         args.arg4 = interactiveRegion;
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findAccessibilityNodeInfosByTextUiThread(Message message) {
@@ -347,7 +513,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void findFocusUiThread(Message message) {
@@ -442,7 +608,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void focusSearchUiThread(Message message) {
@@ -501,7 +667,7 @@
 
         message.obj = args;
 
-        scheduleMessage(message, interrogatingPid, interrogatingTid);
+        scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
     }
 
     private void performAccessibilityActionUiThread(Message message) {
@@ -787,7 +953,7 @@
             AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
             // Determine if we'll be populating extra data
             final String extraDataRequested = (arguments == null) ? null
-                    : arguments.getString(AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY);
+                    : arguments.getString(EXTRA_DATA_REQUESTED_KEY);
             if (provider == null) {
                 AccessibilityNodeInfo root = view.createAccessibilityNodeInfo();
                 if (root != null) {
@@ -1115,6 +1281,9 @@
         private static final int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4;
         private static final int MSG_FIND_FOCUS = 5;
         private static final int MSG_FOCUS_SEARCH = 6;
+        private static final int MSG_PREPARE_FOR_EXTRA_DATA_REQUEST = 7;
+        private static final int MSG_APP_PREPARATION_FINISHED = 8;
+        private static final int MSG_APP_PREPARATION_TIMEOUT = 9;
 
         public PrivateHandler(Looper looper) {
             super(looper);
@@ -1136,6 +1305,12 @@
                     return "MSG_FIND_FOCUS";
                 case MSG_FOCUS_SEARCH:
                     return "MSG_FOCUS_SEARCH";
+                case MSG_PREPARE_FOR_EXTRA_DATA_REQUEST:
+                    return "MSG_PREPARE_FOR_EXTRA_DATA_REQUEST";
+                case MSG_APP_PREPARATION_FINISHED:
+                    return "MSG_APP_PREPARATION_FINISHED";
+                case MSG_APP_PREPARATION_TIMEOUT:
+                    return "MSG_APP_PREPARATION_TIMEOUT";
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1163,6 +1338,15 @@
                 case MSG_FOCUS_SEARCH: {
                     focusSearchUiThread(message);
                 } break;
+                case MSG_PREPARE_FOR_EXTRA_DATA_REQUEST: {
+                    prepareForExtraDataRequestUiThread(message);
+                } break;
+                case MSG_APP_PREPARATION_FINISHED: {
+                    requestPreparerDoneUiThread(message);
+                } break;
+                case MSG_APP_PREPARATION_TIMEOUT: {
+                    requestPreparerTimeoutUiThread();
+                } break;
                 default:
                     throw new IllegalArgumentException("Unknown message type: " + type);
             }
@@ -1191,4 +1375,16 @@
             return false;
         }
     }
+
+    private static final class MessageHolder {
+        final Message mMessage;
+        final int mInterrogatingPid;
+        final long mInterrogatingTid;
+
+        MessageHolder(Message message, int interrogatingPid, long interrogatingTid) {
+            mMessage = message;
+            mInterrogatingPid = interrogatingPid;
+            mInterrogatingTid = interrogatingTid;
+        }
+    }
 }
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 3e9fab1..9778893 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -854,6 +855,9 @@
 
     /**
      * Returns whether this display can be used to display wide color gamut content.
+     * This does not necessarily mean the device itself can render wide color gamut
+     * content. To ensure wide color gamut content can be produced, refer to
+     * {@link Configuration#isScreenWideColorGamut()}.
      */
     public boolean isWideColorGamut() {
         synchronized (this) {
@@ -1118,6 +1122,15 @@
     }
 
     /**
+     * Returns true if the display may be in a reduced operating mode while in the
+     * specified display power state.
+     * @hide
+     */
+    public static boolean isDozeState(int state) {
+        return state == STATE_DOZE || state == STATE_DOZE_SUSPEND;
+    }
+
+    /**
      * A mode supported by a given display.
      *
      * @see Display#getSupportedModes()
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 48e5ca9..af26a88 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -193,6 +193,8 @@
     private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
         // check for user specified next focus
         View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
+        View cycleCheck = userSetNextFocus;
+        boolean cycleStep = true; // we want the first toggle to yield false
         while (userSetNextFocus != null) {
             if (userSetNextFocus.isFocusable()
                     && userSetNextFocus.getVisibility() == View.VISIBLE
@@ -201,6 +203,14 @@
                 return userSetNextFocus;
             }
             userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
+            if (cycleStep = !cycleStep) {
+                cycleCheck = cycleCheck.findUserSetNextFocus(root, direction);
+                if (cycleCheck == userSetNextFocus) {
+                    // found a cycle, user-specified focus forms a loop and none of the views
+                    // are currently focusable.
+                    break;
+                }
+            }
         }
         return null;
     }
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 2f87d2e..c431323 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -29,12 +29,12 @@
      * in an action being performed.
      */
     public static final int LONG_PRESS = 0;
-    
+
     /**
      * The user has pressed on a virtual on-screen key.
      */
     public static final int VIRTUAL_KEY = 1;
-    
+
     /**
      * The user has pressed a soft keyboard key.
      */
@@ -57,24 +57,31 @@
     public static final int CONTEXT_CLICK = 6;
 
     /**
-     * This is a private constant.  Feel free to renumber as desired.
+     * The user has released a virtual or software keyboard key.
      * @hide
      */
-    public static final int SAFE_MODE_DISABLED = 10000;
-    
+    public static final int VIRTUAL_KEY_RELEASE = 7;
+
     /**
+     * The user has performed a selection/insertion handle move on text field.
+     * @hide
+     */
+    public static final int TEXT_HANDLE_MOVE = 8;
+
+    /**
+     * The phone has booted with safe mode enabled.
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
     public static final int SAFE_MODE_ENABLED = 10001;
-    
+
     /**
      * Flag for {@link View#performHapticFeedback(int, int)
      * View.performHapticFeedback(int, int)}: Ignore the setting in the
      * view for whether to perform haptic feedback, do it always.
      */
     public static final int FLAG_IGNORE_VIEW_SETTING = 0x0001;
-    
+
     /**
      * Flag for {@link View#performHapticFeedback(int, int)
      * View.performHapticFeedback(int, int)}: Ignore the global setting
diff --git a/core/java/android/view/IWallpaperVisibilityListener.aidl b/core/java/android/view/IWallpaperVisibilityListener.aidl
new file mode 100644
index 0000000..349f984
--- /dev/null
+++ b/core/java/android/view/IWallpaperVisibilityListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.view;
+
+/**
+ * Listener to be invoked when wallpaper visibility changes.
+ * {@hide}
+ */
+oneway interface IWallpaperVisibilityListener {
+    /**
+     * Method that will be invoked when wallpaper becomes visible or hidden.
+     * @param visible True if wallpaper is being displayed; false otherwise.
+     * @param displayId The id of the display where wallpaper visibility changed.
+     */
+    void onWallpaperVisibilityChanged(boolean visible, int displayId);
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 58a6a5e..e576a0f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -29,6 +29,7 @@
 import android.graphics.GraphicBuffer;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.os.ParcelFileDescriptor;
@@ -38,6 +39,7 @@
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
+import android.view.IWallpaperVisibilityListener;
 import android.view.IWindowSession;
 import android.view.IWindowSessionCallback;
 import android.view.KeyEvent;
@@ -255,6 +257,19 @@
     Bitmap screenshotWallpaper();
 
     /**
+     * Registers a wallpaper visibility listener.
+     * @return Current visibility.
+     */
+    boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+        int displayId);
+
+    /**
+     * Remove a visibility watcher that was added using registerWallpaperVisibilityListener.
+     */
+    void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+        int displayId);
+
+    /**
      * Used only for assist -- request a screenshot of the current application.
      */
     boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver);
@@ -377,4 +392,9 @@
      * associated with that InputConsumer.
      */
     boolean destroyInputConsumer(String name);
+
+    /**
+     * Return the touch region for the current IME window, or an empty region if there is none.
+     */
+    Region getCurrentImeTouchRegion();
 }
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index ea2434e..15be2b0 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.InputManager;
@@ -768,6 +770,37 @@
     }
 
     /**
+     * Returns true if input device is enabled.
+     * @return Whether the input device is enabled.
+     * @hide
+     */
+    public boolean isEnabled() {
+        return InputManager.getInstance().isInputDeviceEnabled(mId);
+    }
+
+    /**
+     * Enables the input device.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
+    @TestApi
+    public void enable() {
+        InputManager.getInstance().enableInputDevice(mId);
+    }
+
+    /**
+     * Disables the input device.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
+    @TestApi
+    public void disable() {
+        InputManager.getInstance().disableInputDevice(mId);
+    }
+
+    /**
      * Reports whether the device has a built-in microphone.
      * @return Whether the device has a built-in microphone.
      */
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 20ab539..c566a65 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -111,9 +111,10 @@
      * to indicate whether the event was handled.  No new input events will be received
      * until {@link #finishInputEvent} is called.
      *
+     * @param displayId The display id on which input event triggered.
      * @param event The input event that was received.
      */
-    public void onInputEvent(InputEvent event) {
+    public void onInputEvent(InputEvent event, int displayId) {
         finishInputEvent(event, false);
     }
 
@@ -180,9 +181,9 @@
 
     // Called from native code.
     @SuppressWarnings("unused")
-    private void dispatchInputEvent(int seq, InputEvent event) {
+    private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
         mSeqMap.put(event.getSequenceNumber(), seq);
-        onInputEvent(event);
+        onInputEvent(event, displayId);
     }
 
     // Called from native code.
diff --git a/core/java/android/view/KeyboardShortcutGroup.java b/core/java/android/view/KeyboardShortcutGroup.java
index 78f0b30..52e9832 100644
--- a/core/java/android/view/KeyboardShortcutGroup.java
+++ b/core/java/android/view/KeyboardShortcutGroup.java
@@ -19,6 +19,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -58,6 +59,7 @@
      * @param isSystemGroup Set this to {@code true} if this is s system group.
      * @hide
      */
+    @TestApi
     public KeyboardShortcutGroup(@Nullable CharSequence label,
             @NonNull List<KeyboardShortcutInfo> items, boolean isSystemGroup) {
         mLabel = label;
@@ -70,6 +72,7 @@
      * @param isSystemGroup Set this to {@code true} if this is s system group.
      * @hide
      */
+    @TestApi
     public KeyboardShortcutGroup(@Nullable CharSequence label, boolean isSystemGroup) {
         this(label, Collections.<KeyboardShortcutInfo>emptyList(), isSystemGroup);
     }
@@ -96,6 +99,7 @@
     }
 
     /** @hide **/
+    @TestApi
     public boolean isSystemGroup() {
         return mSystemGroup;
     }
@@ -123,11 +127,11 @@
 
     public static final Creator<KeyboardShortcutGroup> CREATOR =
             new Creator<KeyboardShortcutGroup>() {
-        public KeyboardShortcutGroup createFromParcel(Parcel source) {
-            return new KeyboardShortcutGroup(source);
-        }
-        public KeyboardShortcutGroup[] newArray(int size) {
-            return new KeyboardShortcutGroup[size];
-        }
-    };
+                public KeyboardShortcutGroup createFromParcel(Parcel source) {
+                    return new KeyboardShortcutGroup(source);
+                }
+                public KeyboardShortcutGroup[] newArray(int size) {
+                    return new KeyboardShortcutGroup[size];
+                }
+            };
 }
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 20f7ace..5804560 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Outline;
 import android.graphics.Rect;
@@ -27,6 +28,7 @@
 import android.widget.ImageView;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
 import com.android.internal.widget.CachingIconView;
 
 import java.util.ArrayList;
@@ -52,9 +54,13 @@
     private int mIconColor;
     private int mOriginalNotificationColor;
     private boolean mExpanded;
+    private boolean mShowExpandButtonAtEnd;
     private boolean mShowWorkBadgeAtEnd;
     private Drawable mBackground;
     private int mHeaderBackgroundHeight;
+    private boolean mEntireHeaderClickable;
+    private boolean mExpandOnlyOnButton;
+    private boolean mAcceptAllTouches;
 
     ViewOutlineProvider mProvider = new ViewOutlineProvider() {
         @Override
@@ -65,7 +71,6 @@
             }
         }
     };
-    private boolean mAcceptAllTouches;
 
     public NotificationHeaderView(Context context) {
         this(context, null);
@@ -81,12 +86,12 @@
 
     public NotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mChildMinWidth = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_header_shrink_min_width);
-        mContentEndMargin = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_end);
-        mHeaderBackgroundHeight = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_header_background_height);
+        Resources res = getResources();
+        mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width);
+        mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end);
+        mHeaderBackgroundHeight = res.getDimensionPixelSize(
+                R.dimen.notification_header_background_height);
+        mEntireHeaderClickable = res.getBoolean(R.bool.config_notificationHeaderClickableForExpand);
     }
 
     @Override
@@ -147,8 +152,9 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         int left = getPaddingStart();
+        int end = getMeasuredWidth();
         int childCount = getChildCount();
-        int ownHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+        int ownHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
             if (child.getVisibility() == GONE) {
@@ -162,13 +168,17 @@
             int bottom = top + childHeight;
             int layoutLeft = left;
             int layoutRight = right;
+            if (child == mExpandButton && mShowExpandButtonAtEnd) {
+                layoutRight = end - mContentEndMargin;
+                end = layoutLeft = layoutRight - child.getMeasuredWidth();
+            }
             if (child == mProfileBadge) {
                 int paddingEnd = getPaddingEnd();
                 if (mShowWorkBadgeAtEnd) {
                     paddingEnd = mContentEndMargin;
                 }
-                layoutRight = getWidth() - paddingEnd;
-                layoutLeft = layoutRight - child.getMeasuredWidth();
+                layoutRight = end - paddingEnd;
+                end = layoutLeft = layoutRight - child.getMeasuredWidth();
             }
             if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                 int ltrLeft = layoutLeft;
@@ -265,13 +275,11 @@
         int drawableId;
         int contentDescriptionId;
         if (mExpanded) {
-            drawableId = com.android.internal.R.drawable.ic_collapse_notification;
-            contentDescriptionId
-                    = com.android.internal.R.string.expand_button_content_description_expanded;
+            drawableId = R.drawable.ic_collapse_notification;
+            contentDescriptionId = R.string.expand_button_content_description_expanded;
         } else {
-            drawableId = com.android.internal.R.drawable.ic_expand_notification;
-            contentDescriptionId
-                    = com.android.internal.R.string.expand_button_content_description_collapsed;
+            drawableId = R.drawable.ic_expand_notification;
+            contentDescriptionId = R.string.expand_button_content_description_collapsed;
         }
         mExpandButton.setImageDrawable(getContext().getDrawable(drawableId));
         mExpandButton.setColorFilter(mOriginalNotificationColor);
@@ -285,6 +293,18 @@
         }
     }
 
+    /**
+     * Sets whether or not the expand button appears at the end of the NotificationHeaderView. If
+     * both this and {@link #setShowWorkBadgeAtEnd(boolean)} have been set to true, then the
+     * expand button will appear closer to the end than the work badge.
+     */
+    public void setShowExpandButtonAtEnd(boolean showExpandButtonAtEnd) {
+        if (showExpandButtonAtEnd != mShowExpandButtonAtEnd) {
+            setClipToPadding(!showExpandButtonAtEnd);
+            mShowExpandButtonAtEnd = showExpandButtonAtEnd;
+        }
+    }
+
     public View getWorkProfileIcon() {
         return mProfileBadge;
     }
@@ -296,6 +316,7 @@
     public class HeaderTouchListener implements View.OnTouchListener {
 
         private final ArrayList<Rect> mTouchRects = new ArrayList<>();
+        private Rect mExpandButtonRect;
         private int mTouchSlop;
         private boolean mTrackGesture;
         private float mDownX;
@@ -306,8 +327,8 @@
 
         public void bindTouchRects() {
             mTouchRects.clear();
-            addRectAroundViewView(mIcon);
-            addRectAroundViewView(mExpandButton);
+            addRectAroundView(mIcon);
+            mExpandButtonRect = addRectAroundView(mExpandButton);
             addWidthRect();
             mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
         }
@@ -321,9 +342,10 @@
             mTouchRects.add(r);
         }
 
-        private void addRectAroundViewView(View view) {
+        private Rect addRectAroundView(View view) {
             final Rect r = getRectAroundView(view);
             mTouchRects.add(r);
+            return r;
         }
 
         private Rect getRectAroundView(View view) {
@@ -376,6 +398,9 @@
             if (mAcceptAllTouches) {
                 return true;
             }
+            if (mExpandOnlyOnButton) {
+                return mExpandButtonRect.contains((int) x, (int) y);
+            }
             for (int i = 0; i < mTouchRects.size(); i++) {
                 Rect r = mTouchRects.get(i);
                 if (r.contains((int) x, (int) y)) {
@@ -412,8 +437,21 @@
         return mTouchListener.isInside(x, y);
     }
 
+    /**
+     * Sets whether or not all touches to this header view will register as a click. Note that
+     * if the config value for {@code config_notificationHeaderClickableForExpand} is {@code true},
+     * then calling this method with {@code false} will not override that configuration.
+     */
     @RemotableViewMethod
     public void setAcceptAllTouches(boolean acceptAllTouches) {
-        mAcceptAllTouches = acceptAllTouches;
+        mAcceptAllTouches = mEntireHeaderClickable || acceptAllTouches;
+    }
+
+    /**
+     * Sets whether only the expand icon itself should serve as the expand target.
+     */
+    @RemotableViewMethod
+    public void setExpandOnlyOnButton(boolean expandOnlyOnButton) {
+        mExpandOnlyOnButton = expandOnlyOnButton;
     }
 }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 22329f4..1a2968f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -65,7 +65,8 @@
     private static native void nativeSetSize(long nativeObject, int w, int h);
     private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
     private static native void nativeSetAlpha(long nativeObject, float alpha);
-    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
+    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+            float dtdy, float dsdy);
     private static native void nativeSetFlags(long nativeObject, int flags, int mask);
     private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
     private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
@@ -272,6 +273,15 @@
     public static final int POWER_MODE_DOZE_SUSPEND = 3;
 
     /**
+     * A value for windowType used to indicate that the window should be omitted from screenshots
+     * and display mirroring. A temporary workaround until we express such things with
+     * the hierarchy.
+     * TODO: b/64227542
+     * @hide
+     */
+    public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
+
+    /**
      * Create a surface with a name.
      * <p>
      * The surface creation flags specify what kind of surface to create and
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b035b7f..cac27af 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;
 
@@ -729,7 +729,7 @@
                 mLocation[1] = getHeight();
 
                 mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
-                        mLocation[0], mLocation[1]);
+                        mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
 
                 if (mTranslator != null) {
                     mTranslator.translateRectInAppWindowToScreen(mScreenRect);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index a140f28..489de56 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -29,6 +29,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
@@ -188,6 +189,11 @@
     public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
             "debug.hwui.show_non_rect_clip";
 
+    static {
+        // Try to check OpenGL support early if possible.
+        isAvailable();
+    }
+
     /**
      * A process can set this flag to false to prevent the use of threaded
      * rendering.
@@ -227,8 +233,7 @@
         sTrimForeground = true;
     }
 
-    private static native boolean nSupportsOpenGL();
-    private static boolean sSupportsOpenGL = nSupportsOpenGL();
+    private static Boolean sSupportsOpenGL;
 
     /**
      * Indicates whether threaded rendering is available under any form for
@@ -238,7 +243,24 @@
      *         false otherwise
      */
     public static boolean isAvailable() {
-        return sSupportsOpenGL;
+        if (sSupportsOpenGL != null) {
+            return sSupportsOpenGL.booleanValue();
+        }
+        if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
+            // Device is not an emulator.
+            sSupportsOpenGL = true;
+            return true;
+        }
+        int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
+        if (qemu_gles == -1) {
+            // In this case, the value of the qemu.gles property is not ready
+            // because the SurfaceFlinger service may not start at this point.
+            return false;
+        }
+        // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
+        // enabled, 0 otherwise. On old emulator versions it will be undefined.
+        sSupportsOpenGL = qemu_gles > 0;
+        return sSupportsOpenGL.booleanValue();
     }
 
     /**
@@ -336,7 +358,6 @@
     private long mNativeProxy;
     private boolean mInitialized = false;
     private RenderNode mRootNode;
-    private Choreographer mChoreographer;
     private boolean mRootNodeNeedsUpdate;
 
     private boolean mEnabled;
@@ -405,8 +426,6 @@
     /**
      * Indicates whether threaded rendering is currently requested but not
      * necessarily enabled yet.
-     *
-     * @return True to request threaded rendering, false otherwise.
      */
     void setRequested(boolean requested) {
         mRequested = requested;
@@ -582,6 +601,13 @@
     }
 
     /**
+     * Enable/disable wide gamut rendering on this renderer.
+     */
+    void setWideGamut(boolean wideGamut) {
+        nSetWideGamut(mNativeProxy, wideGamut);
+    }
+
+    /**
      * Gets the current width of the surface. This is the width that the surface
      * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
      *
@@ -918,11 +944,11 @@
             if (mInitialized) return;
             mInitialized = true;
             mAppContext = context.getApplicationContext();
-            initSched(context, renderProxy);
+            initSched(renderProxy);
             initGraphicsStats();
         }
 
-        private void initSched(Context context, long renderProxy) {
+        private void initSched(long renderProxy) {
             try {
                 int tid = nGetRenderThreadTid(renderProxy);
                 ActivityManager.getService().setRenderThread(tid);
@@ -995,6 +1021,7 @@
     private static native void nSetLightCenter(long nativeProxy,
             float lightX, float lightY, float lightZ);
     private static native void nSetOpaque(long nativeProxy, boolean opaque);
+    private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
     private static native void nDestroy(long nativeProxy, long rootRenderNode);
     private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4882165..47e8b58 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -724,6 +724,8 @@
  * @attr ref android.R.styleable#View_nextFocusUp
  * @attr ref android.R.styleable#View_onClick
  * @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingHorizontal
+ * @attr ref android.R.styleable#View_paddingVertical
  * @attr ref android.R.styleable#View_paddingBottom
  * @attr ref android.R.styleable#View_paddingLeft
  * @attr ref android.R.styleable#View_paddingRight
@@ -2108,8 +2110,6 @@
 
     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
 
-    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
-
     /**
      * The view's tag.
      * {@hide}
@@ -11162,11 +11162,21 @@
         if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
             return;
         }
-        if (mSendViewStateChangedAccessibilityEvent == null) {
-            mSendViewStateChangedAccessibilityEvent =
-                    new SendViewStateChangedAccessibilityEvent();
+        // If this is a live region, we should send a subtree change event
+        // from this view immediately. Otherwise, we can let it propagate up.
+        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
+            final AccessibilityEvent event = AccessibilityEvent.obtain();
+            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+            event.setContentChangeTypes(changeType);
+            sendAccessibilityEventUnchecked(event);
+        } else if (mParent != null) {
+            try {
+                mParent.notifySubtreeAccessibilityStateChanged(this, this, changeType);
+            } catch (AbstractMethodError e) {
+                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                        " does not fully implement ViewParent", e);
+            }
         }
-        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
     }
 
     /**
@@ -13271,7 +13281,7 @@
                 // about in case nothing has focus.  even if this specific view
                 // isn't focusable, it may contain something that is, so let
                 // the root view try to give this focus if nothing else does.
-                if ((mParent != null)) {
+                if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
                     mParent.focusableViewAvailable(this);
                 }
             }
@@ -25897,8 +25907,8 @@
          * </p>
          * <p>
          * The default implementation behaves as
-         * {@link View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, int) for
-         * the case where no accessibility delegate is set.
+         * {@link View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, String, Bundle)
+         * for the case where no accessibility delegate is set.
          * </p>
          *
          * @param host The View hosting the delegate. Never {@code null}.
@@ -26006,79 +26016,6 @@
         }
     }
 
-    private class SendViewStateChangedAccessibilityEvent implements Runnable {
-        private int mChangeTypes = 0;
-        private boolean mPosted;
-        private boolean mPostedWithDelay;
-        private long mLastEventTimeMillis;
-
-        @Override
-        public void run() {
-            mPosted = false;
-            mPostedWithDelay = false;
-            mLastEventTimeMillis = SystemClock.uptimeMillis();
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                final AccessibilityEvent event = AccessibilityEvent.obtain();
-                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-                event.setContentChangeTypes(mChangeTypes);
-                sendAccessibilityEventUnchecked(event);
-            }
-            mChangeTypes = 0;
-        }
-
-        public void runOrPost(int changeType) {
-            mChangeTypes |= changeType;
-
-            // If this is a live region or the child of a live region, collect
-            // all events from this frame and send them on the next frame.
-            if (inLiveRegion()) {
-                // If we're already posted with a delay, remove that.
-                if (mPostedWithDelay) {
-                    removeCallbacks(this);
-                    mPostedWithDelay = false;
-                }
-                // Only post if we're not already posted.
-                if (!mPosted) {
-                    post(this);
-                    mPosted = true;
-                }
-                return;
-            }
-
-            if (mPosted) {
-                return;
-            }
-
-            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
-            final long minEventIntevalMillis =
-                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
-            if (timeSinceLastMillis >= minEventIntevalMillis) {
-                removeCallbacks(this);
-                run();
-            } else {
-                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
-                mPostedWithDelay = true;
-            }
-        }
-    }
-
-    private boolean inLiveRegion() {
-        if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-            return true;
-        }
-
-        ViewParent parent = getParent();
-        while (parent instanceof View) {
-            if (((View) parent).getAccessibilityLiveRegion()
-                    != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-                return true;
-            }
-            parent = parent.getParent();
-        }
-
-        return false;
-    }
-
     /**
      * Dump all private flags in readable format, useful for documentation and
      * sanity checking.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 66df335..ecdfa3f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3565,7 +3565,8 @@
         // If this is a live region, we should send a subtree change event
         // from this view. Otherwise, we can let it propagate up.
         if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
-            notifyViewAccessibilityStateChangedIfNeeded(changeType);
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
         } else if (mParent != null) {
             try {
                 mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
@@ -7608,6 +7609,16 @@
      * See
      * {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}
      * for a list of all child view attributes that this class supports.
+     *
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_margin
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginHorizontal
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginVertical
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
+     * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
      */
     public static class MarginLayoutParams extends ViewGroup.LayoutParams {
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fd950db..7ace841 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -35,6 +35,7 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -961,8 +962,13 @@
                 final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
                         || insets.top != 0 || insets.bottom != 0;
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
+                final boolean wideGamut =
+                        mContext.getResources().getConfiguration().isScreenWideColorGamut()
+                        && attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
+
                 mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
                         attrs.getTitle().toString());
+                mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
                 if (mAttachInfo.mThreadedRenderer != null) {
                     mAttachInfo.mHardwareAccelerated =
                             mAttachInfo.mHardwareAccelerationRequested = true;
@@ -1898,14 +1904,16 @@
                         + " outsets=" + mPendingOutsets.toShortString()
                         + " surface=" + mSurface);
 
-                final Configuration pendingMergedConfig =
-                        mPendingMergedConfiguration.getMergedConfiguration();
-                if (pendingMergedConfig.seq != 0) {
+                // If the pending {@link MergedConfiguration} handed back from
+                // {@link #relayoutWindow} does not match the one last reported,
+                // WindowManagerService has reported back a frame from a configuration not yet
+                // handled by the client. In this case, we need to accept the configuration so we
+                // do not lay out and draw with the wrong configuration.
+                if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
                     if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
-                            + pendingMergedConfig);
+                            + mPendingMergedConfiguration.getMergedConfiguration());
                     performConfigurationChange(mPendingMergedConfiguration, !mFirst,
                             INVALID_DISPLAY /* same display */);
-                    pendingMergedConfig.seq = 0;
                     updatedConfiguration = true;
                 }
 
@@ -3590,6 +3598,13 @@
                 mView.setLayoutDirection(currentLayoutDirection);
             }
             mView.dispatchConfigurationChanged(config);
+
+            // We could have gotten this {@link Configuration} update after we called
+            // {@link #performTraversals} with an older {@link Configuration}. As a result, our
+            // window frame may be stale. We must ensure the next pass of {@link #performTraversals}
+            // catches this.
+            mForceNextWindowRelayout = true;
+            requestLayout();
         }
     }
 
@@ -3751,10 +3766,10 @@
                     SomeArgs args = (SomeArgs) msg.obj;
 
                     final int displayId = args.argi3;
-                    final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+                    MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
                     final boolean displayChanged = mDisplay.getDisplayId() != displayId;
 
-                    if (mergedConfiguration != null) {
+                    if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
                         // If configuration changed - notify about that and, maybe, about move to
                         // display.
                         performConfigurationChange(mergedConfiguration, false /* force */,
@@ -6088,7 +6103,7 @@
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
-        mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
+
         //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
@@ -6741,7 +6756,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             enqueueInputEvent(event, this, 0, true);
         }
 
@@ -7072,6 +7087,14 @@
         if (mView == null || mStopped || mPausedForTransition) {
             return false;
         }
+
+        // Immediately flush pending content changed event (if any) to preserve event order
+        if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                && mSendWindowContentChangedAccessibilityEvent != null
+                && mSendWindowContentChangedAccessibilityEvent.mSource != null) {
+            mSendWindowContentChangedAccessibilityEvent.removeCallbacksAndRun();
+        }
+
         // Intercept accessibility focus events fired by virtual nodes to keep
         // track of accessibility focus position in such nodes.
         final int eventType = event.getEventType();
@@ -7881,23 +7904,46 @@
 
         @Override
         public void run() {
+            // Protect against re-entrant code and attempt to do the right thing in the case that
+            // we're multithreaded.
+            View source = mSource;
+            mSource = null;
+            if (source == null) {
+                Log.e(TAG, "Accessibility content change has no source");
+                return;
+            }
             // The accessibility may be turned off while we were waiting so check again.
             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                 mLastEventTimeMillis = SystemClock.uptimeMillis();
                 AccessibilityEvent event = AccessibilityEvent.obtain();
                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                 event.setContentChangeTypes(mChangeTypes);
-                mSource.sendAccessibilityEventUnchecked(event);
+                source.sendAccessibilityEventUnchecked(event);
             } else {
                 mLastEventTimeMillis = 0;
             }
             // In any case reset to initial state.
-            mSource.resetSubtreeAccessibilityStateChanged();
-            mSource = null;
+            source.resetSubtreeAccessibilityStateChanged();
             mChangeTypes = 0;
         }
 
         public void runOrPost(View source, int changeType) {
+            if (mHandler.getLooper() != Looper.myLooper()) {
+                CalledFromWrongThreadException e = new CalledFromWrongThreadException("Only the "
+                        + "original thread that created a view hierarchy can touch its views.");
+                // TODO: Throw the exception
+                Log.e(TAG, "Accessibility content change on non-UI thread. Future Android "
+                        + "versions will throw an exception.", e);
+                // Attempt to recover. This code does not eliminate the thread safety issue, but
+                // it should force any issues to happen near the above log.
+                mHandler.removeCallbacks(this);
+                if (mSource != null) {
+                    // Dispatch whatever was pending. It's still possible that the runnable started
+                    // just before we removed the callbacks, and bad things will happen, but at
+                    // least they should happen very close to the logged error.
+                    run();
+                }
+            }
             if (mSource != null) {
                 // If there is no common predecessor, then mSource points to
                 // a removed view, hence in this case always prefer the source.
@@ -7912,11 +7958,15 @@
             final long minEventIntevalMillis =
                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
             if (timeSinceLastMillis >= minEventIntevalMillis) {
-                mSource.removeCallbacks(this);
-                run();
+                removeCallbacksAndRun();
             } else {
-                mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
+                mHandler.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
             }
         }
+
+        public void removeCallbacksAndRun() {
+            mHandler.removeCallbacks(this);
+            run();
+        }
     }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 4060b9a..d60ba16 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -27,6 +28,7 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -169,6 +171,18 @@
      */
     public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
 
+    /**
+     * Return the touch region for the current IME window, or an empty region if there is none.
+     *
+     * @return The region of the IME that is accepting touch inputs, or null if there is no IME, no
+     *         region or there was an error.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
+    public Region getCurrentImeTouchRegion();
+
     public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
         /**
          * X position for this window.  With the default gravity it is ignored.
@@ -1391,6 +1405,14 @@
         public static final int PRIVATE_FLAG_TASK_SNAPSHOT = 0x00080000;
 
         /**
+         * Indicates that this window is the rounded corners overlay present on some
+         * devices this means that it will be excluded from: screenshots,
+         * screen magnification, and mirroring.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -1722,6 +1744,13 @@
         public float buttonBrightness = BRIGHTNESS_OVERRIDE_NONE;
 
         /**
+         * Unspecified value for {@link #rotationAnimation} indicating
+         * a lack of preference.
+         * @hide
+         */
+        public static final int ROTATION_ANIMATION_UNSPECIFIED = -1;
+
+        /**
          * Value for {@link #rotationAnimation} which specifies that this
          * window will visually rotate in or out following a rotation.
          */
@@ -2087,6 +2116,7 @@
             out.writeInt(needsMenuKey);
             out.writeInt(accessibilityIdOfAnchor);
             TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
+            out.writeInt(mColorMode);
             out.writeLong(hideTimeoutMilliseconds);
         }
 
@@ -2141,6 +2171,7 @@
             needsMenuKey = in.readInt();
             accessibilityIdOfAnchor = in.readInt();
             accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            mColorMode = in.readInt();
             hideTimeoutMilliseconds = in.readLong();
         }
 
@@ -2186,6 +2217,8 @@
         @TestApi
         public static final int ACCESSIBILITY_TITLE_CHANGED = 1 << 25;
         /** {@hide} */
+        public static final int COLOR_MODE_CHANGED = 1 << 26;
+        /** {@hide} */
         public static final int EVERYTHING_CHANGED = 0xffffffff;
 
         // internal buffer to backup/restore parameters under compatibility mode.
@@ -2363,6 +2396,11 @@
                 changes |= ACCESSIBILITY_TITLE_CHANGED;
             }
 
+            if (mColorMode != o.mColorMode) {
+                mColorMode = o.mColorMode;
+                changes |= COLOR_MODE_CHANGED;
+            }
+
             // This can't change, it's only set at window creation time.
             hideTimeoutMilliseconds = o.hideTimeoutMilliseconds;
 
@@ -2554,5 +2592,16 @@
             encoder.addProperty("type", type);
             encoder.addProperty("flags", flags);
         }
+
+        /**
+         * @hide
+         * @return True if the layout parameters will cause the window to cover the full screen;
+         *         false otherwise.
+         */
+        public boolean isFullscreen() {
+            return x == 0 && y == 0
+                    && width == WindowManager.LayoutParams.MATCH_PARENT
+                    && height == WindowManager.LayoutParams.MATCH_PARENT;
+        }
     }
 }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index c1b8f04..a8722f1 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -145,4 +146,13 @@
     public Display getDefaultDisplay() {
         return mContext.getDisplay();
     }
+
+    @Override
+    public Region getCurrentImeTouchRegion() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().getCurrentImeTouchRegion();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
 }
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 55aed52..98f8dc8 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -229,6 +229,11 @@
     public abstract boolean isKeyguardGoingAway();
 
     /**
+    * @return Whether the keyguard is showing and not occluded.
+    */
+    public abstract boolean isKeyguardShowingAndNotOccluded();
+
+    /**
      * Gets the frame of a window given its token.
      *
      * @param token The token.
@@ -342,4 +347,11 @@
      * Requests the window manager to recompute the windows for accessibility.
      */
     public abstract void computeWindowsForAccessibility();
+
+    /**
+     * Called after virtual display Id is updated by
+     * {@link com.android.server.vr.Vr2dDisplay} with a specific
+     * {@param vr2dDisplayId}.
+     */
+    public abstract void setVr2dDisplayId(int vr2dDisplayId);
 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 13ffeec..49b7ed8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -149,6 +150,11 @@
     public final static int PRESENCE_INTERNAL = 1 << 0;
     public final static int PRESENCE_EXTERNAL = 1 << 1;
 
+    // Navigation bar position values
+    int NAV_BAR_LEFT = 1 << 0;
+    int NAV_BAR_RIGHT = 1 << 1;
+    int NAV_BAR_BOTTOM = 1 << 2;
+
     public final static boolean WATCH_POINTER = false;
 
     /**
@@ -611,7 +617,16 @@
          * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
          * copy() must be made and the copy must be recycled.
          **/
-        public void onPointerEvent(MotionEvent motionEvent);
+        void onPointerEvent(MotionEvent motionEvent);
+
+        /**
+         * @see #onPointerEvent(MotionEvent)
+         **/
+        default void onPointerEvent(MotionEvent motionEvent, int displayId) {
+            if (displayId == DEFAULT_DISPLAY) {
+                onPointerEvent(motionEvent);
+            }
+        }
     }
 
     /** Window has been added to the screen. */
@@ -1311,6 +1326,14 @@
     public boolean isScreenOn();
 
     /**
+     * @return whether the device is currently allowed to animate.
+     *
+     * Note: this can be true even if it is not appropriate to animate for reasons that are outside
+     *       of the policy's authority.
+     */
+    boolean okToAnimate();
+
+    /**
      * 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.
@@ -1667,6 +1690,14 @@
     public boolean isNavBarForcedShownLw(WindowState win);
 
     /**
+     * @return The side of the screen where navigation bar is positioned.
+     * @see #NAV_BAR_LEFT
+     * @see #NAV_BAR_RIGHT
+     * @see #NAV_BAR_BOTTOM
+     */
+    int getNavBarPosition();
+
+    /**
      * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
      * bar or button bar. See {@link #getNonDecorDisplayWidth}.
      *
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index eecfdca..9dd0fb0 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -21,6 +21,8 @@
 import android.text.TextUtils;
 import android.util.Pools.SynchronizedPool;
 
+import com.android.internal.util.BitUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -851,6 +853,22 @@
         return mContentChangeTypes;
     }
 
+    private static String contentChangeTypesToString(int types) {
+        return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString);
+    }
+
+    private static String singleContentChangeTypeToString(int type) {
+        switch (type) {
+            case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: {
+                return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION";
+            }
+            case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE";
+            case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT";
+            case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED";
+            default: return Integer.toHexString(type);
+        }
+    }
+
     /**
      * Sets the bit mask of node tree changes signaled by an
      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
@@ -1109,7 +1127,7 @@
         record.mParcelableData = parcel.readParcelable(null);
         parcel.readList(record.mText, null);
         record.mSourceWindowId = parcel.readInt();
-        record.mSourceNode = parcel.readParcelable(null);
+        record.mSourceNodeId = parcel.readLong();
         record.mSealed = (parcel.readInt() == 1);
     }
 
@@ -1161,10 +1179,7 @@
         parcel.writeParcelable(record.mParcelableData, flags);
         parcel.writeList(record.mText);
         parcel.writeInt(record.mSourceWindowId);
-        // create copy of the node here because the node would be recycled just after it is written
-        // to parcel
-        parcel.writeParcelable(record.mSourceNode != null ?
-                AccessibilityNodeInfo.obtain(record.mSourceNode) : null, flags);
+        parcel.writeLong(record.mSourceNodeId);
         parcel.writeInt(record.mSealed ? 1 : 0);
     }
 
@@ -1186,11 +1201,10 @@
         builder.append(super.toString());
         if (DEBUG) {
             builder.append("\n");
-            builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
+            builder.append("; ContentChangeTypes: ").append(
+                    contentChangeTypesToString(mContentChangeTypes));
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
-            if (mSourceNode != null) {
-                builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId());
-            }
+            builder.append("; mSourceNodeId: ").append(mSourceNodeId);
             for (int i = 0; i < getRecordCount(); i++) {
                 final AccessibilityRecord record = getRecord(i);
                 builder.append("  Record ");
@@ -1239,183 +1253,13 @@
         while (eventType != 0) {
             final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType);
             eventType &= ~eventTypeFlag;
-            switch (eventTypeFlag) {
-                case TYPE_VIEW_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_LONG_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_LONG_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SELECTED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SELECTED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_ENTER: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_ENTER");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_EXIT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_EXIT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_NOTIFICATION_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_NOTIFICATION_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_CONTENT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_CONTENT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_SELECTION_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_SELECTION_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SCROLLED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SCROLLED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ANNOUNCEMENT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ANNOUNCEMENT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOWS_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOWS_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_CONTEXT_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CONTEXT_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ASSIST_READING_CONTEXT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ASSIST_READING_CONTEXT");
-                    eventTypeCount++;
-                } break;
+
+            if (eventTypeCount > 0) {
+                builder.append(", ");
             }
+            builder.append(singleEventTypeToString(eventTypeFlag));
+
+            eventTypeCount++;
         }
         if (eventTypeCount > 1) {
             builder.insert(0, '[');
@@ -1424,6 +1268,43 @@
         return builder.toString();
     }
 
+    private static String singleEventTypeToString(int eventType) {
+        switch (eventType) {
+            case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED";
+            case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED";
+            case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED";
+            case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED";
+            case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED";
+            case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED";
+            case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER";
+            case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT";
+            case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED";
+            case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
+                return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
+            }
+            case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
+            case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED";
+            case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
+            case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED";
+            case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
+                return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
+            }
+            case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
+                return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY";
+            }
+            case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START";
+            case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END";
+            case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START";
+            case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END";
+            case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED";
+            case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED";
+            case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT";
+            default: return Integer.toHexString(eventType);
+        }
+    }
+
     /**
      * @see Parcelable.Creator
      */
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index bdadcc7..69892d9 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -42,6 +43,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.IWindow;
 import android.view.View;
 
@@ -145,6 +147,11 @@
             mServicesStateChangeListeners = new ArrayMap<>();
 
     /**
+     * Map from a view's accessibility id to the list of request preparers set for that view
+     */
+    private SparseArray<List<AccessibilityRequestPreparer>> mRequestPreparerLists;
+
+    /**
      * Listener for the system accessibility state. To listen for changes to the
      * accessibility state on the device, implement this interface and register
      * it with the system by calling {@link #addAccessibilityStateChangeListener}.
@@ -697,6 +704,58 @@
     }
 
     /**
+     * Registers a {@link AccessibilityRequestPreparer}.
+     * @hide
+     */
+    @TestApi
+    public void addAccessibilityRequestPreparer(AccessibilityRequestPreparer preparer) {
+        if (mRequestPreparerLists == null) {
+            mRequestPreparerLists = new SparseArray<>(1);
+        }
+        int id = preparer.getView().getAccessibilityViewId();
+        List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(id);
+        if (requestPreparerList == null) {
+            requestPreparerList = new ArrayList<>(1);
+            mRequestPreparerLists.put(id, requestPreparerList);
+        }
+        requestPreparerList.add(preparer);
+    }
+
+    /**
+     * Unregisters a {@link AccessibilityRequestPreparer}.
+     * @hide
+     */
+    @TestApi
+    public void removeAccessibilityRequestPreparer(AccessibilityRequestPreparer preparer) {
+        if (mRequestPreparerLists == null) {
+            return;
+        }
+        int viewId = preparer.getView().getAccessibilityViewId();
+        List<AccessibilityRequestPreparer> requestPreparerList = mRequestPreparerLists.get(viewId);
+        if (requestPreparerList != null) {
+            requestPreparerList.remove(preparer);
+            if (requestPreparerList.isEmpty()) {
+                mRequestPreparerLists.remove(viewId);
+            }
+        }
+    }
+
+    /**
+     * Get the preparers that are registered for an accessibility ID
+     *
+     * @param id The ID of interest
+     * @return The list of preparers, or {@code null} if there are none.
+     *
+     * @hide
+     */
+    public List<AccessibilityRequestPreparer> getRequestPreparersForAccessibilityId(int id) {
+        if (mRequestPreparerLists == null) {
+            return null;
+        }
+        return mRequestPreparerLists.get(id);
+    }
+
+    /**
      * Registers a {@link HighTextContrastChangeListener} for changes in
      * the global high text contrast state of the system.
      *
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5148d92..82a6de7 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -16,6 +16,9 @@
 
 package android.view.accessibility;
 
+import static com.android.internal.util.BitUtils.bitAt;
+import static com.android.internal.util.BitUtils.isBitSet;
+
 import static java.util.Collections.EMPTY_LIST;
 
 import android.accessibilityservice.AccessibilityService;
@@ -41,10 +44,12 @@
 import android.view.View;
 
 import com.android.internal.R;
+import com.android.internal.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -85,7 +90,6 @@
     /** @hide */
     public static final int UNDEFINED_SELECTION_INDEX = -1;
 
-    /* Special IDs for node source IDs */
     /** @hide */
     public static final int UNDEFINED_ITEM_ID = Integer.MAX_VALUE;
 
@@ -636,7 +640,6 @@
      * Bits that provide the id of a virtual descendant of a view.
      */
     private static final long VIRTUAL_DESCENDANT_ID_MASK = 0xffffffff00000000L;
-
     /**
      * Bit shift of {@link #VIRTUAL_DESCENDANT_ID_MASK} to get to the id for a
      * virtual descendant of a view. Such a descendant does not exist in the view
@@ -692,6 +695,8 @@
     private static final SynchronizedPool<AccessibilityNodeInfo> sPool =
             new SynchronizedPool<>(MAX_POOL_SIZE);
 
+    private static final AccessibilityNodeInfo DEFAULT = new AccessibilityNodeInfo();
+
     private boolean mSealed;
 
     // Data.
@@ -1068,11 +1073,7 @@
      * Gets the actions that can be performed on the node.
      */
     public List<AccessibilityAction> getActionList() {
-        if (mActions == null) {
-            return Collections.emptyList();
-        }
-
-        return mActions;
+        return CollectionUtils.emptyIfNull(mActions);
     }
 
     /**
@@ -3050,127 +3051,227 @@
      */
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(isSealed() ? 1 : 0);
-        parcel.writeLong(mSourceNodeId);
-        parcel.writeInt(mWindowId);
-        parcel.writeLong(mParentNodeId);
-        parcel.writeLong(mLabelForId);
-        parcel.writeLong(mLabeledById);
-        parcel.writeLong(mTraversalBefore);
-        parcel.writeLong(mTraversalAfter);
-
-        parcel.writeInt(mConnectionId);
-
-        final LongArray childIds = mChildNodeIds;
-        if (childIds == null) {
-            parcel.writeInt(0);
-        } else {
-            final int childIdsSize = childIds.size();
-            parcel.writeInt(childIdsSize);
-            for (int i = 0; i < childIdsSize; i++) {
-                parcel.writeLong(childIds.get(i));
-            }
+        // Write bit set of indices of fields with values differing from default
+        long nonDefaultFields = 0;
+        int fieldIndex = 0; // index of the current field
+        if (isSealed() != DEFAULT.isSealed()) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mSourceNodeId != DEFAULT.mSourceNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mWindowId != DEFAULT.mWindowId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mParentNodeId != DEFAULT.mParentNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabelForId != DEFAULT.mLabelForId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabeledById != DEFAULT.mLabeledById) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalBefore != DEFAULT.mTraversalBefore) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalAfter != DEFAULT.mTraversalAfter) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mConnectionId != DEFAULT.mConnectionId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mChildNodeIds, DEFAULT.mChildNodeIds)) {
+            nonDefaultFields |= bitAt(fieldIndex);
         }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInParent, DEFAULT.mBoundsInParent)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInScreen, DEFAULT.mBoundsInScreen)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mActions, DEFAULT.mActions)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMaxTextLength != DEFAULT.mMaxTextLength) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMovementGranularities != DEFAULT.mMovementGranularities) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mBooleanProperties != DEFAULT.mBooleanProperties) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mPackageName, DEFAULT.mPackageName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mClassName, DEFAULT.mClassName)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mText, DEFAULT.mText)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mHintText, DEFAULT.mHintText)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mError, DEFAULT.mError)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mContentDescription, DEFAULT.mContentDescription)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mViewIdResourceName, DEFAULT.mViewIdResourceName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionStart != DEFAULT.mTextSelectionStart) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionEnd != DEFAULT.mTextSelectionEnd) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mInputType != DEFAULT.mInputType) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLiveRegion != DEFAULT.mLiveRegion) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mDrawingOrderInParent != DEFAULT.mDrawingOrderInParent) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtraDataKeys, DEFAULT.mExtraDataKeys)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtras, DEFAULT.mExtras)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mRangeInfo, DEFAULT.mRangeInfo)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mCollectionInfo, DEFAULT.mCollectionInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mCollectionItemInfo, DEFAULT.mCollectionItemInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        int totalFields = fieldIndex;
+        parcel.writeLong(nonDefaultFields);
 
-        parcel.writeInt(mBoundsInParent.top);
-        parcel.writeInt(mBoundsInParent.bottom);
-        parcel.writeInt(mBoundsInParent.left);
-        parcel.writeInt(mBoundsInParent.right);
+        fieldIndex = 0;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(isSealed() ? 1 : 0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mSourceNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mWindowId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mParentNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabelForId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabeledById);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalBefore);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalAfter);
 
-        parcel.writeInt(mBoundsInScreen.top);
-        parcel.writeInt(mBoundsInScreen.bottom);
-        parcel.writeInt(mBoundsInScreen.left);
-        parcel.writeInt(mBoundsInScreen.right);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mConnectionId);
 
-        if (mActions != null && !mActions.isEmpty()) {
-            final int actionCount = mActions.size();
-
-            int nonLegacyActionCount = 0;
-            int defaultLegacyStandardActions = 0;
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (isDefaultLegacyStandardAction(action)) {
-                    defaultLegacyStandardActions |= action.getId();
-                } else {
-                    nonLegacyActionCount++;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final LongArray childIds = mChildNodeIds;
+            if (childIds == null) {
+                parcel.writeInt(0);
+            } else {
+                final int childIdsSize = childIds.size();
+                parcel.writeInt(childIdsSize);
+                for (int i = 0; i < childIdsSize; i++) {
+                    parcel.writeLong(childIds.get(i));
                 }
             }
-            parcel.writeInt(defaultLegacyStandardActions);
-            parcel.writeInt(nonLegacyActionCount);
+        }
 
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (!isDefaultLegacyStandardAction(action)) {
-                    parcel.writeInt(action.getId());
-                    parcel.writeCharSequence(action.getLabel());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInParent.top);
+            parcel.writeInt(mBoundsInParent.bottom);
+            parcel.writeInt(mBoundsInParent.left);
+            parcel.writeInt(mBoundsInParent.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInScreen.top);
+            parcel.writeInt(mBoundsInScreen.bottom);
+            parcel.writeInt(mBoundsInScreen.left);
+            parcel.writeInt(mBoundsInScreen.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            if (mActions != null && !mActions.isEmpty()) {
+                final int actionCount = mActions.size();
+
+                int nonLegacyActionCount = 0;
+                int defaultLegacyStandardActions = 0;
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (isDefaultLegacyStandardAction(action)) {
+                        defaultLegacyStandardActions |= action.getId();
+                    } else {
+                        nonLegacyActionCount++;
+                    }
                 }
+                parcel.writeInt(defaultLegacyStandardActions);
+                parcel.writeInt(nonLegacyActionCount);
+
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (!isDefaultLegacyStandardAction(action)) {
+                        parcel.writeInt(action.getId());
+                        parcel.writeCharSequence(action.getLabel());
+                    }
+                }
+            } else {
+                parcel.writeInt(0);
+                parcel.writeInt(0);
             }
-        } else {
-            parcel.writeInt(0);
-            parcel.writeInt(0);
         }
 
-        parcel.writeInt(mMaxTextLength);
-        parcel.writeInt(mMovementGranularities);
-        parcel.writeInt(mBooleanProperties);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMaxTextLength);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMovementGranularities);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mBooleanProperties);
 
-        parcel.writeCharSequence(mPackageName);
-        parcel.writeCharSequence(mClassName);
-        parcel.writeCharSequence(mText);
-        parcel.writeCharSequence(mHintText);
-        parcel.writeCharSequence(mError);
-        parcel.writeCharSequence(mContentDescription);
-        parcel.writeString(mViewIdResourceName);
-
-        parcel.writeInt(mTextSelectionStart);
-        parcel.writeInt(mTextSelectionEnd);
-        parcel.writeInt(mInputType);
-        parcel.writeInt(mLiveRegion);
-        parcel.writeInt(mDrawingOrderInParent);
-        if (mExtraDataKeys != null) {
-            parcel.writeInt(1);
-            parcel.writeStringList(mExtraDataKeys);
-        } else {
-            parcel.writeInt(0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mPackageName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mClassName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mHintText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mError);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeCharSequence(mContentDescription);
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeString(mViewIdResourceName);
 
-        if (mExtras != null) {
-            parcel.writeInt(1);
-            parcel.writeBundle(mExtras);
-        } else {
-            parcel.writeInt(0);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionStart);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionEnd);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mInputType);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mLiveRegion);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mDrawingOrderInParent);
 
-        if (mRangeInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeStringList(mExtraDataKeys);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeBundle(mExtras);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mRangeInfo.getType());
             parcel.writeFloat(mRangeInfo.getMin());
             parcel.writeFloat(mRangeInfo.getMax());
             parcel.writeFloat(mRangeInfo.getCurrent());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionInfo.getRowCount());
             parcel.writeInt(mCollectionInfo.getColumnCount());
             parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
             parcel.writeInt(mCollectionInfo.getSelectionMode());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionItemInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionItemInfo.getRowIndex());
             parcel.writeInt(mCollectionItemInfo.getRowSpan());
             parcel.writeInt(mCollectionItemInfo.getColumnIndex());
             parcel.writeInt(mCollectionItemInfo.getColumnSpan());
             parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
             parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
-        } else {
-            parcel.writeInt(0);
+        }
+
+        if (DEBUG) {
+            fieldIndex--;
+            if (totalFields != fieldIndex) {
+                throw new IllegalStateException("Number of fields mismatch: " + totalFields
+                        + " vs " + fieldIndex);
+            }
         }
 
         // Since instances of this class are fetched via synchronous i.e. blocking
@@ -3203,12 +3304,12 @@
         mContentDescription = other.mContentDescription;
         mViewIdResourceName = other.mViewIdResourceName;
 
+        if (mActions != null) mActions.clear();
         final ArrayList<AccessibilityAction> otherActions = other.mActions;
         if (otherActions != null && otherActions.size() > 0) {
             if (mActions == null) {
                 mActions = new ArrayList(otherActions);
             } else {
-                mActions.clear();
                 mActions.addAll(other.mActions);
             }
         }
@@ -3217,12 +3318,13 @@
         mMaxTextLength = other.mMaxTextLength;
         mMovementGranularities = other.mMovementGranularities;
 
+
+        if (mChildNodeIds != null) mChildNodeIds.clear();
         final LongArray otherChildNodeIds = other.mChildNodeIds;
         if (otherChildNodeIds != null && otherChildNodeIds.size() > 0) {
             if (mChildNodeIds == null) {
                 mChildNodeIds = otherChildNodeIds.clone();
             } else {
-                mChildNodeIds.clear();
                 mChildNodeIds.addAll(otherChildNodeIds);
             }
         }
@@ -3232,17 +3334,18 @@
         mInputType = other.mInputType;
         mLiveRegion = other.mLiveRegion;
         mDrawingOrderInParent = other.mDrawingOrderInParent;
+
         mExtraDataKeys = other.mExtraDataKeys;
 
-        if (other.mExtras != null) {
-            mExtras = new Bundle(other.mExtras);
-        } else {
-            mExtras = null;
-        }
+        mExtras = other.mExtras != null ? new Bundle(other.mExtras) : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
         mRangeInfo = (other.mRangeInfo != null)
                 ? RangeInfo.obtain(other.mRangeInfo) : null;
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
         mCollectionInfo = (other.mCollectionInfo != null)
                 ? CollectionInfo.obtain(other.mCollectionInfo) : null;
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
         mCollectionItemInfo =  (other.mCollectionItemInfo != null)
                 ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null;
     }
@@ -3253,103 +3356,117 @@
      * @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
      */
     private void initFromParcel(Parcel parcel) {
-        final boolean sealed = (parcel.readInt()  == 1);
-        mSourceNodeId = parcel.readLong();
-        mWindowId = parcel.readInt();
-        mParentNodeId = parcel.readLong();
-        mLabelForId = parcel.readLong();
-        mLabeledById = parcel.readLong();
-        mTraversalBefore = parcel.readLong();
-        mTraversalAfter = parcel.readLong();
+        // Bit mask of non-default-valued field indices
+        long nonDefaultFields = parcel.readLong();
+        int fieldIndex = 0;
+        final boolean sealed = isBitSet(nonDefaultFields, fieldIndex++)
+                ? (parcel.readInt() == 1)
+                : DEFAULT.mSealed;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mSourceNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mWindowId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mParentNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabelForId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabeledById = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalBefore = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalAfter = parcel.readLong();
 
-        mConnectionId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mConnectionId = parcel.readInt();
 
-        final int childrenSize = parcel.readInt();
-        if (childrenSize <= 0) {
-            mChildNodeIds = null;
-        } else {
-            mChildNodeIds = new LongArray(childrenSize);
-            for (int i = 0; i < childrenSize; i++) {
-                final long childId = parcel.readLong();
-                mChildNodeIds.add(childId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int childrenSize = parcel.readInt();
+            if (childrenSize <= 0) {
+                mChildNodeIds = null;
+            } else {
+                mChildNodeIds = new LongArray(childrenSize);
+                for (int i = 0; i < childrenSize; i++) {
+                    final long childId = parcel.readLong();
+                    mChildNodeIds.add(childId);
+                }
             }
         }
 
-        mBoundsInParent.top = parcel.readInt();
-        mBoundsInParent.bottom = parcel.readInt();
-        mBoundsInParent.left = parcel.readInt();
-        mBoundsInParent.right = parcel.readInt();
-
-        mBoundsInScreen.top = parcel.readInt();
-        mBoundsInScreen.bottom = parcel.readInt();
-        mBoundsInScreen.left = parcel.readInt();
-        mBoundsInScreen.right = parcel.readInt();
-
-        final int legacyStandardActions = parcel.readInt();
-        addLegacyStandardActions(legacyStandardActions);
-        final int nonLegacyActionCount = parcel.readInt();
-        for (int i = 0; i < nonLegacyActionCount; i++) {
-            final AccessibilityAction action = new AccessibilityAction(
-                    parcel.readInt(), parcel.readCharSequence());
-            addActionUnchecked(action);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInParent.top = parcel.readInt();
+            mBoundsInParent.bottom = parcel.readInt();
+            mBoundsInParent.left = parcel.readInt();
+            mBoundsInParent.right = parcel.readInt();
         }
 
-        mMaxTextLength = parcel.readInt();
-        mMovementGranularities = parcel.readInt();
-        mBooleanProperties = parcel.readInt();
-
-        mPackageName = parcel.readCharSequence();
-        mClassName = parcel.readCharSequence();
-        mText = parcel.readCharSequence();
-        mHintText = parcel.readCharSequence();
-        mError = parcel.readCharSequence();
-        mContentDescription = parcel.readCharSequence();
-        mViewIdResourceName = parcel.readString();
-
-        mTextSelectionStart = parcel.readInt();
-        mTextSelectionEnd = parcel.readInt();
-
-        mInputType = parcel.readInt();
-        mLiveRegion = parcel.readInt();
-        mDrawingOrderInParent = parcel.readInt();
-
-        if (parcel.readInt() == 1) {
-            mExtraDataKeys = parcel.createStringArrayList();
-        } else {
-            mExtraDataKeys = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInScreen.top = parcel.readInt();
+            mBoundsInScreen.bottom = parcel.readInt();
+            mBoundsInScreen.left = parcel.readInt();
+            mBoundsInScreen.right = parcel.readInt();
         }
 
-        if (parcel.readInt() == 1) {
-            mExtras = parcel.readBundle();
-        } else {
-            mExtras = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int legacyStandardActions = parcel.readInt();
+            addLegacyStandardActions(legacyStandardActions);
+            final int nonLegacyActionCount = parcel.readInt();
+            for (int i = 0; i < nonLegacyActionCount; i++) {
+                final AccessibilityAction action = new AccessibilityAction(
+                        parcel.readInt(), parcel.readCharSequence());
+                addActionUnchecked(action);
+            }
         }
 
-        if (parcel.readInt() == 1) {
-            mRangeInfo = RangeInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readFloat(),
-                    parcel.readFloat(),
-                    parcel.readFloat());
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMaxTextLength = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMovementGranularities = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mBooleanProperties = parcel.readInt();
 
-        if (parcel.readInt() == 1) {
-            mCollectionInfo = CollectionInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mPackageName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mClassName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mHintText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mError = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mContentDescription = parcel.readCharSequence();
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mViewIdResourceName = parcel.readString();
 
-        if (parcel.readInt() == 1) {
-            mCollectionItemInfo = CollectionItemInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt() == 1);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionStart = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionEnd = parcel.readInt();
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mInputType = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLiveRegion = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mDrawingOrderInParent = parcel.readInt();
+
+        mExtraDataKeys = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.createStringArrayList()
+                : null;
+
+        mExtras = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.readBundle()
+                : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
+        mRangeInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? RangeInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readFloat(),
+                        parcel.readFloat(),
+                        parcel.readFloat())
+                : null;
+
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
+        mCollectionInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt())
+                : null;
+
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
+        mCollectionItemInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionItemInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt() == 1)
+                : null;
 
         mSealed = sealed;
     }
@@ -3358,50 +3475,7 @@
      * Clears the state of this instance.
      */
     private void clear() {
-        mSealed = false;
-        mSourceNodeId = UNDEFINED_NODE_ID;
-        mParentNodeId = UNDEFINED_NODE_ID;
-        mLabelForId = UNDEFINED_NODE_ID;
-        mLabeledById = UNDEFINED_NODE_ID;
-        mTraversalBefore = UNDEFINED_NODE_ID;
-        mTraversalAfter = UNDEFINED_NODE_ID;
-        mWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        mConnectionId = UNDEFINED_CONNECTION_ID;
-        mMaxTextLength = -1;
-        mMovementGranularities = 0;
-        if (mChildNodeIds != null) {
-            mChildNodeIds.clear();
-        }
-        mBoundsInParent.set(0, 0, 0, 0);
-        mBoundsInScreen.set(0, 0, 0, 0);
-        mBooleanProperties = 0;
-        mDrawingOrderInParent = 0;
-        mExtraDataKeys = null;
-        mPackageName = null;
-        mClassName = null;
-        mText = null;
-        mHintText = null;
-        mError = null;
-        mContentDescription = null;
-        mViewIdResourceName = null;
-        removeAllActions();
-        mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
-        mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
-        mInputType = InputType.TYPE_NULL;
-        mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
-        mExtras = null;
-        if (mRangeInfo != null) {
-            mRangeInfo.recycle();
-            mRangeInfo = null;
-        }
-        if (mCollectionInfo != null) {
-            mCollectionInfo.recycle();
-            mCollectionInfo = null;
-        }
-        if (mCollectionItemInfo != null) {
-            mCollectionItemInfo.recycle();
-            mCollectionItemInfo = null;
-        }
+        init(DEFAULT);
     }
 
     private static boolean isDefaultLegacyStandardAction(AccessibilityAction action) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index 722b659..73733a0 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -76,7 +76,7 @@
 
     /**
      * Returns an {@link AccessibilityNodeInfo} representing a virtual view,
-     * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
+     * such as a descendant of the host View, with the given <code>virtualViewId</code>
      * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      * <p>
      * A virtual descendant is an imaginary View that is reported as a part of the view
@@ -123,7 +123,7 @@
     }
 
     /**
-     * Performs an accessibility action on a virtual view, i.e. a descendant of the
+     * Performs an accessibility action on a virtual view, such as a descendant of the
      * host View, with the given <code>virtualViewId</code> or the host View itself
      * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      *
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Find the virtual view, i.e. a descendant of the host View, that has the
+     * Find the virtual view, such as a descendant of the host View, that has the
      * specified focus type.
      *
      * @param focus The focus to find. One of
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 3f1fece..02b6185 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.annotation.Nullable;
 import android.os.Parcelable;
 import android.view.View;
 
@@ -90,7 +91,7 @@
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
-    AccessibilityNodeInfo mSourceNode;
+    long mSourceNodeId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
     int mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
 
     CharSequence mClassName;
@@ -116,7 +117,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setSource(View source) {
-        setSource(source, UNDEFINED);
+        setSource(source, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -133,46 +134,28 @@
      * @param root The root of the virtual subtree.
      * @param virtualDescendantId The id of the virtual descendant.
      */
-    public void setSource(View root, int virtualDescendantId) {
+    public void setSource(@Nullable View root, int virtualDescendantId) {
         enforceNotSealed();
         boolean important = true;
+        int rootViewId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
         mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        clearSourceNode();
         if (root != null) {
-            if (virtualDescendantId == View.NO_ID
-                    || virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID
-                    || virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
-                important = root.isImportantForAccessibility();
-                mSourceNode = root.createAccessibilityNodeInfo();
-            } else {
-                AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
-                if (provider != null) {
-                    mSourceNode = provider.createAccessibilityNodeInfo(virtualDescendantId);
-                }
-            }
-
+            important = root.isImportantForAccessibility();
+            rootViewId = root.getAccessibilityViewId();
             mSourceWindowId = root.getAccessibilityWindowId();
         }
         setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
+        mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
     }
 
     /**
-     * Set the source directly to an AccessibilityNodeInfo rather than indirectly via a View
+     * Set the source node ID directly
      *
-     * @param info The source
-     *
+     * @param sourceNodeId The source node Id
      * @hide
      */
-    public void setSource(AccessibilityNodeInfo info) {
-        enforceNotSealed();
-        clearSourceNode();
-        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        if (info != null) {
-            mSourceNode = AccessibilityNodeInfo.obtain(info);
-            setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY,
-                    mSourceNode.isImportantForAccessibility());
-            mSourceWindowId = info.getWindowId();
-        }
+    public void setSourceNodeId(long sourceNodeId) {
+        mSourceNodeId = sourceNodeId;
     }
 
     /**
@@ -186,11 +169,15 @@
      */
     public AccessibilityNodeInfo getSource() {
         enforceSealed();
-        if (mSourceNode != null) {
-            return AccessibilityNodeInfo.obtain(mSourceNode);
+        if ((mConnectionId == UNDEFINED)
+                || (mSourceWindowId == AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
+                || (AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId)
+                        == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)) {
+            return null;
         }
-
-        return null;
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
+                mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS, null);
     }
 
     /**
@@ -336,6 +323,20 @@
     }
 
     /**
+     * Sets if the source is important for accessibility.
+     *
+     * @param importantForAccessibility True if the source is important for accessibility,
+     *                                  false otherwise.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     * @hide
+     */
+    public void setImportantForAccessibility(boolean importantForAccessibility) {
+        enforceNotSealed();
+        setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, importantForAccessibility);
+    }
+
+    /**
      * Gets the number of items that can be visited.
      *
      * @return The number of items.
@@ -647,7 +648,7 @@
      * @hide
      */
     public long getSourceNodeId() {
-        return mSourceNode != null ? mSourceNode.getSourceNodeId() : UNDEFINED;
+        return mSourceNodeId;
     }
 
     /**
@@ -661,9 +662,6 @@
     public void setConnectionId(int connectionId) {
         enforceNotSealed();
         mConnectionId = connectionId;
-        if (mSourceNode != null) {
-            mSourceNode.setConnectionId(mConnectionId);
-        }
     }
 
     /**
@@ -675,9 +673,6 @@
      */
     public void setSealed(boolean sealed) {
         mSealed = sealed;
-        if (mSourceNode != null) {
-            mSourceNode.setSealed(sealed);
-        }
     }
 
     /**
@@ -816,9 +811,7 @@
         mParcelableData = record.mParcelableData;
         mText.addAll(record.mText);
         mSourceWindowId = record.mSourceWindowId;
-        if (record.mSourceNode != null) {
-            mSourceNode = AccessibilityNodeInfo.obtain(record.mSourceNode);
-        }
+        mSourceNodeId = record.mSourceNodeId;
         mConnectionId = record.mConnectionId;
     }
 
@@ -843,19 +836,11 @@
         mBeforeText = null;
         mParcelableData = null;
         mText.clear();
-        clearSourceNode();
-        mSourceWindowId = UNDEFINED;
+        mSourceNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
         mConnectionId = UNDEFINED;
     }
 
-    private void clearSourceNode() {
-        if (mSourceNode != null) {
-            mSourceNode.recycle();
-            mSourceNode = null;
-        }
-
-    }
-
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder();
diff --git a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java
new file mode 100644
index 0000000..c032390
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java
@@ -0,0 +1,125 @@
+/*
+ * 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.view.accessibility;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Message;
+import android.view.View;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+
+/**
+ * Object responsible to ensuring that a {@link View} is prepared to meet a synchronous request for
+ * accessibility data.
+ * <p>
+ * Because accessibility requests arrive to {@link View}s synchronously on the UI thread, a View
+ * that requires information from other processes can struggle to meet those requests. Registering
+ * an instance of this class with {@link AccessibilityManager} allows a View to be notified when
+ * a request is about to be made, and to asynchronously inform the accessibility system when it is
+ * ready to meet the request.
+ * <p>
+ * <strong>Note:</strong> This class should only be needed in exceptional situations where a
+ * {@link View} cannot otherwise synchronously meet the request for accessibility data.
+ * @hide
+ */
+@TestApi
+public abstract class AccessibilityRequestPreparer {
+    public static final int REQUEST_TYPE_EXTRA_DATA = 0x00000001;
+
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                REQUEST_TYPE_EXTRA_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestTypes {}
+
+    private final WeakReference<View> mViewRef;
+    private final int mRequestTypes;
+
+    /**
+     * @param view The view whose requests need preparation. It must be attached to a
+     * window. This object will retain a weak reference to this view, and will unregister itself
+     * from AccessibilityManager if the view is detached from a window. It will not re-register
+     * itself.
+     * @param requestTypes The types of requests that require preparation. Different types may
+     * be ORed together.
+     *
+     * @throws IllegalStateException if the view is not attached to a window.
+     */
+    public AccessibilityRequestPreparer(View view, @RequestTypes int requestTypes) {
+        if (!view.isAttachedToWindow()) {
+            throw new IllegalStateException("View must be attached to a window");
+        }
+        mViewRef = new WeakReference<>(view);
+        mRequestTypes = requestTypes;
+        view.addOnAttachStateChangeListener(new ViewAttachStateListener());
+    }
+
+    /**
+     * Callback to allow preparation for filling extra data. Only called back if
+     * REQUEST_TYPE_EXTRA_DATA is requested.
+     *
+     * @param virtualViewId The ID of a virtual child node, if the {@link View} for this preparer
+     * supports virtual descendents, or {@link AccessibilityNodeProvider#HOST_VIEW_ID}
+     * if the request is for the view itself.
+     * @param extraDataKey The extra data key for the request
+     * @param args The arguments for the request
+     * @param preparationFinishedMessage A message that must be sent to its target when preparations
+     * are complete.
+     *
+     * @see View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, String, Bundle)
+     * @see AccessibilityDelegate#addExtraDataToAccessibilityNodeInfo(View, AccessibilityNodeInfo,
+     * String, Bundle)
+     * @see AccessibilityNodeProvider#addExtraDataToAccessibilityNodeInfo(
+     * int, AccessibilityNodeInfo, String, Bundle)
+     */
+    public abstract void onPrepareExtraData(int virtualViewId, String extraDataKey,
+            Bundle args, Message preparationFinishedMessage);
+
+    /**
+     * Get the view this object was created with.
+     *
+     * @return The view this object was created with, or {@code null} if the weak reference held
+     * to the view is no longer valid.
+     */
+    public @Nullable View getView() {
+        return mViewRef.get();
+    }
+
+    private class ViewAttachStateListener implements View.OnAttachStateChangeListener {
+        @Override
+        public void onViewAttachedToWindow(View v) {
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            Context context = v.getContext();
+            if (context != null) {
+                context.getSystemService(AccessibilityManager.class)
+                        .removeAccessibilityRequestPreparer(AccessibilityRequestPreparer.this);
+            }
+            v.removeOnAttachStateChangeListener(this);
+        }
+    }
+}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 5b04f41..c123a80 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -52,9 +52,64 @@
 import java.util.Objects;
 
 /**
- * App entry point to the Autofill Framework.
+ * The {@link AutofillManager} provides ways for apps and custom views to integrate with the
+ * Autofill Framework lifecycle.
  *
- * <p>It is safe to call into this from any thread.
+ * <p>The autofill lifecycle starts with the creation of an autofill context associated with an
+ * activity context; the autofill context is created when one of the following methods is called for
+ * the first time in an activity context, and the current user has an enabled autofill service:
+ *
+ * <ul>
+ *   <li>{@link #notifyViewEntered(View)}
+ *   <li>{@link #notifyViewEntered(View, int, Rect)}
+ *   <li>{@link #requestAutofill(View)}
+ * </ul>
+ *
+ * <p>Tipically, the context is automatically created when the first view of the activity is
+ * focused because {@code View.onFocusChanged()} indirectly calls
+ * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to
+ * explicitly create it (for example, a custom view developer could offer a contextual menu action
+ * in a text-field view to let users manually request autofill).
+ *
+ * <p>After the context is created, the Android System creates a {@link android.view.ViewStructure}
+ * that represents the view hierarchy by calling
+ * {@link View#dispatchProvideAutofillStructure(android.view.ViewStructure, int)} in the root views
+ * of all application windows. By default, {@code dispatchProvideAutofillStructure()} results in
+ * subsequent calls to {@link View#onProvideAutofillStructure(android.view.ViewStructure, int)} and
+ * {@link View#onProvideAutofillVirtualStructure(android.view.ViewStructure, int)} for each view in
+ * the hierarchy.
+ *
+ * <p>The resulting {@link android.view.ViewStructure} is then passed to the autofill service, which
+ * parses it looking for views that can be autofilled. If the service finds such views, it returns
+ * a data structure to the Android System containing the following optional info:
+ *
+ * <ul>
+ *   <li>Datasets used to autofill subsets of views in the activity.
+ *   <li>Id of views that the service can save their values for future autofilling.
+ * </ul>
+ *
+ * <p>When the service returns datasets, the Android System displays an autofill dataset picker
+ * UI affordance associated with the view, when the view is focused on and is part of a dataset.
+ * The application can be notified when the affordance is shown by registering an
+ * {@link AutofillCallback} through {@link #registerCallback(AutofillCallback)}. When the user
+ * selects a dataset from the affordance, all views present in the dataset are autofilled, through
+ * calls to {@link View#autofill(AutofillValue)} or {@link View#autofill(SparseArray)}.
+ *
+ * <p>When the service returns ids of savable views, the Android System keeps track of changes
+ * made to these views, so they can be used to determine if the autofill save UI is shown later.
+ *
+ * <p>The context is then finished when one of the following occurs:
+ *
+ * <ul>
+ *   <li>{@link #commit()} is called or all savable views are gone.
+ *   <li>{@link #cancel()} is called.
+ * </ul>
+ *
+ * <p>Finally, after the autofill context is commited (i.e., not cancelled), the Android System
+ * shows a save UI affordance if the value of savable views have changed. If the user selects the
+ * option to Save, the current value of the views is then sent to the autofill service.
+ *
+ * <p>It is safe to call into its methods from any thread.
  */
 @SystemService(Context.AUTOFILL_MANAGER_SERVICE)
 public final class AutofillManager {
@@ -671,8 +726,13 @@
     /**
      * Called to indicate the current autofill context should be commited.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method after the form is submitted and another page is rendered.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method after the form is submitted and
+     * another page is rendered.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void commit() {
         if (!hasAutofillFeature()) {
@@ -690,8 +750,13 @@
     /**
      * Called to indicate the current autofill context should be cancelled.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method if the user does not post the form but moves to another form in this page.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method if the user does not post the
+     * form but moves to another form in this page.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void cancel() {
         if (!hasAutofillFeature()) {
@@ -741,7 +806,8 @@
     }
 
     /**
-     * Returns {@code true} if Autofill is supported for this user.
+     * Returns {@code true} if autofill is supported by the current device and
+     * is supported for this user.
      *
      * <p>Autofill is typically supported, but it could be unsupported in cases like:
      * <ol>
@@ -1461,10 +1527,10 @@
     }
 
     /**
-     * Callback for auto-fill related events.
+     * Callback for autofill related events.
      *
      * <p>Typically used for applications that display their own "auto-complete" views, so they can
-     * enable / disable such views when the auto-fill UI affordance is shown / hidden.
+     * enable / disable such views when the autofill UI affordance is shown / hidden.
      */
     public abstract static class AutofillCallback {
 
@@ -1474,7 +1540,7 @@
         public @interface AutofillEventType {}
 
         /**
-         * The auto-fill input UI affordance associated with the view was shown.
+         * The autofill input UI affordance associated with the view was shown.
          *
          * <p>If the view provides its own auto-complete UI affordance and its currently shown, it
          * should be hidden upon receiving this event.
@@ -1482,7 +1548,7 @@
         public static final int EVENT_INPUT_SHOWN = 1;
 
         /**
-         * The auto-fill input UI affordance associated with the view was hidden.
+         * The autofill input UI affordance associated with the view was hidden.
          *
          * <p>If the view provides its own auto-complete UI affordance that was hidden upon a
          * {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
@@ -1490,7 +1556,7 @@
         public static final int EVENT_INPUT_HIDDEN = 2;
 
         /**
-         * The auto-fill input UI affordance associated with the view won't be shown because
+         * The autofill input UI affordance associated with the view isn't shown because
          * autofill is not available.
          *
          * <p>If the view provides its own auto-complete UI affordance but was not displaying it
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 2e2056c..779eefb 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -29,6 +29,8 @@
 import com.android.internal.textservice.ITextServicesManager;
 import com.android.internal.textservice.ITextServicesSessionListener;
 
+import dalvik.system.CloseGuard;
+
 import java.util.LinkedList;
 import java.util.Queue;
 
@@ -98,7 +100,7 @@
     private final SpellCheckerSessionListener mSpellCheckerSessionListener;
     private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
 
-    private boolean mIsUsed;
+    private final CloseGuard mGuard = CloseGuard.get();
 
     /** Handler that will execute the main tasks */
     private final Handler mHandler = new Handler() {
@@ -128,8 +130,9 @@
         mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
         mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
         mTextServicesManager = tsm;
-        mIsUsed = true;
         mSpellCheckerSessionListener = listener;
+
+        mGuard.open("finishSession");
     }
 
     /**
@@ -160,7 +163,7 @@
      * checker.
      */
     public void close() {
-        mIsUsed = false;
+        mGuard.close();
         try {
             mSpellCheckerSessionListenerImpl.close();
             mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
@@ -542,11 +545,14 @@
 
     @Override
     protected void finalize() throws Throwable {
-        super.finalize();
-        if (mIsUsed) {
-            Log.e(TAG, "SpellCheckerSession was not finished properly." +
-                    "You should call finishSession() when you finished to use a spell checker.");
-            close();
+        try {
+            // Note that mGuard will be null if the constructor threw.
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+                close();
+            }
+        } finally {
+            super.finalize();
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index dda5df6..a0b4a03 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -31,15 +31,15 @@
 import android.graphics.Picture;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.net.http.SslCertificate;
 import android.net.Uri;
+import android.net.http.SslCertificate;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.StrictMode;
 import android.os.RemoteException;
+import android.os.StrictMode;
 import android.print.PrintDocumentAdapter;
 import android.security.KeyChain;
 import android.util.AttributeSet;
@@ -49,10 +49,10 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewStructure;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewHierarchyEncoder;
+import android.view.ViewStructure;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -1621,6 +1621,25 @@
     }
 
     /**
+     * Starts Safe Browsing initialization. This should only be called once.
+     * @param context is the activity context the WebView will be used in.
+     * @param callback will be called with the value true if initialization is
+     * successful. The callback will be run on the UI thread.
+     * @hide
+     */
+    public static void initSafeBrowsing(Context context, ValueCallback<Boolean> callback) {
+        getFactory().getStatics().initSafeBrowsing(context, callback);
+    }
+
+    /**
+     * Shuts down Safe Browsing. This should only be called once.
+     * @hide
+     */
+    public static void shutdownSafeBrowsing() {
+        getFactory().getStatics().shutdownSafeBrowsing();
+    }
+
+    /**
      * Gets the WebBackForwardList for this WebView. This contains the
      * back/forward list for use in querying each item in the history stack.
      * This is a copy of the private WebBackForwardList so it contains only a
@@ -1939,12 +1958,12 @@
      * messages to a certain target origin. See
      * <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages">
      * HTML5 spec</a> for how target origin can be used.
+     * <p>
+     * A target origin can be set as a wildcard ("*"). However this is not recommended.
+     * See the page above for security issues.
      *
      * @param message the WebMessage
-     * @param targetOrigin the target origin. This is the origin of the page
-     *          that is intended to receive the message. For best security
-     *          practices, the user should not specify a wildcard (*) when
-     *          specifying the origin.
+     * @param targetOrigin the target origin.
      */
     public void postWebMessage(WebMessage message, Uri targetOrigin) {
         checkThread();
@@ -2648,6 +2667,18 @@
      * understood by the {@link android.service.autofill.AutofillService} implementations:
      *
      * <ol>
+     *   <li>Only the HTML nodes inside a {@code FORM} are generated.
+     *   <li>The source of the HTML is set using {@link ViewStructure#setWebDomain(String)} in the
+     *   node representing the WebView.
+     *   <li>If a web page has multiple {@code FORM}s, only the data for the current form is
+     *   represented&mdash;if the user taps a field from another form, then the current autofill
+     *   context is canceled (by calling {@link android.view.autofill.AutofillManager#cancel()} and
+     *   a new context is created for that {@code FORM}.
+     *   <li>Similarly, if the page has {@code IFRAME} nodes, they are not initially represented in
+     *   the view structure until the user taps a field from a {@code FORM} inside the
+     *   {@code IFRAME}, in which case it would be treated the same way as multiple forms described
+     *   above, except that the {@link ViewStructure#setWebDomain(String) web domain} of the
+     *   {@code FORM} contains the {@code src} attribute from the {@code IFRAME} node.
      *   <li>If the Android SDK provides a similar View, then should be set with the
      *   fully-qualified class name of such view.
      *   <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 71db6b1..1b6b392 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -107,6 +107,7 @@
     // error for namespace lookup
     public static final int LIBLOAD_FAILED_TO_FIND_NAMESPACE = 10;
 
+
     private static String getWebViewPreparationErrorReason(int error) {
         switch (error) {
             case LIBLOAD_FAILED_WAITING_FOR_RELRO:
@@ -119,10 +120,7 @@
         return "Unknown";
     }
 
-    /**
-     * @hide
-     */
-    public static class MissingWebViewPackageException extends AndroidRuntimeException {
+    private static class MissingWebViewPackageException extends Exception {
         public MissingWebViewPackageException(String message) { super(message); }
         public MissingWebViewPackageException(Exception e) { super(e); }
     }
@@ -184,11 +182,16 @@
             return LIBLOAD_WRONG_PACKAGE_NAME;
         }
 
-        int loadNativeRet = loadNativeLibrary(clazzLoader, packageInfo);
-        // If we failed waiting for relro we want to return that fact even if we successfully load
-        // the relro file.
-        if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
-        return loadNativeRet;
+        try {
+            int loadNativeRet = loadNativeLibrary(clazzLoader, packageInfo);
+            // If we failed waiting for relro we want to return that fact even if we successfully
+            // load the relro file.
+            if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
+            return loadNativeRet;
+        } catch (MissingWebViewPackageException e) {
+            Log.e(LOGTAG, "Couldn't load native library: " + e);
+            return LIBLOAD_FAILED_TO_LOAD_LIBRARY;
+        }
     }
 
     static WebViewFactoryProvider getProvider() {
@@ -259,7 +262,8 @@
     }
 
     // Throws MissingWebViewPackageException on failure
-    private static void verifyPackageInfo(PackageInfo chosen, PackageInfo toUse) {
+    private static void verifyPackageInfo(PackageInfo chosen, PackageInfo toUse)
+            throws MissingWebViewPackageException {
         if (!chosen.packageName.equals(toUse.packageName)) {
             throw new MissingWebViewPackageException("Failed to verify WebView provider, "
                     + "packageName mismatch, expected: "
@@ -285,7 +289,8 @@
      * required values from the donor package. If the ApplicationInfo is for a full WebView,
      * leave it alone. Throws MissingWebViewPackageException if the donor is missing.
      */
-    private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm) {
+    private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm)
+            throws MissingWebViewPackageException {
         String donorPackageName = null;
         if (ai.metaData != null) {
             donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage");
@@ -318,7 +323,7 @@
         }
     }
 
-    private static Context getWebViewContextAndSetProvider() {
+    private static Context getWebViewContextAndSetProvider() throws MissingWebViewPackageException {
         Application initialApplication = AppGlobals.getInitialApplication();
         try {
             WebViewProviderResponse response = null;
@@ -549,10 +554,10 @@
         return prepareWebViewInSystemServer(nativeLibs);
     }
 
-    // throws MissingWebViewPackageException
     private static String getLoadFromApkPath(String apkPath,
                                              String[] abiList,
-                                             String nativeLibFileName) {
+                                             String nativeLibFileName)
+            throws MissingWebViewPackageException {
         // Search the APK for a native library conforming to a listed ABI.
         try (ZipFile z = new ZipFile(apkPath)) {
             for (String abi : abiList) {
@@ -569,8 +574,8 @@
         return "";
     }
 
-    // throws MissingWebViewPackageException
-    private static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo) {
+    private static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo)
+            throws MissingWebViewPackageException {
         ApplicationInfo ai = packageInfo.applicationInfo;
         final String NATIVE_LIB_FILE_NAME = getWebViewLibrary(ai);
 
@@ -695,7 +700,8 @@
     }
 
     // Assumes that we have waited for relro creation
-    private static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo) {
+    private static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo)
+            throws MissingWebViewPackageException {
         if (!sAddressSpaceReserved) {
             Log.e(LOGTAG, "can't load with relro file; address space not reserved");
             return LIBLOAD_ADDRESS_SPACE_NOT_RESERVED;
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 8359a10..00fdac8 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -74,6 +74,22 @@
          * {@link android.webkit.WebChromeClient.FileChooserParams#parseResult(int, Intent)}
          */
         Uri[] parseFileChooserResult(int resultCode, Intent intent);
+
+        /**
+         * Implement the API method
+         * {@link android.webkit.WebView#initSafeBrowsing(Context , ValueCallback<Boolean>)}
+         * @hide
+         */
+        default void initSafeBrowsing(Context context, ValueCallback<Boolean> callback) {
+        }
+
+        /**
+         * Implement the API method
+         * {@link android.webkit.WebView#shutdownSafeBrowsing()}
+         * @hide
+         */
+        default void shutdownSafeBrowsing() {
+        }
     }
 
     Statics getStatics();
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index b519ec9..0204dff 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -218,7 +218,7 @@
             final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
                     TextUtils.join(File.pathSeparator, zipPaths);
 
-            waitForZygote();
+            ZygoteProcess.waitForConnectionToZygote(WEBVIEW_ZYGOTE_SOCKET);
 
             Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
             sZygote.preloadPackageForAbi(zip, librarySearchPath, sPackageCacheKey,
@@ -228,25 +228,4 @@
             sZygote = null;
         }
     }
-
-    /**
-     * Wait until a connection to the Zygote can be established.
-     */
-    private static void waitForZygote() {
-        while (true) {
-            try {
-                final ZygoteProcess.ZygoteState zs =
-                        ZygoteProcess.ZygoteState.connect(WEBVIEW_ZYGOTE_SOCKET);
-                zs.close();
-                break;
-            } catch (IOException ioe) {
-                Log.w(LOGTAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ie) {
-            }
-        }
-    }
 }
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 98d8a13..f9f5901 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -59,7 +59,8 @@
     // Time it will take in ms for a pulled glow to decay to partial strength before release
     private static final int PULL_DECAY_TIME = 2000;
 
-    private static final float MAX_ALPHA = 0.5f;
+    private static final float MAX_ALPHA = 0.15f;
+    private static final float GLOW_ALPHA_START = .09f;
 
     private static final float MAX_GLOW_SCALE = 2.f;
 
@@ -75,6 +76,7 @@
     private static final double ANGLE = Math.PI / 6;
     private static final float SIN = (float) Math.sin(ANGLE);
     private static final float COS = (float) Math.cos(ANGLE);
+    private static final float RADIUS_FACTOR = 0.6f;
 
     private float mGlowAlpha;
     private float mGlowScaleY;
@@ -134,10 +136,10 @@
      * @param height Effect height in pixels
      */
     public void setSize(int width, int height) {
-        final float r = width * 0.75f / SIN;
+        final float r = width * RADIUS_FACTOR / SIN;
         final float y = COS * r;
         final float h = r - y;
-        final float or = height * 0.75f / SIN;
+        final float or = height * RADIUS_FACTOR / SIN;
         final float oy = COS * or;
         final float oh = or - oy;
 
@@ -272,7 +274,7 @@
 
         // The glow depends more on the velocity, and therefore starts out
         // nearly invisible.
-        mGlowAlphaStart = 0.3f;
+        mGlowAlphaStart = GLOW_ALPHA_START;
         mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
 
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 45e5f8a..6374aa2 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3909,25 +3909,30 @@
             menu.removeItem(TextView.ID_ASSIST);
             final TextClassification textClassification =
                     getSelectionActionModeHelper().getTextClassification();
-            if (textClassification != null) {
-                final Drawable icon = textClassification.getIcon();
-                final CharSequence label = textClassification.getLabel();
-                final OnClickListener onClickListener =
-                        textClassification.getOnClickListener();
-                final Intent intent = textClassification.getIntent();
-                if ((icon != null || !TextUtils.isEmpty(label))
-                        && (onClickListener != null || intent != null)) {
-                    menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
-                            .setIcon(icon)
-                            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-                    mMetricsLogger.write(
-                            new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST)
-                                    .setType(MetricsEvent.TYPE_OPEN)
-                                    .setSubtype(textClassification.getLogType()));
-                }
+            if (canAssist()) {
+                menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST,
+                        textClassification.getLabel())
+                        .setIcon(textClassification.getIcon())
+                        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+                mMetricsLogger.write(
+                        new LogMaker(MetricsEvent.TEXT_SELECTION_MENU_ITEM_ASSIST)
+                                .setType(MetricsEvent.TYPE_OPEN)
+                                .setSubtype(textClassification.getLogType()));
             }
         }
 
+        private boolean canAssist() {
+            final TextClassification textClassification =
+                    getSelectionActionModeHelper().getTextClassification();
+            return mTextView.isDeviceProvisioned()
+                    && textClassification != null
+                    && (textClassification.getIcon() != null
+                            || !TextUtils.isEmpty(textClassification.getLabel()))
+                    && (textClassification.getOnClickListener() != null
+                            || (textClassification.getIntent() != null
+                                    && mTextView.getContext().canStartActivityForResult()));
+        }
+
         @Override
         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
             getSelectionActionModeHelper().onSelectionAction();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index aa6ffce..6e62351 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -99,6 +99,26 @@
      */
     private static final int MAX_NESTED_VIEWS = 10;
 
+    // The unique identifiers for each custom {@link Action}.
+    private static final int SET_ON_CLICK_PENDING_INTENT_TAG = 1;
+    private static final int REFLECTION_ACTION_TAG = 2;
+    private static final int SET_DRAWABLE_PARAMETERS_TAG = 3;
+    private static final int VIEW_GROUP_ACTION_ADD_TAG = 4;
+    private static final int SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG = 5;
+    private static final int SET_EMPTY_VIEW_ACTION_TAG = 6;
+    private static final int VIEW_GROUP_ACTION_REMOVE_TAG = 7;
+    private static final int SET_PENDING_INTENT_TEMPLATE_TAG = 8;
+    private static final int SET_ON_CLICK_FILL_IN_INTENT_TAG = 9;
+    private static final int SET_REMOTE_VIEW_ADAPTER_INTENT_TAG = 10;
+    private static final int TEXT_VIEW_DRAWABLE_ACTION_TAG = 11;
+    private static final int BITMAP_REFLECTION_ACTION_TAG = 12;
+    private static final int TEXT_VIEW_SIZE_ACTION_TAG = 13;
+    private static final int VIEW_PADDING_ACTION_TAG = 14;
+    private static final int SET_REMOTE_VIEW_ADAPTER_LIST_TAG = 15;
+    private static final int TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG = 17;
+    private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18;
+    private static final int LAYOUT_PARAM_ACTION_TAG = 19;
+
     /**
      * Application that hosts the remote views.
      *
@@ -179,6 +199,22 @@
     }
 
     /**
+     * Reduces all images and ensures that they are all below the given sizes.
+     *
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @hide
+     */
+    public void reduceImageSizes(int maxWidth, int maxHeight) {
+        ArrayList<Bitmap> cache = mBitmapCache.mBitmaps;
+        for (int i = 0; i < cache.size(); i++) {
+            Bitmap bitmap = cache.get(i);
+            cache.set(i, Icon.scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
+        }
+    }
+
+    /**
      * Handle with care!
      */
     static class MutablePair<F, S> {
@@ -441,8 +477,6 @@
         int viewId;
         int emptyViewId;
 
-        public final static int TAG = 6;
-
         SetEmptyView(int viewId, int emptyViewId) {
             this.viewId = viewId;
             this.emptyViewId = emptyViewId;
@@ -454,7 +488,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(SET_EMPTY_VIEW_ACTION_TAG);
             out.writeInt(this.viewId);
             out.writeInt(this.emptyViewId);
         }
@@ -489,7 +523,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_ON_CLICK_FILL_IN_INTENT_TAG);
             dest.writeInt(viewId);
             fillInIntent.writeToParcel(dest, 0 /* no flags */);
         }
@@ -555,8 +589,6 @@
         }
 
         Intent fillInIntent;
-
-        public final static int TAG = 9;
     }
 
     private class SetPendingIntentTemplate extends Action {
@@ -571,7 +603,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_PENDING_INTENT_TEMPLATE_TAG);
             dest.writeInt(viewId);
             pendingIntentTemplate.writeToParcel(dest, 0 /* no flags */);
         }
@@ -632,8 +664,6 @@
         }
 
         PendingIntent pendingIntentTemplate;
-
-        public final static int TAG = 8;
     }
 
     private class SetRemoteViewsAdapterList extends Action {
@@ -656,7 +686,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_VIEW_ADAPTER_LIST_TAG);
             dest.writeInt(viewId);
             dest.writeInt(viewTypeCount);
 
@@ -715,7 +745,6 @@
 
         int viewTypeCount;
         ArrayList<RemoteViews> list;
-        public final static int TAG = 15;
     }
 
     private class SetRemoteViewsAdapterIntent extends Action {
@@ -730,7 +759,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_VIEW_ADAPTER_INTENT_TAG);
             dest.writeInt(viewId);
             intent.writeToParcel(dest, flags);
         }
@@ -782,8 +811,6 @@
 
         Intent intent;
         boolean isAsync = false;
-
-        public final static int TAG = 10;
     }
 
     /**
@@ -807,7 +834,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_ON_CLICK_PENDING_INTENT_TAG);
             dest.writeInt(viewId);
 
             // We use a flag to indicate whether the parcel contains a valid object.
@@ -860,8 +887,6 @@
         }
 
         PendingIntent pendingIntent;
-
-        public final static int TAG = 1;
     }
 
     private static Rect getSourceBounds(View v) {
@@ -997,7 +1022,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_DRAWABLE_PARAMETERS_TAG);
             dest.writeInt(viewId);
             dest.writeInt(targetBackground ? 1 : 0);
             dest.writeInt(alpha);
@@ -1048,15 +1073,11 @@
         int colorFilter;
         PorterDuff.Mode filterMode;
         int level;
-
-        public final static int TAG = 3;
     }
 
     private final class ReflectionActionWithoutParams extends Action {
         final String methodName;
 
-        public final static int TAG = 5;
-
         ReflectionActionWithoutParams(int viewId, String methodName) {
             this.viewId = viewId;
             this.methodName = methodName;
@@ -1068,7 +1089,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG);
             out.writeInt(this.viewId);
             out.writeString(this.methodName);
         }
@@ -1192,7 +1213,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(BITMAP_REFLECTION_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeString(methodName);
             dest.writeInt(bitmapId);
@@ -1214,16 +1235,12 @@
         public String getActionName() {
             return "BitmapReflectionAction";
         }
-
-        public final static int TAG = 12;
     }
 
     /**
      * Base class for the reflection actions.
      */
     private final class ReflectionAction extends Action {
-        static final int TAG = 2;
-
         static final int BOOLEAN = 1;
         static final int BYTE = 2;
         static final int SHORT = 3;
@@ -1330,7 +1347,7 @@
         }
 
         public void writeToParcel(Parcel out, int flags) {
-            out.writeInt(TAG);
+            out.writeInt(REFLECTION_ACTION_TAG);
             out.writeInt(this.viewId);
             out.writeString(this.methodName);
             out.writeInt(this.type);
@@ -1555,137 +1572,222 @@
     }
 
     /**
-     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
-     * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
-     * when null. This allows users to build "nested" {@link RemoteViews}.
+     * ViewGroup methods that are related to adding Views.
      */
-    private class ViewGroupAction extends Action {
-        public ViewGroupAction(int viewId, RemoteViews nestedViews) {
+    private class ViewGroupActionAdd extends Action {
+        private RemoteViews mNestedViews;
+        private int mIndex;
+
+        ViewGroupActionAdd(int viewId, RemoteViews nestedViews) {
+            this(viewId, nestedViews, -1 /* index */);
+        }
+
+        ViewGroupActionAdd(int viewId, RemoteViews nestedViews, int index) {
             this.viewId = viewId;
-            this.nestedViews = nestedViews;
+            mNestedViews = nestedViews;
+            mIndex = index;
             if (nestedViews != null) {
                 configureRemoteViewsAsChild(nestedViews);
             }
         }
 
-        ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) {
+        ViewGroupActionAdd(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info,
+                int depth) {
             viewId = parcel.readInt();
-            boolean nestedViewsNull = parcel.readInt() == 0;
-            if (!nestedViewsNull) {
-                nestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
-            } else {
-                nestedViews = null;
-            }
+            mIndex = parcel.readInt();
+            mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth);
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(VIEW_GROUP_ACTION_ADD_TAG);
             dest.writeInt(viewId);
-            if (nestedViews != null) {
-                dest.writeInt(1);
-                nestedViews.writeToParcel(dest, flags);
-            } else {
-                // signifies null
-                dest.writeInt(0);
-            }
+            dest.writeInt(mIndex);
+            mNestedViews.writeToParcel(dest, flags);
         }
 
         @Override
         public boolean hasSameAppInfo(ApplicationInfo parentInfo) {
-            return nestedViews != null
-                    && nestedViews.mApplication.packageName.equals(parentInfo.packageName)
-                    && nestedViews.mApplication.uid == parentInfo.uid;
+            return mNestedViews.mApplication.packageName.equals(parentInfo.packageName)
+                    && mNestedViews.mApplication.uid == parentInfo.uid;
         }
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
             final Context context = root.getContext();
             final ViewGroup target = root.findViewById(viewId);
-            if (target == null) return;
-            if (nestedViews != null) {
-                // Inflate nested views and add as children
-                target.addView(nestedViews.apply(context, target, handler));
-            } else {
-                // Clear all children when nested views omitted
-                target.removeAllViews();
+
+            if (target == null) {
+                return;
             }
+
+            // Inflate nested views and add as children
+            target.addView(mNestedViews.apply(context, target, handler), mIndex);
         }
 
         @Override
         public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
             // In the async implementation, update the view tree so that subsequent calls to
-            // findViewById return the currect view.
+            // findViewById return the current view.
             root.createTree();
             ViewTree target = root.findViewTreeById(viewId);
             if ((target == null) || !(target.mRoot instanceof ViewGroup)) {
                 return ACTION_NOOP;
             }
             final ViewGroup targetVg = (ViewGroup) target.mRoot;
-            if (nestedViews == null) {
-                // Clear all children when nested views omitted
-                target.mChildren = null;
-                return new RuntimeAction() {
-                    @Override
-                    public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
-                            throws ActionException {
-                        targetVg.removeAllViews();
-                    }
-                };
-            } else {
-                // Inflate nested views and perform all the async tasks for the child remoteView.
-                final Context context = root.mRoot.getContext();
-                final AsyncApplyTask task = nestedViews.getAsyncApplyTask(
-                        context, targetVg, null, handler);
-                final ViewTree tree = task.doInBackground();
-                if (tree == null) {
-                    throw new ActionException(task.mError);
-                }
 
-                // Update the global view tree, so that next call to findViewTreeById
-                // goes through the subtree as well.
-                target.addChild(tree);
+            // Inflate nested views and perform all the async tasks for the child remoteView.
+            final Context context = root.mRoot.getContext();
+            final AsyncApplyTask task = mNestedViews.getAsyncApplyTask(
+                    context, targetVg, null, handler);
+            final ViewTree tree = task.doInBackground();
 
-                return new RuntimeAction() {
-
-                    @Override
-                    public void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException {
-                        task.onPostExecute(tree);
-                        targetVg.addView(task.mResult);
-                    }
-                };
+            if (tree == null) {
+                throw new ActionException(task.mError);
             }
+
+            // Update the global view tree, so that next call to findViewTreeById
+            // goes through the subtree as well.
+            target.addChild(tree, mIndex);
+
+            return new RuntimeAction() {
+                @Override
+                public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
+                        throws ActionException {
+                    task.onPostExecute(tree);
+                    targetVg.addView(task.mResult, mIndex);
+                }
+            };
         }
 
         @Override
         public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
-            if (nestedViews != null) {
-                counter.increment(nestedViews.estimateMemoryUsage());
-            }
+            counter.increment(mNestedViews.estimateMemoryUsage());
         }
 
         @Override
         public void setBitmapCache(BitmapCache bitmapCache) {
-            if (nestedViews != null) {
-                nestedViews.setBitmapCache(bitmapCache);
-            }
+            mNestedViews.setBitmapCache(bitmapCache);
         }
 
-        public String getActionName() {
-            return "ViewGroupAction" + (nestedViews == null ? "Remove" : "Add");
-        }
-
+        @Override
         public int mergeBehavior() {
             return MERGE_APPEND;
         }
 
         @Override
         public boolean prefersAsyncApply() {
-            return nestedViews != null && nestedViews.prefersAsyncApply();
+            return mNestedViews.prefersAsyncApply();
         }
 
-        RemoteViews nestedViews;
 
-        public final static int TAG = 4;
+        @Override
+        public String getActionName() {
+            return "ViewGroupActionAdd";
+        }
+    }
+
+    /**
+     * ViewGroup methods related to removing child views.
+     */
+    private class ViewGroupActionRemove extends Action {
+        /**
+         * Id that indicates that all child views of the affected ViewGroup should be removed.
+         *
+         * <p>Using -2 because the default id is -1. This avoids accidentally matching that.
+         */
+        private static final int REMOVE_ALL_VIEWS_ID = -2;
+
+        private int mViewIdToKeep;
+
+        ViewGroupActionRemove(int viewId) {
+            this(viewId, REMOVE_ALL_VIEWS_ID);
+        }
+
+        ViewGroupActionRemove(int viewId, int viewIdToKeep) {
+            this.viewId = viewId;
+            mViewIdToKeep = viewIdToKeep;
+        }
+
+        ViewGroupActionRemove(Parcel parcel) {
+            viewId = parcel.readInt();
+            mViewIdToKeep = parcel.readInt();
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(VIEW_GROUP_ACTION_REMOVE_TAG);
+            dest.writeInt(viewId);
+            dest.writeInt(mViewIdToKeep);
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+            final ViewGroup target = root.findViewById(viewId);
+
+            if (target == null) {
+                return;
+            }
+
+            if (mViewIdToKeep == REMOVE_ALL_VIEWS_ID) {
+                target.removeAllViews();
+                return;
+            }
+
+            removeAllViewsExceptIdToKeep(target);
+        }
+
+        @Override
+        public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
+            // In the async implementation, update the view tree so that subsequent calls to
+            // findViewById return the current view.
+            root.createTree();
+            ViewTree target = root.findViewTreeById(viewId);
+
+            if ((target == null) || !(target.mRoot instanceof ViewGroup)) {
+                return ACTION_NOOP;
+            }
+
+            final ViewGroup targetVg = (ViewGroup) target.mRoot;
+
+            // Clear all children when nested views omitted
+            target.mChildren = null;
+            return new RuntimeAction() {
+                @Override
+                public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
+                        throws ActionException {
+                    if (mViewIdToKeep == REMOVE_ALL_VIEWS_ID) {
+                        targetVg.removeAllViews();
+                        return;
+                    }
+
+                    removeAllViewsExceptIdToKeep(targetVg);
+                }
+            };
+        }
+
+        /**
+         * Iterates through the children in the given ViewGroup and removes all the views that
+         * do not have an id of {@link #mViewIdToKeep}.
+         */
+        private void removeAllViewsExceptIdToKeep(ViewGroup viewGroup) {
+            // Otherwise, remove all the views that do not match the id to keep.
+            int index = viewGroup.getChildCount() - 1;
+            while (index >= 0) {
+                if (viewGroup.getChildAt(index).getId() != mViewIdToKeep) {
+                    viewGroup.removeViewAt(index);
+                }
+                index--;
+            }
+        }
+
+        @Override
+        public String getActionName() {
+            return "ViewGroupActionRemove";
+        }
+
+        @Override
+        public int mergeBehavior() {
+            return MERGE_APPEND;
+        }
     }
 
     /**
@@ -1740,7 +1842,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_DRAWABLE_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(isRelative ? 1 : 0);
             dest.writeInt(useIcons ? 1 : 0);
@@ -1850,8 +1952,6 @@
 
         boolean drawablesLoaded = false;
         Drawable id1, id2, id3, id4;
-
-        public final static int TAG = 11;
     }
 
     /**
@@ -1871,7 +1971,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_SIZE_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(units);
             dest.writeFloat(size);
@@ -1890,8 +1990,6 @@
 
         int units;
         float size;
-
-        public final static int TAG = 13;
     }
 
     /**
@@ -1915,7 +2013,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(VIEW_PADDING_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(left);
             dest.writeInt(top);
@@ -1935,8 +2033,6 @@
         }
 
         int left, top, right, bottom;
-
-        public final static int TAG = 14;
     }
 
     /**
@@ -1968,7 +2064,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(LAYOUT_PARAM_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(property);
             dest.writeInt(value);
@@ -2021,8 +2117,6 @@
 
         int property;
         int value;
-
-        public final static int TAG = 19;
     }
 
     /**
@@ -2057,7 +2151,7 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeInt(isRelative ? 1 : 0);
             dest.writeInt(index);
@@ -2090,8 +2184,6 @@
         final int index;
         final int color;
         final PorterDuff.Mode mode;
-
-        public final static int TAG = 17;
     }
 
     /**
@@ -2110,14 +2202,14 @@
         }
 
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(TAG);
+            dest.writeInt(SET_REMOTE_INPUTS_ACTION_TAG);
             dest.writeInt(viewId);
             dest.writeTypedArray(remoteInputs, flags);
         }
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = (TextView) root.findViewById(viewId);
+            final View target = root.findViewById(viewId);
             if (target == null) return;
 
             target.setTagInternal(R.id.remote_input_tag, remoteInputs);
@@ -2128,7 +2220,6 @@
         }
 
         final Parcelable[] remoteInputs;
-        public final static int TAG = 18;
     }
 
     /**
@@ -2271,56 +2362,59 @@
                 for (int i=0; i<count; i++) {
                     int tag = parcel.readInt();
                     switch (tag) {
-                        case SetOnClickPendingIntent.TAG:
+                        case SET_ON_CLICK_PENDING_INTENT_TAG:
                             mActions.add(new SetOnClickPendingIntent(parcel));
                             break;
-                        case SetDrawableParameters.TAG:
+                        case SET_DRAWABLE_PARAMETERS_TAG:
                             mActions.add(new SetDrawableParameters(parcel));
                             break;
-                        case ReflectionAction.TAG:
+                        case REFLECTION_ACTION_TAG:
                             mActions.add(new ReflectionAction(parcel));
                             break;
-                        case ViewGroupAction.TAG:
-                            mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication,
+                        case VIEW_GROUP_ACTION_ADD_TAG:
+                            mActions.add(new ViewGroupActionAdd(parcel, mBitmapCache, mApplication,
                                     depth));
                             break;
-                        case ReflectionActionWithoutParams.TAG:
+                        case VIEW_GROUP_ACTION_REMOVE_TAG:
+                            mActions.add(new ViewGroupActionRemove(parcel));
+                            break;
+                        case SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG:
                             mActions.add(new ReflectionActionWithoutParams(parcel));
                             break;
-                        case SetEmptyView.TAG:
+                        case SET_EMPTY_VIEW_ACTION_TAG:
                             mActions.add(new SetEmptyView(parcel));
                             break;
-                        case SetPendingIntentTemplate.TAG:
+                        case SET_PENDING_INTENT_TEMPLATE_TAG:
                             mActions.add(new SetPendingIntentTemplate(parcel));
                             break;
-                        case SetOnClickFillInIntent.TAG:
+                        case SET_ON_CLICK_FILL_IN_INTENT_TAG:
                             mActions.add(new SetOnClickFillInIntent(parcel));
                             break;
-                        case SetRemoteViewsAdapterIntent.TAG:
+                        case SET_REMOTE_VIEW_ADAPTER_INTENT_TAG:
                             mActions.add(new SetRemoteViewsAdapterIntent(parcel));
                             break;
-                        case TextViewDrawableAction.TAG:
+                        case TEXT_VIEW_DRAWABLE_ACTION_TAG:
                             mActions.add(new TextViewDrawableAction(parcel));
                             break;
-                        case TextViewSizeAction.TAG:
+                        case TEXT_VIEW_SIZE_ACTION_TAG:
                             mActions.add(new TextViewSizeAction(parcel));
                             break;
-                        case ViewPaddingAction.TAG:
+                        case VIEW_PADDING_ACTION_TAG:
                             mActions.add(new ViewPaddingAction(parcel));
                             break;
-                        case BitmapReflectionAction.TAG:
+                        case BITMAP_REFLECTION_ACTION_TAG:
                             mActions.add(new BitmapReflectionAction(parcel));
                             break;
-                        case SetRemoteViewsAdapterList.TAG:
+                        case SET_REMOTE_VIEW_ADAPTER_LIST_TAG:
                             mActions.add(new SetRemoteViewsAdapterList(parcel));
                             break;
-                        case TextViewDrawableColorFilterAction.TAG:
+                        case TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG:
                             mActions.add(new TextViewDrawableColorFilterAction(parcel));
                             break;
-                        case SetRemoteInputsAction.TAG:
+                        case SET_REMOTE_INPUTS_ACTION_TAG:
                             mActions.add(new SetRemoteInputsAction(parcel));
                             break;
-                        case LayoutParamAction.TAG:
+                        case LAYOUT_PARAM_ACTION_TAG:
                             mActions.add(new LayoutParamAction(parcel));
                             break;
                         default:
@@ -2471,7 +2565,23 @@
      * @param nestedView {@link RemoteViews} that describes the child.
      */
     public void addView(int viewId, RemoteViews nestedView) {
-        addAction(new ViewGroupAction(viewId, nestedView));
+        addAction(nestedView == null
+                ? new ViewGroupActionRemove(viewId)
+                : new ViewGroupActionAdd(viewId, nestedView));
+    }
+
+    /**
+     * Equivalent to calling {@link ViewGroup#addView(View, int)} after inflating the
+     * given {@link RemoteViews}.
+     *
+     * @param viewId The id of the parent {@link ViewGroup} to add the child into.
+     * @param nestedView {@link RemoveViews} of the child to add.
+     * @param index The position at which to add the child.
+     *
+     * @hide
+     */
+    public void addView(int viewId, RemoteViews nestedView, int index) {
+        addAction(new ViewGroupActionAdd(viewId, nestedView, index));
     }
 
     /**
@@ -2481,7 +2591,20 @@
      *            children from.
      */
     public void removeAllViews(int viewId) {
-        addAction(new ViewGroupAction(viewId, null));
+        addAction(new ViewGroupActionRemove(viewId));
+    }
+
+    /**
+     * Removes all views in the {@link ViewGroup} specified by the {@code viewId} except for any
+     * child that has the {@code viewIdToKeep} as its id.
+     *
+     * @param viewId The id of the parent {@link ViewGroup} to remove children from.
+     * @param viewIdToKeep The id of a child that should not be removed.
+     *
+     * @hide
+     */
+    public void removeAllViewsExceptId(int viewId, int viewIdToKeep) {
+        addAction(new ViewGroupActionRemove(viewId, viewIdToKeep));
     }
 
     /**
@@ -3654,8 +3777,8 @@
      * and can be searched.
      */
     private static class ViewTree {
+        private static final int INSERT_AT_END_INDEX = -1;
         private View mRoot;
-
         private ArrayList<ViewTree> mChildren;
 
         private ViewTree(View root) {
@@ -3708,11 +3831,26 @@
         }
 
         public void addChild(ViewTree child) {
+            addChild(child, INSERT_AT_END_INDEX);
+        }
+
+        /**
+         * Adds the given {@link ViewTree} as a child at the given index.
+         *
+         * @param index The position at which to add the child or -1 to add last.
+         */
+        public void addChild(ViewTree child, int index) {
             if (mChildren == null) {
                 mChildren = new ArrayList<>();
             }
             child.createTree();
-            mChildren.add(child);
+
+            if (index == INSERT_AT_END_INDEX) {
+                mChildren.add(child);
+                return;
+            }
+
+            mChildren.add(index, child);
         }
 
         private void addViewChild(View v) {
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
index 11b7514d..0cf8faa 100644
--- a/core/java/android/widget/TextInputTimePickerView.java
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.content.Context;
+import android.os.LocaleList;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.TextWatcher;
@@ -141,6 +142,9 @@
                 new InputFilter.LengthFilter(maxCharLength)});
         mMinuteEditText.setFilters(new InputFilter[] {
                 new InputFilter.LengthFilter(maxCharLength)});
+        final LocaleList locales = mContext.getResources().getConfiguration().getLocales();
+        mHourEditText.setImeHintLocales(locales);
+        mMinuteEditText.setImeHintLocales(locales);
     }
 
     boolean validateInput() {
diff --git a/core/java/com/android/internal/alsa/AlsaCardsParser.java b/core/java/com/android/internal/alsa/AlsaCardsParser.java
index 17e8c9c..5b92a17 100644
--- a/core/java/com/android/internal/alsa/AlsaCardsParser.java
+++ b/core/java/com/android/internal/alsa/AlsaCardsParser.java
@@ -49,7 +49,7 @@
 
         public AlsaCardRecord() {}
 
-        public boolean parse(String line, int lineIndex) {
+        private boolean parse(String line, int lineIndex) {
             int tokenIndex = 0;
             int delimIndex = 0;
 
@@ -258,7 +258,7 @@
     //
     // Logging
     //
-    public void Log(String heading) {
+    private void Log(String heading) {
         if (DEBUG) {
             Slog.i(TAG, heading);
             for (AlsaCardRecord cardRec : mCardRecords) {
@@ -267,7 +267,7 @@
         }
     }
 
-    static public void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
+    static private void LogDevices(String caption, ArrayList<AlsaCardRecord> deviceList) {
         Slog.d(TAG, caption + " ----------------");
         int listIndex = 0;
         for (AlsaCardRecord device : deviceList) {
diff --git a/core/java/com/android/internal/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
index 5203723..7cdd897 100644
--- a/core/java/com/android/internal/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -155,6 +155,7 @@
 
             switch (mDeviceType) {
             case kDeviceType_Unknown:
+            default:
                 sb.append(" N/A");
                 break;
             case kDeviceType_Audio:
@@ -170,6 +171,7 @@
 
             switch (mDeviceDir) {
             case kDeviceDir_Unknown:
+            default:
                 sb.append(" N/A");
                 break;
             case kDeviceDir_Capture:
@@ -282,7 +284,7 @@
     //
     // Loging
     //
-    public void Log(String heading) {
+    private void Log(String heading) {
         if (DEBUG) {
             Slog.i(TAG, heading);
             for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
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/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 35d4ba8..7a119b4 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -48,4 +48,6 @@
     void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
     void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages);
     void removeUser(int userHandle);
+
+    boolean isOperationActive(int code, int uid, String packageName);
 }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 04f7c76..a44fd67 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -130,7 +130,7 @@
     long getAwakeTimePlugged();
 
     void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
-    void noteBleScanStopped(in WorkSource ws);
+    void noteBleScanStopped(in WorkSource ws, boolean isUnoptimized);
     void noteResetBleScan();
     void noteBleScanResults(in WorkSource ws, int numNewResults);
 
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index f4c18c3..1bee692 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.app.PendingIntent;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
 import android.os.ParcelUuid;
@@ -26,7 +27,6 @@
  */
 interface ISoundTriggerService {
 
-
     SoundTrigger.GenericSoundModel getSoundModel(in ParcelUuid soundModelId);
 
     void updateSoundModel(in SoundTrigger.GenericSoundModel soundModel);
@@ -36,8 +36,17 @@
     int startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback,
          in SoundTrigger.RecognitionConfig config);
 
-    /**
-     * Stops recognition.
-     */
     int stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+
+    int loadGenericSoundModel(in SoundTrigger.GenericSoundModel soundModel);
+    int loadKeyphraseSoundModel(in SoundTrigger.KeyphraseSoundModel soundModel);
+
+    int startRecognitionForIntent(in ParcelUuid soundModelId, in PendingIntent callbackIntent,
+         in SoundTrigger.RecognitionConfig config);
+
+    int stopRecognitionForIntent(in ParcelUuid soundModelId);
+
+    int unloadSoundModel(in ParcelUuid soundModelId);
+
+    boolean isRecognitionActive(in ParcelUuid parcelUuid);
 }
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 0b27c60..398d087 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -16,16 +16,14 @@
 
 package com.android.internal.app;
 
-import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
-
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -34,8 +32,12 @@
 import android.util.Slog;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.List;
 
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+
 /**
  * This is used in conjunction with
  * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to
@@ -51,15 +53,17 @@
     public static String FORWARD_INTENT_TO_MANAGED_PROFILE
             = "com.android.internal.app.ForwardIntentToManagedProfile";
 
+    private Injector mInjector;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Intent intentReceived = getIntent();
+        mInjector = createInjector();
 
+        Intent intentReceived = getIntent();
         String className = intentReceived.getComponent().getClassName();
         final int targetUserId;
         final int userMessageId;
-
         if (className.equals(FORWARD_INTENT_TO_PARENT)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_owner;
             targetUserId = getProfileParent();
@@ -76,17 +80,12 @@
             finish();
             return;
         }
-        Intent newIntent = new Intent(intentReceived);
-        newIntent.setComponent(null);
-        // Apps should not be allowed to target a specific package in the target user.
-        newIntent.setPackage(null);
-        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
-                |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
-        int callingUserId = getUserId();
 
-        if (canForward(newIntent, targetUserId)) {
+        final int callingUserId = getUserId();
+        final Intent newIntent = canForward(intentReceived, targetUserId);
+        if (newIntent != null) {
             if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) {
-                Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+                Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
                 // At this point, innerIntent is not null. Otherwise, canForward would have returned
                 // false.
                 innerIntent.prepareToLeaveUser(callingUserId);
@@ -94,15 +93,18 @@
                 newIntent.prepareToLeaveUser(callingUserId);
             }
 
-            final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
-                        newIntent, MATCH_DEFAULT_ONLY, targetUserId);
+            final android.content.pm.ResolveInfo ri =
+                    mInjector.getPackageManager().resolveActivityAsUser(
+                            newIntent,
+                            MATCH_DEFAULT_ONLY,
+                            targetUserId);
 
             // Don't show the disclosure if next activity is ResolverActivity or ChooserActivity
             // as those will already have shown work / personal as neccesary etc.
             final boolean shouldShowDisclosure = ri == null || ri.activityInfo == null ||
                     !"android".equals(ri.activityInfo.packageName) ||
                     !(ResolverActivity.class.getName().equals(ri.activityInfo.name)
-                    || ChooserActivity.class.getName().equals(ri.activityInfo.name));
+                            || ChooserActivity.class.getName().equals(ri.activityInfo.name));
 
             try {
                 startActivityAsCaller(newIntent, null, false, targetUserId);
@@ -126,44 +128,56 @@
                 Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
             }
         } else {
-            Slog.wtf(TAG, "the intent: " + newIntent + " cannot be forwarded from user "
+            Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
                     + callingUserId + " to user " + targetUserId);
         }
         finish();
     }
 
-    boolean canForward(Intent intent, int targetUserId)  {
-        IPackageManager ipm = AppGlobals.getPackageManager();
-        if (Intent.ACTION_CHOOSER.equals(intent.getAction())) {
+    /**
+     * Check whether the intent can be forwarded to target user. Return the intent used for
+     * forwarding if it can be forwarded, {@code null} otherwise.
+     */
+    Intent canForward(Intent incomingIntent, int targetUserId)  {
+        Intent forwardIntent = new Intent(incomingIntent);
+        forwardIntent.addFlags(
+                Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+        sanitizeIntent(forwardIntent);
+
+        Intent intentToCheck = forwardIntent;
+        if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) {
             // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
-            if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
                 Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
                         + " a different user");
-                return false;
+                return null;
             }
-            if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
                 Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
                         + " different user");
-                return false;
+                return null;
             }
-            intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
-            if (intent == null) {
+            intentToCheck = forwardIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+            if (intentToCheck == null) {
                 Slog.wtf(TAG, "Cannot forward a chooser intent with no extra "
                         + Intent.EXTRA_INTENT);
-                return false;
+                return null;
             }
         }
-        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
-        if (intent.getSelector() != null) {
-            intent = intent.getSelector();
+        if (forwardIntent.getSelector() != null) {
+            intentToCheck = forwardIntent.getSelector();
         }
+        String resolvedType = intentToCheck.resolveTypeIfNeeded(getContentResolver());
+        sanitizeIntent(intentToCheck);
         try {
-            return ipm.canForwardTo(intent, resolvedType, getUserId(),
-                    targetUserId);
+            if (mInjector.getIPackageManager().
+                    canForwardTo(intentToCheck, resolvedType, getUserId(), targetUserId)) {
+                return forwardIntent;
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "PackageManagerService is dead?");
-            return false;
         }
+        return null;
     }
 
     /**
@@ -174,8 +188,7 @@
      * on the device.
      */
     private int getManagedProfile() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.myUserId());
+        List<UserInfo> relatedUsers = mInjector.getUserManager().getProfiles(UserHandle.myUserId());
         for (UserInfo userInfo : relatedUsers) {
             if (userInfo.isManagedProfile()) return userInfo.id;
         }
@@ -189,8 +202,7 @@
      * no parent.
      */
     private int getProfileParent() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        UserInfo parent = userManager.getProfileParent(UserHandle.myUserId());
+        UserInfo parent = mInjector.getUserManager().getProfileParent(UserHandle.myUserId());
         if (parent == null) {
             Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT
                     + " has been called, but there is no parent");
@@ -198,4 +210,44 @@
         }
         return parent.id;
     }
+
+    /**
+     * Sanitize the intent in place.
+     */
+    private void sanitizeIntent(Intent intent) {
+        // Apps should not be allowed to target a specific package/ component in the target user.
+        intent.setPackage(null);
+        intent.setComponent(null);
+    }
+
+    @VisibleForTesting
+    protected Injector createInjector() {
+        return new InjectorImpl();
+    }
+
+    private class InjectorImpl implements Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return AppGlobals.getPackageManager();
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return getSystemService(UserManager.class);
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return IntentForwarderActivity.this.getPackageManager();
+        }
+    }
+
+    public interface Injector {
+        IPackageManager getIPackageManager();
+
+        UserManager getUserManager();
+
+        PackageManager getPackageManager();
+    }
 }
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialog.java b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
index 47d2a9c..7108d14 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialog.java
@@ -24,6 +24,7 @@
 import android.media.MediaRouter.RouteInfo;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -130,7 +131,8 @@
 
         // Must be called after setContentView.
         getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
-                R.drawable.ic_media_route_off_holo_dark);
+                isLightTheme(getContext()) ? R.drawable.ic_media_route_off_holo_light
+                    : R.drawable.ic_media_route_off_holo_dark);
 
         mAdapter = new RouteAdapter(getContext());
         mListView = (ListView)findViewById(R.id.media_route_list);
@@ -176,6 +178,12 @@
         }
     }
 
+    static boolean isLightTheme(Context context) {
+        TypedValue value = new TypedValue();
+        return context.getTheme().resolveAttribute(R.attr.isLightTheme, value, true)
+                && value.data != 0;
+    }
+
     private final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
             implements ListView.OnItemClickListener {
         private final LayoutInflater mInflater;
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index 237feed..3cbc9ea 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -43,8 +43,12 @@
      * </p>
      */
     public MediaRouteChooserDialogFragment() {
+        int theme = MediaRouteChooserDialog.isLightTheme(getContext())
+                ? android.R.style.Theme_DeviceDefault_Light_Dialog
+                : android.R.style.Theme_DeviceDefault_Dialog;
+
         setCancelable(true);
-        setStyle(STYLE_NORMAL, android.R.style.Theme_DeviceDefault_Dialog);
+        setStyle(STYLE_NORMAL, theme);
     }
 
     public int getRouteTypes() {
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 5ce3e54..635a868 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -142,7 +142,11 @@
                     @Override
                     public void onClick(DialogInterface dialogInterface, int id) {
                         if (mRoute.isSelected()) {
-                            mRouter.getDefaultRoute().select();
+                            if (mRoute.isBluetooth()) {
+                                mRouter.getDefaultRoute().select();
+                            } else {
+                                mRouter.getFallbackRoute().select();
+                            }
                         }
                         dismiss();
                     }
diff --git a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
index fad7fd4..bb2d7fa 100644
--- a/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
+++ b/core/java/com/android/internal/app/MediaRouteDialogPresenter.java
@@ -71,16 +71,18 @@
         final MediaRouter router = (MediaRouter)context.getSystemService(
                 Context.MEDIA_ROUTER_SERVICE);
 
+        int theme = MediaRouteChooserDialog.isLightTheme(context)
+                ? android.R.style.Theme_DeviceDefault_Light_Dialog
+                : android.R.style.Theme_DeviceDefault_Dialog;
+
         MediaRouter.RouteInfo route = router.getSelectedRoute();
         if (route.isDefault() || !route.matchesTypes(routeTypes)) {
-            final MediaRouteChooserDialog d = new MediaRouteChooserDialog(
-                    context, android.R.style.Theme_DeviceDefault_Dialog);
+            final MediaRouteChooserDialog d = new MediaRouteChooserDialog(context, theme);
             d.setRouteTypes(routeTypes);
             d.setExtendedSettingsClickListener(extendedSettingsClickListener);
             return d;
         } else {
-            MediaRouteControllerDialog d = new MediaRouteControllerDialog(
-                    context, android.R.style.Theme_DeviceDefault_Dialog);
+            MediaRouteControllerDialog d = new MediaRouteControllerDialog(context, theme);
             return d;
         }
     }
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index bb54085..860c5c4 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -182,6 +182,10 @@
             throw new IllegalArgumentException("Invalid autoMode: " + autoMode);
         }
 
+        if (getAutoMode() != autoMode) {
+            Secure.putLongForUser(mContext.getContentResolver(),
+                    Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1L, mUserId);
+        }
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId);
     }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 9c6f1d0..5c1bafd 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1681,7 +1681,14 @@
         // We assume that at this point we've already filtered out the only intent for a different
         // targetUserId which we're going to use.
         private void addResolveInfo(DisplayResolveInfo dri) {
-            if (dri.mResolveInfo.targetUserId == UserHandle.USER_CURRENT) {
+            if (dri != null && dri.mResolveInfo != null
+                    && dri.mResolveInfo.targetUserId == UserHandle.USER_CURRENT) {
+                // Checks if this info is already listed in display.
+                for (DisplayResolveInfo existingInfo : mDisplayList) {
+                    if (resolveInfoMatch(dri.mResolveInfo, existingInfo.mResolveInfo)) {
+                        return;
+                    }
+                }
                 mDisplayList.add(dri);
             }
         }
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index 54b9cd8..a0f58a9 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -553,7 +553,9 @@
                 Log.e(TAG, "Error in Predict: " + e);
             }
         }
-        mAfterCompute.afterCompute();
+        if (mAfterCompute != null) {
+            mAfterCompute.afterCompute();
+        }
     }
 
     // adds select prob as the default values, according to a pre-trained Logistic Regression model.
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 5ab17e44..2ab2d20 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -30,6 +30,7 @@
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.InterruptedException;
@@ -55,7 +56,11 @@
     private static final String TAG = "ResolverListController";
     private static final boolean DEBUG = false;
 
+    Object mLock = new Object();
+
+    @GuardedBy("mLock")
     private ResolverComparator mResolverComparator;
+    private boolean isComputed = false;
 
     public ResolverListController(
             Context context,
@@ -68,6 +73,10 @@
         mLaunchedFromUid = launchedFromUid;
         mTargetIntent = targetIntent;
         mReferrerPackage = referrerPackage;
+        synchronized (mLock) {
+            mResolverComparator =
+                    new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, null);
+        }
     }
 
     @VisibleForTesting
@@ -232,25 +241,29 @@
     @VisibleForTesting
     @WorkerThread
     public void sort(List<ResolverActivity.ResolvedComponentInfo> inputList) {
-        final CountDownLatch finishComputeSignal = new CountDownLatch(1);
-        ComputeCallback callback = new ComputeCallback(finishComputeSignal);
-        if (mResolverComparator == null) {
-            mResolverComparator =
-                    new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, callback);
-        } else {
-            mResolverComparator.setCallBack(callback);
-        }
-        try {
-            long beforeRank = System.currentTimeMillis();
-            mResolverComparator.compute(inputList);
-            finishComputeSignal.await();
-            Collections.sort(inputList, mResolverComparator);
-            long afterRank = System.currentTimeMillis();
-            if (DEBUG) {
-                Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+        synchronized (mLock) {
+            if (mResolverComparator == null) {
+                Log.d(TAG, "Comparator has already been destroyed; skipped.");
+                return;
             }
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Compute & Sort was interrupted: " + e);
+            final CountDownLatch finishComputeSignal = new CountDownLatch(1);
+            ComputeCallback callback = new ComputeCallback(finishComputeSignal);
+            mResolverComparator.setCallBack(callback);
+            try {
+                long beforeRank = System.currentTimeMillis();
+                if (!isComputed) {
+                    mResolverComparator.compute(inputList);
+                    finishComputeSignal.await();
+                    isComputed = true;
+                }
+                Collections.sort(inputList, mResolverComparator);
+                long afterRank = System.currentTimeMillis();
+                if (DEBUG) {
+                    Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Compute & Sort was interrupted: " + e);
+            }
         }
     }
 
@@ -271,27 +284,36 @@
 
     @VisibleForTesting
     public float getScore(ResolverActivity.DisplayResolveInfo target) {
-        if (mResolverComparator == null) {
-            return 0.0f;
+        synchronized (mLock) {
+            if (mResolverComparator == null) {
+                return 0.0f;
+            }
+            return mResolverComparator.getScore(target.getResolvedComponentName());
         }
-        return mResolverComparator.getScore(target.getResolvedComponentName());
     }
 
     public void updateModel(ComponentName componentName) {
-        if (mResolverComparator != null) {
-            mResolverComparator.updateModel(componentName);
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.updateModel(componentName);
+            }
         }
     }
 
     public void updateChooserCounts(String packageName, int userId, String action) {
-        if (mResolverComparator != null) {
-            mResolverComparator.updateChooserCounts(packageName, userId, action);
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.updateChooserCounts(packageName, userId, action);
+            }
         }
     }
 
     public void destroy() {
-        if (mResolverComparator != null) {
-            mResolverComparator.destroy();
+        synchronized (mLock) {
+            if (mResolverComparator != null) {
+                mResolverComparator.destroy();
+            }
+            mResolverComparator = null;
         }
     }
 }
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/core/java/com/android/internal/car/ICarServiceHelper.aidl b/core/java/com/android/internal/car/ICarServiceHelper.aidl
new file mode 100644
index 0000000..9ee330b
--- /dev/null
+++ b/core/java/com/android/internal/car/ICarServiceHelper.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.internal.car;
+
+/**
+ * Helper API for car service. Only for itneraction between system server and car service.
+ * @hide
+ */
+interface ICarServiceHelper {
+}
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
new file mode 100644
index 0000000..ef98a5e
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -0,0 +1,286 @@
+/*
+ * 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.internal.colorextraction;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Class to process wallpaper colors and generate a tonal palette based on them.
+ */
+public class ColorExtractor implements WallpaperManager.OnColorsChangedListener {
+
+    public static final int TYPE_NORMAL = 0;
+    public static final int TYPE_DARK = 1;
+    public static final int TYPE_EXTRA_DARK = 2;
+    private static final int[] sGradientTypes = new int[]{TYPE_NORMAL, TYPE_DARK, TYPE_EXTRA_DARK};
+
+    private static final String TAG = "ColorExtractor";
+    private static final boolean DEBUG = false;
+
+    protected final SparseArray<GradientColors[]> mGradientColors;
+    private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners;
+    private final Context mContext;
+    private final ExtractionType mExtractionType;
+    protected WallpaperColors mSystemColors;
+    protected WallpaperColors mLockColors;
+
+    public ColorExtractor(Context context) {
+        this(context, new Tonal(context));
+    }
+
+    @VisibleForTesting
+    public ColorExtractor(Context context, ExtractionType extractionType) {
+        mContext = context;
+        mExtractionType = extractionType;
+
+        mGradientColors = new SparseArray<>();
+        for (int which : new int[] { WallpaperManager.FLAG_LOCK, WallpaperManager.FLAG_SYSTEM}) {
+            GradientColors[] colors = new GradientColors[sGradientTypes.length];
+            mGradientColors.append(which, colors);
+            for (int type : sGradientTypes) {
+                colors[type] = new GradientColors();
+            }
+        }
+
+        mOnColorsChangedListeners = new ArrayList<>();
+        GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+        GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+
+        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
+        if (wallpaperManager == null) {
+            Log.w(TAG, "Can't listen to color changes!");
+        } else {
+            wallpaperManager.addOnColorsChangedListener(this);
+
+            // Initialize all gradients with the current colors
+            Trace.beginSection("ColorExtractor#getWallpaperColors");
+            mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+            mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
+            Trace.endSection();
+        }
+
+        // Initialize all gradients with the current colors
+        extractInto(mSystemColors,
+                systemColors[TYPE_NORMAL],
+                systemColors[TYPE_DARK],
+                systemColors[TYPE_EXTRA_DARK]);
+        extractInto(mLockColors,
+                lockColors[TYPE_NORMAL],
+                lockColors[TYPE_DARK],
+                lockColors[TYPE_EXTRA_DARK]);
+    }
+
+    /**
+     * Retrieve gradient colors for a specific wallpaper.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return colors
+     */
+    @NonNull
+    public GradientColors getColors(int which) {
+        return getColors(which, TYPE_DARK);
+    }
+
+    /**
+     * Get current gradient colors for one of the possible gradient types
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @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(
+                    "type should be TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK");
+        }
+        if (which != WallpaperManager.FLAG_LOCK && which != WallpaperManager.FLAG_SYSTEM) {
+            throw new IllegalArgumentException("which should be FLAG_SYSTEM or FLAG_NORMAL");
+        }
+        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) {
+        if (DEBUG) {
+            Log.d(TAG, "New wallpaper colors for " + which + ": " + colors);
+        }
+        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]);
+            changed = true;
+        }
+
+        if (changed) {
+            triggerColorsChanged(which);
+        }
+    }
+
+    protected void triggerColorsChanged(int which) {
+        ArrayList<WeakReference<OnColorsChangedListener>> references =
+                new ArrayList<>(mOnColorsChangedListeners);
+        final int size = references.size();
+        for (int i = 0; i < size; i++) {
+            final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+            final OnColorsChangedListener listener = weakReference.get();
+            if (listener == null) {
+                mOnColorsChangedListeners.remove(weakReference);
+            } else {
+                listener.onColorsChanged(this, which);
+            }
+        }
+    }
+
+    private void extractInto(WallpaperColors inWallpaperColors,
+            GradientColors outGradientColorsNormal, GradientColors outGradientColorsDark,
+            GradientColors outGradientColorsExtraDark) {
+        mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal,
+                outGradientColorsDark, outGradientColorsExtraDark);
+    }
+
+    public void destroy() {
+        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
+        if (wallpaperManager != null) {
+            wallpaperManager.removeOnColorsChangedListener(this);
+        }
+    }
+
+    public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        mOnColorsChangedListeners.add(new WeakReference<>(listener));
+    }
+
+    public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
+        ArrayList<WeakReference<OnColorsChangedListener>> references =
+                new ArrayList<>(mOnColorsChangedListeners);
+        final int size = references.size();
+        for (int i = 0; i < size; i++) {
+            final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+            if (weakReference.get() == listener) {
+                mOnColorsChangedListeners.remove(weakReference);
+                break;
+            }
+        }
+    }
+
+    public static class GradientColors {
+        private int mMainColor;
+        private int mSecondaryColor;
+        private boolean mSupportsDarkText;
+
+        public void setMainColor(int mainColor) {
+            mMainColor = mainColor;
+        }
+
+        public void setSecondaryColor(int secondaryColor) {
+            mSecondaryColor = secondaryColor;
+        }
+
+        public void setSupportsDarkText(boolean supportsDarkText) {
+            mSupportsDarkText = supportsDarkText;
+        }
+
+        public void set(GradientColors other) {
+            mMainColor = other.mMainColor;
+            mSecondaryColor = other.mSecondaryColor;
+            mSupportsDarkText = other.mSupportsDarkText;
+        }
+
+        public int getMainColor() {
+            return mMainColor;
+        }
+
+        public int getSecondaryColor() {
+            return mSecondaryColor;
+        }
+
+        public boolean supportsDarkText() {
+            return mSupportsDarkText;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null || o.getClass() != getClass()) {
+                return false;
+            }
+            GradientColors other = (GradientColors) o;
+            return other.mMainColor == mMainColor &&
+                    other.mSecondaryColor == mSecondaryColor &&
+                    other.mSupportsDarkText == mSupportsDarkText;
+        }
+
+        @Override
+        public int hashCode() {
+            int code = mMainColor;
+            code = 31 * code + mSecondaryColor;
+            code = 31 * code + (mSupportsDarkText ? 0 : 1);
+            return code;
+        }
+
+        @Override
+        public String toString() {
+            return "GradientColors(" + Integer.toHexString(mMainColor) + ", "
+                    + Integer.toHexString(mSecondaryColor) + ")";
+        }
+    }
+
+    public interface OnColorsChangedListener {
+        void onColorsChanged(ColorExtractor colorExtractor, int which);
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
new file mode 100644
index 0000000..500c028
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/drawable/GradientDrawable.java
@@ -0,0 +1,223 @@
+/*
+ * 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.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;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RadialGradient;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.Xfermode;
+import android.graphics.drawable.Drawable;
+import android.view.animation.DecelerateInterpolator;
+
+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
+ */
+public class GradientDrawable extends Drawable {
+    private static final String TAG = "GradientDrawable";
+
+    private static final float CENTRALIZED_CIRCLE_1 = -2;
+    private static final int GRADIENT_RADIUS = 480; // in dp
+    private static final long COLOR_ANIMATION_DURATION = 2000;
+
+    private int mAlpha = 255;
+
+    private float mDensity;
+    private final Paint mPaint;
+    private final Rect mWindowBounds;
+    private final Splat mSplat;
+
+    private int mMainColor;
+    private int mSecondaryColor;
+    private ValueAnimator mColorAnimation;
+
+    public GradientDrawable(@NonNull Context context) {
+        mDensity = context.getResources().getDisplayMetrics().density;
+        mSplat = new Splat(0.50f, 1.00f, GRADIENT_RADIUS, CENTRALIZED_CIRCLE_1);
+        mWindowBounds = new Rect();
+
+        mPaint = new Paint();
+        mPaint.setStyle(Paint.Style.FILL);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors) {
+        setColors(colors.getMainColor(), colors.getSecondaryColor(), true);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
+        setColors(colors.getMainColor(), colors.getSecondaryColor(), animated);
+    }
+
+    public void setColors(int mainColor, int secondaryColor, boolean animated) {
+        if (mainColor == mMainColor && secondaryColor == mSecondaryColor) {
+            return;
+        }
+
+        if (mColorAnimation != null && mColorAnimation.isRunning()) {
+            mColorAnimation.cancel();
+        }
+
+        if (animated) {
+            final int mainFrom = mMainColor;
+            final int secFrom = mSecondaryColor;
+
+            ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+            anim.setDuration(COLOR_ANIMATION_DURATION);
+            anim.addUpdateListener(animation -> {
+                float ratio = (float) animation.getAnimatedValue();
+                mMainColor = ColorUtils.blendARGB(mainFrom, mainColor, ratio);
+                mSecondaryColor = ColorUtils.blendARGB(secFrom, secondaryColor, ratio);
+                buildPaints();
+                invalidateSelf();
+            });
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation, boolean isReverse) {
+                    if (mColorAnimation == animation) {
+                        mColorAnimation = null;
+                    }
+                }
+            });
+            anim.setInterpolator(new DecelerateInterpolator());
+            anim.start();
+            mColorAnimation = anim;
+        } else {
+            mMainColor = mainColor;
+            mSecondaryColor = secondaryColor;
+            buildPaints();
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        if (alpha != mAlpha) {
+            mAlpha = alpha;
+            mPaint.setAlpha(mAlpha);
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public int getAlpha() {
+        return mAlpha;
+    }
+
+    @Override
+    public void setXfermode(@Nullable Xfermode mode) {
+        mPaint.setXfermode(mode);
+        invalidateSelf();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public ColorFilter getColorFilter() {
+        return mPaint.getColorFilter();
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    public void setScreenSize(int width, int height) {
+        mWindowBounds.set(0, 0, width, height);
+        setBounds(0, 0, width, height);
+        buildPaints();
+    }
+
+    private void buildPaints() {
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            return;
+        }
+
+        float w = bounds.width();
+        float h = bounds.height();
+
+        float x = mSplat.x * w;
+        float y = mSplat.y * h;
+
+        float radius = mSplat.radius * mDensity;
+
+        // When we have only a single alpha gradient, we increase quality
+        // (avoiding banding) by merging the background solid color into
+        // the gradient directly
+        RadialGradient radialGradient = new RadialGradient(x, y, radius,
+                mSecondaryColor, mMainColor, Shader.TileMode.CLAMP);
+        mPaint.setShader(radialGradient);
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            throw new IllegalStateException("You need to call setScreenSize before drawing.");
+        }
+
+        // Splat each gradient
+        float w = bounds.width();
+        float h = bounds.height();
+
+        float x = mSplat.x * w;
+        float y = mSplat.y * h;
+
+        float radius = Math.max(w, h);
+        canvas.drawRect(x - radius, y - radius, x + radius, y + radius, mPaint);
+    }
+
+    @VisibleForTesting
+    public int getMainColor() {
+        return mMainColor;
+    }
+
+    @VisibleForTesting
+    public int getSecondaryColor() {
+        return mSecondaryColor;
+    }
+
+    static final class Splat {
+        final float x;
+        final float y;
+        final float radius;
+        final float colorIndex;
+
+        Splat(float x, float y, float radius, float colorIndex) {
+            this.x = x;
+            this.y = y;
+            this.radius = radius;
+            this.colorIndex = colorIndex;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/colorextraction/types/ExtractionType.java b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
new file mode 100644
index 0000000..7000e79
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
@@ -0,0 +1,46 @@
+/*
+ * 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.internal.colorextraction.types;
+
+import android.app.WallpaperColors;
+
+import com.android.internal.colorextraction.ColorExtractor;
+
+/**
+ * Interface to allow various color extraction implementations.
+ */
+public interface ExtractionType {
+
+    /**
+     * Executes color extraction by reading WallpaperColors and setting
+     * main and secondary colors on GradientColors.
+     *
+     * Extraction is expected to happen with 3 different gradient types:
+     *     Normal, with the main extracted colors
+     *     Dark, with extra contrast
+     *     ExtraDark, for places where GAR is mandatory, like the emergency dialer
+     *
+     * @param inWallpaperColors where to read from
+     * @param outGradientColorsNormal object that should receive normal colors
+     * @param outGradientColorsDark object that should receive dark colors
+     * @param outGradientColorsExtraDark object that should receive extra dark colors
+     */
+    void extractInto(WallpaperColors inWallpaperColors,
+            ColorExtractor.GradientColors outGradientColorsNormal,
+            ColorExtractor.GradientColors outGradientColorsDark,
+            ColorExtractor.GradientColors outGradientColorsExtraDark);
+}
diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
new file mode 100644
index 0000000..dbc086c
--- /dev/null
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -0,0 +1,600 @@
+/*
+ * 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.internal.colorextraction.types;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.content.Context;
+import android.graphics.Color;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.Range;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.graphics.ColorUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Implementation of tonal color extraction
+ */
+public class Tonal implements ExtractionType {
+    private static final String TAG = "Tonal";
+
+    // Used for tonal palette fitting
+    private static final float FIT_WEIGHT_H = 1.0f;
+    private static final float FIT_WEIGHT_S = 1.0f;
+    private static final float FIT_WEIGHT_L = 10.0f;
+
+    private static final boolean DEBUG = true;
+
+    public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0;
+    public static final int SECONDARY_COLOR_LIGHT = 0xff9e9e9e;
+    public static final int MAIN_COLOR_DARK = 0xff212121;
+    public static final int SECONDARY_COLOR_DARK = 0xff000000;
+
+    private final TonalPalette mGreyPalette;
+    private final ArrayList<TonalPalette> mTonalPalettes;
+    private final ArrayList<ColorRange> mBlacklistedColors;
+
+    // Temporary variable to avoid allocations
+    private float[] mTmpHSL = new float[3];
+
+    public Tonal(Context context) {
+
+        ConfigParser parser = new ConfigParser(context);
+        mTonalPalettes = parser.getTonalPalettes();
+        mBlacklistedColors = parser.getBlacklistedColors();
+
+        mGreyPalette = mTonalPalettes.get(0);
+        mTonalPalettes.remove(0);
+    }
+
+    /**
+     * Grab colors from WallpaperColors and set them into GradientColors.
+     * Also applies the default gradient in case extraction fails.
+     *
+     * @param inWallpaperColors Input.
+     * @param outColorsNormal Colors for normal theme.
+     * @param outColorsDark Colors for dar theme.
+     * @param outColorsExtraDark Colors for extra dark theme.
+     */
+    public void extractInto(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
+            @NonNull GradientColors outColorsExtraDark) {
+        boolean success = runTonalExtraction(inWallpaperColors, outColorsNormal, outColorsDark,
+                outColorsExtraDark);
+        if (!success) {
+            applyFallback(inWallpaperColors, outColorsNormal, outColorsDark, outColorsExtraDark);
+        }
+    }
+
+    /**
+     * Grab colors from WallpaperColors and set them into GradientColors.
+     *
+     * @param inWallpaperColors Input.
+     * @param outColorsNormal Colors for normal theme.
+     * @param outColorsDark Colors for dar theme.
+     * @param outColorsExtraDark Colors for extra dark theme.
+     * @return True if succeeded or false if failed.
+     */
+    private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
+            @NonNull GradientColors outColorsExtraDark) {
+
+        if (inWallpaperColors == null) {
+            return false;
+        }
+
+        final List<Color> mainColors = inWallpaperColors.getMainColors();
+        final int mainColorsSize = mainColors.size();
+        final boolean supportsDarkText = (inWallpaperColors.getColorHints() &
+                WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+
+        if (mainColorsSize == 0) {
+            return false;
+        }
+        // Tonal is not really a sort, it takes a color from the extracted
+        // palette and finds a best fit amongst a collection of pre-defined
+        // palettes. The best fit is tweaked to be closer to the source color
+        // and replaces the original palette
+
+        // Get the most preeminent, non-blacklisted color.
+        Color bestColor = null;
+        final float[] hsl = new float[3];
+        for (int i = 0; i < mainColorsSize; i++) {
+            final Color color = mainColors.get(i);
+            final int colorValue = color.toArgb();
+            ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
+                    Color.blue(colorValue), hsl);
+
+            // Stop when we find a color that meets our criteria
+            if (!isBlacklisted(hsl)) {
+                bestColor = color;
+                break;
+            }
+        }
+
+        // Fail if not found
+        if (bestColor == null) {
+            return false;
+        }
+
+        int colorValue = bestColor.toArgb();
+        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
+                hsl);
+
+        // The Android HSL definition requires the hue to go from 0 to 360 but
+        // the Material Tonal Palette defines hues from 0 to 1.
+        hsl[0] /= 360f;
+
+        // Find the palette that contains the closest color
+        TonalPalette palette = findTonalPalette(hsl[0], hsl[1]);
+        if (palette == null) {
+            Log.w(TAG, "Could not find a tonal palette!");
+            return false;
+        }
+
+        // Figure out what's the main color index in the optimal palette
+        int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]);
+        if (fitIndex == -1) {
+            Log.w(TAG, "Could not find best fit!");
+            return false;
+        }
+
+        // Generate the 10 colors palette by offsetting each one of them
+        float[] h = fit(palette.h, hsl[0], fitIndex,
+                Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+        float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
+        float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
+
+        if (DEBUG) {
+            StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex +
+                    ". Main color: " + Integer.toHexString(getColorInt(fitIndex, h, s, l)) +
+                    "\nColors: ");
+
+            for (int i=0; i < h.length; i++) {
+                builder.append(Integer.toHexString(getColorInt(i, h, s, l)));
+                if (i < h.length - 1) {
+                    builder.append(", ");
+                }
+            }
+            Log.d(TAG, builder.toString());
+        }
+
+        int primaryIndex = fitIndex;
+        int mainColor = getColorInt(primaryIndex, h, s, l);
+
+        // We might want use the fallback in case the extracted color is brighter than our
+        // light fallback or darker than our dark fallback.
+        ColorUtils.colorToHSL(mainColor, mTmpHSL);
+        final float mainLuminosity = mTmpHSL[2];
+        ColorUtils.colorToHSL(MAIN_COLOR_LIGHT, mTmpHSL);
+        final float lightLuminosity = mTmpHSL[2];
+        if (mainLuminosity > lightLuminosity) {
+            return false;
+        }
+        ColorUtils.colorToHSL(MAIN_COLOR_DARK, mTmpHSL);
+        final float darkLuminosity = mTmpHSL[2];
+        if (mainLuminosity < darkLuminosity) {
+            return false;
+        }
+
+        // Normal colors:
+        // best fit + a 2 colors offset
+        outColorsNormal.setMainColor(mainColor);
+        int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsNormal.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        // Dark colors:
+        // Stops at 4th color, only lighter if dark text is supported
+        if (supportsDarkText) {
+            primaryIndex = h.length - 1;
+        } else if (fitIndex < 2) {
+            primaryIndex = 0;
+        } else {
+            primaryIndex = Math.min(fitIndex, 3);
+        }
+        secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsDark.setMainColor(getColorInt(primaryIndex, h, s, l));
+        outColorsDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        // Extra Dark:
+        // Stay close to dark colors until dark text is supported
+        if (supportsDarkText) {
+            primaryIndex = h.length - 1;
+        } else if (fitIndex < 2) {
+            primaryIndex = 0;
+        } else {
+            primaryIndex = 2;
+        }
+        secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        outColorsExtraDark.setMainColor(getColorInt(primaryIndex, h, s, l));
+        outColorsExtraDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
+
+        outColorsNormal.setSupportsDarkText(supportsDarkText);
+        outColorsDark.setSupportsDarkText(supportsDarkText);
+        outColorsExtraDark.setSupportsDarkText(supportsDarkText);
+
+        if (DEBUG) {
+            Log.d(TAG, "Gradients: \n\tNormal " + outColorsNormal + "\n\tDark " + outColorsDark
+                    + "\n\tExtra dark: " + outColorsExtraDark);
+        }
+
+        return true;
+    }
+
+    private void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+            GradientColors outColorsNormal, GradientColors outColorsDark,
+            GradientColors outColorsExtraDark) {
+        applyFallback(inWallpaperColors, outColorsNormal);
+        applyFallback(inWallpaperColors, outColorsDark);
+        applyFallback(inWallpaperColors, outColorsExtraDark);
+    }
+
+    /**
+     * Sets the gradient to the light or dark fallbacks based on the current wallpaper colors.
+     *
+     * @param inWallpaperColors Colors to read.
+     * @param outGradientColors Destination.
+     */
+    public static void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+            @NonNull GradientColors outGradientColors) {
+        boolean light = inWallpaperColors != null
+                && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT)
+                != 0;
+        int innerColor = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK;
+        int outerColor = light ? SECONDARY_COLOR_LIGHT : SECONDARY_COLOR_DARK;
+
+        outGradientColors.setMainColor(innerColor);
+        outGradientColors.setSecondaryColor(outerColor);
+        outGradientColors.setSupportsDarkText(light);
+    }
+
+    private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) {
+        mTmpHSL[0] = fract(h[fitIndex]) * 360.0f;
+        mTmpHSL[1] = s[fitIndex];
+        mTmpHSL[2] = l[fitIndex];
+        return ColorUtils.HSLToColor(mTmpHSL);
+    }
+
+    /**
+     * Checks if a given color exists in the blacklist
+     * @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1)
+     * @return true if color should be avoided
+     */
+    private boolean isBlacklisted(float[] hsl) {
+        for (int i = mBlacklistedColors.size() - 1; i >= 0; i--) {
+            ColorRange badRange = mBlacklistedColors.get(i);
+            if (badRange.containsColor(hsl[0], hsl[1], hsl[2])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Offsets all colors by a delta, clamping values that go beyond what's
+     * supported on the color space.
+     * @param data what you want to fit
+     * @param v how big should be the offset
+     * @param index which index to calculate the delta against
+     * @param min minimum accepted value (clamp)
+     * @param max maximum accepted value (clamp)
+     * @return new shifted palette
+     */
+    private static float[] fit(float[] data, float v, int index, float min, float max) {
+        float[] fitData = new float[data.length];
+        float delta = v - data[index];
+
+        for (int i = 0; i < data.length; i++) {
+            fitData[i] = MathUtils.constrain(data[i] + delta, min, max);
+        }
+
+        return fitData;
+    }
+
+    /**
+     * Finds the closest color in a palette, given another HSL color
+     *
+     * @param palette where to search
+     * @param h hue
+     * @param s saturation
+     * @param l lightness
+     * @return closest index or -1 if palette is empty.
+     */
+    private static int bestFit(@NonNull TonalPalette palette, float h, float s, float l) {
+        int minErrorIndex = -1;
+        float minError = Float.POSITIVE_INFINITY;
+
+        for (int i = 0; i < palette.h.length; i++) {
+            float error =
+                    FIT_WEIGHT_H * Math.abs(h - palette.h[i])
+                            + FIT_WEIGHT_S * Math.abs(s - palette.s[i])
+                            + FIT_WEIGHT_L * Math.abs(l - palette.l[i]);
+            if (error < minError) {
+                minError = error;
+                minErrorIndex = i;
+            }
+        }
+
+        return minErrorIndex;
+    }
+
+    @VisibleForTesting
+    public List<ColorRange> getBlacklistedColors() {
+        return mBlacklistedColors;
+    }
+
+    @Nullable
+    private TonalPalette findTonalPalette(float h, float s) {
+        // Fallback to a grey palette if the color is too desaturated.
+        // This avoids hue shifts.
+        if (s < 0.05f) {
+            return mGreyPalette;
+        }
+
+        TonalPalette best = null;
+        float error = Float.POSITIVE_INFINITY;
+
+        final int tonalPalettesCount = mTonalPalettes.size();
+        for (int i = 0; i < tonalPalettesCount; i++) {
+            final TonalPalette candidate = mTonalPalettes.get(i);
+
+            if (h >= candidate.minHue && h <= candidate.maxHue) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.maxHue > 1.0f && h >= 0.0f && h <= fract(candidate.maxHue)) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.minHue < 0.0f && h >= fract(candidate.minHue) && h <= 1.0f) {
+                best = candidate;
+                break;
+            }
+
+            if (h <= candidate.minHue && candidate.minHue - h < error) {
+                best = candidate;
+                error = candidate.minHue - h;
+            } else if (h >= candidate.maxHue && h - candidate.maxHue < error) {
+                best = candidate;
+                error = h - candidate.maxHue;
+            } else if (candidate.maxHue > 1.0f && h >= fract(candidate.maxHue)
+                    && h - fract(candidate.maxHue) < error) {
+                best = candidate;
+                error = h - fract(candidate.maxHue);
+            } else if (candidate.minHue < 0.0f && h <= fract(candidate.minHue)
+                    && fract(candidate.minHue) - h < error) {
+                best = candidate;
+                error = fract(candidate.minHue) - h;
+            }
+        }
+
+        return best;
+    }
+
+    private static float fract(float v) {
+        return v - (float) Math.floor(v);
+    }
+
+    static class TonalPalette {
+        final float[] h;
+        final float[] s;
+        final float[] l;
+        final float minHue;
+        final float maxHue;
+
+        TonalPalette(float[] h, float[] s, float[] l) {
+            if (h.length != s.length || s.length != l.length) {
+                throw new IllegalArgumentException("All arrays should have the same size. h: "
+                        + Arrays.toString(h) + " s: " + Arrays.toString(s) + " l: "
+                        + Arrays.toString(l));
+            }
+            this.h = h;
+            this.s = s;
+            this.l = l;
+
+            float minHue = Float.POSITIVE_INFINITY;
+            float maxHue = Float.NEGATIVE_INFINITY;
+
+            for (float v : h) {
+                minHue = Math.min(v, minHue);
+                maxHue = Math.max(v, maxHue);
+            }
+
+            this.minHue = minHue;
+            this.maxHue = maxHue;
+        }
+    }
+
+    /**
+     * Representation of an HSL color range.
+     * <ul>
+     * <li>hsl[0] is Hue [0 .. 360)</li>
+     * <li>hsl[1] is Saturation [0...1]</li>
+     * <li>hsl[2] is Lightness [0...1]</li>
+     * </ul>
+     */
+    @VisibleForTesting
+    public static class ColorRange {
+        private Range<Float> mHue;
+        private Range<Float> mSaturation;
+        private Range<Float> mLightness;
+
+        public ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) {
+            mHue = hue;
+            mSaturation = saturation;
+            mLightness = lightness;
+        }
+
+        public boolean containsColor(float h, float s, float l) {
+            if (!mHue.contains(h)) {
+                return false;
+            } else if (!mSaturation.contains(s)) {
+                return false;
+            } else if (!mLightness.contains(l)) {
+                return false;
+            }
+            return true;
+        }
+
+        public float[] getCenter() {
+            return new float[] {
+                    mHue.getLower() + (mHue.getUpper() - mHue.getLower()) / 2f,
+                    mSaturation.getLower() + (mSaturation.getUpper() - mSaturation.getLower()) / 2f,
+                    mLightness.getLower() + (mLightness.getUpper() - mLightness.getLower()) / 2f
+            };
+        }
+
+        @Override
+        public String toString() {
+            return String.format("H: %s, S: %s, L %s", mHue, mSaturation, mLightness);
+        }
+    }
+
+    @VisibleForTesting
+    public static class ConfigParser {
+        private final ArrayList<TonalPalette> mTonalPalettes;
+        private final ArrayList<ColorRange> mBlacklistedColors;
+
+        public ConfigParser(Context context) {
+            mTonalPalettes = new ArrayList<>();
+            mBlacklistedColors = new ArrayList<>();
+
+            // Load all palettes and the blacklist from an XML.
+            try {
+                XmlPullParser parser = context.getResources().getXml(R.xml.color_extraction);
+                int eventType = parser.getEventType();
+                while (eventType != XmlPullParser.END_DOCUMENT) {
+                    if (eventType == XmlPullParser.START_DOCUMENT ||
+                            eventType == XmlPullParser.END_TAG) {
+                        // just skip
+                    } else if (eventType == XmlPullParser.START_TAG) {
+                        String tagName = parser.getName();
+                        if (tagName.equals("palettes")) {
+                            parsePalettes(parser);
+                        } else if (tagName.equals("blacklist")) {
+                            parseBlacklist(parser);
+                        }
+                    } else {
+                        throw new XmlPullParserException("Invalid XML event " + eventType + " - "
+                                + parser.getName(), parser, null);
+                    }
+                    eventType = parser.next();
+                }
+            } catch (XmlPullParserException | IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public ArrayList<TonalPalette> getTonalPalettes() {
+            return mTonalPalettes;
+        }
+
+        public ArrayList<ColorRange> getBlacklistedColors() {
+            return mBlacklistedColors;
+        }
+
+        private void parseBlacklist(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "blacklist");
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                String name = parser.getName();
+                // Starts by looking for the entry tag
+                if (name.equals("range")) {
+                    mBlacklistedColors.add(readRange(parser));
+                    parser.next();
+                } else {
+                    throw new XmlPullParserException("Invalid tag: " + name, parser, null);
+                }
+            }
+        }
+
+        private ColorRange readRange(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "range");
+            float[] h = readFloatArray(parser.getAttributeValue(null, "h"));
+            float[] s = readFloatArray(parser.getAttributeValue(null, "s"));
+            float[] l = readFloatArray(parser.getAttributeValue(null, "l"));
+
+            if (h == null || s == null || l == null) {
+                throw new XmlPullParserException("Incomplete range tag.", parser, null);
+            }
+
+            return new ColorRange(new Range<>(h[0], h[1]), new Range<>(s[0], s[1]),
+                    new Range<>(l[0], l[1]));
+        }
+
+        private void parsePalettes(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "palettes");
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                String name = parser.getName();
+                // Starts by looking for the entry tag
+                if (name.equals("palette")) {
+                    mTonalPalettes.add(readPalette(parser));
+                    parser.next();
+                } else {
+                    throw new XmlPullParserException("Invalid tag: " + name);
+                }
+            }
+        }
+
+        private TonalPalette readPalette(XmlPullParser parser)
+                throws XmlPullParserException, IOException {
+            parser.require(XmlPullParser.START_TAG, null, "palette");
+
+            float[] h = readFloatArray(parser.getAttributeValue(null, "h"));
+            float[] s = readFloatArray(parser.getAttributeValue(null, "s"));
+            float[] l = readFloatArray(parser.getAttributeValue(null, "l"));
+
+            if (h == null || s == null || l == null) {
+                throw new XmlPullParserException("Incomplete range tag.", parser, null);
+            }
+
+            return new TonalPalette(h, s, l);
+        }
+
+        private float[] readFloatArray(String attributeValue)
+                throws IOException, XmlPullParserException {
+            String[] tokens = attributeValue.replaceAll(" ", "").replaceAll("\n", "").split(",");
+            float[] numbers = new float[tokens.length];
+            for (int i = 0; i < tokens.length; i++) {
+                numbers[i] = Float.parseFloat(tokens[i]);
+            }
+            return numbers;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 79544df..ebea1a4 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -27,6 +27,7 @@
 import android.database.MatrixCursor.RowBuilder;
 import android.graphics.Point;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.FileObserver;
 import android.os.FileUtils;
@@ -156,11 +157,17 @@
         if (visibleFolder != null) {
             assert (visibleFolder.isDirectory());
 
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri uri = MediaStore.Files.getDirectoryUri("external");
-            ContentValues values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, visibleFolder.getAbsolutePath());
-            resolver.insert(uri, values);
+            final long token = Binder.clearCallingIdentity();
+
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri uri = MediaStore.Files.getDirectoryUri("external");
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.Files.FileColumns.DATA, visibleFolder.getAbsolutePath());
+                resolver.insert(uri, values);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
     }
 
@@ -214,22 +221,28 @@
         // They should be all null or not null at the same time. File#renameTo() doesn't work across
         // volumes so an exception will be thrown before calling this method.
         if (oldVisibleFile != null && newVisibleFile != null) {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri externalUri = newVisibleFile.isDirectory()
-                    ? MediaStore.Files.getDirectoryUri("external")
-                    : MediaStore.Files.getContentUri("external");
+            final long token = Binder.clearCallingIdentity();
 
-            ContentValues values = new ContentValues();
-            values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri externalUri = newVisibleFile.isDirectory()
+                        ? MediaStore.Files.getDirectoryUri("external")
+                        : MediaStore.Files.getContentUri("external");
 
-            // Logic borrowed from MtpDatabase.
-            // note - we are relying on a special case in MediaProvider.update() to update
-            // the paths for all children in the case where this is a directory.
-            final String path = oldVisibleFile.getAbsolutePath();
-            resolver.update(externalUri,
-                    values,
-                    "_data LIKE ? AND lower(_data)=lower(?)",
-                    new String[] { path, path });
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
+
+                // Logic borrowed from MtpDatabase.
+                // note - we are relying on a special case in MediaProvider.update() to update
+                // the paths for all children in the case where this is a directory.
+                final String path = oldVisibleFile.getAbsolutePath();
+                resolver.update(externalUri,
+                        values,
+                        "_data LIKE ? AND lower(_data)=lower(?)",
+                        new String[]{path, path});
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
     }
 
@@ -253,23 +266,29 @@
             throws FileNotFoundException {
         // visibleFolder is null if we're removing a document from external thumb drive or SD card.
         if (visibleFile != null) {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri externalUri = MediaStore.Files.getContentUri("external");
+            final long token = Binder.clearCallingIdentity();
 
-            // Remove media store entries for any files inside this directory, using
-            // path prefix match. Logic borrowed from MtpDatabase.
-            if (isFolder) {
-                final String path = visibleFile.getAbsolutePath() + "/";
+            try {
+                final ContentResolver resolver = getContext().getContentResolver();
+                final Uri externalUri = MediaStore.Files.getContentUri("external");
+
+                // Remove media store entries for any files inside this directory, using
+                // path prefix match. Logic borrowed from MtpDatabase.
+                if (isFolder) {
+                    final String path = visibleFile.getAbsolutePath() + "/";
+                    resolver.delete(externalUri,
+                            "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
+                            new String[]{path + "%", Integer.toString(path.length()), path});
+                }
+
+                // Remove media store entry for this exact file.
+                final String path = visibleFile.getAbsolutePath();
                 resolver.delete(externalUri,
-                        "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
-                        new String[] { path + "%", Integer.toString(path.length()), path });
+                        "_data LIKE ?1 AND lower(_data)=lower(?2)",
+                        new String[]{path, path});
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
-
-            // Remove media store entry for this exact file.
-            final String path = visibleFile.getAbsolutePath();
-            resolver.delete(externalUri,
-                    "_data LIKE ?1 AND lower(_data)=lower(?2)",
-                    new String[] { path, path });
         }
     }
 
diff --git a/core/java/com/android/internal/graphics/ColorUtils.java b/core/java/com/android/internal/graphics/ColorUtils.java
index 6c1efa4..8b2a2dc 100644
--- a/core/java/com/android/internal/graphics/ColorUtils.java
+++ b/core/java/com/android/internal/graphics/ColorUtils.java
@@ -106,6 +106,31 @@
     }
 
     /**
+     * Calculates the minimum alpha value which can be applied to {@code background} so that would
+     * have a contrast value of at least {@code minContrastRatio} when alpha blended to
+     * {@code foreground}.
+     *
+     * @param foreground       the foreground color
+     * @param background       the background color, opacity will be ignored
+     * @param minContrastRatio the minimum contrast ratio
+     * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+     */
+    public static int calculateMinimumBackgroundAlpha(@ColorInt int foreground,
+            @ColorInt int background, float minContrastRatio) {
+        // Ignore initial alpha that the background might have since this is
+        // what we're trying to calculate.
+        background = setAlphaComponent(background, 255);
+        final int leastContrastyColor = setAlphaComponent(foreground, 255);
+        return binaryAlphaSearch(foreground, background, minContrastRatio, (fg, bg, alpha) -> {
+            int testBackground = blendARGB(leastContrastyColor, bg, alpha/255f);
+            // Float rounding might set this alpha to something other that 255,
+            // raising an exception in calculateContrast.
+            testBackground = setAlphaComponent(testBackground, 255);
+            return calculateContrast(fg, testBackground);
+        });
+    }
+
+    /**
      * Calculates the minimum alpha value which can be applied to {@code foreground} so that would
      * have a contrast value of at least {@code minContrastRatio} when compared to
      * {@code background}.
@@ -122,14 +147,33 @@
                     + Integer.toHexString(background));
         }
 
+        ContrastCalculator contrastCalculator = (fg, bg, alpha) -> {
+            int testForeground = setAlphaComponent(fg, alpha);
+            return calculateContrast(testForeground, bg);
+        };
+
         // First lets check that a fully opaque foreground has sufficient contrast
-        int testForeground = setAlphaComponent(foreground, 255);
-        double testRatio = calculateContrast(testForeground, background);
+        double testRatio = contrastCalculator.calculateContrast(foreground, background, 255);
         if (testRatio < minContrastRatio) {
             // Fully opaque foreground does not have sufficient contrast, return error
             return -1;
         }
+        foreground = setAlphaComponent(foreground, 255);
+        return binaryAlphaSearch(foreground, background, minContrastRatio, contrastCalculator);
+    }
 
+    /**
+     * Calculates the alpha value using binary search based on a given contrast evaluation function
+     * and target contrast that needs to be satisfied.
+     *
+     * @param foreground         the foreground color
+     * @param background         the opaque background color
+     * @param minContrastRatio   the minimum contrast ratio
+     * @param calculator function that calculates contrast
+     * @return the alpha value in the range 0-255, or -1 if no value could be calculated
+     */
+    private static int binaryAlphaSearch(@ColorInt int foreground, @ColorInt int background,
+            float minContrastRatio, ContrastCalculator calculator) {
         // Binary search to find a value with the minimum value which provides sufficient contrast
         int numIterations = 0;
         int minAlpha = 0;
@@ -139,9 +183,8 @@
                 (maxAlpha - minAlpha) > MIN_ALPHA_SEARCH_PRECISION) {
             final int testAlpha = (minAlpha + maxAlpha) / 2;
 
-            testForeground = setAlphaComponent(foreground, testAlpha);
-            testRatio = calculateContrast(testForeground, background);
-
+            final double testRatio = calculator.calculateContrast(foreground, background,
+                    testAlpha);
             if (testRatio < minContrastRatio) {
                 minAlpha = testAlpha;
             } else {
@@ -615,4 +658,8 @@
         return result;
     }
 
+    private interface ContrastCalculator {
+        double calculateContrast(int foreground, int background, int alpha);
+    }
+
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java b/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
index 2d0ad66..9ac753b 100644
--- a/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/ColorCutQuantizer.java
@@ -61,7 +61,7 @@
  * This means that the color space is divided into distinct colors, rather than representative
  * colors.
  */
-final class ColorCutQuantizer {
+final class ColorCutQuantizer implements Quantizer {
 
     private static final String LOG_TAG = "ColorCutQuantizer";
     private static final boolean LOG_TIMINGS = false;
@@ -73,22 +73,22 @@
     private static final int QUANTIZE_WORD_WIDTH = 5;
     private static final int QUANTIZE_WORD_MASK = (1 << QUANTIZE_WORD_WIDTH) - 1;
 
-    final int[] mColors;
-    final int[] mHistogram;
-    final List<Swatch> mQuantizedColors;
-    final TimingLogger mTimingLogger;
-    final Palette.Filter[] mFilters;
+    int[] mColors;
+    int[] mHistogram;
+    List<Swatch> mQuantizedColors;
+    TimingLogger mTimingLogger;
+    Palette.Filter[] mFilters;
 
     private final float[] mTempHsl = new float[3];
 
     /**
-     * Constructor.
+     * Execute color quantization.
      *
      * @param pixels histogram representing an image's pixel data
      * @param maxColors The maximum number of colors that should be in the result palette.
      * @param filters Set of filters to use in the quantization stage
      */
-    ColorCutQuantizer(final int[] pixels, final int maxColors, final Palette.Filter[] filters) {
+    public void quantize(final int[] pixels, final int maxColors, final Palette.Filter[] filters) {
         mTimingLogger = LOG_TIMINGS ? new TimingLogger(LOG_TAG, "Creation") : null;
         mFilters = filters;
 
@@ -160,7 +160,7 @@
     /**
      * @return the list of quantized colors
      */
-    List<Swatch> getQuantizedColors() {
+    public List<Swatch> getQuantizedColors() {
         return mQuantizedColors;
     }
 
@@ -376,7 +376,9 @@
             for (int i = mLowerIndex, count = 0; i <= mUpperIndex; i++)  {
                 count += hist[colors[i]];
                 if (count >= midPoint) {
-                    return i;
+                    // we never want to split on the upperIndex, as this will result in the same
+                    // box
+                    return Math.min(mUpperIndex - 1, i);
                 }
             }
 
diff --git a/core/java/com/android/internal/graphics/palette/Palette.java b/core/java/com/android/internal/graphics/palette/Palette.java
index 9f1504a..a4f9a59 100644
--- a/core/java/com/android/internal/graphics/palette/Palette.java
+++ b/core/java/com/android/internal/graphics/palette/Palette.java
@@ -613,6 +613,8 @@
         private final List<Palette.Filter> mFilters = new ArrayList<>();
         private Rect mRegion;
 
+        private Quantizer mQuantizer;
+
         /**
          * Construct a new {@link Palette.Builder} using a source {@link Bitmap}
          */
@@ -726,6 +728,18 @@
         }
 
         /**
+         * Set a specific quantization algorithm. {@link ColorCutQuantizer} will
+         * be used if unspecified.
+         *
+         * @param quantizer Quantizer implementation.
+         */
+        @NonNull
+        public Palette.Builder setQuantizer(Quantizer quantizer) {
+            mQuantizer = quantizer;
+            return this;
+        }
+
+        /**
          * Set a region of the bitmap to be used exclusively when calculating the palette.
          * <p>This only works when the original input is a {@link Bitmap}.</p>
          *
@@ -818,17 +832,19 @@
                 }
 
                 // Now generate a quantizer from the Bitmap
-                final ColorCutQuantizer quantizer = new ColorCutQuantizer(
-                        getPixelsFromBitmap(bitmap),
-                        mMaxColors,
-                        mFilters.isEmpty() ? null : mFilters.toArray(new Palette.Filter[mFilters.size()]));
+                if (mQuantizer == null) {
+                    mQuantizer = new ColorCutQuantizer();
+                }
+                mQuantizer.quantize(getPixelsFromBitmap(bitmap),
+                            mMaxColors, mFilters.isEmpty() ? null :
+                            mFilters.toArray(new Palette.Filter[mFilters.size()]));
 
                 // If created a new bitmap, recycle it
                 if (bitmap != mBitmap) {
                     bitmap.recycle();
                 }
 
-                swatches = quantizer.getQuantizedColors();
+                swatches = mQuantizer.getQuantizedColors();
 
                 if (logger != null) {
                     logger.addSplit("Color quantization completed");
diff --git a/core/java/com/android/internal/graphics/palette/Quantizer.java b/core/java/com/android/internal/graphics/palette/Quantizer.java
new file mode 100644
index 0000000..db60f2e
--- /dev/null
+++ b/core/java/com/android/internal/graphics/palette/Quantizer.java
@@ -0,0 +1,27 @@
+/*
+ * 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.internal.graphics.palette;
+
+import java.util.List;
+
+/**
+ * Definition of an algorithm that receives pixels and outputs a list of colors.
+ */
+public interface Quantizer {
+    void quantize(final int[] pixels, final int maxColors, final Palette.Filter[] filters);
+    List<Palette.Swatch> getQuantizedColors();
+}
diff --git a/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java b/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java
new file mode 100644
index 0000000..b035535
--- /dev/null
+++ b/core/java/com/android/internal/graphics/palette/VariationalKMeansQuantizer.java
@@ -0,0 +1,154 @@
+/*
+ * 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.internal.graphics.palette;
+
+import android.util.Log;
+
+import com.android.internal.graphics.ColorUtils;
+import com.android.internal.ml.clustering.KMeans;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * A quantizer that uses k-means
+ */
+public class VariationalKMeansQuantizer implements Quantizer {
+
+    private static final String TAG = "KMeansQuantizer";
+    private static final boolean DEBUG = false;
+
+    /**
+     * Clusters closer than this value will me merged.
+     */
+    private final float mMinClusterSqDistance;
+
+    /**
+     * K-means can get stuck in local optima, this can be avoided by
+     * repeating it and getting the "best" execution.
+     */
+    private final int mInitializations;
+
+    /**
+     * Initialize KMeans with a fixed random state to have
+     * consistent results across multiple runs.
+     */
+    private final KMeans mKMeans = new KMeans(new Random(0), 30, 0);
+
+    private List<Palette.Swatch> mQuantizedColors;
+
+    public VariationalKMeansQuantizer() {
+        this(0.25f /* cluster distance */);
+    }
+
+    public VariationalKMeansQuantizer(float minClusterDistance) {
+        this(minClusterDistance, 1 /* initializations */);
+    }
+
+    public VariationalKMeansQuantizer(float minClusterDistance, int initializations) {
+        mMinClusterSqDistance = minClusterDistance * minClusterDistance;
+        mInitializations = initializations;
+    }
+
+    /**
+     * K-Means quantizer.
+     *
+     * @param pixels Pixels to quantize.
+     * @param maxColors Maximum number of clusters to extract.
+     * @param filters Colors that should be ignored
+     */
+    @Override
+    public void quantize(int[] pixels, int maxColors, Palette.Filter[] filters) {
+        // Start by converting all colors to HSL.
+        // HLS is way more meaningful for clustering than RGB.
+        final float[] hsl = {0, 0, 0};
+        final float[][] hslPixels = new float[pixels.length][3];
+        for (int i = 0; i < pixels.length; i++) {
+            ColorUtils.colorToHSL(pixels[i], hsl);
+            // Normalize hue so all values go from 0 to 1.
+            hslPixels[i][0] = hsl[0] / 360f;
+            hslPixels[i][1] = hsl[1];
+            hslPixels[i][2] = hsl[2];
+        }
+
+        final List<KMeans.Mean> optimalMeans = getOptimalKMeans(maxColors, hslPixels);
+
+        // Ideally we should run k-means again to merge clusters but it would be too expensive,
+        // instead we just merge all clusters that are closer than a threshold.
+        for (int i = 0; i < optimalMeans.size(); i++) {
+            KMeans.Mean current = optimalMeans.get(i);
+            float[] currentCentroid = current.getCentroid();
+            for (int j = i + 1; j < optimalMeans.size(); j++) {
+                KMeans.Mean compareTo = optimalMeans.get(j);
+                float[] compareToCentroid = compareTo.getCentroid();
+                float sqDistance = KMeans.sqDistance(currentCentroid, compareToCentroid);
+                // Merge them
+                if (sqDistance < mMinClusterSqDistance) {
+                    optimalMeans.remove(compareTo);
+                    current.getItems().addAll(compareTo.getItems());
+                    for (int k = 0; k < currentCentroid.length; k++) {
+                        currentCentroid[k] += (compareToCentroid[k] - currentCentroid[k]) / 2.0;
+                    }
+                    j--;
+                }
+            }
+        }
+
+        // Convert data to final format, de-normalizing the hue.
+        mQuantizedColors = new ArrayList<>();
+        for (KMeans.Mean mean : optimalMeans) {
+            if (mean.getItems().size() == 0) {
+                continue;
+            }
+            float[] centroid = mean.getCentroid();
+            mQuantizedColors.add(new Palette.Swatch(new float[]{
+                    centroid[0] * 360f,
+                    centroid[1],
+                    centroid[2]
+            }, mean.getItems().size()));
+        }
+    }
+
+    private List<KMeans.Mean> getOptimalKMeans(int k, float[][] inputData) {
+        List<KMeans.Mean> optimal = null;
+        double optimalScore = -Double.MAX_VALUE;
+        int runs = mInitializations;
+        while (runs > 0) {
+            if (DEBUG) {
+                Log.d(TAG, "k-means run: " + runs);
+            }
+            List<KMeans.Mean> means = mKMeans.predict(k, inputData);
+            double score = KMeans.score(means);
+            if (optimal == null || score > optimalScore) {
+                if (DEBUG) {
+                    Log.d(TAG, "\tnew optimal score: " + score);
+                }
+                optimalScore = score;
+                optimal = means;
+            }
+            runs--;
+        }
+
+        return optimal;
+    }
+
+    @Override
+    public List<Palette.Swatch> getQuantizedColors() {
+        return mQuantizedColors;
+    }
+}
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index ddf07f4..1811800c 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.text.TextUtils;
 
@@ -35,6 +36,7 @@
         return pulseOnNotificationEnabled(user)
                 || pulseOnPickupEnabled(user)
                 || pulseOnDoubleTapEnabled(user)
+                || pulseOnLongPressEnabled(user)
                 || alwaysOnEnabled(user);
     }
 
@@ -52,8 +54,8 @@
     }
 
     public boolean pulseOnPickupEnabled(int user) {
-        return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user)
-                && pulseOnPickupAvailable();
+        boolean settingEnabled = boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user);
+        return (settingEnabled || alwaysOnEnabled(user)) && pulseOnPickupAvailable();
     }
 
     public boolean pulseOnPickupAvailable() {
@@ -61,6 +63,10 @@
                 && ambientDisplayAvailable();
     }
 
+    public boolean pulseOnPickupCanBeModified(int user) {
+        return !alwaysOnEnabled(user);
+    }
+
     public boolean pulseOnDoubleTapEnabled(int user) {
         return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, user)
                 && pulseOnDoubleTapAvailable();
@@ -74,24 +80,54 @@
         return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
     }
 
+    public String longPressSensorType() {
+        return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
+    }
+
+    public boolean pulseOnLongPressEnabled(int user) {
+        return pulseOnLongPressAvailable() && boolSettingDefaultOff(
+                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);
+    }
+
+    private boolean pulseOnLongPressAvailable() {
+        return !TextUtils.isEmpty(longPressSensorType());
+    }
+
     public boolean alwaysOnEnabled(int user) {
-        return boolSettingDefaultOff(Settings.Secure.DOZE_ALWAYS_ON, user)
-                && alwaysOnAvailable();
+        return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user) && alwaysOnAvailable()
+                && !accessibilityInversionEnabled(user);
     }
 
     public boolean alwaysOnAvailable() {
-        // Does not work properly yet.
-        return false;
+        return (alwaysOnDisplayDebuggingEnabled() || alwaysOnDisplayAvailable())
+                && ambientDisplayAvailable();
+    }
+
+    public boolean alwaysOnAvailableForUser(int user) {
+        return alwaysOnAvailable() && !accessibilityInversionEnabled(user);
     }
 
     public String ambientDisplayComponent() {
         return mContext.getResources().getString(R.string.config_dozeComponent);
     }
 
+    public boolean accessibilityInversionEnabled(int user) {
+        return boolSettingDefaultOff(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, user);
+    }
+
     private boolean ambientDisplayAvailable() {
         return !TextUtils.isEmpty(ambientDisplayComponent());
     }
 
+    private boolean alwaysOnDisplayAvailable() {
+        return mContext.getResources().getBoolean(R.bool.config_dozeAlwaysOnDisplayAvailable);
+    }
+
+    private boolean alwaysOnDisplayDebuggingEnabled() {
+        return SystemProperties.getBoolean("debug.doze.aod", false) && Build.IS_DEBUGGABLE;
+    }
+
+
     private boolean boolSettingDefaultOn(String name, int user) {
         return boolSetting(name, user, 1);
     }
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/ml/clustering/KMeans.java b/core/java/com/android/internal/ml/clustering/KMeans.java
new file mode 100644
index 0000000..4d5b333
--- /dev/null
+++ b/core/java/com/android/internal/ml/clustering/KMeans.java
@@ -0,0 +1,243 @@
+/*
+ * 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.internal.ml.clustering;
+
+import android.annotation.NonNull;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Simple K-Means implementation
+ */
+public class KMeans {
+
+    private static final boolean DEBUG = false;
+    private static final String TAG = "KMeans";
+    private final Random mRandomState;
+    private final int mMaxIterations;
+    private float mSqConvergenceEpsilon;
+
+    public KMeans() {
+        this(new Random());
+    }
+
+    public KMeans(Random random) {
+        this(random, 30 /* maxIterations */, 0.005f /* convergenceEpsilon */);
+    }
+    public KMeans(Random random, int maxIterations, float convergenceEpsilon) {
+        mRandomState = random;
+        mMaxIterations = maxIterations;
+        mSqConvergenceEpsilon = convergenceEpsilon * convergenceEpsilon;
+    }
+
+    /**
+     * Runs k-means on the input data (X) trying to find k means.
+     *
+     * K-Means is known for getting stuck into local optima, so you might
+     * want to run it multiple time and argmax on {@link KMeans#score(List)}
+     *
+     * @param k The number of points to return.
+     * @param inputData Input data.
+     * @return An array of k Means, each representing a centroid and data points that belong to it.
+     */
+    public List<Mean> predict(final int k, final float[][] inputData) {
+        checkDataSetSanity(inputData);
+        int dimension = inputData[0].length;
+
+        final ArrayList<Mean> means = new ArrayList<>();
+        for (int i = 0; i < k; i++) {
+            Mean m = new Mean(dimension);
+            for (int j = 0; j < dimension; j++) {
+                m.mCentroid[j] = mRandomState.nextFloat();
+            }
+            means.add(m);
+        }
+
+        // Iterate until we converge or run out of iterations
+        boolean converged = false;
+        for (int i = 0; i < mMaxIterations; i++) {
+            converged = step(means, inputData);
+            if (converged) {
+                if (DEBUG) Log.d(TAG, "Converged at iteration: " + i);
+                break;
+            }
+        }
+        if (!converged && DEBUG) Log.d(TAG, "Did not converge");
+
+        return means;
+    }
+
+    /**
+     * Score calculates the inertia between means.
+     * This can be considered as an E step of an EM algorithm.
+     *
+     * @param means Means to use when calculating score.
+     * @return The score
+     */
+    public static double score(@NonNull List<Mean> means) {
+        double score = 0;
+        final int meansSize = means.size();
+        for (int i = 0; i < meansSize; i++) {
+            Mean mean = means.get(i);
+            for (int j = 0; j < meansSize; j++) {
+                Mean compareTo = means.get(j);
+                if (mean == compareTo) {
+                    continue;
+                }
+                double distance = Math.sqrt(sqDistance(mean.mCentroid, compareTo.mCentroid));
+                score += distance;
+            }
+        }
+        return score;
+    }
+
+    @VisibleForTesting
+    public void checkDataSetSanity(float[][] inputData) {
+        if (inputData == null) {
+            throw new IllegalArgumentException("Data set is null.");
+        } else if (inputData.length == 0) {
+            throw new IllegalArgumentException("Data set is empty.");
+        } else if (inputData[0] == null) {
+            throw new IllegalArgumentException("Bad data set format.");
+        }
+
+        final int dimension = inputData[0].length;
+        final int length = inputData.length;
+        for (int i = 1; i < length; i++) {
+            if (inputData[i] == null || inputData[i].length != dimension) {
+                throw new IllegalArgumentException("Bad data set format.");
+            }
+        }
+    }
+
+    /**
+     * K-Means iteration.
+     *
+     * @param means Current means
+     * @param inputData Input data
+     * @return True if data set converged
+     */
+    private boolean step(final ArrayList<Mean> means, final float[][] inputData) {
+
+        // Clean up the previous state because we need to compute
+        // which point belongs to each mean again.
+        for (int i = means.size() - 1; i >= 0; i--) {
+            final Mean mean = means.get(i);
+            mean.mClosestItems.clear();
+        }
+        for (int i = inputData.length - 1; i >= 0; i--) {
+            final float[] current = inputData[i];
+            final Mean nearest = nearestMean(current, means);
+            nearest.mClosestItems.add(current);
+        }
+
+        boolean converged = true;
+        // Move each mean towards the nearest data set points
+        for (int i = means.size() - 1; i >= 0; i--) {
+            final Mean mean = means.get(i);
+            if (mean.mClosestItems.size() == 0) {
+                continue;
+            }
+
+            // Compute the new mean centroid:
+            //   1. Sum all all points
+            //   2. Average them
+            final float[] oldCentroid = mean.mCentroid;
+            mean.mCentroid = new float[oldCentroid.length];
+            for (int j = 0; j < mean.mClosestItems.size(); j++) {
+                // Update each centroid component
+                for (int p = 0; p < mean.mCentroid.length; p++) {
+                    mean.mCentroid[p] += mean.mClosestItems.get(j)[p];
+                }
+            }
+            for (int j = 0; j < mean.mCentroid.length; j++) {
+                mean.mCentroid[j] /= mean.mClosestItems.size();
+            }
+
+            // We converged if the centroid didn't move for any of the means.
+            if (sqDistance(oldCentroid, mean.mCentroid) > mSqConvergenceEpsilon) {
+                converged = false;
+            }
+        }
+        return converged;
+    }
+
+    @VisibleForTesting
+    public static Mean nearestMean(float[] point, List<Mean> means) {
+        Mean nearest = null;
+        float nearestDistance = Float.MAX_VALUE;
+
+        final int meanCount = means.size();
+        for (int i = 0; i < meanCount; i++) {
+            Mean next = means.get(i);
+            // We don't need the sqrt when comparing distances in euclidean space
+            // because they exist on both sides of the equation and cancel each other out.
+            float nextDistance = sqDistance(point, next.mCentroid);
+            if (nextDistance < nearestDistance) {
+                nearest = next;
+                nearestDistance = nextDistance;
+            }
+        }
+        return nearest;
+    }
+
+    @VisibleForTesting
+    public static float sqDistance(float[] a, float[] b) {
+        float dist = 0;
+        final int length = a.length;
+        for (int i = 0; i < length; i++) {
+            dist += (a[i] - b[i]) * (a[i] - b[i]);
+        }
+        return dist;
+    }
+
+    /**
+     * Definition of a mean, contains a centroid and points on its cluster.
+     */
+    public static class Mean {
+        float[] mCentroid;
+        final ArrayList<float[]> mClosestItems = new ArrayList<>();
+
+        public Mean(int dimension) {
+            mCentroid = new float[dimension];
+        }
+
+        public Mean(float ...centroid) {
+            mCentroid = centroid;
+        }
+
+        public float[] getCentroid() {
+            return mCentroid;
+        }
+
+        public List<float[]> getItems() {
+            return mClosestItems;
+        }
+
+        @Override
+        public String toString() {
+            return "Mean(centroid: " + Arrays.toString(mCentroid) + ", size: "
+                    + mClosestItems.size() + ")";
+        }
+    }
+}
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index d327180..d64c9a1 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -132,10 +132,12 @@
                 context.getString(R.string.notification_channel_usb),
                 NotificationManager.IMPORTANCE_MIN));
 
-        channelsList.add(new NotificationChannel(
+        NotificationChannel foregroundChannel = new NotificationChannel(
                 FOREGROUND_SERVICE,
                 context.getString(R.string.notification_channel_foreground_service),
-                NotificationManager.IMPORTANCE_LOW));
+                NotificationManager.IMPORTANCE_LOW);
+        foregroundChannel.setBlockableSystem(true);
+        channelsList.add(foregroundChannel);
 
         nm.createNotificationChannels(channelsList);
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index f3632f0..f085e29 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -840,7 +840,10 @@
             if (sipper.shouldHide) {
                 if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
                         && sipper.drainType != BatterySipper.DrainType.SCREEN
-                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED) {
+                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
+                        && sipper.drainType != BatterySipper.DrainType.BLUETOOTH
+                        && sipper.drainType != BatterySipper.DrainType.WIFI
+                        && sipper.drainType != BatterySipper.DrainType.IDLE) {
                     // Don't add it if it is overcounted, unaccounted or screen
                     proportionalSmearPowerMah += sipper.totalPowerMah;
                 }
@@ -861,19 +864,19 @@
      * time.
      */
     public void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
-        final long rawRealtimeMs = SystemClock.elapsedRealtime();
         long totalActivityTimeMs = 0;
         final SparseLongArray activityTimeArray = new SparseLongArray();
         for (int i = 0, size = sippers.size(); i < size; i++) {
             final BatteryStats.Uid uid = sippers.get(i).uidObj;
             if (uid != null) {
-                final long timeMs = getForegroundActivityTotalTimeMs(uid, rawRealtimeMs);
+                final long timeMs = getProcessForegroundTimeMs(uid,
+                        BatteryStats.STATS_SINCE_CHARGED);
                 activityTimeArray.put(uid.getUid(), timeMs);
                 totalActivityTimeMs += timeMs;
             }
         }
 
-        if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
+        if (screenSipper != null && totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
             final double screenPowerMah = screenSipper.totalPowerMah;
             for (int i = 0, size = sippers.size(); i < size; i++) {
                 final BatterySipper sipper = sippers.get(i);
@@ -936,17 +939,42 @@
         return false;
     }
 
+    public long convertUsToMs(long timeUs) {
+        return timeUs / 1000;
+    }
+
+    public long convertMsToUs(long timeMs) {
+        return timeMs * 1000;
+    }
+
     @VisibleForTesting
-    public long getForegroundActivityTotalTimeMs(BatteryStats.Uid uid, long rawRealtimeMs) {
+    public long getForegroundActivityTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
         final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
         if (timer != null) {
-            return timer.getTotalTimeLocked(rawRealtimeMs, BatteryStats.STATS_SINCE_CHARGED);
+            return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
         }
 
         return 0;
     }
 
     @VisibleForTesting
+    public long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
+        final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
+        final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP};
+
+        long timeUs = 0;
+        for (int type : foregroundTypes) {
+            final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
+            timeUs += localTime;
+        }
+
+        // Return the min value of STATE_TOP time and foreground activity time, since both of these
+        // time have some errors.
+        return convertUsToMs(
+                Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
+    }
+
+    @VisibleForTesting
     public void setPackageManager(PackageManager packageManager) {
         mPackageManager = packageManager;
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 235ebc8..3bb20b4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -171,6 +171,7 @@
 
     public interface PlatformIdleStateCallback {
         public String getPlatformLowPowerStats();
+        public String getSubsystemLowPowerStats();
     }
 
     private final PlatformIdleStateCallback mPlatformIdleStateCallback;
@@ -2878,6 +2879,12 @@
                         mPlatformIdleStateCallback.getPlatformLowPowerStats();
                 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
                         mCurHistoryStepDetails.statPlatformIdleState);
+
+                mCurHistoryStepDetails.statSubsystemPowerState =
+                        mPlatformIdleStateCallback.getSubsystemLowPowerStats();
+                if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
+                        mCurHistoryStepDetails.statSubsystemPowerState);
+
             }
             computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
             if (includeStepDetails != 0) {
@@ -3590,7 +3597,12 @@
     }
 
     public void noteUidProcessStateLocked(int uid, int state) {
-        uid = mapUid(uid);
+        int parentUid = mapUid(uid);
+        if (uid != parentUid) {
+            // Isolated UIDs process state is already rolled up into parent, so no need to track
+            // Otherwise the parent's process state will get downgraded incorrectly
+            return;
+        }
         getUidStatsLocked(uid).updateUidProcessStateLocked(state);
     }
 
@@ -4845,7 +4857,7 @@
         }
     }
 
-    private void noteBluetoothScanStoppedLocked(int uid) {
+    private void noteBluetoothScanStoppedLocked(int uid, boolean isUnoptimized) {
         uid = mapUid(uid);
         final long elapsedRealtime = mClocks.elapsedRealtime();
         final long uptime = mClocks.uptimeMillis();
@@ -4857,13 +4869,13 @@
             addHistoryRecordLocked(elapsedRealtime, uptime);
             mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime);
+        getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
     }
 
-    public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws) {
+    public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            noteBluetoothScanStoppedLocked(ws.get(i));
+            noteBluetoothScanStoppedLocked(ws.get(i), isUnoptimized);
         }
     }
 
@@ -6114,14 +6126,11 @@
             }
         }
 
-        public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) {
+        public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
             if (mBluetoothScanTimer != null) {
                 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
-            // In the ble code, a scan cannot change types and nested starts are not possible.
-            // So if an unoptimizedScan is running, it is now being stopped.
-            if (mBluetoothUnoptimizedScanTimer != null
-                    && mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
+            if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) {
                 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
@@ -6546,9 +6555,12 @@
          * inactive so can be dropped.
          */
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-        public boolean reset() {
+        public boolean reset(long uptime, long realtime) {
             boolean active = false;
 
+            mOnBatteryBackgroundTimeBase.init(uptime, realtime);
+            mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
+
             if (mWifiRunningTimer != null) {
                 active |= !mWifiRunningTimer.reset(false);
                 active |= mWifiRunning;
@@ -6734,11 +6746,6 @@
             mLastStepUserTime = mLastStepSystemTime = 0;
             mCurStepUserTime = mCurStepSystemTime = 0;
 
-            mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
-                    mBsi.mClocks.uptimeMillis() * 1000);
-            mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
-                    mBsi.mClocks.uptimeMillis() * 1000);
-
             if (!active) {
                 if (mWifiRunningTimer != null) {
                     mWifiRunningTimer.detach();
@@ -9330,7 +9337,7 @@
         mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
 
         for (int i=0; i<mUidStats.size(); i++) {
-            if (mUidStats.valueAt(i).reset()) {
+            if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
                 mUidStats.remove(mUidStats.keyAt(i));
                 i--;
             }
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/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 1d26df0..89a4e17 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -33,6 +33,8 @@
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_LOW_RAM =
             SystemProperties.getBoolean("ro.config.low_ram", false);
+    public static final boolean CONFIG_SMALL_BATTERY =
+            SystemProperties.getBoolean("ro.config.small_battery", false);
 
     // ------ ro.fw.* ------------ //
     public static final boolean FW_SYSTEM_USER_SPLIT =
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 1d286fc..3ee8b47 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -112,7 +112,7 @@
                   fdsToIgnore, instructionSet, appDataDir);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
-            Trace.setTracingEnabled(true);
+            Trace.setTracingEnabled(true, runtimeFlags);
 
             // Note that this event ends at the end of handleChildProc,
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
@@ -162,7 +162,7 @@
                 uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
         // Enable tracing as soon as we enter the system_server.
         if (pid == 0) {
-            Trace.setTracingEnabled(true);
+            Trace.setTracingEnabled(true, runtimeFlags);
         }
         VM_HOOKS.postForkCommon();
         return pid;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ee19163..6d8b811 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -132,6 +132,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 +187,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) &&
@@ -751,7 +756,7 @@
             bootTimingsTraceLog.traceEnd(); // ZygoteInit
             // Disable tracing so that forked processes do not inherit stale tracing tags from
             // Zygote.
-            Trace.setTracingEnabled(false);
+            Trace.setTracingEnabled(false, 0);
 
             // Zygote process unmounts root storage spaces.
             Zygote.nativeUnmountStorageOnInit();
@@ -805,21 +810,7 @@
     private static void waitForSecondaryZygote(String socketName) {
         String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
                 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
-        while (true) {
-            try {
-                final ZygoteProcess.ZygoteState zs =
-                        ZygoteProcess.ZygoteState.connect(otherZygoteName);
-                zs.close();
-                break;
-            } catch (IOException ioe) {
-                Log.w(TAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ie) {
-            }
-        }
+        ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
     }
 
     static boolean isPreloadComplete() {
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/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 3f35c91..69184c3 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -64,6 +64,11 @@
     void onStartedWakingUp();
 
     /**
+     * Called when the device has finished waking up.
+     */
+    void onFinishedWakingUp();
+
+    /**
      * Called when the device screen is turning on.
      */
     void onScreenTurningOn(IKeyguardDrawnCallback callback);
@@ -74,6 +79,11 @@
     void onScreenTurnedOn();
 
     /**
+     * Called when the screen starts turning off.
+     */
+    void onScreenTurningOff();
+
+    /**
      * Called when the screen has turned off.
      */
     void onScreenTurnedOff();
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 8fe9100..544afd9 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3103,12 +3103,29 @@
     }
 
     /**
+     * Check if Setup or Post-Setup update is completed on TV
+     * @return true if completed
+     */
+    private boolean isTvUserSetupComplete() {
+        boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+        isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
+        return isTvSetupComplete;
+    }
+
+    /**
      * Helper method for adding launch-search to most applications. Opens the
      * search window using default settings.
      *
      * @return true if search window opened
      */
     private boolean launchDefaultSearch(KeyEvent event) {
+        if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                && !isTvUserSetupComplete()) {
+            // If we are in Setup or Post-Setup update mode on TV, consume the search key
+            return false;
+        }
         boolean result;
         final Callback cb = getCallback();
         if (cb == null || isDestroyed()) {
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index 95d714f..749d00c1 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -49,9 +49,6 @@
     // Allows snapping on the long edge in each orientation and magnets towards corners
     private static final int SNAP_MODE_LONG_EDGE_MAGNET_CORNERS = 4;
 
-    // The friction multiplier to control how slippery the PIP is when flung
-    private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
-
     // Threshold to magnet to a corner
     private static final float CORNER_MAGNET_THRESHOLD = 0.3f;
 
@@ -64,8 +61,8 @@
     private final float mDefaultSizePercent;
     private final float mMinAspectRatioForMinSize;
     private final float mMaxAspectRatioForMinSize;
+    private final int mFlingDeceleration;
 
-    private Scroller mScroller;
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
     private final int mMinimizedVisibleSize;
@@ -81,6 +78,8 @@
         mMaxAspectRatioForMinSize = res.getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
         mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
+        mFlingDeceleration = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.pip_fling_deceleration);
         onConfigurationChanged();
     }
 
@@ -107,20 +106,97 @@
      * those for the given {@param stackBounds}.
      */
     public Rect findClosestSnapBounds(Rect movementBounds, Rect stackBounds, float velocityX,
-            float velocityY) {
-        final Rect finalStackBounds = new Rect(stackBounds);
-        if (mScroller == null) {
-            final ViewConfiguration viewConfig = ViewConfiguration.get(mContext);
-            mScroller = new Scroller(mContext);
-            mScroller.setFriction(viewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER);
+            float velocityY, Point dragStartPosition) {
+        final Rect intersectStackBounds = new Rect(stackBounds);
+        final Point intersect = getEdgeIntersect(stackBounds, movementBounds, velocityX, velocityY,
+                dragStartPosition);
+        intersectStackBounds.offsetTo(intersect.x, intersect.y);
+        return findClosestSnapBounds(movementBounds, intersectStackBounds);
+    }
+
+    /**
+     * @return The point along the {@param movementBounds} that the PIP would intersect with based
+     *         on the provided {@param velX}, {@param velY} along with the position of the PIP when
+     *         the gesture started, {@param dragStartPosition}.
+     */
+    public Point getEdgeIntersect(Rect stackBounds, Rect movementBounds, float velX, float velY,
+            Point dragStartPosition) {
+        final boolean isLandscape = mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+        final int x = stackBounds.left;
+        final int y = stackBounds.top;
+
+        // Find the line of movement the PIP is on. Line defined by: y = slope * x + yIntercept
+        final float slope = velY / velX; // slope = rise / run
+        final float yIntercept = y - slope * x; // rearrange line equation for yIntercept
+        // The PIP can have two intercept points:
+        // 1) Where the line intersects with one of the edges of the screen (vertical line)
+        Point vertPoint = new Point();
+        // 2) Where the line intersects with the top or bottom of the screen (horizontal line)
+        Point horizPoint = new Point();
+
+        // Find the vertical line intersection, x will be one of the edges
+        vertPoint.x = velX > 0 ? movementBounds.right : movementBounds.left;
+        // Sub in x in our line equation to determine y position
+        vertPoint.y = findY(slope, yIntercept, vertPoint.x);
+
+        // Find the horizontal line intersection, y will be the top or bottom of the screen
+        horizPoint.y = velY > 0 ? movementBounds.bottom : movementBounds.top;
+        // Sub in y in our line equation to determine x position
+        horizPoint.x = findX(slope, yIntercept, horizPoint.y);
+
+        // Now pick one of these points -- first determine if we're flinging along the current edge.
+        // Only fling along current edge if it's a direction with space for the PIP to move to
+        int maxDistance;
+        if (isLandscape) {
+            maxDistance = velX > 0
+                    ? movementBounds.right - stackBounds.left
+                    : stackBounds.left - movementBounds.left;
+        } else {
+            maxDistance = velY > 0
+                    ? movementBounds.bottom - stackBounds.top
+                    : stackBounds.top - movementBounds.top;
         }
-        mScroller.fling(stackBounds.left, stackBounds.top,
-                (int) velocityX, (int) velocityY,
-                movementBounds.left, movementBounds.right,
-                movementBounds.top, movementBounds.bottom);
-        finalStackBounds.offsetTo(mScroller.getFinalX(), mScroller.getFinalY());
-        mScroller.abortAnimation();
-        return findClosestSnapBounds(movementBounds, finalStackBounds);
+        if (maxDistance > 0) {
+            // Only fling along the current edge if the start and end point are on the same side
+            final int startPoint = isLandscape ? dragStartPosition.y : dragStartPosition.x;
+            final int endPoint = isLandscape ? horizPoint.y : horizPoint.x;
+            final int center = movementBounds.centerX();
+            if ((startPoint < center && endPoint < center)
+                    || (startPoint > center && endPoint > center)) {
+                // We are flinging along the current edge, figure out how far it should travel
+                // based on velocity and assumed deceleration.
+                int distance = (int) (0 - Math.pow(isLandscape ? velX : velY, 2))
+                        / (2 * mFlingDeceleration);
+                distance = Math.min(distance, maxDistance);
+                // Adjust the point for the distance
+                if (isLandscape) {
+                    horizPoint.x = stackBounds.left + (velX > 0 ? distance : -distance);
+                } else {
+                    horizPoint.y = stackBounds.top + (velY > 0 ? distance : -distance);
+                }
+                return horizPoint;
+            }
+        }
+        // If we're not flinging along the current edge, find the closest point instead.
+        final double distanceVert = Math.hypot(vertPoint.x - x, vertPoint.y - y);
+        final double distanceHoriz = Math.hypot(horizPoint.x - x, horizPoint.y - y);
+        // Ensure that we're actually going somewhere
+        if (distanceVert == 0) {
+            return horizPoint;
+        }
+        if (distanceHoriz == 0) {
+            return vertPoint;
+        }
+        // Otherwise use the closest point
+        return Math.abs(distanceVert) > Math.abs(distanceHoriz) ? horizPoint : vertPoint;
+    }
+
+    private int findY(float slope, float yIntercept, float x) {
+        return (int) ((slope * x) + yIntercept);
+    }
+
+    private int findX(float slope, float yIntercept, float y) {
+        return (int) ((y - yIntercept) / slope);
     }
 
     /**
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 7d9538f..6f54b0c 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -114,5 +114,7 @@
     void addQsTile(in ComponentName tile);
     void remQsTile(in ComponentName tile);
     void clickQsTile(in ComponentName tile);
-    void handleSystemNavigationKey(in int key);
+    void handleSystemKey(in int key);
+
+    void showShutdownUi(boolean isReboot, String reason);
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 20db499..22eef07 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -75,5 +75,5 @@
     void addTile(in ComponentName tile);
     void remTile(in ComponentName tile);
     void clickTile(in ComponentName tile);
-    void handleSystemNavigationKey(in int key);
+    void handleSystemKey(in int key);
 }
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/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
index eabe3b9..ba80aea 100644
--- a/core/java/com/android/internal/util/BitUtils.java
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -18,12 +18,14 @@
 package com.android.internal.util;
 
 import android.annotation.Nullable;
+import android.text.TextUtils;
 
 import libcore.util.Objects;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.UUID;
+import java.util.function.IntFunction;
 
 /**
  * A utility class for handling unsigned integers and unsigned arithmetics, as well as syntactic
@@ -128,4 +130,26 @@
         buffer.put(bytes);
         buffer.position(original);
     }
+
+    public static boolean isBitSet(long flags, int bitIndex) {
+        return (flags & bitAt(bitIndex)) != 0;
+    }
+
+    public static long bitAt(int bitIndex) {
+        return 1L << bitIndex;
+    }
+
+    public static String flagsToString(int flags, IntFunction<String> getFlagName) {
+        StringBuilder builder = new StringBuilder();
+        int count = 0;
+        while (flags != 0) {
+            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+            flags &= ~flag;
+            if (count > 0) builder.append(", ");
+            builder.append(getFlagName.apply(flag));
+            count++;
+        }
+        TextUtils.wrap(builder, "[", "]");
+        return builder.toString();
+    }
 }
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index b8c062e..ee16ab6 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,7 +28,7 @@
     boolean getBoolean(in String key, in boolean defaultValue, in int userId);
     long getLong(in String key, in long defaultValue, in int userId);
     String getString(in String key, in String defaultValue, in int userId);
-    void setLockCredential(in String credential, int type, in String savedCredential, int userId);
+    void setLockCredential(in String credential, int type, in String savedCredential, int requestedQuality, int userId);
     void resetKeyStore(int userId);
     VerifyCredentialResponse checkCredential(in String credential, int type, int userId,
             in ICheckCredentialProgressCallback progressCallback);
@@ -49,6 +49,7 @@
     long addEscrowToken(in byte[] token, int userId);
     boolean removeEscrowToken(long handle, int userId);
     boolean isEscrowTokenActive(long handle, int userId);
-    boolean setLockCredentialWithToken(String credential, int type, long tokenHandle, in byte[] token, int userId);
+    boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
+            in byte[] token, int requestedQuality, int userId);
     void unlockUserWithToken(long tokenHandle, in byte[] token, int userId);
 }
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 6b53368..31b167d 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -22,6 +22,7 @@
 import android.text.Layout;
 import android.text.StaticLayout;
 import android.text.TextUtils;
+import android.text.method.TransformationMethod;
 import android.util.AttributeSet;
 import android.view.RemotableViewMethod;
 import android.widget.RemoteViews;
@@ -68,7 +69,12 @@
     protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
             Layout.Alignment alignment, boolean shouldEllipsize,
             TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
-        CharSequence text = getText() == null ? "" : getText();
+        TransformationMethod transformationMethod = getTransformationMethod();
+        CharSequence text = getText();
+        if (transformationMethod != null) {
+            text = transformationMethod.getTransformation(text, this);
+        }
+        text = text == null ? "" : text;
         StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
                 getPaint(), wantWidth)
                 .setAlignment(alignment)
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 0aba9c2..53a9654 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -34,6 +35,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.IStorageManager;
@@ -65,6 +67,8 @@
 
     private static final String TAG = "LockPatternUtils";
     private static final boolean DEBUG = false;
+    private static final boolean FRP_CREDENTIAL_ENABLED =
+            Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.frpcredential.enable", false);
 
     /**
      * The key to identify when the lock pattern enabled flag is being accessed for legacy reasons.
@@ -112,6 +116,11 @@
 
     public static final int CREDENTIAL_TYPE_PASSWORD = 2;
 
+    /**
+     * Special user id for triggering the FRP verification flow.
+     */
+    public static final int USER_FRP = UserHandle.USER_NULL + 1;
+
     @Deprecated
     public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
     public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
@@ -295,24 +304,39 @@
     }
 
     public void reportFailedPasswordAttempt(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
     }
 
     public void reportSuccessfulPasswordAttempt(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
     }
 
     public void reportPasswordLockout(int timeoutMs, int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return;
+        }
         getTrustManager().reportUnlockLockout(timeoutMs, userId);
     }
 
     public int getCurrentFailedPasswordAttempts(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return 0;
+        }
         return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
     }
 
     public int getMaximumFailedPasswordsForWipe(int userId) {
+        if (userId == USER_FRP && frpCredentialEnabled()) {
+            return 0;
+        }
         return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
                 null /* componentName */, userId);
     }
@@ -539,6 +563,14 @@
     }
 
     /**
+     * Records that the user has chosen a pattern at some time, even if the pattern is
+     * currently cleared.
+     */
+    public void reportPatternWasChosen(int userId) {
+        setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
+    }
+
+    /**
      * Used by device policy manager to validate the current password
      * information it has.
      */
@@ -578,7 +610,7 @@
 
         try{
             getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential,
-                    userHandle);
+                    DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
         } catch (RemoteException e) {
             // well, we tried...
         }
@@ -616,8 +648,12 @@
         boolean disabledByDefault = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_disableLockscreenByDefault);
         boolean isSystemUser = UserManager.isSplitSystemUser() && userId == UserHandle.USER_SYSTEM;
+        UserInfo userInfo = getUserManager().getUserInfo(userId);
+        boolean isDemoUser = UserManager.isDeviceInDemoMode(mContext) && userInfo != null
+                && userInfo.isDemo();
         return getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId)
-                || (disabledByDefault && !isSystemUser);
+                || (disabledByDefault && !isSystemUser)
+                || isDemoUser;
     }
 
     /**
@@ -643,7 +679,7 @@
 
             setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
             getLockSettings().setLockCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN,
-                    savedPattern, userId);
+                    savedPattern, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
 
             // Update the device encryption password.
             if (userId == UserHandle.USER_SYSTEM
@@ -656,7 +692,7 @@
                 }
             }
 
-            setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
+            reportPatternWasChosen(userId);
             onAfterChangingPassword(userId);
         } catch (RemoteException re) {
             Log.e(TAG, "Couldn't save lock pattern " + re);
@@ -757,10 +793,10 @@
      * password.
      * @param password The password to save
      * @param savedPassword The previously saved lock password, or null if none
-     * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
      * @param userHandle The userId of the user to change the password for
      */
-    public void saveLockPassword(String password, String savedPassword, int quality,
+    public void saveLockPassword(String password, String savedPassword, int requestedQuality,
             int userHandle) {
         try {
             if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) {
@@ -769,9 +805,9 @@
             }
 
             final int computedQuality = PasswordMetrics.computeForPassword(password).quality;
-            setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
+            setLong(PASSWORD_TYPE_KEY, Math.max(requestedQuality, computedQuality), userHandle);
             getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
-                    userHandle);
+                    requestedQuality, userHandle);
 
             updateEncryptionPasswordIfNeeded(password, computedQuality, userHandle);
             updatePasswordHistory(password, userHandle);
@@ -1125,6 +1161,10 @@
         }
     }
 
+    public boolean isVisiblePatternEverChosen(int userId) {
+        return getString(Settings.Secure.LOCK_PATTERN_VISIBLE, userId) != null;
+    }
+
     /**
      * Set whether the visible password is enabled for cryptkeeper screen.
      */
@@ -1252,6 +1292,10 @@
         return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
     }
 
+    public boolean isPowerButtonInstantlyLocksEverChosen(int userId) {
+        return getString(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, userId) != null;
+    }
+
     public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
         StringBuilder sb = new StringBuilder();
         for (ComponentName cn : activeTrustAgents) {
@@ -1458,12 +1502,13 @@
                 }
 
                 final int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
+                int quality = Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+                        computedQuality);
                 if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle,
-                        token, userId)) {
+                        token, quality, userId)) {
                     return false;
                 }
-                setLong(PASSWORD_TYPE_KEY, Math.max(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
-                        computedQuality), userId);
+                setLong(PASSWORD_TYPE_KEY, quality, userId);
 
                 updateEncryptionPasswordIfNeeded(credential, computedQuality, userId);
                 updatePasswordHistory(credential, userId);
@@ -1472,7 +1517,8 @@
                     throw new IllegalArgumentException("password must be emtpy for NONE type");
                 }
                 if (!getLockSettings().setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE,
-                        tokenHandle, token, userId)) {
+                        tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                        userId)) {
                     return false;
                 }
                 setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
@@ -1672,7 +1718,19 @@
         setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM);
     }
 
+    public void disableSyntheticPassword() {
+        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM);
+    }
+
     public boolean isSyntheticPasswordEnabled() {
         return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0;
     }
+
+    public static boolean userOwnsFrpCredential(UserInfo info) {
+        return info != null && info.isPrimary() && info.isAdmin() && frpCredentialEnabled();
+    }
+
+    public static boolean frpCredentialEnabled() {
+        return FRP_CREDENTIAL_ENABLED;
+    }
 }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index cc1c65e..32a7a2d 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -39,6 +39,7 @@
 import android.util.AttributeSet;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.DisplayListCanvas;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
@@ -54,7 +55,6 @@
 import com.android.internal.R;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -1340,8 +1340,7 @@
 
     private final class PatternExploreByTouchHelper extends ExploreByTouchHelper {
         private Rect mTempRect = new Rect();
-        private HashMap<Integer, VirtualViewContainer> mItems = new HashMap<Integer,
-                VirtualViewContainer>();
+        private final SparseArray<VirtualViewContainer> mItems = new SparseArray<>();
 
         class VirtualViewContainer {
             public VirtualViewContainer(CharSequence description) {
@@ -1352,6 +1351,9 @@
 
         public PatternExploreByTouchHelper(View forView) {
             super(forView);
+            for (int i = VIRTUAL_BASE_VIEW_ID; i < VIRTUAL_BASE_VIEW_ID + 9; i++) {
+                mItems.put(i, new VirtualViewContainer(getTextForVirtualView(i)));
+            }
         }
 
         @Override
@@ -1369,10 +1371,6 @@
                 return;
             }
             for (int i = VIRTUAL_BASE_VIEW_ID; i < VIRTUAL_BASE_VIEW_ID + 9; i++) {
-                if (!mItems.containsKey(i)) {
-                    VirtualViewContainer item = new VirtualViewContainer(getTextForVirtualView(i));
-                    mItems.put(i, item);
-                }
                 // Add all views. As views are added to the pattern, we remove them
                 // from notification by making them non-clickable below.
                 virtualViewIds.add(i);
@@ -1383,9 +1381,9 @@
         protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
             if (DEBUG_A11Y) Log.v(TAG, "onPopulateEventForVirtualView(" + virtualViewId + ")");
             // Announce this view
-            if (mItems.containsKey(virtualViewId)) {
-                CharSequence contentDescription = mItems.get(virtualViewId).description;
-                event.getText().add(contentDescription);
+            VirtualViewContainer container = mItems.get(virtualViewId);
+            if (container != null) {
+                event.getText().add(container.description);
             }
         }
 
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index bbebcc2..7609b67 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -33,13 +33,13 @@
 @RemoteViews.RemoteView
 public class MediaNotificationView extends FrameLayout {
 
-    private final int mSmallImageSize;
     private final int mNotificationContentMarginEnd;
     private final int mNotificationContentImageMarginEnd;
     private ImageView mRightIcon;
     private View mActions;
     private View mHeader;
     private View mMainColumn;
+    private int mImagePushIn;
 
     public MediaNotificationView(Context context) {
         this(context, null);
@@ -62,6 +62,7 @@
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         int mode = MeasureSpec.getMode(widthMeasureSpec);
         boolean reMeasure = false;
+        mImagePushIn = 0;
         if (hasIcon && mode != MeasureSpec.UNSPECIFIED) {
             int size = MeasureSpec.getSize(widthMeasureSpec);
             size = size - mActions.getMeasuredWidth();
@@ -70,14 +71,15 @@
             int imageEndMargin = layoutParams.getMarginEnd();
             size -= imageEndMargin;
             int fullHeight = getMeasuredHeight();
-            if (size < fullHeight) {
-                size = mSmallImageSize;
-            } else {
+            if (size > fullHeight) {
                 size = fullHeight;
+            } else if (size < fullHeight) {
+                size = Math.max(0, size);
+                mImagePushIn = fullHeight - size;
             }
-            if (layoutParams.width != size || layoutParams.height != size) {
-                layoutParams.width = size;
-                layoutParams.height = size;
+            if (layoutParams.width != fullHeight || layoutParams.height != fullHeight) {
+                layoutParams.width = fullHeight;
+                layoutParams.height = fullHeight;
                 mRightIcon.setLayoutParams(layoutParams);
                 reMeasure = true;
             }
@@ -111,6 +113,15 @@
         }
     }
 
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (mImagePushIn > 0) {
+            mRightIcon.layout(mRightIcon.getLeft() + mImagePushIn, mRightIcon.getTop(),
+                    mRightIcon.getRight()  + mImagePushIn, mRightIcon.getBottom());
+        }
+    }
+
     private void resetHeaderIndention() {
         if (mHeader.getPaddingEnd() != mNotificationContentMarginEnd) {
             mHeader.setPaddingRelative(mHeader.getPaddingStart(),
@@ -130,8 +141,6 @@
     public MediaNotificationView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mSmallImageSize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.media_notification_expanded_image_small_size);
         mNotificationContentMarginEnd = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_end);
         mNotificationContentImageMarginEnd = context.getResources().getDimensionPixelSize(
diff --git a/core/java/com/android/internal/widget/VerifyCredentialResponse.java b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
index 48109ca..ad6020c 100644
--- a/core/java/com/android/internal/widget/VerifyCredentialResponse.java
+++ b/core/java/com/android/internal/widget/VerifyCredentialResponse.java
@@ -18,6 +18,8 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.util.Slog;
 
 /**
  * Response object for a ILockSettings credential verification request.
@@ -32,6 +34,7 @@
     public static final VerifyCredentialResponse OK = new VerifyCredentialResponse();
     public static final VerifyCredentialResponse ERROR
             = new VerifyCredentialResponse(RESPONSE_ERROR, 0, null);
+    private static final String TAG = "VerifyCredentialResponse";
 
     private int mResponseCode;
     private byte[] mPayload;
@@ -123,4 +126,29 @@
     private void setPayload(byte[] payload) {
         mPayload = payload;
     }
+
+    public VerifyCredentialResponse stripPayload() {
+        return new VerifyCredentialResponse(mResponseCode, mTimeout, new byte[0]);
+    }
+
+    public static VerifyCredentialResponse fromGateKeeperResponse(
+            GateKeeperResponse gateKeeperResponse) {
+        VerifyCredentialResponse response;
+        int responseCode = gateKeeperResponse.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
+        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            byte[] token = gateKeeperResponse.getPayload();
+            if (token == null) {
+                // something's wrong if there's no payload with a challenge
+                Slog.e(TAG, "verifyChallenge response had no associated payload");
+                response = VerifyCredentialResponse.ERROR;
+            } else {
+                response = new VerifyCredentialResponse(token);
+            }
+        } else {
+            response = VerifyCredentialResponse.ERROR;
+        }
+        return response;
+    }
 }
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/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 37d0991..18990cf 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -143,7 +143,6 @@
         try {
             return FileUtils.readTextFile(lastHeaderFile, 0, null);
         } catch (IOException e) {
-            Slog.e(TAG, "Error reading " + lastHeaderFile, e);
             return null;
         }
     }
@@ -444,6 +443,7 @@
             String currentPass = "";
             boolean foundTreeOptimization = false;
             boolean foundQuotaFix = false;
+            boolean foundTimestampAdjustment = false;
             boolean foundOtherFix = false;
             String otherFixLine = null;
             for (int i = startLineNumber; i < endLineNumber; i++) {
@@ -476,6 +476,16 @@
                     }
                 } else if (line.startsWith("Update quota info") && currentPass.equals("5")) {
                     // follows "[QUOTA WARNING]", ignore
+                } else if (line.startsWith("Timestamp(s) on inode") &&
+                        line.contains("beyond 2310-04-04 are likely pre-1970") &&
+                        currentPass.equals("1")) {
+                    Slog.i(TAG, "fs_stat, partition:" + partition + " found timestamp adjustment:"
+                            + line);
+                    // followed by next line, "Fix? yes"
+                    if (lines[i + 1].contains("Fix? yes")) {
+                        i++;
+                    }
+                    foundTimestampAdjustment = true;
                 } else {
                     line = line.trim();
                     // ignore empty msg or any msg before Pass 1
@@ -486,15 +496,17 @@
                     }
                 }
             }
-            if (!foundOtherFix && foundTreeOptimization && foundQuotaFix) {
-                // not a real fix, so clear it.
-                Slog.i(TAG, "fs_stat, partition:" + partition +
-                        " quota fix due to tree optimization");
-                stat &= ~FS_STAT_FS_FIXED;
-            } else {
+            if (foundOtherFix) {
                 if (otherFixLine != null) {
                     Slog.i(TAG, "fs_stat, partition:" + partition + " fix:" + otherFixLine);
                 }
+            } else if (foundQuotaFix && !foundTreeOptimization) {
+                Slog.i(TAG, "fs_stat, got quota fix without tree optimization, partition:" +
+                        partition);
+            } else if ((foundTreeOptimization && foundQuotaFix) || foundTimestampAdjustment) {
+                // not a real fix, so clear it.
+                Slog.i(TAG, "fs_stat, partition:" + partition + " fix ignored");
+                stat &= ~FS_STAT_FS_FIXED;
             }
         }
         return stat;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index c5279e1..3d71d1d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -188,6 +188,7 @@
         "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 6d5d71c..d64c371 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -206,6 +206,7 @@
 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",
@@ -265,8 +266,6 @@
         mArgBlockLength(argBlockLength)
 {
     SkGraphics::Init();
-    // There is also a global font cache, but its budget is specified by
-    // SK_DEFAULT_FONT_CACHE_COUNT_LIMIT and SK_DEFAULT_FONT_CACHE_LIMIT.
 
     // Pre-allocate enough space to hold a fair number of options.
     mOptions.setCapacity(20);
@@ -277,7 +276,6 @@
 
 AndroidRuntime::~AndroidRuntime()
 {
-    SkGraphics::Term();
 }
 
 /*
@@ -1310,7 +1308,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),
@@ -1412,6 +1410,7 @@
     REG_JNI(register_android_os_MemoryFile),
     REG_JNI(register_com_android_internal_os_PathClassLoaderFactory),
     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/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index b171a7e..b03c346 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -278,9 +278,7 @@
     if (!localBitmap->valid()) return nullptr;
 
     SkPixelRef& pixelRef = localBitmap->bitmap();
-    pixelRef.lockPixels();
     if (!pixelRef.pixels()) {
-        pixelRef.unlockPixels();
         return nullptr;
     }
     pixelRef.ref();
@@ -298,7 +296,6 @@
 
     SkPixelRef& pixelRef = localBitmap->bitmap();
     pixelRef.notifyPixelsChanged();
-    pixelRef.unlockPixels();
     pixelRef.unref();
     return true;
 }
@@ -331,11 +328,12 @@
     uint64_t* d = (uint64_t*)dst;
 
     for (int i = 0; i < width; i++) {
-        const float* color = SkColor4f::FromColor(*src++).vec();
+        const SkColor4f color = SkColor4f::FromColor(*src++);
         uint16_t* scratch = reinterpret_cast<uint16_t*>(d++);
-        for (int i = 0; i < 4; ++i) {
-            scratch[i] = SkFloatToHalf(color[i]);
-        }
+        scratch[0] = SkFloatToHalf(color.fR);
+        scratch[1] = SkFloatToHalf(color.fG);
+        scratch[2] = SkFloatToHalf(color.fB);
+        scratch[3] = SkFloatToHalf(color.fA);
     }
 }
 
@@ -438,7 +436,6 @@
 
 bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
         int x, int y, int width, int height, const SkBitmap& dstBitmap) {
-    SkAutoLockPixels alp(dstBitmap);
     void* dst = dstBitmap.getPixels();
     FromColorProc proc = ChooseFromColorProc(dstBitmap);
 
@@ -755,31 +752,54 @@
 
 static bool bitmapCopyTo(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src,
         SkBitmap::Allocator* alloc) {
+    LOG_ALWAYS_FATAL_IF(kIndex_8_SkColorType == dstCT &&
+            kIndex_8_SkColorType != src.colorType(), "Error, cannot copyTo kIndex8.");
+
+    SkPixmap srcPM;
+    if (!src.peekPixels(&srcPM)) {
+        return false;
+    }
+
+    SkImageInfo dstInfo = srcPM.info().makeColorType(dstCT);
+    switch (dstCT) {
+        case kRGB_565_SkColorType:
+            // copyTo() has never been strict on alpha type.  Here we set the src to opaque to
+            // allow the call to readPixels() to succeed and preserve this lenient behavior.
+            if (kOpaque_SkAlphaType != srcPM.alphaType()) {
+                srcPM = SkPixmap(srcPM.info().makeAlphaType(kOpaque_SkAlphaType), srcPM.addr(),
+                                 srcPM.rowBytes(), srcPM.ctable());
+                dstInfo = dstInfo.makeAlphaType(kOpaque_SkAlphaType);
+            }
+            break;
+        case kRGBA_F16_SkColorType:
+            // The caller does not have an opportunity to pass a dst color space.  Assume that
+            // they want linear sRGB.
+            dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
+
+            if (!srcPM.colorSpace()) {
+                // Skia needs a color space to convert to F16.  nullptr should be treated as sRGB.
+                srcPM.setColorSpace(SkColorSpace::MakeSRGB());
+            }
+            break;
+        default:
+            break;
+    }
+
+    if (!dst->setInfo(dstInfo)) {
+        return false;
+    }
+    if (!dst->tryAllocPixels(alloc, srcPM.ctable())) {
+        return false;
+    }
+
     // Skia does not support copying from kAlpha8 to types that are not alpha only.
     // We will handle this case here.
-    if (kAlpha_8_SkColorType == src.colorType() && kAlpha_8_SkColorType != dstCT) {
-        SkAutoPixmapUnlock srcUnlocker;
-        if (!src.requestLock(&srcUnlocker)) {
-            return false;
-        }
-        SkPixmap srcPixmap = srcUnlocker.pixmap();
-
-        SkImageInfo dstInfo = src.info().makeColorType(dstCT);
-        if (dstCT == kRGBA_F16_SkColorType) {
-             dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
-        }
-        if (!dst->setInfo(dstInfo)) {
-            return false;
-        }
-        if (!dst->tryAllocPixels(alloc, nullptr)) {
-            return false;
-        }
-
+    if (kAlpha_8_SkColorType == srcPM.colorType() && kAlpha_8_SkColorType != dstCT) {
         switch (dstCT) {
             case kRGBA_8888_SkColorType:
             case kBGRA_8888_SkColorType: {
                 for (int y = 0; y < src.height(); y++) {
-                    const uint8_t* srcRow = srcPixmap.addr8(0, y);
+                    const uint8_t* srcRow = srcPM.addr8(0, y);
                     uint32_t* dstRow = dst->getAddr32(0, y);
                     ToColor_SA8(dstRow, srcRow, src.width(), nullptr);
                 }
@@ -794,7 +814,7 @@
             }
             case kRGBA_F16_SkColorType: {
                for (int y = 0; y < src.height(); y++) {
-                   const uint8_t* srcRow = srcPixmap.addr8(0, y);
+                   const uint8_t* srcRow = srcPM.addr8(0, y);
                    void* dstRow = dst->getAddr(0, y);
                    ToF16_SA8(dstRow, srcRow, src.width());
                }
@@ -805,7 +825,25 @@
         }
     }
 
-    return src.copyTo(dst, dstCT, alloc);
+    SkPixmap dstPM;
+    if (!dst->peekPixels(&dstPM)) {
+        return false;
+    }
+
+    // Skia needs a color space to convert from F16.  nullptr should be treated as sRGB.
+    if (kRGBA_F16_SkColorType == srcPM.colorType() && !dstPM.colorSpace()) {
+        dstPM.setColorSpace(SkColorSpace::MakeSRGB());
+    }
+
+    // readPixels does not support color spaces with parametric transfer functions.  This
+    // works around that restriction when the color spaces are equal.
+    if (kRGBA_F16_SkColorType != dstCT && kRGBA_F16_SkColorType != srcPM.colorType() &&
+            dstPM.colorSpace() == srcPM.colorSpace()) {
+        dstPM.setColorSpace(nullptr);
+        srcPM.setColorSpace(nullptr);
+    }
+
+    return srcPM.readPixels(dstPM);
 }
 
 static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle,
@@ -1074,7 +1112,7 @@
         return NULL;
     }
 
-    SkColorTable* ctable = NULL;
+    sk_sp<SkColorTable> ctable = NULL;
     if (colorType == kIndex_8_SkColorType) {
         int count = p->readInt32();
         if (count < 0 || count > 256) {
@@ -1088,7 +1126,7 @@
             if (src == NULL) {
                 return NULL;
             }
-            ctable = new SkColorTable(src, count);
+            ctable = SkColorTable::Make(src, count);
         }
     }
 
@@ -1097,7 +1135,6 @@
     android::Parcel::ReadableBlob blob;
     android::status_t status = p->readBlob(size, &blob);
     if (status) {
-        SkSafeUnref(ctable);
         doThrowRE(env, "Could not read bitmap blob.");
         return NULL;
     }
@@ -1118,15 +1155,13 @@
         if (dupFd < 0) {
             ALOGE("Error allocating dup fd. Error:%d", errno);
             blob.release();
-            SkSafeUnref(ctable);
             doThrowRE(env, "Could not allocate dup blob fd.");
             return NULL;
         }
 
         // Map the pixels in place and take ownership of the ashmem region.
         nativeBitmap = sk_sp<Bitmap>(GraphicsJNI::mapAshmemBitmap(env, bitmap.get(),
-                ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable));
-        SkSafeUnref(ctable);
+                ctable.get(), dupFd, const_cast<void*>(blob.data()), size, !isMutable));
         if (!nativeBitmap) {
             close(dupFd);
             blob.release();
@@ -1152,15 +1187,12 @@
 
         // Copy the pixels into a new buffer.
         nativeBitmap = Bitmap::allocateHeapBitmap(bitmap.get(), ctable);
-        SkSafeUnref(ctable);
         if (!nativeBitmap) {
             blob.release();
             doThrowRE(env, "Could not allocate java pixel ref.");
             return NULL;
         }
-        bitmap->lockPixels();
         memcpy(bitmap->getPixels(), blob.data(), size);
-        bitmap->unlockPixels();
 
         // Release the blob handle.
         blob.release();
@@ -1211,7 +1243,6 @@
 
     if (bitmap.colorType() == kIndex_8_SkColorType) {
         // The bitmap needs to be locked to access its color table.
-        SkAutoLockPixels alp(bitmap);
         SkColorTable* ctable = bitmap.getColorTable();
         if (ctable != NULL) {
             int count = ctable->count();
@@ -1258,14 +1289,12 @@
         return JNI_FALSE;
     }
 
-    bitmap.lockPixels();
     const void* pSrc =  bitmap.getPixels();
     if (pSrc == NULL) {
         memset(blob.data(), 0, size);
     } else {
         memcpy(blob.data(), pSrc, size);
     }
-    bitmap.unlockPixels();
 
     blob.release();
     return JNI_TRUE;
@@ -1355,7 +1384,6 @@
         jint x, jint y) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
 
     ToColorProc proc = ChooseToColorProc(bitmap);
     if (NULL == proc) {
@@ -1387,7 +1415,6 @@
         jint x, jint y, jint width, jint height) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
 
     ToColorProc proc = ChooseToColorProc(bitmap);
     if (NULL == proc) {
@@ -1436,7 +1463,6 @@
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
     SkColor color = static_cast<SkColor>(colorHandle);
-    SkAutoLockPixels alp(bitmap);
     if (NULL == bitmap.getPixels()) {
         return;
     }
@@ -1473,7 +1499,6 @@
                                       jlong bitmapHandle, jobject jbuffer) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
     const void* src = bitmap.getPixels();
 
     if (NULL != src) {
@@ -1488,7 +1513,6 @@
                                         jlong bitmapHandle, jobject jbuffer) {
     SkBitmap bitmap;
     reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
-    SkAutoLockPixels alp(bitmap);
     void* dst = bitmap.getPixels();
 
     if (NULL != dst) {
@@ -1523,9 +1547,6 @@
         return JNI_FALSE;
     }
 
-    SkAutoLockPixels alp0(bm0);
-    SkAutoLockPixels alp1(bm1);
-
     // if we can't load the pixels, return false
     if (NULL == bm0.getPixels() || NULL == bm1.getPixels()) {
         return JNI_FALSE;
@@ -1593,7 +1614,7 @@
 
     SkBitmap result;
     HeapAllocator allocator;
-    if (!src.copyTo(&result, hwuiBitmap.info().colorType(), &allocator)) {
+    if (!bitmapCopyTo(&result, hwuiBitmap.info().colorType(), src, &allocator)) {
         doThrowRE(env, "Could not copy a hardware bitmap.");
         return NULL;
     }
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index c5bd7a5..8b2a50d 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -195,13 +195,8 @@
             return false;
         }
 
-        mBitmap->reconfigure(info, bitmap->rowBytes(), ctable);
-        mBitmap->ref();
-        bitmap->setPixelRef(mBitmap)->unref();
-
-        // since we're already allocated, we lockPixels right away
-        // HeapAllocator behaves this way too
-        bitmap->lockPixels();
+        mBitmap->reconfigure(info, bitmap->rowBytes(), sk_ref_sp(ctable));
+        bitmap->setPixelRef(sk_ref_sp(mBitmap), 0, 0);
         return true;
     }
 
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 5553a3e..4b6578b 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,9 +30,12 @@
 
 class SkColorFilterGlue {
 public:
-    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
-        SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-        SkSafeUnref(filter);
+    static void SafeUnref(SkShader* shader) {
+        SkSafeUnref(shader);
+    }
+
+    static jlong GetNativeFinalizer(JNIEnv*, jobject) {
+        return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SafeUnref));
     }
 
     static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) {
@@ -57,7 +60,7 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
+    {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer }
 };
 
 static const JNINativeMethod porterduff_methods[] = {
diff --git a/core/jni/android/graphics/GraphicBuffer.cpp b/core/jni/android/graphics/GraphicBuffer.cpp
index 73e53c6..1017cba 100644
--- a/core/jni/android/graphics/GraphicBuffer.cpp
+++ b/core/jni/android/graphics/GraphicBuffer.cpp
@@ -18,6 +18,7 @@
 
 #include "jni.h"
 #include "JNIHelp.h"
+#include <inttypes.h>
 
 #include "android_os_Parcel.h"
 #include "GraphicBuffer.h"
@@ -27,6 +28,8 @@
 
 #include <binder/Parcel.h>
 
+#include <log/log.h>
+
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 
@@ -90,9 +93,15 @@
 class GraphicBufferWrapper {
 public:
     explicit GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) {
+        LOG_ALWAYS_FATAL_IF(buffer == nullptr, "creating a null GraphicBuffer");
+    }
+    const sp<GraphicBuffer>& get() const {
+        return buffer;
     }
 
-    sp<GraphicBuffer> buffer;
+private:
+    // make sure this is immutable
+    sp<GraphicBuffer> const buffer;
 };
 
 // ----------------------------------------------------------------------------
@@ -102,6 +111,8 @@
 static jlong android_graphics_GraphicBuffer_wrap(JNIEnv* env, jobject clazz,
         jlong unwrapped) {
     sp<GraphicBuffer> b(reinterpret_cast<GraphicBuffer*>(unwrapped));
+    LOG_ALWAYS_FATAL_IF(b == nullptr,
+            "*** android_graphics_GraphicBuffer_wrap() invalid state, b is null, unwrapped=%#" PRIx64, unwrapped);
     GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(b);
     return reinterpret_cast<jlong>(wrapper);
 }
@@ -159,7 +170,7 @@
         return JNI_FALSE;
     }
 
-    sp<GraphicBuffer> buffer(wrapper->buffer);
+    sp<GraphicBuffer> buffer(wrapper->get());
 
     Rect rect(Rect::EMPTY_RECT);
     if (dirtyRect) {
@@ -217,7 +228,7 @@
     nativeCanvas->setBitmap(SkBitmap());
 
     if (wrapper) {
-        status_t status = wrapper->buffer->unlock();
+        status_t status = wrapper->get()->unlock();
         return status == 0 ? JNI_TRUE : JNI_FALSE;
     }
 
@@ -230,11 +241,12 @@
 
 static void android_graphics_GraphicBuffer_write(JNIEnv* env, jobject clazz,
         jlong wrapperHandle, jobject dest) {
+
     GraphicBufferWrapper* wrapper =
                 reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle);
     Parcel* parcel = parcelForJavaObject(env, dest);
     if (parcel) {
-        parcel->write(*wrapper->buffer);
+        parcel->write(*wrapper->get());
     }
 }
 
@@ -260,7 +272,7 @@
         jlong nativeObject = env->GetLongField(obj, gGraphicBufferClassInfo.mNativeObject);
         GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject;
         if (wrapper != NULL) {
-            sp<GraphicBuffer> buffer(wrapper->buffer);
+            sp<GraphicBuffer> buffer(wrapper->get());
             return buffer;
         }
     }
@@ -271,7 +283,7 @@
     GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(buffer);
     jobject obj = env->NewObject(gGraphicBufferClassInfo.mClass,
             gGraphicBufferClassInfo.mConstructorMethodID, buffer->getWidth(), buffer->getHeight(),
-            buffer->getPixelFormat(), buffer->getUsage(), reinterpret_cast<jlong>(wrapper));
+            buffer->getPixelFormat(), (jint)buffer->getUsage(), reinterpret_cast<jlong>(wrapper));
     return obj;
 }
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index f581e20..36ebcd7 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -456,15 +456,11 @@
     // attempting to compute our own.
     const size_t rowBytes = bitmap->rowBytes();
 
-    auto wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, ctable);
+    auto wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, sk_ref_sp(ctable));
     wrapper->getSkBitmap(bitmap);
     if (readOnly) {
         bitmap->pixelRef()->setImmutable();
     }
-    // since we're already allocated, we lockPixels right away
-    // HeapAllocator behaves this way too
-    bitmap->lockPixels();
-
     return wrapper;
 }
 
@@ -614,7 +610,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 bool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
-    mStorage = android::Bitmap::allocateHeapBitmap(bitmap, ctable);
+    mStorage = android::Bitmap::allocateHeapBitmap(bitmap, sk_ref_sp(ctable));
     return !!mStorage;
 }
 
@@ -662,20 +658,18 @@
         // storage needs
         mRecycledBitmap->reconfigure(
                 mRecycledBitmap->info().makeColorSpace(bitmap->refColorSpace()),
-                rowBytes, ctable);
+                rowBytes, sk_ref_sp(ctable));
 
         // Give the bitmap the same pixelRef as mRecycledBitmap.
         // skbug.com/4538: We also need to make sure that the rowBytes on the pixel ref
         //                 match the rowBytes on the bitmap.
         bitmap->setInfo(bitmap->info(), rowBytes);
-        mRecycledBitmap->ref();
-        bitmap->setPixelRef(mRecycledBitmap)->unref();
+        bitmap->setPixelRef(sk_ref_sp(mRecycledBitmap), 0, 0);
 
         // Make sure that the recycled bitmap has the correct alpha type.
         mRecycledBitmap->setAlphaType(bitmap->alphaType());
 
         bitmap->notifyPixelsChanged();
-        bitmap->lockPixels();
         mNeedsCopy = false;
 
         // TODO: If the dimensions of the SkBitmap are smaller than those of
@@ -723,7 +717,7 @@
 }
 
 bool AshmemPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
-    mStorage = android::Bitmap::allocateAshmemBitmap(bitmap, ctable);
+    mStorage = android::Bitmap::allocateAshmemBitmap(bitmap, sk_ref_sp(ctable));
     return !!mStorage;
 }
 
diff --git a/core/jni/android/graphics/Movie.h b/core/jni/android/graphics/Movie.h
index c0fbe4f..736890d 100644
--- a/core/jni/android/graphics/Movie.h
+++ b/core/jni/android/graphics/Movie.h
@@ -10,8 +10,9 @@
 #ifndef Movie_DEFINED
 #define Movie_DEFINED
 
-#include "SkRefCnt.h"
+#include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkRefCnt.h"
 
 class SkStreamRewindable;
 
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 5f803da..f04abec 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -63,14 +63,17 @@
 static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
         jint tileModeX, jint tileModeY) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
-    SkBitmap bitmap;
+    sk_sp<SkImage> image;
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
+        image = android::bitmap::toBitmap(env, jbitmap).makeImage();
     }
 
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!image.get()) {
+        SkBitmap bitmap;
+        image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    }
     sk_sp<SkShader> baseShader = image->makeShader(
             (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY);
 
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index b5a4b20..95cdbb5 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -83,8 +83,6 @@
     SkBitmap skBitmap;
     GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
 
-    SkAutoLockPixels alp(skBitmap);
-
     const int stride = skBitmap.width() * 4;
 
     FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 825c19f..79cc1e6 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -716,7 +716,6 @@
     int err = checkFormat(colorType, internalformat, type);
     if (err)
         return err;
-    bitmap.lockPixels();
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
@@ -743,7 +742,6 @@
         glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
     }
 error:
-    bitmap.unlockPixels();
     return err;
 }
 
@@ -762,12 +760,10 @@
     int err = checkFormat(colorType, format, type);
     if (err)
         return err;
-    bitmap.lockPixels();
     const int w = bitmap.width();
     const int h = bitmap.height();
     const void* p = bitmap.getPixels();
     glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p);
-    bitmap.unlockPixels();
     return 0;
 }
 
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 253daaa..c0f719e 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -28,6 +28,7 @@
 #include "SkDrawFilter.h"
 #include "SkGraphics.h"
 #include "SkRegion.h"
+#include "SkVertices.h"
 
 namespace android {
 
@@ -311,15 +312,15 @@
 }
 
 static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
-                         jint modeHandle, jint vertexCount,
+                         jint modeHandle, jint floatCount,
                          jfloatArray jverts, jint vertIndex,
                          jfloatArray jtexs, jint texIndex,
                          jintArray jcolors, jint colorIndex,
                          jshortArray jindices, jint indexIndex,
                          jint indexCount, jlong paintHandle) {
-    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
-    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
-    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
+    AutoJavaFloatArray  vertA(env, jverts, vertIndex + floatCount);
+    AutoJavaFloatArray  texA(env, jtexs, texIndex + floatCount);
+    AutoJavaIntArray    colorA(env, jcolors, colorIndex + floatCount);
     AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);
 
     const float* verts = vertA.ptr() + vertIndex;
@@ -334,10 +335,15 @@
         indices = (const uint16_t*)(indexA.ptr() + indexIndex);
     }
 
-    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
+    int vertexCount = floatCount >> 1;  // 2 floats per SkPoint
+    SkVertices::VertexMode mode = static_cast<SkVertices::VertexMode>(modeHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
-                                           indices, indexCount, *paint);
+    get_canvas(canvasHandle)->drawVertices(SkVertices::MakeCopy(mode, vertexCount,
+                                           reinterpret_cast<const SkPoint*>(verts),
+                                           reinterpret_cast<const SkPoint*>(texs),
+                                           reinterpret_cast<const SkColor*>(colors),
+                                           indexCount, indices).get(),
+                                           SkBlendMode::kModulate, *paint);
 }
 
 static void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index 18cf8ca..39e615c 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -325,13 +325,16 @@
 
     ALOGV("%s channel %d tuned %d", __FUNCTION__, nProgramInfo->channel, nProgramInfo->tuned);
 
+    int flags = 0;  // TODO(b/32621193): pass from the HAL
+    jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
     *jProgramInfo = env->NewObject(gRadioProgramInfoClass, gRadioProgramInfoCstor,
                                   nProgramInfo->channel, nProgramInfo->sub_channel,
                                   nProgramInfo->tuned, nProgramInfo->stereo,
                                   nProgramInfo->digital, nProgramInfo->signal_strength,
-                                  jMetadata);
+                                  jMetadata, flags, jVendorExension);
 
     env->DeleteLocalRef(jMetadata);
+    env->DeleteLocalRef(jVendorExension);
     return (jint)RADIO_STATUS_OK;
 }
 
@@ -443,19 +446,22 @@
         jstring jProduct = env->NewStringUTF(nModules[i].product);
         jstring jVersion = env->NewStringUTF(nModules[i].version);
         jstring jSerial = env->NewStringUTF(nModules[i].serial);
+        bool isBgscanSupported = false;  // TODO(b/32621193): pass from the HAL
+        jstring jVendorExension = env->NewStringUTF("");  // TODO(b/32621193): pass from the HAL
         jobject jModule = env->NewObject(gModulePropertiesClass, gModulePropertiesCstor,
                                                nModules[i].handle, nModules[i].class_id,
                                                jImplementor, jProduct, jVersion, jSerial,
                                                nModules[i].num_tuners,
                                                nModules[i].num_audio_sources,
                                                nModules[i].supports_capture,
-                                               jBands);
+                                               jBands, isBgscanSupported, jVendorExension);
 
         env->DeleteLocalRef(jImplementor);
         env->DeleteLocalRef(jProduct);
         env->DeleteLocalRef(jVersion);
         env->DeleteLocalRef(jSerial);
         env->DeleteLocalRef(jBands);
+        env->DeleteLocalRef(jVendorExension);
         if (jModule == NULL) {
             continue;
         }
@@ -882,7 +888,7 @@
     jclass modulePropertiesClass = FindClassOrDie(env, kModulePropertiesClassPathName);
     gModulePropertiesClass = MakeGlobalRefOrDie(env, modulePropertiesClass);
     gModulePropertiesCstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>",
-            "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;)V");
+            "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;ZLjava/lang/String;)V");
 
     jclass bandDescriptorClass = FindClassOrDie(env, kRadioBandDescriptorClassPathName);
     gRadioBandDescriptorClass = MakeGlobalRefOrDie(env, bandDescriptorClass);
@@ -932,7 +938,7 @@
     jclass programInfoClass = FindClassOrDie(env, kRadioProgramInfoClassPathName);
     gRadioProgramInfoClass = MakeGlobalRefOrDie(env, programInfoClass);
     gRadioProgramInfoCstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
-            "(IIZZZILandroid/hardware/radio/RadioMetadata;)V");
+            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
 
     jclass metadataClass = FindClassOrDie(env, kRadioMetadataClassPathName);
     gRadioMetadataClass = MakeGlobalRefOrDie(env, metadataClass);
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 040981d..fad5b0e 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -442,10 +442,12 @@
 
         if (threadRet != 0) {
             close(writeFd);
+            close(readFd);
 
             jniThrowExceptionFmt(env, "java/io/IOException",
                     "Failed to create thread for writing (errno = %#x, message = '%s')",
                     threadRet, strerror(threadRet));
+            return;
         }
     }
 
@@ -476,6 +478,8 @@
         } else if (!logLine.isEmpty()) {
             ALOGD("%s", logLine.string());
         }
+
+        close(readFd);
     }
 
     int res;
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 609111e..954e46e 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1761,6 +1761,14 @@
     return nativeToJavaStatus(AudioSystem::systemReady());
 }
 
+static jfloat
+android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
+                                            jint stream, jint index, jint device)
+{
+    return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
+                                                  (int)index,
+                                                  (audio_devices_t)device);
+}
 
 // ----------------------------------------------------------------------------
 
@@ -1814,6 +1822,7 @@
     {"native_register_recording_callback", "()V",
                                     (void *)android_media_AudioSystem_registerRecordingCallback},
     {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
+    {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
 };
 
 
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index fdbb1ed..37bada4 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -33,12 +33,14 @@
 #include <string>
 
 #include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
 #include <debuggerd/client.h>
 #include <log/log.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
 
-#include "JNIHelp.h"
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include "jni.h"
 #include <memtrack/memtrack.h>
 #include <memunreachable/memunreachable.h>
@@ -1038,30 +1040,34 @@
     ALOGD("Native heap dump complete.\n");
 }
 
-static void android_os_Debug_dumpNativeBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
-    jint pid, jstring fileName, jint timeoutSecs)
-{
-    if (fileName == NULL) {
-        jniThrowNullPointerException(env, "file == null");
-        return;
-    }
-    const jchar* str = env->GetStringCritical(fileName, 0);
-    String8 fileName8;
-    if (str) {
-        fileName8 = String8(reinterpret_cast<const char16_t*>(str),
-                            env->GetStringLength(fileName));
-        env->ReleaseStringCritical(fileName, str);
+static bool dumpTraces(JNIEnv* env, jint pid, jstring fileName, jint timeoutSecs,
+                       DebuggerdDumpType dumpType) {
+    const ScopedUtfChars fileNameChars(env, fileName);
+    if (fileNameChars.c_str() == nullptr) {
+        return false;
     }
 
-    int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND, 0666);
+    android::base::unique_fd fd(open(fileNameChars.c_str(),
+                                     O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
+                                     0666));
     if (fd < 0) {
-        fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno));
-        return;
+        fprintf(stderr, "Can't open %s: %s\n", fileNameChars.c_str(), strerror(errno));
+        return false;
     }
 
-    dump_backtrace_to_file_timeout(pid, kDebuggerdNativeBacktrace, timeoutSecs, fd);
+    return (dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd) == 0);
+}
 
-    close(fd);
+static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
+        jint pid, jstring fileName, jint timeoutSecs) {
+    const bool ret =  dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
+    return ret ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_os_Debug_dumpNativeBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
+        jint pid, jstring fileName, jint timeoutSecs) {
+    const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdNativeBacktrace);
+    return ret ? JNI_TRUE : JNI_FALSE;
 }
 
 static jstring android_os_Debug_getUnreachableMemory(JNIEnv* env, jobject clazz,
@@ -1104,7 +1110,9 @@
             (void*)android_os_Debug_getProxyObjectCount },
     { "getBinderDeathObjectCount", "()I",
             (void*)android_os_Debug_getDeathObjectCount },
-    { "dumpNativeBacktraceToFileTimeout", "(ILjava/lang/String;I)V",
+    { "dumpJavaBacktraceToFileTimeout", "(ILjava/lang/String;I)Z",
+            (void*)android_os_Debug_dumpJavaBacktraceToFileTimeout },
+    { "dumpNativeBacktraceToFileTimeout", "(ILjava/lang/String;I)Z",
             (void*)android_os_Debug_dumpNativeBacktraceToFileTimeout },
     { "getUnreachableMemory", "(IZ)Ljava/lang/String;",
             (void*)android_os_Debug_getUnreachableMemory },
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 8941002..fc8b8f3 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -164,8 +164,8 @@
     }
 }
 
-static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
-                                          jint offset, jint length)
+static void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                             jobject data, jint offset, jint length)
 {
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     if (parcel == NULL) {
@@ -346,6 +346,28 @@
     return ret;
 }
 
+static jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                                jobject dest, jint destLen)
+{
+    jboolean ret = JNI_FALSE;
+    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+    if (parcel == NULL) {
+        return ret;
+    }
+
+    int32_t len = parcel->readInt32();
+    if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) {
+        jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0);
+        if (ar) {
+            const void* data = parcel->readInplace(len);
+            memcpy(ar, data, len);
+            env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0);
+            ret = JNI_TRUE;
+        }
+    }
+    return ret;
+}
+
 static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
 {
     jbyteArray ret = NULL;
@@ -757,7 +779,7 @@
     // @FastNative
     {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},
 
-    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
+    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
     {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
     // @FastNative
     {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
@@ -772,6 +794,7 @@
     {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
 
     {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
+    {"nativeReadByteArray",       "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
     {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
     // @FastNative
     {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index c04c339..44f15cd 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -356,6 +356,7 @@
         case SP_FOREGROUND:
         case SP_AUDIO_APP:
         case SP_AUDIO_SYS:
+        case SP_RT_APP:
             filename = "/dev/cpuset/foreground/cpus";
             break;
         case SP_TOP_APP:
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 31e954b..c457ab0 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -233,8 +233,9 @@
     for (;;) {
         uint32_t seq;
         InputEvent* inputEvent;
+        int32_t displayId;
         status_t status = mInputConsumer.consume(&mInputEventFactory,
-                consumeBatches, frameTime, &seq, &inputEvent);
+                consumeBatches, frameTime, &seq, &inputEvent, &displayId);
         if (status) {
             if (status == WOULD_BLOCK) {
                 if (!skipCallbacks && !mBatchedInputEventPending
@@ -311,7 +312,8 @@
                     ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName());
                 }
                 env->CallVoidMethod(receiverObj.get(),
-                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
+                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj,
+                        displayId);
                 if (env->ExceptionCheck()) {
                     ALOGE("Exception dispatching input event.");
                     skipCallbacks = true;
@@ -417,7 +419,7 @@
 
     gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
             gInputEventReceiverClassInfo.clazz,
-            "dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
+            "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V");
     gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
             gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");
 
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 420ff2a..58ccef18 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -39,6 +39,8 @@
 
 // Log debug messages about the dispatch cycle.
 static const bool kDebugDispatchCycle = false;
+// Display id for default(primary) display.
+static const int32_t kDefaultDisplayId = 0;
 
 static struct {
     jclass clazz;
@@ -136,6 +138,7 @@
         publishedSeq = mNextPublishedSeq++;
         status_t status = mInputPublisher.publishMotionEvent(publishedSeq,
                 event->getDeviceId(), event->getSource(),
+                kDefaultDisplayId /* TODO(multi-display): propagate display id */,
                 event->getAction(), event->getActionButton(), event->getFlags(),
                 event->getEdgeFlags(), event->getMetaState(), event->getButtonState(),
                 event->getXOffset(), event->getYOffset(),
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ec3e06c..215a00e 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -135,6 +135,7 @@
         case PublicFormat::DEPTH16:
             return HAL_PIXEL_FORMAT_Y16;
         case PublicFormat::RAW_SENSOR:
+        case PublicFormat::RAW_DEPTH:
             return HAL_PIXEL_FORMAT_RAW16;
         default:
             // Most formats map 1:1
@@ -149,6 +150,7 @@
             return HAL_DATASPACE_V0_JFIF;
         case PublicFormat::DEPTH_POINT_CLOUD:
         case PublicFormat::DEPTH16:
+        case PublicFormat::RAW_DEPTH:
             return HAL_DATASPACE_DEPTH;
         case PublicFormat::RAW_SENSOR:
         case PublicFormat::RAW_PRIVATE:
@@ -182,8 +184,12 @@
             // Enums overlap in both name and value
             return static_cast<PublicFormat>(format);
         case HAL_PIXEL_FORMAT_RAW16:
-            // Name differs, though value is the same
-            return PublicFormat::RAW_SENSOR;
+            switch (dataSpace) {
+                case HAL_DATASPACE_DEPTH:
+                  return PublicFormat::RAW_DEPTH;
+                default:
+                  return PublicFormat::RAW_SENSOR;
+            }
         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
             // Name differs, though value is the same
             return PublicFormat::RAW_PRIVATE;
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 19fa25e..2bf8d93 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -167,7 +167,7 @@
             buffer->getWidth(),
             buffer->getHeight(),
             buffer->getPixelFormat(),
-            buffer->getUsage(),
+            (jint)buffer->getUsage(),
             (jlong)buffer.get());
 }
 
@@ -222,11 +222,20 @@
             return NULL;
         }
     }
+
+    sk_sp<SkColorSpace> colorSpace;
+    if (screenshot->getDataSpace() == HAL_DATASPACE_DISPLAY_P3) {
+        colorSpace = SkColorSpace::MakeRGB(
+                SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+    } else {
+        colorSpace = SkColorSpace::MakeSRGB();
+    }
+
     SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(),
                                                    screenshot->getHeight(),
                                                    colorType,
                                                    alphaType,
-                                                   GraphicsJNI::defaultColorSpace());
+                                                   colorSpace);
 
     const size_t rowBytes =
             screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index a635269..46b0a79 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -581,18 +581,6 @@
     mObserver->decStrong(nullptr);
 }
 
-static jboolean android_view_ThreadedRenderer_supportsOpenGL(JNIEnv* env, jobject clazz) {
-    char prop[PROPERTY_VALUE_MAX];
-    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
-        // not in the emulator
-        return JNI_TRUE;
-    }
-    // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
-    // enabled, 0 otherwise. On old emulator versions it will be undefined.
-    property_get("qemu.gles", prop, "0");
-    return atoi(prop) > 0 ? JNI_TRUE : JNI_FALSE;
-}
-
 static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
     RenderProxy::rotateProcessStatsBuffer();
 }
@@ -693,6 +681,12 @@
     proxy->setOpaque(opaque);
 }
 
+static void android_view_ThreadedRenderer_setWideGamut(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jboolean wideGamut) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->setWideGamut(wideGamut);
+}
+
 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
     LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
@@ -983,7 +977,6 @@
 const char* const kClassPathName = "android/view/ThreadedRenderer";
 
 static const JNINativeMethod gMethods[] = {
-    { "nSupportsOpenGL", "()Z", (void*) android_view_ThreadedRenderer_supportsOpenGL },
     { "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
     { "nSetProcessStatsBuffer", "(I)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
     { "nGetRenderThreadTid", "(J)I", (void*) android_view_ThreadedRenderer_getRenderThreadTid },
@@ -999,6 +992,7 @@
     { "nSetup", "(JFII)V", (void*) android_view_ThreadedRenderer_setup },
     { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
+    { "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
     { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
     { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
     { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
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/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index d6692ad..940ac22 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -45,7 +45,6 @@
 static jfieldID gDisplay_EGLDisplayFieldID;
 static jfieldID gContext_EGLContextFieldID;
 static jfieldID gSurface_EGLSurfaceFieldID;
-static jfieldID gSurface_NativePixelRefFieldID;
 static jfieldID gConfig_EGLConfigFieldID;
 
 static inline EGLDisplay getDisplay(JNIEnv* env, jobject o) {
@@ -84,7 +83,6 @@
 
     jclass surface_class = _env->FindClass("com/google/android/gles_jni/EGLSurfaceImpl");
     gSurface_EGLSurfaceFieldID = _env->GetFieldID(surface_class, "mEGLSurface", "J");
-    gSurface_NativePixelRefFieldID = _env->GetFieldID(surface_class, "mNativePixelRef", "J");
 }
 
 static const jint gNull_attrib_base[] = {EGL_NONE};
@@ -398,15 +396,6 @@
     }
     EGLDisplay dpy = getDisplay(_env, display);
     EGLSurface sur = getSurface(_env, surface);
-
-    if (sur) {
-        SkPixelRef* ref = (SkPixelRef*)(_env->GetLongField(surface,
-                gSurface_NativePixelRefFieldID));
-        if (ref) {
-            ref->unlockPixels();
-            SkSafeUnref(ref);
-        }
-    }
     return EglBoolToJBool(eglDestroySurface(dpy, sur));
 }
 
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 2641ab8..36487b3 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -53,6 +53,7 @@
     RGBA_1010102      = 0x2b,
     JPEG              = 0x100,
     DEPTH_POINT_CLOUD = 0x101,
+    RAW_DEPTH         = 0x1002, // @hide
     YV12              = 0x32315659,
     Y8                = 0x20203859, // @hide
     Y16               = 0x20363159, // @hide
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 2042bf62..0ee71bd 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -22,7 +22,6 @@
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
 import "frameworks/base/core/proto/android/service/appwidget.proto";
 import "frameworks/base/core/proto/android/service/battery.proto";
-import "frameworks/base/core/proto/android/service/graphicsstats.proto";
 import "frameworks/base/core/proto/android/service/fingerprint.proto";
 import "frameworks/base/core/proto/android/service/diskstats.proto";
 import "frameworks/base/core/proto/android/service/netstats.proto";
@@ -66,5 +65,4 @@
     android.service.notification.NotificationServiceDumpProto notification = 3004;
     android.service.pm.PackageServiceDumpProto package = 3008;
     android.service.power.PowerServiceDumpProto power = 3009;
-    android.service.GraphicsStatsServiceDumpProto graphicsstats = 3005;
 }
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index e212c43..fa645f4 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -315,7 +315,6 @@
     SettingProto boot_count = 270;
     SettingProto safe_boot_disallowed = 271;
     SettingProto device_demo_mode = 272;
-    SettingProto retail_demo_mode_constants = 273;
     SettingProto database_downgrade_reason = 274;
     SettingProto contacts_database_wal_enabled = 275;
     SettingProto multi_sim_voice_call_subscription = 276;
diff --git a/core/proto/android/service/graphicsstats.proto b/core/proto/android/service/graphicsstats.proto
index 6dbfe48..b8679b0 100644
--- a/core/proto/android/service/graphicsstats.proto
+++ b/core/proto/android/service/graphicsstats.proto
@@ -20,6 +20,7 @@
 
 option java_multiple_files = true;
 option java_outer_classname = "GraphicsStatsServiceProto";
+option optimize_for = LITE_RUNTIME;
 
 message GraphicsStatsServiceDumpProto {
     repeated GraphicsStatsProto stats = 1;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 29f67a8..9953c7e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -304,6 +304,7 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
     <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" />
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
@@ -1684,6 +1685,20 @@
     <permission android:name="android.permission.BIND_IMS_SERVICE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- 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 and remove com. prefix.
+         @hide -->
+    <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 and remove com. prefix.
+         @hide -->
+    <permission android:name="com.android.permission.BIND_EUICC_SERVICE"
+                android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -1893,6 +1908,11 @@
         android:description="@string/permdesc_useDataInBackground"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an application to set display offsets for the screen.
+         This permission is not available to third party applications. -->
+    <permission android:name="android.permission.SET_DISPLAY_OFFSET"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows a companion app to run in the background.
          <p>Protection level: normal
     -->
@@ -2753,6 +2773,13 @@
     <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to disable/enable input devices.
+         Could be used to prevent unwanted touch events
+         on a touchscreen, for example during swimming or rain.
+         @hide -->
+    <permission android:name="com.android.permission.DISABLE_INPUT_DEVICE"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
@@ -3144,6 +3171,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"
@@ -3765,6 +3797,10 @@
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
+        <service android:name="com.android.server.camera.CameraStatsJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
+
         <service android:name="com.android.server.timezone.TimeZoneUpdateIdler"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index b07f470..bea0ee5 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+        android:shareInterpolator="false" android:zAdjustment="normal">
 
     <alpha android:fromAlpha="0.6" android:toAlpha="1.0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index d23c74f..b6a0807 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -18,7 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+        android:shareInterpolator="false" android:zAdjustment="top">
 
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
deleted file mode 100644
index e0a2ba1..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..8ad305d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..887fde4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
deleted file mode 100644
index d37e8ee..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..5739df7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..58c344a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
deleted file mode 100644
index 0c604d9..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..ac699cf
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..84c5a11
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
deleted file mode 100644
index 2c3f4ff..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..372ab35
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..7fc993d6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
deleted file mode 100644
index 991c50e..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..3261626
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..36adcd0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
deleted file mode 100644
index 05fb919..0000000
--- a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..9fbc9b0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..086aefe
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_frame.9.png b/core/res/res/drawable-hdpi/toast_frame.9.png
deleted file mode 100644
index a804a8a..0000000
--- a/core/res/res/drawable-hdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/toast_frame.9.png b/core/res/res/drawable-ldpi/toast_frame.9.png
deleted file mode 100644
index e64dc75..0000000
--- a/core/res/res/drawable-ldpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..4446ea4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..4d790c6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..c401dc0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..e24d58650
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..5a9fea0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..3029695
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..d8d0b7b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..868c7f4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..83a1b69
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..269ee8e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..9f3d12e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..ca865f2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_frame.9.png b/core/res/res/drawable-mdpi/toast_frame.9.png
deleted file mode 100644
index 778e4e6..0000000
--- a/core/res/res/drawable-mdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..c4dc132
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..b14617c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..bb30773
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..a05d7d7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..8690cf4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..2cf94ce
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..e3fd200
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..0af22be
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..6cb970c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..9577e7b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..8290b98
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..abdecfb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_frame.9.png b/core/res/res/drawable-xhdpi/toast_frame.9.png
deleted file mode 100644
index 77e69c7..0000000
--- a/core/res/res/drawable-xhdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png
new file mode 100644
index 0000000..fdb2121
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png
new file mode 100644
index 0000000..9ce7e3a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png
new file mode 100644
index 0000000..e8601ce
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png
new file mode 100644
index 0000000..34928d7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png
new file mode 100644
index 0000000..23d8ba8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png
new file mode 100644
index 0000000..ef5039c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png
new file mode 100644
index 0000000..4c0f0e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png
new file mode 100644
index 0000000..8cd82da
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png
new file mode 100644
index 0000000..ecfe346
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png
new file mode 100644
index 0000000..d25288d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png
new file mode 100644
index 0000000..8e47095
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png
new file mode 100644
index 0000000..4b64a48
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_mtrl_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/toast_frame.9.png b/core/res/res/drawable-xxhdpi/toast_frame.9.png
deleted file mode 100644
index edecb63..0000000
--- a/core/res/res/drawable-xxhdpi/toast_frame.9.png
+++ /dev/null
Binary files differ
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_media_route_connecting_material.xml b/core/res/res/drawable/ic_media_route_connecting_material_dark.xml
similarity index 100%
rename from core/res/res/drawable/ic_media_route_connecting_material.xml
rename to core/res/res/drawable/ic_media_route_connecting_material_dark.xml
diff --git a/core/res/res/drawable/ic_media_route_connecting_material.xml b/core/res/res/drawable/ic_media_route_connecting_material_light.xml
similarity index 100%
copy from core/res/res/drawable/ic_media_route_connecting_material.xml
copy to core/res/res/drawable/ic_media_route_connecting_material_light.xml
diff --git a/core/res/res/drawable/ic_media_route_material.xml b/core/res/res/drawable/ic_media_route_material.xml
deleted file mode 100644
index 3e3f388..0000000
--- a/core/res/res/drawable/ic_media_route_material.xml
+++ /dev/null
@@ -1,33 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:state_enabled="true"
-        android:drawable="@android:drawable/ic_media_route_connecting_material" />
-    <item android:state_activated="true" android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-    <item android:state_enabled="true">
-        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-    <item>
-        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
-            android:tint="?attr/colorControlNormal" />
-    </item>
-</selector>
diff --git a/core/res/res/drawable/ic_media_route_material_dark.xml b/core/res/res/drawable/ic_media_route_material_dark.xml
new file mode 100644
index 0000000..eb26ac8
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_material_dark.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true"
+        android:drawable="@android:drawable/ic_media_route_connecting_material_dark" />
+    <item android:state_activated="true" android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item>
+        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/ic_media_route_material_light.xml b/core/res/res/drawable/ic_media_route_material_light.xml
new file mode 100644
index 0000000..37bbf14
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_material_light.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true"
+        android:drawable="@android:drawable/ic_media_route_connecting_material_light" />
+    <item android:state_activated="true" android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_on_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item android:state_enabled="true">
+        <bitmap android:src="@android:drawable/ic_media_route_off_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+    <item>
+        <bitmap android:src="@android:drawable/ic_media_route_disabled_mtrl_alpha"
+            android:tint="?attr/colorControlNormal" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/ic_reply_notification.xml b/core/res/res/drawable/ic_reply_notification.xml
new file mode 100644
index 0000000..88b8c5b
--- /dev/null
+++ b/core/res/res/drawable/ic_reply_notification.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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="10dp"
+        android:height="10dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M10.0,9.0L10.0,5.0l-7.0,7.0 7.0,7.0l0.0,-4.1c5.0,0.0 8.5,1.6 11.0,5.1 -1.0,-5.0 -4.0,-10.0 -11.0,-11.0z"/>
+    <path
+        android:pathData="M0 0h24v24H0z"
+        android:fillColor="#00000000"/>
+</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/drawable/notification_reply_background.xml b/core/res/res/drawable/notification_reply_background.xml
new file mode 100644
index 0000000..08e22f2
--- /dev/null
+++ b/core/res/res/drawable/notification_reply_background.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ 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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid
+        android:color="#ff757575"/>
+    <size
+        android:width="16dp"
+        android:height="16dp"/>
+</shape>
diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml
new file mode 100644
index 0000000..d57bd6a
--- /dev/null
+++ b/core/res/res/drawable/toast_frame.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 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.
+*/
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <!-- background is material_grey_200 with .9 alpha -->
+    <solid android:color="#E6EEEEEE" />
+    <corners android:radius="22dp" />
+</shape>
+
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/notification_material_media_action.xml b/core/res/res/layout/notification_material_media_action.xml
index 19a6f84..900ca2d 100644
--- a/core/res/res/layout/notification_material_media_action.xml
+++ b/core/res/res/layout/notification_material_media_action.xml
@@ -15,11 +15,12 @@
   ~ limitations under the License
   -->
 
-<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+<ImageButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
     style="@android:style/Widget.Material.Button.Borderless.Small"
     android:id="@+id/action0"
-    android:layout_width="48dp"
-    android:layout_height="48dp"
+    android:layout_width="@dimen/media_notification_action_button_size"
+    android:layout_height="@dimen/media_notification_action_button_size"
     android:paddingBottom="8dp"
     android:paddingTop="8dp"
     android:paddingStart="8dp"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 5a2bf4e..f0c980c 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -28,15 +28,15 @@
         android:id="@+id/icon"
         android:layout_width="?attr/notificationHeaderIconSize"
         android:layout_height="?attr/notificationHeaderIconSize"
-        android:layout_marginEnd="3dp"
+        android:layout_marginEnd="@dimen/notification_header_icon_margin_end"
         />
     <TextView
         android:id="@+id/app_name_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="3dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_app_name_margin_start"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:singleLine="true"
         />
     <TextView
@@ -44,8 +44,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:text="@string/notification_header_divider_symbol"
         android:visibility="gone"/>
     <TextView
@@ -53,8 +53,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:visibility="gone"
         android:singleLine="true"/>
     <TextView
@@ -62,8 +62,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?attr/notificationHeaderTextAppearance"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:text="@string/notification_header_divider_symbol"
         android:singleLine="true"
         android:visibility="gone"/>
@@ -73,8 +73,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:showRelative="true"
         android:singleLine="true"
         android:visibility="gone" />
@@ -82,21 +82,22 @@
         android:id="@+id/chronometer"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="2dp"
-        android:layout_marginEnd="2dp"
+        android:layout_marginStart="@dimen/notification_header_separating_margin"
+        android:layout_marginEnd="@dimen/notification_header_separating_margin"
         android:layout="@layout/notification_template_part_chronometer"
         android:visibility="gone"
         />
     <com.android.internal.widget.NotificationExpandButton
         android:id="@+id/expand_button"
         android:background="@null"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingTop="1dp"
+        android:layout_width="@dimen/notification_header_expand_icon_size"
+        android:layout_height="@dimen/notification_header_expand_icon_size"
+        android:paddingTop="@dimen/notification_expand_button_padding_top"
         android:visibility="gone"
         android:contentDescription="@string/expand_button_content_description_collapsed"
         />
-    <ImageView android:id="@+id/profile_badge"
+    <ImageView
+        android:id="@+id/profile_badge"
         android:layout_width="@dimen/notification_badge_size"
         android:layout_height="@dimen/notification_badge_size"
         android:layout_gravity="center"
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index ccd26fb..353a1a5 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -15,12 +15,12 @@
   ~ limitations under the License
   -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:tag="base"
-    >
+    android:tag="base" >
     <include layout="@layout/notification_template_header" />
     <LinearLayout
         android:id="@+id/notification_main_column"
@@ -31,19 +31,14 @@
         android:layout_marginEnd="@dimen/notification_content_margin_end"
         android:layout_marginTop="@dimen/notification_content_margin_top"
         android:layout_marginBottom="@dimen/notification_content_margin_bottom"
-        android:orientation="vertical"
-        >
+        android:orientation="vertical" >
         <include layout="@layout/notification_template_part_line1" />
         <include layout="@layout/notification_template_text" />
+        <include
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/notification_progress_bar_height"
+            android:layout_marginTop="@dimen/notification_progress_margin_top"
+            layout="@layout/notification_template_progress" />
     </LinearLayout>
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom"
-        android:layout_marginStart="@dimen/notification_content_margin_start"
-        android:layout_marginBottom="15dp"
-        android:layout_marginEnd="@dimen/notification_content_margin_end" >
-        <include layout="@layout/notification_template_progress" />
-    </FrameLayout>
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index 8b0b476..6b1049a 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -20,51 +20,42 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:tag="big"
-    >
+    android:tag="big" >
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="@dimen/notification_action_list_height"
-            android:orientation="vertical"
-            >
+            android:orientation="vertical" >
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="top"
-            >
+            android:layout_gravity="top" >
             <include layout="@layout/notification_template_header" />
             <LinearLayout
                 android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_gravity="top"
+                android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:layout_marginTop="@dimen/notification_content_margin_top"
                 android:layout_marginBottom="@dimen/notification_content_margin_bottom"
-                android:orientation="vertical"
-                >
+                android:orientation="vertical" >
                 <include layout="@layout/notification_template_part_line1" />
                 <include layout="@layout/notification_template_text" />
+                <include
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/notification_progress_bar_height"
+                    android:layout_marginTop="@dimen/notification_progress_margin_top"
+                    layout="@layout/notification_template_progress" />
             </LinearLayout>
-            <FrameLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_gravity="bottom"
-                android:layout_marginStart="@dimen/notification_content_margin_start"
-                android:layout_marginBottom="15dp"
-                android:layout_marginEnd="@dimen/notification_content_margin_end">
-                <include layout="@layout/notification_template_progress" />
-            </FrameLayout>
             <include layout="@layout/notification_template_right_icon" />
         </FrameLayout>
-        <ViewStub android:layout="@layout/notification_material_reply_text"
-                android:id="@+id/notification_material_reply_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-        />
+        <ViewStub
+            android:layout="@layout/notification_material_reply_text"
+            android:id="@+id/notification_material_reply_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
     </LinearLayout>
     <include layout="@layout/notification_material_action_list" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index 532f28e..cc4dd387 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -16,7 +16,8 @@
   -->
 
 <!-- Layout for the expanded media notification -->
-<com.android.internal.widget.MediaNotificationView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.MediaNotificationView
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -32,7 +33,7 @@
     />
     <include layout="@layout/notification_template_header"
         android:layout_width="match_parent"
-        android:layout_height="53dp"
+        android:layout_height="@dimen/media_notification_header_height"
         android:layout_gravity="start"/>
     <LinearLayout
         android:layout_width="match_parent"
@@ -55,15 +56,9 @@
         </LinearLayout>
         <LinearLayout
             android:id="@+id/media_actions"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="-21dp"
-            android:paddingStart="8dp"
-            android:paddingBottom="12dp"
-            android:gravity="top"
             android:orientation="horizontal"
             android:layoutDirection="ltr"
-            >
+            style="@style/NotificationMediaActionContainer" >
             <!-- media buttons will be added here -->
         </LinearLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 1aca99f..0cfe689 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -55,6 +55,7 @@
                 android:singleLine="false"
                 android:gravity="top"
                 android:visibility="gone"
+                android:textAlignment="viewStart"
                 />
         </LinearLayout>
 
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 4be53e0..2c69b90 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -31,8 +31,8 @@
         android:scaleType="centerCrop"
     />
     <include layout="@layout/notification_template_header"
-        android:layout_width="fill_parent"
-        android:layout_height="53dp" />
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/media_notification_header_height" />
     <LinearLayout
         android:id="@+id/notification_main_column"
         android:layout_width="match_parent"
@@ -61,7 +61,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="bottom|end"
             android:layout_marginStart="10dp"
-            android:layout_marginBottom="12dp"
+            android:layout_marginBottom="@dimen/media_notification_actions_padding_bottom"
             android:layoutDirection="ltr"
             android:orientation="horizontal"
             >
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index 308b30f..ca35de3 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -28,6 +28,7 @@
         android:singleLine="true"
         android:ellipsize="marquee"
         android:fadingEdge="horizontal"
+        android:textAlignment="viewStart"
         />
     <TextView android:id="@+id/text_line_1"
         android:textAppearance="@style/TextAppearance.Material.Notification"
diff --git a/core/res/res/layout/notification_template_progressbar.xml b/core/res/res/layout/notification_template_progressbar.xml
index 61480b8..98e2c03 100644
--- a/core/res/res/layout/notification_template_progressbar.xml
+++ b/core/res/res/layout/notification_template_progressbar.xml
@@ -18,6 +18,6 @@
 <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/progress"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="@dimen/notification_progress_bar_height"
     style="@style/Widget.Material.Light.ProgressBar.Horizontal"
     />
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index 65a5015..d379256 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -15,13 +15,29 @@
   ~ limitations under the License
   -->
 
-<ImageView android:id="@+id/right_icon" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="40dp"
-    android:layout_height="40dp"
-    android:layout_marginEnd="@dimen/notification_content_margin_end"
-    android:layout_marginTop="36dp"
-    android:layout_gravity="top|end"
-    android:scaleType="centerCrop"
-    />
-
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/right_icon_container"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:layout_gravity="top|end">
+    <ImageView android:id="@+id/right_icon"
+               android:layout_width="@dimen/notification_right_icon_size"
+               android:layout_height="@dimen/notification_right_icon_size"
+               android:layout_gravity="top|end"
+               android:layout_marginTop="36dp"
+               android:layout_marginEnd="@dimen/notification_content_margin_end"
+               android:scaleType="centerCrop"
+               android:importantForAccessibility="no" />
+    <ImageButton android:id="@+id/reply_icon_action"
+               android:layout_width="16dp"
+               android:layout_height="16dp"
+               android:layout_gravity="top|end"
+               android:layout_marginTop="64dp"
+               android:layout_marginEnd="12dp"
+               android:background="@drawable/notification_reply_background"
+               android:src="@drawable/ic_reply_notification"
+               android:scaleType="center"
+               android:contentDescription="@string/notification_reply_button_accessibility"
+               visiblity="gone"/>
+</FrameLayout>
 
diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml
index 20c2896..68f34c8 100644
--- a/core/res/res/layout/notification_template_text.xml
+++ b/core/res/res/layout/notification_template_text.xml
@@ -24,5 +24,6 @@
     android:fadingEdge="horizontal"
     android:gravity="top"
     android:singleLine="true"
+    android:textAlignment="viewStart"
     android:textAppearance="@style/TextAppearance.Material.Notification"
     />
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/layout/shutdown_dialog.xml b/core/res/res/layout/shutdown_dialog.xml
new file mode 100644
index 0000000..398bfb1
--- /dev/null
+++ b/core/res/res/layout/shutdown_dialog.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:gravity="center_horizontal" >
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="6" />
+
+    <TextView
+        android:id="@id/text1"
+        android:layout_width="wrap_content"
+        android:layout_height="32dp"
+        android:text="@string/shutdown_progress"
+        android:textDirection="locale"
+        android:textSize="24sp"
+        android:textAppearance="?attr/textAppearanceLarge"
+        android:gravity="center"
+        android:layout_marginBottom="24dp"
+        android:fontFamily="@string/config_headlineFontFamily"/>
+
+    <ProgressBar
+        android:id="@id/progress"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        style="?attr/progressBarStyleLarge" />
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="10" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index daa9faf..db586ec 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -29,11 +29,11 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:layout_marginHorizontal="24dp"
+        android:layout_marginVertical="15dp"
         android:layout_gravity="center_horizontal"
         android:textAppearance="@style/TextAppearance.Toast"
-        android:textColor="@color/bright_foreground_dark"
-        android:shadowColor="#BB000000"
-        android:shadowRadius="2.75"
+        android:textColor="@color/primary_text_default_material_light"
         />
 
 </LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cbc9a05..9b838d5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Diens nie verskaf nie."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Jy kan nie die beller-ID-instelling verander nie."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Geen datadiens nie"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Geen noodoproepe nie"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Geen nooddiens nie"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Geen stemdiens nie"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Geen stem- of nooddiens nie"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Word tydelik nie deur die selnetwerk by jou ligging aangebied nie"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Jou diensverskaffer het tydelik datadiens by hierdie ligging opgeskort"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Jou diensverskaffer het tydelik noodoproepe by hierdie ligging opgeskort"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Jou diensverskaffer het tydelik stemoproepe by hierdie ligging opgeskort"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Jou diensverskaffer het tydelik stem- en noodoproepe by hierdie ligging opgeskort"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk nie bereik nie"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Om die opvangs te verbeter, probeer die tipe verander wat gekies is by Stelsel &gt; Netwerk en internet &gt; Mobiele netwerke &gt; Voorkeurnetwerktipe."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Opletberigte"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB vir MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Gekoppel aan \'n USB-toebehoorsel"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tik vir meer opsies."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Oudiobykomstigheid word nie gesteun nie"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tik vir meer inligting"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-ontfouting te deaktiveer."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om taal en uitleg te kies"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Wys oor ander programme"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> word bo-oor ander programme gewys"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> wys bo-oor ander programme"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"As jy nie wil hê dat <xliff:g id="NAME">%s</xliff:g> hierdie kenmerk gebruik nie, tik om instellings oop te maak en skakel dit af."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tik om motormodus te verlaat."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Terug"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Volgende"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Slaan oor"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0f2652b..00e3ece 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"አገልግሎት አልቀረበም።"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"የደዋይ መታወቂያ ቅንብሮች  መለወጥ አትችልም፡፡"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ምንም የውሂብ አገልግሎት የለም"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ምንም የአስቸኳይ አደጋ ጥሪ የለም"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ምንም የድንገተኛ አደጋ ጥሪ አገልግሎት የለም"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ምንም የድምፅ ጥሪ አገልግሎት የለም"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ምንም የድምፅ እና የድንገተኛ አደጋ ጥሪ አገልግሎት የለም"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"ለጊዜው በአካባቢዎ ባለው የተንቀሳቃሽ ስልክ አውታረ መረብ አይቀርብም"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"የእርስዎ አገልግሎት አቅራቢ ከዚህ መገኛ አካባቢ ላይ ለጊዜው የውሂብ አገልግሎትን አግዷል"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"የእርስዎ አገልግሎት አቅራቢ ከዚህ መገኛ አካባቢ ላይ ለጊዜው የድንገተኛ አደጋ ጥሪዎችን አግዷል"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"የእርስዎ አገልግሎት አቅራቢ ከዚህ መገኛ አካባቢ ላይ ለጊዜው የድምፅ ጥሪዎችን አግዷል"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"የእርስዎ አገልግሎት አቅራቢ ከዚህ መገኛ አካባቢ ላይ ለጊዜው የድምፅ እና የድንገተኛ አደጋ ጥሪዎችን አግዷል"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"አውታረ መረብ ላይ መድረስ አይቻልም"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ቅበላን ለማሻሻል የተመረጠውን ዓይነት በሥርዓት &gt; አውታረ መረቦች እና በይነመረብ &gt; የተንቀሳቃሽ ስልክ አውታረ መረቦች &gt; ተመራጭ የአውታረ መረብ ዓይነት ላይ ለመለወጥ ይሞክሩ።"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ማንቂያዎች"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"ዩኤስቢ ለMIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ለUSB ተቀጥላ ተያይዟል"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"የኦዲዮ መለዋወጫ አይደገፍም"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ተጨማሪ መረጃ ለማግኘት መታ ያድርጉ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"የዩኤስቢ ማረሚያን ለማሰናከል መታ ያድርጉ።"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ቋንቋ እና አቀማመጥን ለመምረጥ መታ ያድርጉ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"በሌሎች መተግበሪያዎች ላይ አሳይ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> በሌሎች መተግበሪያዎች ላይ እያሳየ ነው"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> በሌሎች መተግበሪያዎች ላይ እያሳየ ነው"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ይህን ባህሪ እንዲጠቀም ካልፈለጉ ቅንብሮችን ለመክፈት መታ ያድርጉና ያጥፉት።"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ከመኪና ሁነታ ለመውጣት መታ ያድርጉ።"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ተመለስ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ቀጥሎ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ዝለል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f3f59d3..158f4e8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -94,10 +94,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"الخدمة غير متوفرة."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"لا يمكنك تغيير إعداد معرّف المتصل."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ليست هناك خدمة بيانات"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"لا يوجد اتصال في حالات الطوارئ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"لا تتوفر خدمة طوارئ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"لا تتوفر خدمة صوتية"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"لا تتوفر خدمة الصوت/الطوارئ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"مؤقتا لا تقدمها شبكة الجوال في موقعك"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"علّق مشغّل شبكة الجوّال خدمة البيانات مؤقتًا في هذا الموقع الجغرافي"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"علّق مشغّل شبكة الجوّال مكالمات الطوارئ مؤقتًا في هذا الموقع الجغرافي"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"علّق مشغّل شبكة الجوّال المكالمات الصوتية مؤقتًا في هذا الموقع الجغرافي"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"علّق مشغّل شبكة الجوّال الصوت ومكالمات الطوارئ مؤقتًا في هذا الموقع الجغرافي"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"يتعذر الوصول إلى الشبكة"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏لتحسين الاستقبال، يمكنك تجربة تغيير النوع المحدّد في النظام &gt; الشبكة والإنترنت &gt; شبكات الجوّال &gt; نوع الشبكة المفضّل."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"التنبيهات"</string>
@@ -234,7 +237,7 @@
     <string name="global_action_emergency" msgid="7112311161137421166">"الطوارئ"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"تقرير الأخطاء"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"إعداد تقرير بالأخطاء"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، يُرجى الانتظار."</string>
+    <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، الرجاء الانتظار."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"تقرير تفاعلي"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"يمكنك استخدام هذا الخيار في معظم الأحيان، حيث يتيح لك إمكانية تتبع مستوى تقدم التقرير والحصول على مزيد من المعلومات حول المشكلة وتسجيل لقطات شاشة. وقد يتم إغفال بعض الأقسام الأقل استخدامًا والتي تستغرق وقتًا طويلاً أثناء إعداد التقرير."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"تقرير كامل"</string>
@@ -260,7 +263,7 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"المحتويات مخفية"</string>
     <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"تم إخفاء المحتويات بواسطة السياسة"</string>
-    <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"لوحة المفاتيح الافتراضية"</string>
+    <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"لوحة المفاتيح الظاهرية"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"لوحة المفاتيح الفعلية"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"الأمان"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"وضع السيارة"</string>
@@ -270,7 +273,7 @@
     <string name="notification_channel_network_status" msgid="5025648583129035447">"حالة الشبكة"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"تنبيهات الشبكة"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"الشبكة متوفرة"</string>
-    <string name="notification_channel_vpn" msgid="8330103431055860618">"حالة الشبكة الافتراضية الخاصة"</string>
+    <string name="notification_channel_vpn" msgid="8330103431055860618">"حالة الشبكة الظاهرية الخاصة"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"إدارة الجهاز"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"التنبيهات"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"عرض توضيحي لبائع التجزئة"</string>
@@ -1208,7 +1211,7 @@
     <item msgid="75483255295529161">"Wi-Fi"</item>
     <item msgid="6862614801537202646">"بلوتوث"</item>
     <item msgid="5447331121797802871">"إيثرنت"</item>
-    <item msgid="8257233890381651999">"‏شبكة افتراضية خاصة (VPN)"</item>
+    <item msgid="8257233890381651999">"‏شبكة ظاهرية خاصة (VPN)"</item>
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"نوع شبكة غير معروف"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"‏تعذر الاتصال بـ Wi-Fi"</string>
@@ -1273,6 +1276,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB لـ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏الاتصال بجهاز USB ملحق"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"انقر للحصول على المزيد من الخيارات."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ملحق الصوت غير متوافق"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"انقر للحصول على مزيد من المعلومات"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏انقر لتعطيل تصحيح أخطاء USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏اختيار تعطيل تصحيح أخطاء USB."</string>
@@ -1284,12 +1289,13 @@
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"رفض"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغيير لوحة المفاتيح"</string>
     <string name="show_ime" msgid="2506087537466597099">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
-    <string name="hardware" msgid="194658061510127999">"إظهار لوحة المفاتيح الافتراضية"</string>
+    <string name="hardware" msgid="194658061510127999">"إظهار لوحة المفاتيح الظاهرية"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"تهيئة لوحة المفاتيح الفعلية"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"انقر لاختيار لغة وتنسيق"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"إظهار فوق التطبيقات الأخرى"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"جارٍ عرض <xliff:g id="NAME">%s</xliff:g> فوق تطبيقات أخرى"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"يتم عرض <xliff:g id="NAME">%s</xliff:g> فوق التطبيقات الأخرى."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"إذا كنت لا تريد أن يستخدم <xliff:g id="NAME">%s</xliff:g> هذه الميزة، فانقر لفتح الإعدادات، ثم اختر تعطيلها."</string>
@@ -1372,14 +1378,14 @@
     <string name="vr_listener_binding_label" msgid="4316591939343607306">"مستمع واقع افتراضي"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"موفر الحالة"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"خدمة ترتيب أهمية الإشعارات"</string>
-    <string name="vpn_title" msgid="19615213552042827">"‏تم تنشيط الشبكة الافتراضية الخاصة (VPN)"</string>
+    <string name="vpn_title" msgid="19615213552042827">"‏تم تنشيط الشبكة الظاهرية الخاصة (VPN)"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"‏تم تنشيط VPN بواسطة <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="1610714069627824309">"انقر لإدارة الشبكة."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"تم الاتصال بـ <xliff:g id="SESSION">%s</xliff:g>. انقر لإدارة الشبكة."</string>
-    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏جارٍ الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل..."</string>
-    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏تم الاتصال بشبكة افتراضية خاصة (VPN) دائمة التشغيل"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏تم فصل الشبكة الافتراضية الخاصة (VPN) دائمة التشغيل"</string>
-    <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏خطأ بشبكة افتراضية خاصة (VPN) دائمة التشغيل"</string>
+    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏جارٍ الاتصال بشبكة ظاهرية خاصة (VPN) دائمة التشغيل..."</string>
+    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"‏تم الاتصال بشبكة ظاهرية خاصة (VPN) دائمة التشغيل"</string>
+    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"‏تم فصل الشبكة الظاهرية الخاصة (VPN) دائمة التشغيل"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"‏خطأ بشبكة ظاهرية خاصة (VPN) دائمة التشغيل"</string>
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"انقر للإعداد."</string>
     <string name="upload_file" msgid="2897957172366730416">"اختيار ملف"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"لم يتم اختيار أي ملف"</string>
@@ -1389,8 +1395,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"انقر للخروج من وضع السيارة."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم تعطيل التوصيل"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
     <string name="back_button_label" msgid="2300470004503343439">"رجوع"</string>
     <string name="next_button_label" msgid="1080555104677992408">"التالي"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"تخطي"</string>
@@ -1719,7 +1723,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>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 75fe7f4..2bce668 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Xidmət təmin edilməyib."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Çağrı kimliyi ayarını dəyişə bilməzsiniz."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Data xidməti yoxdur"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Təcili zəng yoxdur"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Təcili xidmət yoxdur"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Səsli xidmət yoxdur"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Səsli/təcili xidmət yoxdur"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Müvəqqəti olaraq məkanda mobil şəbəkə tərəfindən təklif edilmir"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operator müvəqqəti olaraq bu məkanda data xidmətini dayandırıb"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operator müvəqqəti olaraq bu məkanda təcili zəngləri dayandırıb"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operator müvəqqəti olaraq bu məkanda səsli zəngləri dayandırıb"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operator müvəqqəti olaraq bu məkanda səsli və təcili zəngləri dayandırıb"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Şəbəkəyə daxil olmaq mümkün deyil"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Qəbulu inkişaf etdirmək üçün seçilmiş növü Sistem &gt; Şəbəkə və İnternet &gt; Mobil şəbəkə &gt; Tərcih edilən şəbəkə növü bölməsində dəyişə bilərsiniz."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Siqnallar"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI üçün USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuara qoşuldu"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Əlavə seçimlər üçün tıklayın."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio aksesuar dəstəklənmir"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Daha çox məlumat üçün klikləyin"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB debaqı deaktivasiya etmək üçün tıklayın."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dil və tərtibatı seçmək üçün tıklayın"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Digər tətbiqlər üzərindən görüntüləyin"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> digər tətbiqlər üzərindən göstərilir"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> tətbiq üzərindən göstərilir"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> adlı şəxsin bu funksiyadan istifadə etməyini istəmirsinizsə, ayarları açmaq və deaktiv etmək üçün klikləyin."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Avtomobil rejimindən çıxmaq üçün tıklayın."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Geri"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Növbəti"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Keç"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 8828633..6203907 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -90,17 +90,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: Nije ograničen."</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Usluga nije dobavljena."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete da promenite podešavanje ID-a korisnika."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga za podatke je blokirana."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Usluga za hitne slučajeve je blokirana."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Glasovna usluga je blokirana."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve glasovne usluge su blokirane."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Glasovna usluga/usluga prenosa podataka su blokirane."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Glasovna usluga i SMS usluga su blokirane."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Sve glasovne i SMS usluge, kao i usluge prenosa podataka su blokirane."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prenosa podataka"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne pozive"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema glasovne usluge"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovne usluge/usluge za hitne pozive"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Mobilni operater je privremeno suspendovao uslugu prenosa podataka na ovoj lokaciji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Mobilni operater je privremeno suspendovao hitne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Mobilni operater je privremeno suspendovao glasovne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Mobilni operater je privremeno suspendovao glasovne i hitne pozive na ovoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezivanje sa mrežom nije uspelo"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Da biste poboljšali prijem, probajte da promenite izabrani tip u odeljku Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Željeni tip mreže."</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"Obaveštenja"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"Preusmeravanje poziva"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Režim za hitan povratni poziv"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Obaveštenja za mobilne podatke"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-ovi"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Pozivanje preko Wi-Fi mreže"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Korisnik zahteva POTPUN režim TTY"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Korisnik zahteva PRENOS ZVUKA za režim TTY"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Korisnik zahteva PRENOS GLASA za režim TTY"</string>
@@ -140,8 +146,7 @@
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +185,16 @@
       <item quantity="other">Instalirani su autoriteti za izdavanje sertifikata</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od strane nepoznate treće strane"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Od strane administratora profila za posao"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Od strane administratora profila za Work"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od strane <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je izbrisan"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je izbrisan jer nedostaje administratorska aplikacija."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Administratorska aplikacija poslovnog profila nedostaje ili je oštećena. Zbog toga su vaš poslovni profil i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za Work više nije dostupan na ovom uređaju."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Profil za Work je izbrisan jer nedostaje aplikacija za administratore"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil za Work više nije dostupan na ovom uređaju"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti obrisan"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Administratorskoj aplikaciji nedostaju neke komponente ili je oštećena i ne može da se koristi. Uređaj će sada biti obrisan. Obratite se administratoru za pomoć."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije za tablet"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -260,11 +263,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Obaveštenja u vezi sa mrežom"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administriranje uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije pokrenute u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> radi u pozadini"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) su pokrenute u pozadini"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Pređi na Lični profil"</string>
@@ -287,15 +296,13 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"upućuje telefonske pozive i upravlja njima"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori za telo"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vitalnim funkcijama"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"da preuzima sadržaj prozora"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi Istraživanja dodirom"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"da uključi Istraživanja dodirom"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete će biti izgovorene naglas, a možete da se krećete po ekranu pokretima."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Uključi poboljšanu pristupačnost veba"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Mogu da se instaliraju skripte da bi sadržaj aplikacija bio pristupačniji."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"da prati tekst koji unosite"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Upravljaj uvećanjem prikaza"</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"da upravlja uvećanjem prikaza"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obavljanje pokreta"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
@@ -413,8 +420,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Dozvoljava aplikaciji da pristupa funkcijama telefona na uređaju. Ova dozvola omogućava aplikaciji da utvrdi broj telefona i ID-ove uređaja, zatim da li je poziv aktivan, kao i broj daljinskog uređaja sa kojim je uspostavljen poziv."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"preusmeravanje poziva preko sistema"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dozvoljava aplikaciji da preusmerava pozive preko sistema da bi poboljšala doživljaj pozivanja."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje broja telefona"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dozvoljava aplikaciji da pristupa broju telefona na uređaju."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje brojeva telefona"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji da pristupa brojevima telefona na uređaju."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje prelaska tableta u stanje spavanja"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"sprečavanje TV-a da pređe u stanje spavanja"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje prelaska telefona u stanje spavanja"</string>
@@ -487,6 +494,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Probajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Probajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Previše pokušaja. Senzor za otisak prsta je onemogućen."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -554,7 +562,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Podešavanje pravila za lozinku"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledanje pokušaja otključavanja ekrana"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Nadgledajte pokušaje otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Nadgleda broj netačnih lozinki koje unesete pri otključavanju ekrana i zaključava TV ili briše sve podatke sa njega ako se unese previše netačnih lozinki."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
@@ -841,7 +849,7 @@
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji da dodaje poruke u prijemno sanduče govorne pošte."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmena dozvola za geografske lokacije Pregledača"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb sajtovima."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb-sajtovima."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da pregledač zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -990,8 +998,7 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Izaberi tekst"</string>
     <string name="undo" msgid="7905788502491742328">"Opozovi"</string>
     <string name="redo" msgid="7759464876566803888">"Ponovi"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Izbor teksta"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rečnik"</string>
     <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
@@ -999,8 +1006,8 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje u vezi sa tekstom"</string>
     <string name="email" msgid="4560673117055050403">"Pošalji imejl"</string>
     <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pregledaj"</string>
+    <string name="map" msgid="6068210738233985748">"Mape"</string>
+    <string name="browse" msgid="6993590095938149861">"Pregledač"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memorijski prostor je na izmaku"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda ne funkcionišu"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
@@ -1043,7 +1050,7 @@
     <string name="noApplications" msgid="2991814273936504689">"Nijedna aplikacija ne može da obavlja ovu radnju."</string>
     <string name="aerr_application" msgid="250320989337856518">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
-    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
+    <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja(ju)"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Ponovo otvori aplikaciju"</string>
     <string name="aerr_report" msgid="5371800241488400617">"Pošaljite povratne informacije"</string>
@@ -1114,6 +1121,16 @@
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obaveštenja"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1123,7 +1140,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"mobilni podaci"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Eternet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznat tip mreže"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nije moguće povezati sa Wi-Fi mrežom"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1187,13 +1210,15 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Povezano sa USB dodatkom"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za još opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Dodatna oprema za audio sadržaj nije podržana"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deli se izveštaj o grešci…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELI"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
@@ -1203,8 +1228,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste izabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplik. <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplik."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite ovu funkciju za <xliff:g id="NAME">%s</xliff:g>, dodirnite da biste otvorili podešavanja i isključili je."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> se priprema"</string>
@@ -1223,7 +1250,7 @@
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"Uređaj <xliff:g id="NAME">%s</xliff:g> je uklonjen; umetnite novi"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"<xliff:g id="NAME">%s</xliff:g> se još uvek izbacuje…"</string>
     <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Ne uklanjajte"</string>
-    <string name="ext_media_init_action" msgid="7952885510091978278">"Podesi"</string>
+    <string name="ext_media_init_action" msgid="7952885510091978278">"Aktiviraj"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izbaci"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"Istraži"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string>
@@ -1296,7 +1323,7 @@
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite da biste podesili"</string>
     <string name="upload_file" msgid="2897957172366730416">"Odaberi datoteku"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nije izabrana nijedna datoteka"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+    <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
     <string name="submit" msgid="1602335572089911941">"Pošalji"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Režim rada u automobilu je omogućen"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite da biste izašli iz režima rada u automobilu."</string>
@@ -1330,7 +1357,7 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"Izbriši stavke"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Opozovi brisanja"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"Izbor naloga"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Izaberite nalog"</string>
     <string name="add_account_label" msgid="2935267344849993553">"Dodaj nalog"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj nalog"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Povećavanje"</string>
@@ -1380,8 +1407,7 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za potrošnju i podešavanja."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Nema više 2G-3G podataka"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Nema više 4G podataka"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostigli ste ograničenje podataka"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Nema više Wi-Fi podataka"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Potrošili ste podatke za ovaj mesec"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Prekoračen prenos 2G-3G podataka"</string>
@@ -1480,18 +1506,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tako što ćete istovremeno zadržati oba dugmeta za jačinu zvuka 3 sekunde.\n\nMožete da promenite uslugu u odeljku Podešavanja &gt; Pristupačnost."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li da koristite prečicu za pristupačnost?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti.\n\n Aktuelna funkcija pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Možete da promenite funkciju u odeljku Podešavanja &gt; Pristupačnost."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pritisnite i zadržite dugme za pristupačnost da biste menjali funkcije."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administrator nije dozvolio ovu promenu"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Administrator nije dozvolio ovu promenu"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1583,7 +1612,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da biste omogućili"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite PIN administratora"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Unesite PIN administratora"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelni PIN"</string>
@@ -1612,17 +1641,17 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i zadržite Nazad i Pregled."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je zakačena: otkačinjanje nije dozvoljeno na ovom uređaju."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija ne može da se otkači"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži šablon za otključavanje pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku pre otkačinjanja"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao je vaš administrator"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao je administrator"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao je vaš admiistrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi produžila vreme trajanja baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Imejl, razmena poruka i druge aplikacije koje se oslanjaju na sinhronizaciju možda neće da se ažuriraju ako ih ne otvorite.\n\nUšteda baterije se automatski isključuje kada se uređaj puni."</string>
+    <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je administrator"</string>
+    <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je administrator"</string>
+    <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je administrator"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi produžila vreme trajanja baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Imejl, razmena poruka i druge aplikacije koje se oslanjaju na sinhronizaciju neće se ažurirati dok ih ne otvorite.\n\nUšteda baterije se automatski isključuje kada se uređaj puni."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1703,7 +1732,7 @@
       <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
       <item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
     </plurals>
-    <string name="default_notification_channel_label" msgid="6950908610709016902">"Razno"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizovano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi podešavate važnost ovih obaveštenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Želite li da dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da napravi novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1715,8 +1744,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Svi regioni"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Pretraži"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Režim za Work je ISKLJUČEN"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Dozvoljava profilu za Work da funkcioniše, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Uključiti režim za Work?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Ovo će uključiti profil za Work, uključujući aplikacije, sinhronizaciju u pozadini i srodne funkcije."</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite aplikaciju za SMS da biste pregledali"</string>
@@ -1759,22 +1788,33 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Unesite vreme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pređite u režim unosa teksta radi unosa vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pređite u režim sata radi unosa vremena."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Želite li da sačuvate u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije automatskog popunjavanja"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Sačuvajte za automatsko popunjavanje"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaj ne može automatski da se popuni"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Nema automatski popunjenih predloga"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjen predlog</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjena predloga</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> automatski popunjenih predloga</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Želite li da sačuvate u: &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Želite li da sačuvate stavku <xliff:g id="TYPE">%1$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Želite li da sačuvate stavke <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> u: &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"imejl adresa"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite mirni i potražite sklonište u okolini."</string>
+    <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>
     <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>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index d12a104..db163bf 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="8340973892742019101">"B"</string>
+    <string name="byteShort" msgid="8340973892742019101">"б"</string>
     <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
     <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
     <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
@@ -91,17 +91,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Налады ідэнтыфікатару АВН па змаўчанні: не абмяжавана. Наступны выклік: не абмежавана"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Служба не прадастаўляецца."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Служба дадзеных блакуецца."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Аварыйная служба блакуецца."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Галасавая служба заблакаваная."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Усе галасавыя службы заблакаваны."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"Служба SMS заблакаваная."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Службы перадачы голаса/дадзеных заблакаваны."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Службы перадачы голаса і SMS заблакаваныя."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Усе службы перадачы дадзеных, галасавыя і SMS-службы заблакаваны."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Няма сэрвісу перадачы даных"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Няма сэрвісу экстранных выклікаў"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма сэрвісу галасавых выклікаў"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма сэрвісу галасавых / экстранных выклікаў"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Ваш аператар часова прыпыніў працу сэрвісу перадачы даных у гэтым месцы"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Ваш аператар часова прыпыніў працу сэрвісу экстранных выклікаў у гэтым месцы"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Ваш аператар часова прыпыніў працу сэрвісу галасавых выклікаў у гэтым месцы"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Ваш аператар часова прыпыніў працу сэрвісу галасавых і экстранных выклікаў у гэтым месцы"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Немагчыма падключыцца да сеткі"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Каб палепшыць якасць прыёму, паспрабуйце змяніць тып, выбраны ў меню \"Сістэма &gt; Сетка і інтэрнэт &gt; Мабільныя сеткі &gt; Прыярытэтны тып сеткі\"."</string>
+    <string name="notification_channel_network_alert" msgid="4427736684338074967">"Абвесткі"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"Пераадрасацыя выкліку"</string>
+    <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Рэжым экстраннага зваротнага выкліку"</string>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Абвесткі пра мабільныя даныя"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-паведамленні"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Паведамленні галасавой пошты"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-тэлефанія"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Аднарангавая прылада запытала рэжым TTY FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Аднарангавая прылада запытала рэжым TTY НСО"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Аднарангавая прылада запытала рэжым TTY VCO"</string>
@@ -141,8 +147,7 @@
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Толькі Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -182,18 +187,16 @@
       <item quantity="other">Усталяваны цэнтры сертыфікацыі</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Невядомая трэцяя асоба"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Адміністратар вашага працоўнага профілю"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Адміністратар вашага працоўнага профілю"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Рабочы профіль выдалены"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Рабочы профіль выдалены з-за адсутнасці праграмы адміністравання."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Праграма для адміністравання рабочага профілю адсутнічае або пашкоджана. У выніку гэтага ваш рабочы профіль і звязаныя з ім даныя былі выдаленыя. Звярніцеся па дапамогу да адміністратара."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Ваш працоўны профіль больш не даступны на гэтай прыладзе."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Працоўны профіль выдалены з-за адсутнасці праграмы адміністратара"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Прылада знаходзіцца пад кіраваннем"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Даныя вашай прылады будуць сцерты"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Праграма для адміністравання не можа быць выкарыстана, таму што ў яе адсутнічаюць кампаненты або яна пашкоджана. Зараз даныя вашай прылады будуць сцерты. Звярніцеся па дапамогу да адміністратара."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Немагчыма выкарыстоўваць праграму адміністратара. Зараз звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара вашай арганізацыі."</string>
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Параметры планшэта"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Параметры ТБ"</string>
@@ -244,7 +247,7 @@
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Бязгучны рэжым"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Гук выкл."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Гук уключаны"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Рэжым \"У самалёце\""</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Рэжым палёту"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Уключаны рэжым \"У самалёце\""</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Рэжым \"У самалёце\" адключаны"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Налады"</string>
@@ -263,11 +266,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Абнаўленні"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Стан сеткі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Абвесткі сеткі"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Сетка даступная"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Стан VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Адміністраванне прылады"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Абвесткi"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Дэманстрацыйны рэжым для пунктаў продажу"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Падключэнне USB"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе ў фонавым рэжыме"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Праграмы (<xliff:g id="NUMBER">%1$d</xliff:g>) працуюць у фонавым рэжыме"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Пераключыцца на асабісты"</string>
@@ -290,14 +299,12 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"рабіць тэлефонныя выклікі і кіраваць імі"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Датчыкі цела"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"атрымліваць з датчыка даныя асноўных фізіялагічных паказчыкаў"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Атрымайце змесцiва акна"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Вывучыце змесцiва акна, з якiм вы працуеце."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Уключыце Explore by Touch"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Атрымліваць змесціва вакна"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Аналізаваць змесціва актыўнага вакна."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Уключаць Азнаямленне дотыкам"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Элементы, да якіх дакрануліся, будуць агучаны, а экранам можна даследаваць пры дапамозе жэстаў."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Уключыце паляпшэнне вэб-даступнасці"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Сцэнарыi могуць быць усталяваны, каб зрабіць змесцiва прыкладання больш даступным."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Глядзiце, што набiраеце"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Уключае ў сябе асабістыя дадзеныя, такія як нумары крэдытных карт і паролі."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Праглядаць тэкст, які вы набіраеце"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"У тым ліку асабістыя даныя, такія як нумары крэдытных карт і паролі."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Кіраваць павелічэннем дысплэя"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Кіраваць маштабам дысплэя і пазіцыянаваннем."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Выконваць жэсты"</string>
@@ -416,8 +423,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дазваляе прыкладанням атрымлiваць доступ да функцый тэлефона на прыладзе. Дзякуючы гэтаму дазволу прыкладанне можа вызначаць iдэнтыфiкатары нумару тэлефона i прылады, незалежна ад таго, цi актыўны выклiк, i аддалены нумар, на якi робiцца выклiк."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"перанакіраванне выклікаў праз сістэму"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Дазваляе праграме перанакіроўваць выклікі праз сістэму ў мэтах паляпшэння выклікаў."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"чытаць нумар тэлефона"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Праграма зможа атрымліваць доступ да тэлефоннага нумара прылады."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"счытваць нумары тэлефонаў"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Дазваляе праграме атрымліваць доступ да нумароў тэлефонаў на прыладзе."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"прадухіліць планшэт ад пераходу ў рэжым сну"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"прадухіленне пераходу тэлевізара ў рэжым сну"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"забараняць тэлефону пераходзіць ў рэжым сну"</string>
@@ -490,6 +497,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час чакання адбіткаў пальцаў выйшаў. Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Аперацыя з адбіткамі пальцаў скасавана."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Занадта шмат спроб. Паспрабуйце яшчэ раз пазней."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Занадта шмат спроб. Сканер адбіткаў пальцаў адключаны."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -557,7 +565,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Кіраваць даўжынёй і сімваламі, дазволенымі пры ўводзе пароляў і PIN-кодаў блакіроўкі экрана."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Сачыць за спробамі разблакіроўкі экрана"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць планшэт або сціраць усе дадзеныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і блакіраваць тэлевізар або сціраць усе даныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць тяэлефон або сціраць усе дадзеныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
@@ -1010,17 +1018,16 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Выбраць тэкст"</string>
     <string name="undo" msgid="7905788502491742328">"Адрабіць"</string>
     <string name="redo" msgid="7759464876566803888">"Узнавіць"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Аўтазапаўненне"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Вылучэнне тэксту"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Дадаць у слоўнік"</string>
     <string name="deleteText" msgid="6979668428458199034">"Выдалiць"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
     <string name="email" msgid="4560673117055050403">"Электронная пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Патэлефанаваць"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Праглядзець"</string>
+    <string name="dial" msgid="4204975095406423102">"Тэлефон"</string>
+    <string name="map" msgid="6068210738233985748">"Карты"</string>
+    <string name="browse" msgid="6993590095938149861">"Браўзер"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Не хапае сховішча для сістэмы. Пераканайцеся, што ў вас ёсць 250 МБ свабоднага месца, і перазапусціце."</string>
@@ -1061,7 +1068,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Выберыце дзеянне"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Выберыце прыкладанне для USB-прылады"</string>
     <string name="noApplications" msgid="2991814273936504689">"Няма прыкладанняў, якія могуць выконваць гэты працэс."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Праграма <xliff:g id="APPLICATION">%1$s</xliff:g> спынілася"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g>: збой у рабоце"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> спыніўся"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> шматразова спыняе працу"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> шматразова спыняе працу"</string>
@@ -1134,6 +1141,18 @@
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Гукі будзільніка"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Гукі апавяшчэнняў"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Невядома"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">сетка Wi-Fi даступная</item>
+      <item quantity="few">сеткі Wi-Fi даступныя</item>
+      <item quantity="many">сетак Wi-Fi даступна</item>
+      <item quantity="other">сеткі Wi-Fi даступна</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">адкрытая сетка Wi-Fi даступная</item>
+      <item quantity="few">адкрытыя сеткі Wi-Fi даступныя</item>
+      <item quantity="many">адкрытых сетак Wi-Fi даступна</item>
+      <item quantity="other">адкрытай сеткі Wi-Fi даступна</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
@@ -1143,7 +1162,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Прылада выкарыстоўвае <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца дадатковая плата."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"мабільная перадача даных"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Ethernet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"невядомы тып сеткі"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Немагчыма падключыцца да Wi-Fi"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" дрэннае падключэнне да Інтэрнэту."</string>
@@ -1207,13 +1232,15 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Падключаны да USB-прылады"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Дакраніцеся, каб атрымаць іншыя параметры."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аксесуар аўдыя не падтрымліваецца"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Націсніце, каб атрымаць дадатковую інфармацыю"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Дакраніцеся, каб адключыць адладку па USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Перадача справаздачы пра памылку..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ІТ-адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Можа адбыцца абагуленне праграм і даных."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Ваш адміністратар запытаў справаздачу пра памылку для яе ліквідацыі на гэтай прыладзе. Звесткі праграм і даныя могуць быць абагулены."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"АБАГУЛІЦЬ"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"АДХІЛІЦЬ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Змяніць клавіятуру"</string>
@@ -1223,8 +1250,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Дакраніцеся, каб выбраць мову і раскладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> паказваецца паверх іншых праграм"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"<xliff:g id="NAME">%s</xliff:g> паказв. паверх інш. праграм."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> паказв. паверх іншых праграм"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць гэта."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"АДКЛЮЧЫЦЬ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Падрыхтоўка <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1401,8 +1430,7 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Прагляд выкарыстання і налад."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Дасягнуты ліміт трафіку 2G-3G"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Дасягнуты ліміт трафіку 4G"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Дасягн. ліміт маб. перад. даных"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Дасягн. ліміт перад. даных Wi-Fi"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Перад.даных спын. да канца цыкла"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Перавышаны ліміт 2G-3G"</string>
@@ -1501,18 +1529,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдалiць"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Камбінацыя хуткага доступу для спецыяльных магчымасцей АКТЫВАВАНА"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Уключайце ці адключайце <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утрымліваючы абедзве кнопкі рэгулявання гучнасці націснутымі на працягу 3 секунд.\n\nВы можаце змяніць сэрвіс у меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Дэактываваць камбінацыю хуткага доступу"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Пакінуць актываванай"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Калі камбінацыя хуткага доступу ўключана, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб уключыць функцыю спецыяльных магчымасцей.\n\n Бягучая функцыя спецыяльных магчымасцей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Вы можаце змяніць гэту функцыю ў меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Дэактываваць камбінацыю хуткага доступу"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў уключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
+    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
     <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Уладальнік"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Памылка"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ваш адміністратар не дазваляе гэту змену"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Ваш адміністратар не дазваляе гэту змену"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
     <string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1604,7 +1635,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Служба друку не ўключана"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Усталявана служба <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Краніце, каб уключыць"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Увядзіце PIN-код адміністратара"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Увядзіце PIN-код адміністратара"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Увядзіце PIN-код"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Няправільны"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Бягучы PIN-код"</string>
@@ -1634,16 +1665,16 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (праца)"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Каб адмацаваць гэты экран, дакраніцеся і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\"."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Праграма замацавана: адмацаванне на гэтай прыладзе не дапускаецца."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Каб адмацаваць гэты экран, краніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Гэту праграму нельга адмацаваць"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Экран замацаваны"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Экран адмацаваны"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Запытваць PIN-код перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запытваць пароль перад адмацаваннем"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Усталявана вашым адміністратарам"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Абноўлена вашым адміністратарам"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Выдалена вашым адміністратарам"</string>
+    <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="data_saver_description" msgid="6015391409098303235">"Каб паменшыць выкарыстанне даных, Эканомія трафіку не дазваляе некаторым праграмам адпраўляць ці атрымліваць даныя ў фонавым рэжыме. Праграма, якую вы зараз выкарыстоўваеце, можа атрымліваць доступ да даных, але можа рабіць гэта радзей. Гэта можа азначаць, напрыклад, што відарысы не паказваюцца, пакуль вы не дакраняцеся да іх."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Уключыць Эканомію трафіка?"</string>
@@ -1734,7 +1765,7 @@
       <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> выбрана</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> выбрана</item>
     </plurals>
-    <string name="default_notification_channel_label" msgid="6950908610709016902">"Рознае"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатэгарызаванае"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Дазволіць <xliff:g id="APP">%1$s</xliff:g> стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1746,8 +1777,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Усе мовы"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Усе рэгіёны"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Шукаць"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Рэжым працы АДКЛЮЧАНЫ"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Дазволіць функцыянаванне працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Уключыць працоўны рэжым?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Гэта прывядзе да ўключэння вашага працоўнага профілю, у тым ліку праграм, фонавай сінхранізацыі і звязаных з імі функцый"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Уключыць"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"У вас ёсць новыя паведамленні"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Праглядзець праз праграму для SMS"</string>
@@ -1783,29 +1814,41 @@
     <string name="app_category_productivity" msgid="3742083261781538852">"Прадукцыйнасць"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Сховішча на прыладзе"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Адладка USB"</string>
-    <string name="time_picker_hour_label" msgid="2979075098868106450">"гадзіна"</string>
+    <string name="time_picker_hour_label" msgid="2979075098868106450">"гадз"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"хвіліна"</string>
     <string name="time_picker_header_text" msgid="143536825321922567">"Задаць час"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Увядзіце дапушчальны час"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Увядзіце час"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пераключыцца на рэжым тэксту пры ўводзе часу."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пераключыцца на рэжым гадзінніка пры ўводзе часу."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Захаваць у <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Захаваць наступнае: <xliff:g id="TYPE">%1$s</xliff:g> у <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Параметры аўтазапаўнення"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Захаваць для аўтазапаўнення"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Для гэтага змесціва аўтазапаўненне немагчымае"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Няма прапаноў аўтазапаўнення"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> прапанова аўтазапаўнення</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> прапановы аўтазапаўнення</item>
+      <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> прапаноў аўтазапаўнення</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> прапановы аўтазапаўнення</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Захаваць у &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Захаваць <xliff:g id="TYPE">%1$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g> і <xliff:g id="TYPE_1">%2$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Захаваць <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g> у &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Захаваць"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Не, дзякуй"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"пароль"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"адрас"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"крэдытная картка"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"карыстальнік"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"адрас электроннай пошты"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Заставайцеся спакойнымі і пашукайце прытулак паблізу."</string>
+    <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>
     <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>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM-карта не дапускаецца"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Тэлефон не дапускаецца"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 3433064..95e41a1 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услугата не е обезпечена."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Не можете да променяте настройката за идентификация на обажданията."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Няма услуга за данни"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Няма достъп до спешните обаждания"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Няма услуга за спешни обаждания"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма услуга за гласови обаждания"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Няма услуга за гласови/спешни обаждания"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Временно не се предлага от мобилната мрежа в местоположението ви"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Операторът ви временно е спрял услугата за данни в това местоположение"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Операторът ви временно е спрял спешните обаждания в това местоположение"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Операторът ви временно е спрял гласовите обаждания в това местоположение"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Операторът ви временно е спрял гласовите и спешните обаждания в това местоположение"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се установи връзка с мрежата"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"За да подобрите сигнала, променете избрания тип мрежа от „Система“ &gt; „Мрежа и интернет“ &gt; „Мобилни мрежи“ &gt; „Предпочитан тип мрежа“."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сигнали"</string>
@@ -280,7 +283,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"има достъп до календара ви"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"да изпраща и преглежда SMS съобщения"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Хранилище"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Съхранение"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"да има достъп до снимките, мултимедията и файловете на устройството ви"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"записва звук"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Установена е връзка с аксесоар за USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Докоснете за още опции."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоаксесоарът не се поддържа"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Докоснете за още информация"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Докоснете, за да изберете език и подредба"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Показване върху други приложения"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> се показва върху други приложения"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> се показва в/у други прилож."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ако не искате <xliff:g id="NAME">%s</xliff:g> да използва тази функция, докоснете, за да отворите настройките, и я изключете."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Докоснете, за да излезете от моторежима."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Напред"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропускане"</string>
@@ -1600,7 +1604,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Опитайте отново по-късно"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Изглед на цял екран"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"За изход плъзнете пръст надолу от горната част."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"За изход прекарайте пръст надолу от горната част."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Разбрах"</string>
     <string name="done_label" msgid="2093726099505892398">"Готово"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Кръгов плъзгач за часовете"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index d09191b..bd5a5b8 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -68,8 +68,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"আগত কলার আইডি"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"আউটগোয়িং কলার আইডি"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"আগত কলার ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"আউটগোয়িং কলার ID"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"সংযুক্ত লাইন ID"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"সংযুক্ত লাইন ID-র বিধিনিষেধ"</string>
     <string name="CfMmi" msgid="5123218989141573515">"কল ফরওয়ার্ড করা"</string>
@@ -79,21 +79,24 @@
     <string name="PinMmi" msgid="3113117780361190304">"পিন পরিবর্তন"</string>
     <string name="CnipMmi" msgid="3110534680557857162">"কল করার নম্বর উপস্থিত"</string>
     <string name="CnirMmi" msgid="3062102121430548731">"যে নম্বরটি থেকে কল করা হয় সেটি না পাঠানো"</string>
-    <string name="ThreeWCMmi" msgid="9051047170321190368">"তিন ভাবে কল করা"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"তিনটি পথে কল করা"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"অবাঞ্ছিত বিরক্তিকর কলগুলি প্রত্যাখ্যান"</string>
     <string name="CndMmi" msgid="3116446237081575808">"যে নম্বরটি থেকে কল করা হয় সেটি পাঠানো"</string>
     <string name="DndMmi" msgid="1265478932418334331">"বিরক্ত করবেন না"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ডিফল্টরুপে কলার ID সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ডিফল্টরুপে কলার ID সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ডিফল্টরুপে কলার ID সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ডিফল্টরুপে কলার ID সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"পরিষেবা প্রস্তুত নয়৷"</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"আপনি কলার আইডি এর সেটিংস পরিবর্তন করতে পারবেন না৷"</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"আপনি কলার ID এর সেটিংস পরিবর্তন করতে পারবেন না৷"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ডেটা পরিষেবা নেই"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"কোনও জরুরী অবস্থার কল নেই"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"জরুরী পরিষেবা নেই"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ভয়েস পরিষেবা নেই"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"কোনো ভয়েস/জরুরী পরিষেবা নেই"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"সাময়িকভাবে মোবাইল নেটওয়ার্ক আপনার অবস্থানে এই পরিষেবা দিচ্ছে না"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"আপনার পরিষেবা প্রদানকারী এই অবস্থানে ডেটা পরিষেবা সাময়িকভাবে সাসপেন্ড করেছে"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"আপনার পরিষেবা প্রদানকারী এই অবস্থানে জরুরি কল সাময়িকভাবে সাসপেন্ড করেছে"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"আপনার পরিষেবা প্রদানকারী এই অবস্থানে ভয়েস কল সাময়িকভাবে সাসপেন্ড করেছে"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"আপনার পরিষেবা প্রদানকারী এই অবস্থানে ভয়েস এবং জরুরি কল সাময়িকভাবে সাসপেন্ড করেছে"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"নেটওয়ার্কের সিগন্যাল নেই"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"রিসেপশন উন্নত করতে সিস্টেম &gt; নেটওয়ার্ক এবং ইন্টারনেট &gt; মোবাইল নেটওয়ার্ক &gt; পছন্দের নেটওয়ার্কের ধরণ এ গিয়ে নির্বাচিত নেটওয়ার্কের ধরণ পরিবর্তন করে দেখুন।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"সতর্কবার্তা"</string>
@@ -299,15 +302,15 @@
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"প্রদর্শনের বৃহত্তরীকরণ ব্যবস্থা নিয়ন্ত্রণ করুন"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"প্রদর্শনের জুমের স্তর এবং অবস্থান নির্ধারন নিয়ন্ত্রণ করুন৷"</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"অঙ্গভঙ্গির কাজগুলি সম্পাদন করুন"</string>
-    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"আলতো চাপ দেওয়া, সোয়াইপ, পিঞ্চ করা এবং অন্যান্য ইঙ্গিতের কাজগুলি সম্পাদন করতে পারবেন৷"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"আলতো চাপ দেওয়া, সোয়াইপ, পিঞ্চ করা এবং অন্যান্য অঙ্গভঙ্গির কাজগুলি সম্পাদন করতে পারবেন৷"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ফিঙ্গারপ্রিন্ট সেন্সরের উপর করা অঙ্গভঙ্গিগুলি"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ডিভাইসের আঙ্গুলের ছাপের সেন্সরের উপর আঙ্গুলের ইঙ্গিত ক্যাপচার করতে পারে।"</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"স্ট্যাটাস বার নিষ্ক্রিয় অথবা সংশোধন করে"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"অ্যাপ্লিকেশনকে স্ট্যাটাস বার অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সরের উপর আঙ্গুলের অঙ্গভঙ্গি ক্যাপচার করতে পারে।"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"স্থিতি দন্ড নিষ্ক্রিয় অথবা সংশোধন করে"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"অ্যাপ্লিকেশানকে স্থিতি দন্ড অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"স্থিতি দন্ডে থাকুন"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"অ্যাপ্লিকেশানটিকে স্থিতি দন্ডে থাকতে দেয়৷"</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"স্ট্যাটাস বার সম্প্রসারিত/সঙ্কুচিত করে"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"অ্যাপ্লিকেশনটিকে স্ট্যাটাস বার প্রসারিত বা সঙ্কুচিত করতে দেয়৷"</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"স্থিতি দন্ড সম্প্রসারিত/সঙ্কুচিত করে"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"অ্যাপ্লিকেশানটিকে স্থিতি দন্ড প্রসারিত বা সঙ্কুচিত করতে দেয়৷"</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"শর্টকাটগুলি ইনস্টল করে"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণে শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"শর্টকাটগুলি আনইনস্টল করে"</string>
@@ -470,7 +473,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ফোনের ব্লুটুথ কনফিগারেশন দেখতে, এবং যুক্ত ডিভাইসগুলির সাথে সংযোগ স্থাপন এবং সংযোগের অনুরোধ স্বীকার করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"অ্যাপ্লিকেশানকে নিয়ার ফিল্ড কমিউনিকেশন (NFC) ট্যাগ, কার্ড এবং রিডারগুলির সাথে যোগাযোগ করতে দেয়৷"</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"আপনার স্ক্রিন লক অক্ষম করুন"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"আপনার স্ক্রীন লক অক্ষম করুন"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"কী-লক এবং যেকোনো সংশ্লিষ্ট পাসওয়ার্ড সুরক্ষা অক্ষম করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ উদাহরণস্বরূপ, একটি ইনকামিং ফোন কল গ্রহণ করার সময়ে ফোনটি কী-লক অক্ষম করে, তারপরে কল শেষ হয়ে গেলে কী-লকটিকে আবার সক্ষম করে৷"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার পরিচালনা করুন"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"ব্যবহার করার জন্য আঙ্গুলের ছাপের টেম্প্লেটগুলি যোগ করা এবং মোছার পদ্ধতিগুলি গ্রহন করতে অ্যাপ্লিকেশানটিতে অমুমতি দেয়৷"</string>
@@ -519,7 +522,7 @@
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"কলে-থাকা স্ক্রীণের সাথে ইন্টারঅ্যাক্ট করে"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ব্যবহারকারী কখন এবং কীভাবে কলে-থাকা স্ক্রীণটিকে দেখতে পাবেন, অ্যাপ্লিকেশানটিকে তা নিয়ন্ত্রণ করতে দেয়৷"</string>
     <string name="permlab_bind_connection_service" msgid="3557341439297014940">"টেলিফোন পরিষেবার সাথে ইন্টারঅ্যাক্ট করুন"</string>
-    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"কল করা/গ্রহণ করার জন্য অ্যাপ্লিকেশনটিকে টেলিফোন পরিষেবার সাথে ইন্টার‌্যাক্ট করার অনুমতি দেয়।"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"কল করা/গ্রহণ করার জন্য অ্যাপ্লিকেশানটিকে টেলিফোন পরিষেবার সাথে ইন্টারঅ্যাক্ট করার অনুমতি দেয়।"</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"কলে-থাকা এক ব্যবহারকারী অভিজ্ঞতা সরবরাহ করুন"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"অ্যাপ্লিকেশানটিকে কলে-থাকা এক ব্যবহারকারী অভিজ্ঞতা সরবরাহের অনুমতি দেয়।"</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"তারিখ অনুযায়ী নেটওয়ার্কের ব্যবহার পড়ে"</string>
@@ -548,14 +551,14 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"এই অ্যাপ্লিকেশানকে বর্তমান Android বীম স্থানান্তর সম্বন্ধে তথ্য গ্রহণ করার অনুমিত দেয়"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM শংসাপত্রগুলি সরান"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"কোনো অ্যাপ্লিকেশানকে DRM শংসাপত্রগুলি সরানোর অনুমতি দেয়। সাধারণ অ্যাপ্লিকেশানগুলির জন্য কখনো প্রয়োজন হয় না।"</string>
-    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"একটি ক্যারিয়ার মেসেজিং পরিষেবা আবদ্ধ করতে"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"ধারককে, একটি ক্যারিয়ার মেসেজিং পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশনগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"একটি ক্যারিয়ার বার্তাপ্রেরণ পরিষেবা আবদ্ধ করতে"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"ধারককে, একটি ক্যারিয়ার বার্তাপ্রেরণ পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশানগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"পরিষেবা প্রদানকারীর সাথে যুক্ত হন"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"কোনো পরিষেবা প্রদানকারীর সাথে যুক্ত হতে ধারককে অনুমতি দিন। সাধারণ অ্যাপ্লিকেশানের জন্য প্র্রয়োজন হয় না।"</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"\'বিরক্ত করবেন না\' -তে অ্যাক্সেস"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অ্যাপটিকে \'বিরক্ত করবেন না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্রিন লক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্রীন লক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"স্ক্রিন আনলক করার প্রচেষ্টাগুলির উপরে নজর রাখুন"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"স্ক্রীণ আনলক করার সময় ভুলভাবে লেখা পাসওয়ার্ড প্রবেশের সংখ্যা মনিটার করে, এবং ট্যাবলেট লক করে এবং অনেক বার পাসওয়ার্ড ভুল ভাবে লেখা হলে ট্যাবলেটের ডেটা মুছে ফেলে৷"</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"স্ক্রীন আনলক করার সময় ভুলভাবে লেখা পাসওয়ার্ড প্রবেশের সংখ্যা মনিটার করে, এবং টিভি লক করে এবং অনেক বার পাসওয়ার্ড ভুল ভাবে লেখা হলে টিভির ডেটা মুছে ফেলে৷"</string>
@@ -563,8 +566,8 @@
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"স্ক্রীন আনলক করার সময় ভুলভাবে লেখা পাসওয়ার্ড প্রবেশের সংখ্যা মনিটার করে, এবং ট্যাবলেট লক করে এবং অনেক বার পাসওয়ার্ড ভুল ভাবে লেখা হলে ব্যবহারকারীর ডেটা মুছে ফেলে৷"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"স্ক্রীন আনলক করার সময় ভুলভাবে লেখা পাসওয়ার্ড প্রবেশের সংখ্যা মনিটার করে, এবং টিভি লক করে এবং অনেক বার পাসওয়ার্ড ভুল ভাবে লেখা হলে ব্যবহারকারীর ডেটা মুছে ফেলে৷"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"স্ক্রীন আনলক করার সময় ভুলভাবে লেখা পাসওয়ার্ড প্রবেশের সংখ্যা মনিটার করে, এবং ফোন লক করে এবং অনেক বার পাসওয়ার্ড ভুল ভাবে লেখা হলে ব্যবহারকারীর ডেটা মুছে ফেলে৷"</string>
-    <string name="policylab_resetPassword" msgid="4934707632423915395">"স্ক্রিন লক পরিবর্তন করুন"</string>
-    <string name="policydesc_resetPassword" msgid="1278323891710619128">"স্ক্রিন লক পরিবর্তন করুন৷"</string>
+    <string name="policylab_resetPassword" msgid="4934707632423915395">"স্ক্রীন লক পরিবর্তন করুন"</string>
+    <string name="policydesc_resetPassword" msgid="1278323891710619128">"স্ক্রীন লক পরিবর্তন করুন৷"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"স্ক্রীণটি লক করে"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"স্ক্রীন কখন কিভাবে লক হবে তা নিয়ন্ত্রণ করে৷"</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"সমস্ত ডেটা মুছে দেয়"</string>
@@ -577,14 +580,14 @@
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"সতর্কীকরণ ছাড়াই এই ফোনে থাকা ব্যাবহারকার্রী ডেটা মুছে ফেলে৷"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ডিভাইসের বৈশ্বিক প্রক্সী সেট করে"</string>
     <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"নীতিযখন নীতি সক্ষম করা হয় তখন ডিভাইসের বৈশ্বিক প্রক্সী ব্যবহার করা হবে সেই হিসাবে সেট করে৷ শুধুমাত্র ডিভাইসের মালিক বৈশ্বিক প্রক্সী সেট করতে পারেন৷"</string>
-    <string name="policylab_expirePassword" msgid="5610055012328825874">"স্ক্রিন লক করার জন্য পাসওয়ার্ডের মেয়াদ শেষ হওয়ার সময় সেট করে"</string>
-    <string name="policydesc_expirePassword" msgid="5367525762204416046">"স্ক্রিন লক করার পাসওয়ার্ড কত ঘন ঘন পরিবর্তন করা আবশ্যক তা পরিবর্তন করুন৷"</string>
+    <string name="policylab_expirePassword" msgid="5610055012328825874">"স্ক্রীন লক করার জন্য পাসওয়ার্ডের মেয়াদ শেষ হওয়ার সময় সেট করে"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"স্ক্রীন লক করার পাসওয়ার্ড কত ঘন ঘন পরিবর্তন করা আবশ্যক তা পরিবর্তন করুন৷"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"সঞ্চয়স্থানের এনক্রিপশান সেট করে"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"এই সঞ্চিত অ্যাপ্লিকেশান ডেটা এনক্রিপ্ট করা দরকার৷"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"ক্যামেরাগুলি অক্ষম করে"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"সমস্ত ডিভাইসের ক্যামেরার ব্যবহার আটকায়৷"</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"কিছু স্ক্রিন লক বৈশিষ্ট্য অক্ষম করুন"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"কিছু স্ক্রিন লক বৈশিষ্ট্যের ব্যবহার আটকান।"</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"কিছু স্ক্রীন লক বৈশিষ্ট্য অক্ষম করুন"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"কিছু স্ক্রীন লক বৈশিষ্ট্যের ব্যবহার আটকান।"</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"বাড়ি"</item>
     <item msgid="869923650527136615">"মোবাইল"</item>
@@ -711,7 +714,7 @@
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"জরুরী নম্বর"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"কোনো পরিষেবা নেই"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"স্ক্রীণ লক করা আছে৷"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"আনলক করতে বা জরুরি কল করতে মেনু টিপুন৷"</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"আনলক করতে বা জরুরী কল করতে মেনু টিপুন৷"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"আনলক করতে মেনু টিপুন৷"</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"আনলক করতে প্যাটার্ন আঁকুন"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"জরুরী"</string>
@@ -736,7 +739,7 @@
     <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"থামান"</string>
     <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"গুটিয়ে নিন"</string>
     <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"দ্রুত সামনে এগোন"</string>
-    <string name="emergency_calls_only" msgid="6733978304386365407">"শুধুমাত্র জরুরি কল"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"শুধুমাত্র জরুরী কল"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"নেটওয়ার্ক লক হয়েছে"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"সিম কার্ডটি PUK কোড দিয়ে লক করা আছে৷"</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ব্যবহারকারীর নির্দেশিকা দেখুন বা গ্রাহক পরিষেবা কেন্দ্রে যোগাযোগ করুন৷"</string>
@@ -744,7 +747,7 @@
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"সিম কার্ড আনলক করা হচ্ছে…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"আপনি আপনার পিন টাইপ করতে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার ট্যাবলেট আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার টিভি আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%2$d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google এ প্রবেশ করে আপনার ফোন আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
@@ -1139,7 +1142,7 @@
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"সংযুক্ত হওয়ার আমন্ত্রণ"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"থেকে:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"প্রাপক:"</string>
-    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"প্রয়োজনীয় পিনটি লিখুন:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"প্রয়োজনীয় PINটি লিখুন:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"পিন:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ট্যাবলেটটি যখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত হবে তখন এটি ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"আপনার টিভি <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত থাকার সময় ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে৷"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI এর জন্য USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"একটি USB যন্ত্রাংশতে সংযুক্ত হয়েছে"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"আরো বিকল্পের জন্য আলতো চাপুন৷"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"অডিও অ্যাক্সেসরি সমর্থিত নয়"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ডিবাগিং অক্ষম করতে আলতো চাপুন৷"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ত্রুটির প্রতিবেদন শেয়ার করা হচ্ছে..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ভাষা এবং লেআউট নির্বাচন করুন আলতো চাপ দিন"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"অন্যান্য অ্যাপের উপরে দেখুন"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> অন্যান্য অ্যাপ্লিকেশানের ওপরেও প্রদর্শিত"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> অন্যান্য অ্যাপের ওপর প্রদর্শিত হচ্ছে"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> কে এই বৈশিষ্ট্যটি ব্যবহার করতে দিতে না চাইলে, ট্যাপ করে সেটিংসে যান ও বৈশিষ্ট্যটি বন্ধ করে দিন।"</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"গাড়ি মোড থেকে প্রস্থান করতে আলতো চাপুন৷"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"সেট আপ করার জন্য আলতো চাপুন৷"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ফিরুন"</string>
     <string name="next_button_label" msgid="1080555104677992408">"পরবর্তী"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"এড়িয়ে যান"</string>
@@ -1464,7 +1469,7 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"অবৈধ ব্যবহারকারী নাম অথবা পাসওয়ার্ড৷"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"আপনার ব্যবহারকারী নাম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"অ্যাকাউন্ট পরীক্ষা করা হচ্ছে..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"আপনি আপনার পিন টাইপ করতে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"আপনি আপনার ট্যাবলেট আনলকের প্রচেষ্টায় <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টা করা হলে, ট্যাবলেটের সেটিংস ফ্যাক্টরি ডিফল্ট অনুযায়ী হয়ে যাবে এবং সমস্ত ব্যবহারকারী ডেটা হারিয়ে যাবে৷"</string>
@@ -1590,7 +1595,7 @@
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"ভুল"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"বর্তমান পিন"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"নতুন পিন"</string>
-    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"নতুন পিনটি নিশ্চিত করুন"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"নতুন PINটি নিশ্চিত করুন"</string>
     <string name="restr_pin_create_pin" msgid="8017600000263450337">"নিষেধাজ্ঞাগুলি পরিবর্তন করার জন্য একটি পিন তৈরি করুন"</string>
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINগুলি মেলেনি৷ আবার চেষ্টা করুন৷"</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"পিন খুবই ছোট৷ এটিকে কমপক্ষে ৪ সংখ্যার হতে হবে৷"</string>
@@ -1615,7 +1620,7 @@
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"তৃতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_toast" msgid="6820571533009838261">"এই স্ক্রিনটিকে আনপিন করতে ফিরে যাওয়া এবং এক নজরে বোতামদুটি ট্যাপ করে ধরে রাখুন"</string>
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"এই অ্যাপটি আনপিন করা যাবে না"</string>
-    <string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রিন পিন করা হয়েছে"</string>
+    <string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রীন পিন করা হয়েছে"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"পিন না করা স্ক্রীন"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"আনপিন করার আগে পিন চান"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
@@ -1623,7 +1628,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>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 92294dc..63a3945 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -28,15 +28,15 @@
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sati"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sat"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
     <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
@@ -90,17 +90,23 @@
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: nije zabranjen"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Uslugu nije moguće koristiti."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete promijeniti postavke ID-a pozivaoca."</string>
-    <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga prijenosa podataka je blokirana."</string>
-    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hitni pozivi su blokirani."</string>
-    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Govorne usluge su blokirane."</string>
-    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve govorne usluge su blokirane."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Blokirane su govorne usluge i usluge prijenosa podataka."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Blokirane su govorne/SMS usluge."</string>
-    <string name="RestrictedOnAll" msgid="5643028264466092821">"Blokirane su sve govorne i SMS usluge te usluge prijenosa podataka."</string>
+    <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nema usluge prijenosa mobilnih podataka"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema usluge za hitne slučajeve"</string>
+    <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema usluge govornih poziva"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema govornih/hitnih usluga"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Vaš operater je privremeno obustavio uslugu prijenosa mobilnih podataka na ovoj lokaciji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Vaš operater je privremeno obustavio hite pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Vaš operater je privremeno obustavio govorne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Vaš operater je na ovoj lokaciji privremeno obustavio govorne i hitne pozive."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nije moguće dosegnuti mrežu"</string>
-    <!-- no translation found for NetworkPreferenceSwitchSummary (4164230263214915351) -->
-    <skip />
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za poboljšanje prijema, pokušajte promijeniti tip odabran u meniju Sistem &gt; Mreža i internet &gt; Mobilne mreže &gt; Preferirani tip 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>
+    <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"Upozorenja za mobilne podatke"</string>
+    <string name="notification_channel_sms" msgid="3441746047346135073">"SMS poruke"</string>
+    <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Poruke govorne pošte"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi pozivanje"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Ravnopravni uređaj zatražio TTY PUNI način rada"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Ravnopravni uređaj zatražio TTY HCO način rada"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Ravnopravni uređaj zatražio TTY VCO način rada"</string>
@@ -140,8 +146,7 @@
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (1988279625335345908) -->
-    <skip />
+    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -180,18 +185,16 @@
       <item quantity="other">Instalirane su ustanove za izdavanje certifikata</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od nepoznate treće strane"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"od strane administratora vašeg profila za posao"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Administrator vašeg radnog profila"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je obrisan"</string>
-    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je obrisan jer nedostaje aplikacija administratora."</string>
-    <string name="work_profile_deleted_details" msgid="226615743462361248">"Aplikacija administratora za poslovni profil nedostaje ili je neispravna. Zbog toga su vaš poslovni profil i vezani podaci obrisani. Za pomoć se obratite administratoru."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za posao više nije dostupan na ovom uređaju."</string>
-    <!-- no translation found for network_logging_notification_title (6399790108123704477) -->
-    <skip />
-    <!-- no translation found for network_logging_notification_text (7930089249949354026) -->
-    <skip />
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"Radni profil je izbrisan jer nedostaje aplikacija administratora"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Radni profil više nije dostupan na ovom uređaju"</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"Uređajem se upravlja."</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti izbrisan"</string>
-    <string name="factory_reset_message" msgid="4905025204141900666">"Aplikaciji administratora nedostaju komponente ili je neispravna, i ne može se koristiti. Vaš uređaj će sada biti izbrisan. Za pomoć se obratite administratoru."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru vaše organizacije."</string>
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tableta"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
@@ -208,7 +211,7 @@
     <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_reset_title" msgid="4142355915340627490">"Vraćanje na tvorničke postavke"</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="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tablet će se isključiti."</string>
@@ -225,7 +228,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opcije telefona"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Zaključavanje ekrana"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Isključi telefon"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Hitni slučaj"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Hitno"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvještaj o greškama"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kreirajte izvještaj o greškama"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao poruka e-pošte. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
@@ -260,11 +263,17 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administracija uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Promotivna demonstracija u maloprodaji"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije koje rade u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta u pozadini"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Broj aplikacija koje rade u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
+    <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
     <string name="user_owner_label" msgid="1119010402169916617">"Prebacite se na lični"</string>
@@ -287,15 +296,13 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"poziva i upravlja pozivima"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Tjelesni senzori"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vašim vitalnim funkcijama"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ponovo prikaži sadržaj prozora"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji trenutno koristite."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključite Istraživanje dodirom"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Pregleda sadržaj prozora koji trenutno koristite."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi opciju Istraživanje dodirom"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete bit će izgovorene naglas, a ekran možete istraživati koristeći pokrete."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Uključite poboljšanu web pristupačnost"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Možda će biti instalirana skripta kako bi sadržaj aplikacije bio dostupniji."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Obratite pažnju na tekst koji tipkate"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Uključuje lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontroliranje uvećanja prikaza na ekranu"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolira uvećanje prikaza na ekranu"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira stepen uvećanja prikaza na ekranu i podešavanje položaja."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Praviti pokrete"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
@@ -403,7 +410,7 @@
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Omogućava aplikaciji slanje naredbi na SIM. Ovo je vrlo opasno."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"snimanje slika i videozapisa"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibriranja"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibracije"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"izravno zvanje telefonskih brojeva"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
@@ -413,8 +420,8 @@
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Omogućava aplikaciji pristup telefonskim funkcijama uređaja. Ova dozvola omogućava aplikaciji određivanje telefonskog i identifikacionog broja uređaja, bez obzira da li je poziv aktivan i da li je uspostavljena veza sa pozivanim brojem."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"usmjeravanje poziva preko sistema"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Dopušta aplikaciji da pozive usmjeri preko sistema radi poboljšanja iskustva pozivanja."</string>
-    <string name="permlab_readPhoneNumber" msgid="6421295519255154171">"čitanje telefonskog broja"</string>
-    <string name="permdesc_readPhoneNumber" msgid="9135856402838173711">"Dopušta aplikaciji pristup telefonskom broju telefona."</string>
+    <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"čitanje telefonskih brojeva"</string>
+    <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Dozvoljava aplikaciji pristup telefonskim brojevima uređaja."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje tableta da uđe u režim mirovanja"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"spriječi ulazak TV-a u režim mirovanja"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje telefona da uđe u režim mirovanja"</string>
@@ -440,7 +447,7 @@
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"prikaz mrežnih veza"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Omogućava aplikaciji pregled informacija o mrežnim vezama, npr. koje mreže postoje i koje su povezane."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"ima potpuni pristup mreži"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Omogućava aplikaciji kreiranje spojnih tačaka sa mrežom i korištenje prilagođenih mrežnih protokola. Preglednik i druge aplikacije omogućavaju slanje podataka na internet, tako da ova dozvola nije potrebna za vršenje te radnje."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Omogućava aplikaciji kreiranje spojnih tačaka sa mrežom i korištenje prilagođenih mrežnih protokola. Preglednik i druge aplikacije omogućavaju slanje podataka na internet, tako da ovo odobrenje nije potrebno za vršenje te radnje."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"izmjene povezivanja na mrežu"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Dozvoljava aplikaciji izmjenu stanja mrežne povezanosti."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"izmjene podijeljenog povezivanja"</string>
@@ -487,6 +494,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Previše pokušaja. Senzor za otisak prsta je onemogućen."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -554,7 +562,7 @@
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju opcije Ne ometaj."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN kodovima."</string>
-    <string name="policylab_watchLogin" msgid="914130646942199503">"Prati pokušaje otključavanja ekrana"</string>
+    <string name="policylab_watchLogin" msgid="5091404125971980158">"Prati pokušaje otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj pogrešno unijetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše sve podatke s njega ukoliko se previše puta unese pogrešna lozinka."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Prati koliko puta je lozinka neispravno otkucana prilikom otključavanja ekrana i zaključaj TV ili izbriši sve podatke s TV-a ako se lozinka neispravno ukuca previše puta."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj pogrešno unesenih lozinki prilikom otključavanja ekrana i zaključava telefon ili briše sve podatke s telefona ukoliko se previše puta unese pogrešna lozinka."</string>
@@ -645,14 +653,14 @@
     <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Poslovni mobilni"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"Poslovni pejdžer"</string>
-    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Pomoćnik"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistent"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
     <string name="eventTypeCustom" msgid="7837586198458073404">"Prilagođeno"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"Rođendan"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Godišnjica"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"Ostalo"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"Prilagođeno"</string>
-    <string name="emailTypeHome" msgid="449227236140433919">"Kućni"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Privatna"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Posao"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Ostalo"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"Mobilni"</string>
@@ -678,7 +686,7 @@
     <string name="orgTypeOther" msgid="3951781131570124082">"Ostalo"</string>
     <string name="orgTypeCustom" msgid="225523415372088322">"Prilagođeno"</string>
     <string name="relationTypeCustom" msgid="3542403679827297300">"Prilagođeno"</string>
-    <string name="relationTypeAssistant" msgid="6274334825195379076">"Pomoćnik"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Asistent"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"Brat"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"Dijete"</string>
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Nevjenčani partner"</string>
@@ -712,7 +720,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pritisnite dugme Meni kako biste otključali uređaj ili obavili hitni poziv."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pritisnite dugme Meni za otključavanje uređaja."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Nacrtajte uzorak za otključavanje"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitni slučaj"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitno"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Povratak na poziv"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ispravno!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Pokušajte ponovo"</string>
@@ -840,8 +848,8 @@
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Dozvoljava aplikaciji postavljanje alarma u instaliranom budilniku. Moguće je da neki budilnici neće primijeniti ovu funkciju."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji dodavanje poruka u vašu ulaznu govornu poštu."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih dozvola preglednika"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih dozvola pretraživača. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web stranicama."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih odobrenja preglednika"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih odobrenja preglednika. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web lokcacijama."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -853,9 +861,9 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"razmak"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"potvrdi"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"izbriši"</string>
-    <string name="search_go" msgid="8298016669822141719">"Traži"</string>
+    <string name="search_go" msgid="8298016669822141719">"Pretraži"</string>
     <string name="search_hint" msgid="1733947260773056054">"Pretraži..."</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"Traži"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Pretraživanje"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"Upit za pretragu"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"Obriši upit"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Potvrditi upit"</string>
@@ -882,7 +890,7 @@
     <string name="minute" msgid="9148878657703769868">"minuta"</string>
     <string name="minutes" msgid="5646001005827034509">"minute"</string>
     <string name="second" msgid="3184235808021478">"sekunda"</string>
-    <string name="seconds" msgid="3161515347216589235">"sekunde"</string>
+    <string name="seconds" msgid="3161515347216589235">"s"</string>
     <string name="week" msgid="5617961537173061583">"sedmica"</string>
     <string name="weeks" msgid="6509623834583944518">"sedmice"</string>
     <string name="year" msgid="4001118221013892076">"godina"</string>
@@ -990,17 +998,16 @@
     <string name="selectTextMode" msgid="1018691815143165326">"Odaberi tekst"</string>
     <string name="undo" msgid="7905788502491742328">"Vrati"</string>
     <string name="redo" msgid="7759464876566803888">"Ponovo uradi"</string>
-    <!-- no translation found for autofill (3035779615680565188) -->
-    <skip />
+    <string name="autofill" msgid="3035779615680565188">"Automatsko popunjavanje"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rječnik"</string>
     <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
-    <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pretraži"</string>
+    <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
+    <string name="map" msgid="6068210738233985748">"Mape"</string>
+    <string name="browse" msgid="6993590095938149861">"Preglednik"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string>
@@ -1096,7 +1103,7 @@
     <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje procesne memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dijela memorije vam je dostupan i možete ga dijeliti sa njegovim programerom. Budite oprezni: ovaj snimak dinamičkog dijela memorije može sadržavati vaše lične podatke kojima aplikacija ima pristup."</string>
     <string name="sendText" msgid="5209874571959469142">"Biranje akcije za tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Jačina zvuka zvona"</string>
-    <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka medija"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Medijski sadržaj se reproducira preko Bluetooth veze"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Postavljena nečujna melodija zvona"</string>
     <string name="volume_call" msgid="3941680041282788711">"Jačina zvuka tokom poziva"</string>
@@ -1107,17 +1114,27 @@
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Jačina zvuka za Bluetooth vezu"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Jačina zvuka melodije"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Jačina zvuka tokom poziva"</string>
-    <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka medija"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Zadano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
-    <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
-    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obavještenja"</string>
+    <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvukovi alarma"</string>
+    <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvukovi obavještenja"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
+    </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
-    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi nema pristup Internetu"</string>
@@ -1125,7 +1142,13 @@
     <string name="network_switch_metered" msgid="4671730921726992671">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"Kada na uređaju <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, koristi se <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
-    <!-- no translation found for network_switch_type_name:0 (3979506840912951943) -->
+  <string-array name="network_switch_type_name">
+    <item msgid="3979506840912951943">"mobilni podaci"</item>
+    <item msgid="75483255295529161">"Wi-Fi"</item>
+    <item msgid="6862614801537202646">"Bluetooth"</item>
+    <item msgid="5447331121797802871">"Ethernet"</item>
+    <item msgid="8257233890381651999">"VPN"</item>
+  </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"nepoznata vrsta mreže"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Problem prilikom spajanja na Wi-Fi mrežu"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
@@ -1142,7 +1165,7 @@
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozivnica poslana"</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Poziv za povezivanje"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Pošiljalac:"</string>
-    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Primalac:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Prima:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Unesite potrebni PIN:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tablet će privremeno prekinuti Wi-Fi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
@@ -1178,10 +1201,10 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavljanje datuma"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Postaviti"</string>
-    <string name="date_time_done" msgid="2507683751759308828">"Završeno"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Gotovo"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> omogućava."</string>
-    <string name="no_permissions" msgid="7283357728219338112">"Nisu potrebne dozvole"</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Nisu potrebna odobrenja"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"ovo se možda dodatno plaća"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Uredu"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"Ovaj uređaj se puni preko USB-a"</string>
@@ -1191,6 +1214,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Uspostavljena veza sa USB pohranom"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio pribor nije podržan"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da onemogućite otklanjanje grešaka putem uređaja spojenog na USB."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1198,18 +1223,20 @@
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Vaš IT administrator je zatražio izvještaj o grešci kako bi pomogao u rješavanju problema ovog uređaja. Aplikacije i podaci se mogu dijeliti."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"Vaš administrator je zatražio izvještaj o greškama kako bi pomogao u rješavanju problema ovog uređaja. Moguće je dijeljenje aplikacija i podataka."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PODIJELI"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string>
     <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
-    <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tastaturu"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaz virtuelne tastature"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguriraj fizičku tastaturu"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite za odabir jezika i rasporeda"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije"</string>
-    <string name="alert_windows_notification_title" msgid="4532185840598192445">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije."</string>
+    <string name="alert_windows_notification_title" msgid="3697657294867638947">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva druge apl."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema se <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1264,7 +1291,7 @@
     <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_search" msgid="658110271822807811">"Traži"</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>
     <string name="ime_action_done" msgid="8971516117910934605">"Gotovo"</string>
@@ -1301,7 +1328,7 @@
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite za postavke"</string>
     <string name="upload_file" msgid="2897957172366730416">"Odabir fajla"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nije izabran nijedan fajl"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
+    <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
     <string name="submit" msgid="1602335572089911941">"Potvrdi"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Način rada u autu omogućen"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite za izlaz iz načina rada u automobilu"</string>
@@ -1336,7 +1363,7 @@
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Poništiti brisanje"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
     <string name="choose_account_label" msgid="5655203089746423927">"Odaberite račun"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"Dodajte račun"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Dodaj račun"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodajte račun"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Povećaj"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"Smanji"</string>
@@ -1382,11 +1409,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Uredi"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"Upozorenje o prijenosu podataka"</string>
-    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz upotrebe i postavki."</string>
+    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz potrošnje i postavki."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dostignut limit za 2G-3G podatke"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dostignut limit za 4G podatke"</string>
-    <!-- no translation found for data_usage_mobile_limit_title (6561099244084267376) -->
-    <skip />
+    <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostignut limit za mob. podatke"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Dostignut limit Wi-Fi podataka"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Podaci pauz. za ostatak ciklusa"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Premašeni 2G-3G podaci"</string>
@@ -1429,9 +1455,9 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bežični prikaz"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"Prebacuj"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Emitiranje"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Poveži na uređaj"</string>
-    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Prebaci ekran na uređaj"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Emitiranje ekrana na uređaj"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Traženje uređajā…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Postavke"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Prekini vezu"</string>
@@ -1486,18 +1512,21 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="5998592821749881862">"Prečica za pristupačnost je UKLJUČENA"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="2987297770937717543">"Držite oba dugmeta za podešavanje jačine zvuka 3 sekunde da uključite ili isključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>.\n\nUslugu možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
-    <string name="disable_accessibility_shortcut" msgid="3683951963271793789">"Isključi prečicu"</string>
-    <string name="leave_accessibility_shortcut_on" msgid="8762106842437042969">"Ostavi uključeno"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Želite li koristiti Prečicu za pristupačnost?"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Kada je prečica uključena, pritiskom na oba dugmeta za podešavanje jačine zvuka u trajanju od 3 sekunde pokrenut će se funkcija za pristupačnost.\n\n Trenutna funkcija za pristupačnost je:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciju možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
+    <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Isključi prečicu"</string>
+    <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Koristi prečicu"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Promjenu ne dopušta vaš administrator"</string>
+    <string name="error_message_change_not_allowed" msgid="1238035947357923497">"Vaš administrator ne dozvoljava ovu promjenu"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija koja će upravljati ovom akcijom."</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1589,7 +1618,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena."</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da omogućite"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite administratorski PIN"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Upišite PIN kôd administratora"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
@@ -1606,8 +1635,8 @@
     <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije."</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Prikazuje se cijeli ekran"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Da izađete, prevucite nadolje odozgo."</string>
-    <string name="immersive_cling_positive" msgid="5016839404568297683">"Jasno mi je"</string>
-    <string name="done_label" msgid="2093726099505892398">"Završeno"</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Razumijem"</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotovo"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač za odabir sata"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač za minute"</string>
     <string name="select_hours" msgid="6043079511766008245">"Odaberite sat"</string>
@@ -1618,17 +1647,17 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="7693684144593484">"Da biste otkačili ovaj ekran, dodirnite i držite dugme Nazad i Pregled."</string>
-    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikačena. Na ovom uređaju nije dozvoljeno otkačivanje."</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"Da otkačite ovaj ekran, dodirnite i držite dugmad Nazad i Pregled."</string>
+    <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija se ne može otkačiti"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN prije nego se otkači"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje prije nego se otkači"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku prije nego se otkači"</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
-    <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao administrator"</string>
-    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se trajanje baterije produžilo, opcija za štednju baterije minimizira rad uređaja i ograničava vibriranje, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu biti ažurirane dok ih ne otvorite.\n\nŠtednja baterije se automatski isključi prilikom punjenja uređaja."</string>
+    <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je vaš administrator"</string>
+    <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je vaš administrator"</string>
+    <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je vaš administrator"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produžilo trajanje baterije, opcija za uštedu baterije minimizira rad uređaja i ograničava vibraciju, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu se ažurirati dok ih ne otvorite.\n\nUšteda baterije se automatski isključuje prilikom punjenja uređaja."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio prijenos podataka, usluga Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali se to može desiti rjeđe. To može značiti, naprimjer, da se slike ne prikazuju sve dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1709,7 +1738,7 @@
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
     </plurals>
-    <string name="default_notification_channel_label" msgid="6950908610709016902">"Razno"</string>
+    <string name="default_notification_channel_label" msgid="5929663562028088222">"Nije kategorizirano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi određujete značaj ovih obavještenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Da li dozvoljavate aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
@@ -1721,8 +1750,8 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Sve regije"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"Pretraga"</string>
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Radni način rada je ISKLJUČEN"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Omogući radnom profilu da funkcionira, uključujući aplikacije, sinhronizaciju u pozadini i povezane funkcije."</string>
+    <string name="work_mode_off_title" msgid="2615362773958585967">"Želite uključiti radni način?"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"Ovim će se uključiti vaš radni profil, uključujući aplikacije, sinhronizacija u pozadini i povezane funkcije"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
@@ -1760,27 +1789,38 @@
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Otklanjanje grešaka putem uređaja spojenog na USB"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"sat"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"minuta"</string>
-    <string name="time_picker_header_text" msgid="143536825321922567">"Postavite vrijeme"</string>
+    <string name="time_picker_header_text" msgid="143536825321922567">"Postavljanje vremena"</string>
     <string name="time_picker_input_error" msgid="7574999942502513765">"Unesite ispravno vrijeme"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Upišite vrijeme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prebacite u način unosa teksta za unos vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prebacite u način rada kao sat za unos vremena."</string>
-    <!-- no translation found for autofill_picker_accessibility_title (8469043291648711535) -->
-    <skip />
-    <string name="autofill_save_title" msgid="7081244500504163245">"Želite li sačuvati u: <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Želite li sačuvati stavku <xliff:g id="TYPE">%1$s</xliff:g> u: <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
+    <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opcije za automatsko popunjavanje"</string>
+    <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Sačuvaj za automatsko popunjavanje"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Sadržaje nije moguće automatski popuniti"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Nema prijedloga za automatsko popunjavanje"</string>
+    <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> prijedlog za automatsko popunjavanje</item>
+      <item quantity="few"><xliff:g id="COUNT">%1$s</xliff:g> prijedloga za automatsko popunjavanje</item>
+      <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> prijedloga za automatsko popunjavanje</item>
+    </plurals>
+    <string name="autofill_save_title" msgid="3345527308992082601">"Želite li sačuvati u &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_type" msgid="8637809388029313305">"Želite li da se <xliff:g id="TYPE">%1$s</xliff:g> sačuva u &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_2types" msgid="5214035651838265325">"Želite li da se <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> sačuvaju u &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt;?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6943161834231458441">"Želite li da se <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, i <xliff:g id="TYPE_2">%3$s</xliff:g> sačuvaju &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt;?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Sačuvaj"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Ne, hvala"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"lozinka"</string>
     <string name="autofill_save_type_address" msgid="4936707762193009542">"adresa"</string>
     <string name="autofill_save_type_credit_card" msgid="7127694776265563071">"kreditna kartica"</string>
-    <!-- no translation found for etws_primary_default_message_earthquake (5541962250262769193) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_tsunami (1887685943498368548) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_earthquake_and_tsunami (998797956848445862) -->
-    <skip />
-    <!-- no translation found for etws_primary_default_message_test (2709597093560037455) -->
-    <skip />
+    <string name="autofill_save_type_username" msgid="239040540379769562">"korisničko ime"</string>
+    <string name="autofill_save_type_email_address" msgid="5752949432129262174">"adresa e-pošte"</string>
+    <string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Ostanite smireni i potražite sklonište u blizini."</string>
+    <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>
     <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>
+    <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM kartica nije dozvoljena"</string>
+    <string name="mmcc_illegal_me" msgid="4438696681169345015">"Telefon nije dozvoljen"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c216e10..c5f8d55 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -90,12 +90,15 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"No s\'ha proveït el servei."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"No pots canviar la configuració de l\'identificador de trucada."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"No hi ha servei de dades"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No es poden fer trucades d\'emergència"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sense servei d\'emergència"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sense servei de veu"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sense servei de veu/emergència"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"La xarxa mòbil de la teva ubicació temporalment no ofereix aquest servei"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"El teu operador de telefonia mòbil ha suspès temporalment el servei de dades en aquesta ubicació"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"El teu operador de telefonia mòbil ha suspès temporalment les trucades d\'emergència en aquesta ubicació"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"El teu operador de telefonia mòbil ha suspès temporalment les trucades de veu en aquesta ubicació"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"El teu operador de telefonia mòbil ha suspès temporalment les trucades de veu i d\'emergència en aquesta ubicació"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No es pot accedir a la xarxa"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Per millorar la recepció, prova de canviar-ne el tipus a Sistema &gt; Xarxa i Internet &gt; Xarxes mòbils &gt; Tipus de xarxa preferit."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Per millorar la recepció, prova de canviar-ne el tipus a Sistema &gt; Xarxa i Internet &gt; Xarxes de telefonia mòbil &gt; Tipus de xarxa preferit."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="2419697808481833249">"Desviació de trucades"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Mode de devolució de trucada d\'emergència"</string>
@@ -471,7 +474,7 @@
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicació de camp proper (NFC)"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada telefònica entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Gestionar el maquinari d\'empremtes digitals"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permet que l\'aplicació invoqui mètodes per afegir i suprimir plantilles d\'empremtes digitals que es puguin fer servir."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"Utilitzar el maquinari d\'empremtes digitals"</string>
@@ -788,13 +791,13 @@
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Desplega l\'àrea de desbloqueig."</string>
-    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueig mitjançant PIN"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueig mitjançant contrasenya"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Àrea de patró"</string>
-    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar el dit"</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -811,7 +814,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmació de la navegació"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Surt d\'aquesta pàgina"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Queda\'t en aquesta pàgina"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nConfirmes que vols sortir d\'aquesta pàgina?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nEstàs segur que vols sortir d\'aquesta pàgina?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirma"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Consell: Pica dos cops per ampliar i per reduir."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Em. aut."</string>
@@ -890,8 +893,8 @@
     <string name="years" msgid="6881577717993213522">"anys"</string>
     <string name="now_string_shortest" msgid="8912796667087856402">"ara"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> m</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> min</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> min</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
@@ -1075,7 +1078,7 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de memòria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"S\'ha recopilat un procés \"heap dump\"; toca per compartir-lo"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vols compartir el \"heap dump\"?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"El procés <xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de <xliff:g id="SIZE">%2$s</xliff:g> de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Ves amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"El procés <xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de <xliff:g id="SIZE">%2$s</xliff:g> de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Vés amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés."</string>
     <string name="sendText" msgid="5209874571959469142">"Tria una acció per al text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volum del timbre"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volum de multimèdia"</string>
@@ -1159,10 +1162,10 @@
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permet sempre"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"No permetis mai"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"Extracció de la targeta SIM"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"La xarxa mòbil no estarà disponible fins que no reiniciïs amb una targeta SIM vàlida inserida."</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"La xarxa de telefonia mòbil no estarà disponible fins que no reiniciïs amb una targeta SIM vàlida inserida."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Fet"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"Addició de la targeta SIM"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"Reinicia el dispositiu per accedir a la xarxa mòbil."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Reinicia el dispositiu per accedir a la xarxa de telefonia mòbil."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Reinicia"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"Perquè la nova SIM funcioni, has d\'instal·lar i obrir una aplicació del teu operador de telefonia mòbil."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"BAIXA L\'APLICACIÓ"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per a MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connectat a un accessori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca per veure més opcions."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"L\'accessori d\'àudio no és compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca per obtenir més informació"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca per desactivar la depuració USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració USB"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca per seleccionar l\'idioma i el disseny"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Mostra sobre altres aplicacions"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"S\'està superposant <xliff:g id="NAME">%s</xliff:g> a altres aplicacions"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> s\'està superposant a altres apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
@@ -1257,7 +1263,7 @@
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Permet que una aplicació demani permís per ignorar les optimitzacions de bateria per a l\'aplicació."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Piqueu dos cops per controlar el zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No s\'ha pogut afegir el widget."</string>
-    <string name="ime_action_go" msgid="8320845651737369027">"Ves"</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Vés"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Cerca"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Envia"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Següent"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca per sortir del mode de cotxe."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Enrere"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Següent"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omet"</string>
@@ -1363,7 +1367,7 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Llisca el dit. Mantén premut."</string>
-    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Llisca per desbloquejar."</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Llisca el dit per desbloquejar."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Torna a la pàgina d\'inici"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Mou cap a dalt"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
@@ -1599,7 +1603,7 @@
       <item quantity="one">Torna-ho a provar d\'aquí a 1 segon</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"Mode de pantalla completa"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Visualització en pantalla completa"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Per sortir, llisca cap avall des de la part superior."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"D\'acord"</string>
     <string name="done_label" msgid="2093726099505892398">"Fet"</string>
@@ -1617,9 +1621,9 @@
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"No es pot deixar de fixar aquesta aplicació"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per deixar de fixar"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
-    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per deixar de fixar"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per anul·lar"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Sol·licita el patró de desbloqueig per anul·lar"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya per anul·lar"</string>
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instal·lat per l\'administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Actualitzat per l\'administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Suprimit per l\'administrador"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 4d80182..b77f6c2 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Služba není zřízena."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nastavení identifikace volajícího nesmíte měnit."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Datová služba není k dispozici"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Žádná tísňová volání"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Tísňová volání nejsou k dispozici"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Hlasová volání nejsou k dispozici"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hlasová ani tísňová volání nejsou k dispozici"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Mobilní síť ve vaší oblasti tuto službu dočasně nenabízí"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Váš operátor v této oblasti dočasně blokuje datovou službu"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Váš operátor v této oblasti dočasně blokuje tísňová volání"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Váš operátor v této oblasti dočasně blokuje hlasová volání"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Váš operátor v této oblasti dočasně blokuje hlasová i tísňová volání"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"K síti se nelze připojit"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Chcete-li zlepšit příjem, zkuste změnit vybraný typ sítě v nastavení Systém &gt; Síť a internet &gt; Mobilní sítě &gt; Preferovaný typ sítě."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornění"</string>
@@ -851,7 +854,7 @@
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"změna oprávnění prohlížeče poskytovat informace o zeměpisné poloze"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Umožňuje aplikaci upravit oprávnění funkce geolokace v prohlížeči. Škodlivé aplikace toho mohou využít k odeslání údajů o poloze na libovolné webové stránky."</string>
     <string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
-    <string name="save_password_notnow" msgid="6389675316706699758">"Teď ne"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Nyní ne"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamatovat"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Nikdy"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"Nemáte povolení otevřít tuto stránku."</string>
@@ -1229,6 +1232,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB v režimu MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno k perifernímu zařízení USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte další možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvukové příslušenství není podporováno"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Klepnutím zobrazíte další informace"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladění USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozvržení"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Zobrazit přes ostatní aplikace"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Klepnutím ukončíte režim V autě."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zpět"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Další"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Přeskočit"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 2fc542b..87ad291 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Tjenesten leveres ikke!"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Du kan ikke ændre indstillingen for opkalds-id\'et."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ingen datatjeneste"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Ingen nødopkald"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ingen nødtjeneste"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ingen taletjeneste"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ingen tale- og nødtjenester"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbydes i øjeblikket ikke af mobilnetværket på din placering"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Dit mobilselskab har midlertidigt suspenderet datatjeneste på dette sted"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Dit mobilselskab har midlertidigt suspenderet nødopkald på dette sted"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Dit mobilselskab har midlertidigt suspenderet taleopkald på dette sted"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Dit mobilselskab har midlertidigt suspenderet tale- og nødopkald på dette sted"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Der er ingen forbindelse til netværket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Hvis du vil forbedre signalet, kan du prøve at ændre den valgte netværkstype i System &gt; Netværk og internet &gt; Mobilnetværk &gt; Foretrukken netværkstype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Underretninger"</string>
@@ -275,7 +278,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersoner"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"få adgang til enhedens placering"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"at få adgang til enhedens placering"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
@@ -302,7 +305,7 @@
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, stryge, knibe sammen og udføre andre bevægelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingeraftryksbevægelser"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan registrere bevægelser, der foretages på enhedernes fingeraftrykslæser."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"deaktivere eller redigere statuslinje"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"deaktiver eller rediger statuslinje"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vær statusbjælken"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Tillader, at appen er statusbjælken."</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB til MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryk for at se flere muligheder."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret understøttes ikke"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryk for at få flere oplysninger"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryk for at deaktivere fejlretning via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryk for at vælge sprog og layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Vis oven på andre apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> vises over andre apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> vises over andre apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Hvis du ikke ønsker, at <xliff:g id="NAME">%s</xliff:g> skal benytte denne funktion, kan du åbne indstillingerne og deaktivere den."</string>
@@ -1288,10 +1294,10 @@
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveres af <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="1610714069627824309">"Tryk for at administrere netværket."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"Forbundet til <xliff:g id="SESSION">%s</xliff:g>. Tryk for at administrere netværket."</string>
-    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Opretter forbindelse til konstant VPN…"</string>
-    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Konstant VPN er forbundet"</string>
-    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Forbindelsen til konstant VPN er afbrudt"</string>
-    <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fejl i konstant VPN"</string>
+    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Opretter forbindelse til altid aktiveret VPN…"</string>
+    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Altid aktiveret VPN er forbundet"</string>
+    <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Forbindelsen til altid aktiveret VPN er afbrudt"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fejl i altid aktiveret VPN"</string>
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tryk for at konfigurere"</string>
     <string name="upload_file" msgid="2897957172366730416">"Vælg fil"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Ingen fil er valgt"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tryk for at afslutte biltilstand."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbage"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Næste"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Spring over"</string>
@@ -1577,8 +1581,8 @@
     <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
     <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
-    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Ukendt stående format"</string>
-    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Ukendt liggende format"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Ukendt portrætformat"</string>
+    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Ukendt landskabsformat"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulleret"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fejl ved skrivning af indhold"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"ukendt"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 69d344b..be1c307 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Dienst nicht eingerichtet."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Du kannst die Einstellung für die Anrufer-ID nicht ändern."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Kein Datendienst"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Keine Notrufe möglich"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Keine Notrufe"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Keine Anrufe"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Keine Anrufe/Notrufe"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Derzeit nicht im Mobilfunknetz in deiner Region verfügbar"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Dein Anbieter hat den Datendienst an diesem Standort vorübergehend ausgesetzt"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Dein Anbieter hat Notrufe an diesem Standort vorübergehend ausgesetzt"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Dein Anbieter hat Anrufe an diesem Standort vorübergehend ausgesetzt"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Dein Anbieter hat Anrufe und Notrufe an diesem Standort vorübergehend ausgesetzt"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Netzwerk nicht erreichbar"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Der Empfang lässt sich möglicherweise verbessern, indem du unter \"System\" &gt; \"Netzwerk\" &amp; \"Internet\" &gt; \"Mobilfunknetze\" &gt; \"Bevorzugter Netzwerktyp\" einen anderen Typ auswählst."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Warnmeldungen"</string>
@@ -447,9 +450,9 @@
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"Tethering-Konnektivität ändern"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Ermöglicht der App, den Status der Tethering-Konnektivität zu ändern"</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"WLAN-Verbindungen abrufen"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLAN-Netzwerken abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte."</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLANs abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"WLAN-Verbindungen herstellen und trennen"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugangspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLANs vorzunehmen."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugangspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"WLAN-Multicast-Empfang zulassen"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an dein Tablet. Dies nicht mehr Leistung in Anspruch als der Nicht-Multicast-Modus."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN gesendet wurden, nicht nur an deinen Fernseher. Dies nimmt mehr Leistung in Anspruch als der Nicht-Multicast-Modus."</string>
@@ -1099,14 +1102,14 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Benachrichtigungstöne"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Unbekannt"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="other">WLANe verfügbar</item>
-      <item quantity="one">WLAN verfügbar</item>
+      <item quantity="other">WLAN-Netzwerke verfügbar</item>
+      <item quantity="one">WLAN-Netzwerk verfügbar</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="other">Verfügbare WLANe öffnen</item>
-      <item quantity="one">Verfügbares WLAN öffnen</item>
+      <item quantity="other">Verfügbare WLAN-Netzwerke öffnen</item>
+      <item quantity="one">Verfügbares WLAN-Netzwerk öffnen</item>
     </plurals>
-    <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN anmelden"</string>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"In WLAN-Netzwerk anmelden"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Im Netzwerk anmelden"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
@@ -1126,7 +1129,7 @@
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Es konnte keine WLAN-Verbindung hergestellt werden."</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" hat eine schlechte Internetverbindung."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Verbindung zulassen?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Die App \"%1$s\" möchte eine Verbindung zum WLAN %2$s herstellen."</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Die App \"%1$s\" möchte eine Verbindung zum WLAN-Netzwerk %2$s herstellen."</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"Eine App"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct-Betrieb starten. Hierdurch wird der WLAN-Client-/-Hotspot-Betrieb deaktiviert."</string>
@@ -1185,8 +1188,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB für MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Mit USB-Zubehör verbunden"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Für weitere Optionen tippen."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audiozubehör wird nicht unterstützt"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tippen, um weitere Informationen zu erhalten"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Fehlerbericht wird abgerufen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Fehlerbericht teilen?"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Zum Auswählen von Sprache und Layout tippen"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Über anderen Apps einblenden"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> wird über anderen Apps angezeigt"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> wird über anderen Apps angezeigt"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"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>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Zum Beenden des Automodus tippen."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Zurück"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Weiter"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Überspringen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 466c9fa..70286ca 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Η υπηρεσία δεν προβλέπεται."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Δεν μπορείτε να αλλάξετε τη ρύθμιση του αναγνωριστικού καλούντος."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Δεν υπάρχει υπηρεσία δεδομένων"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Δεν επιτρέπονται οι κλήσεις έκτακτης ανάγκης"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Δεν υπάρχει υπηρεσία έκτακτης ανάγκης"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Δεν υπάρχει φωνητική υπηρεσία"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Δεν υπάρχει φωνητική υπηρεσία/υπηρεσία έκτακτης ανάγκης"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Δεν προσφέρεται προσωρινά από το δίκτυο κινητής τηλεφωνίας στην τοποθεσία σας"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Η υπηρεσία δεδομένων έχει τεθεί προσωρινά σε αναστολή από την εταιρεία κινητής τηλεφωνίας σας σε αυτήν την περιοχή"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Οι κλήσεις έκτακτης ανάγκης έχουν τεθεί προσωρινά σε αναστολή από την εταιρεία κινητής τηλεφωνίας σας σε αυτήν την περιοχή"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Οι φωνητικές κλήσεις έχουν τεθεί προσωρινά σε αναστολή από την εταιρεία κινητής τηλεφωνίας σας"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Οι φωνητικές κλήσεις και οι κλήσεις έκτακτης ανάγκης έχουν τεθεί προσωρινά σε αναστολή από την εταιρεία κινητής τηλεφωνίας σας σε αυτήν την περιοχή"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Δεν είναι δυνατή η σύνδεση στο δίκτυο"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Για να βελτιώσετε τη λήψη, δοκιμάστε να αλλάξετε τον επιλεγμένο τύπο από το Σύστημα &gt; Δίκτυο και διαδίκτυο &gt; Δίκτυα κινητής τηλεφωνίας &gt; Προτιμώμενος τύπος δικτύου."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ειδοποιήσεις"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB για MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Σύνδεση σε αξεσουάρ USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Πατήστε για περισσότερες επιλογές."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Το εξάρτημα ήχου δεν υποστηρίζεται"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Πατήστε για να δείτε περισσότερες πληροφορίες"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Πατήστε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Πατήστε για να επιλέξετε γλώσσα και διάταξη"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Εμφάνιση πάνω σε άλλες εφαρμογές"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> προβάλλεται πάνω από άλλες εφαρμογές"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> επικαλύπτει άλλες"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Εάν δεν θέλετε να χρησιμοποιείται αυτή η λειτουργία από την εφαρμογή <xliff:g id="NAME">%s</xliff:g>, πατήστε για να ανοίξετε τις ρυθμίσεις και απενεργοποιήστε την."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Πατήστε για έξοδο από τη λειτουργία αυτοκινήτου."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Πίσω"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Επόμενο"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Παράλειψη"</string>
@@ -1369,7 +1373,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"Εσωτ. κοινόχρ. αποθ. χώρος"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"Εσωτερικός κοινόχρηστος αποθηκευτικός χώρος"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Κάρτα SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Κάρτα SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Μονάδα USB"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index afc977a..e3b72b0 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"No data service"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No emergency calling"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"No emergency service"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"No voice service"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Your operator has temporarily suspended data service at this location"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Your operator has temporarily suspended emergency calls at this location"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Your operator has temporarily suspended voice calls at this location"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Your operator has temporarily suspended voice and emergency calls at this location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Display over other apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> displaying over other apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> is displaying over other apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"If you don’t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index afc977a..e3b72b0 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"No data service"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No emergency calling"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"No emergency service"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"No voice service"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Your operator has temporarily suspended data service at this location"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Your operator has temporarily suspended emergency calls at this location"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Your operator has temporarily suspended voice calls at this location"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Your operator has temporarily suspended voice and emergency calls at this location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Display over other apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> displaying over other apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> is displaying over other apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"If you don’t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index afc977a..e3b72b0 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"No data service"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No emergency calling"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"No emergency service"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"No voice service"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"No voice/emergency service"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Temporarily not offered by the mobile network at your location"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Your operator has temporarily suspended data service at this location"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Your operator has temporarily suspended emergency calls at this location"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Your operator has temporarily suspended voice calls at this location"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Your operator has temporarily suspended voice and emergency calls at this location"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t find network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerts"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio accessory not supported"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap for more info"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Display over other apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> displaying over other apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> is displaying over other apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"If you don’t want <xliff:g id="NAME">%s</xliff:g> to use this feature, tap to open settings and turn it off."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tap to exit car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Back"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Skip"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 4808a7a..cdda07b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Servicio no suministrado."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"No puedes cambiar la configuración del identificador de llamadas."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Sin servicio de datos"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No se pueden hacer llamadas de emergencia"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sin servicio de emergencia"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sin servicio de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sin servicio de voz/emergencia"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil de tu ubicación no ofrece este servicio de forma temporal"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Tu proveedor suspendió temporalmente el servicio de datos en esta ubicación"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Tu proveedor suspendió temporalmente las llamadas de emergencia en esta ubicación"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Tu proveedor suspendió temporalmente las llamadas de voz en esta ubicación"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Tu proveedor suspendió temporalmente las llamadas de emergencia y de voz en esta ubicación"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mejorar la recepción, cambia el tipo de red. Selecciona Sistema &gt; Internet y red &gt; Redes móviles &gt; Tipo de red preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -379,7 +382,7 @@
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite que la aplicación modifique el registro de llamadas de la TV, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite que la aplicación modifique el registro de llamadas del dispositivo, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"acceder a los sensores corporales (como los monitores de frecuencia cardíaca)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la app acceda a datos de sensores que monitorean tu estado físico, como el ritmo cardíaco."</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la aplicación acceda a datos de sensores que controlan tu condición física, como el ritmo cardíaco."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"Leer eventos y detalles del calendario"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"Esta app puede leer todos los eventos del calendario de tu tablet y compartir o guardar los datos correspondientes."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"Esta app puede leer todos los eventos del calendario de tu TV y compartir o guardar los datos correspondientes."</string>
@@ -1178,13 +1181,15 @@
     <string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"esto puede costarte dinero"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"Cargando este dispositivo por USB"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"Este dispositivo se está cargando mediante USB"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"El dispositivo conectado se está cargando mediante USB"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB para transferir archivos"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB para transferir fotos"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Presiona para ver más opciones."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"El accesorio de audio no es compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Presiona para obtener más información"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Presiona para inhabilitar la depuración por USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Presiona para seleccionar el idioma y el diseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Mostrar sobre otras apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> use esta función, presiona para abrir la configuración y desactivarla."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Presiona para salir del modo auto."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
@@ -1623,7 +1627,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Tu administrador instaló este paquete"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Tu administrador actualizó este paquete"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Tu administrador borró este paquete"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Para mejorar la duración de la batería, la función de ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayoría de los datos en segundo plano. Es posible que no puedan actualizarse el correo electrónico, la mensajería y otras aplicaciones que se basan en la sincronización, a menos que los abras.\n\nEl ahorro de batería se desactiva de forma automática cuando el dispositivo se está cargando."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Para ayudar a mejorar la duración de la batería, el ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayoría de los datos en segundo plano. Es posible que el correo electrónico, la mensajería y otras aplicaciones que se basan en la sincronización no puedan actualizarse, a menos que los abras.\n\nEl ahorro de batería se desactiva de forma automática cuando el dispositivo se está cargando."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Para reducir el uso de datos, \"Reducir datos\" evita que algunas apps envíen y reciban datos en segundo plano. La app que estés usando podrá acceder a los datos, pero con menor frecuencia. De esta forma, por ejemplo, las imágenes no se mostrarán hasta que las presiones."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"¿Activar Ahorro de datos?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Activar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 651c5fe..d2dd87b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"El servicio no se suministra."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"No puedes modificar el ID de emisor."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Sin servicio de datos"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"No se pueden hacer llamadas de emergencia"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sin servicio de emergencia"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sin servicio de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sin servicio de emergencia ni de voz"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"La red móvil disponible en tu ubicación no ofrece esta opción de forma temporal"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Tu operador ha suspendido temporalmente el servicio de datos en esta ubicación"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Tu operador ha suspendido temporalmente las llamadas de emergencia en esta ubicación"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Tu operador ha suspendido temporalmente las llamadas de voz en esta ubicación"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Tu operador ha suspendido temporalmente las llamadas de emergencia y de voz en esta ubicación"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"No se puede establecer conexión con la red"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mejorar la recepción, prueba a cambiar el tipo de red seleccionado en Sistema &gt; Red e Internet &gt; Redes móviles &gt; Tipo de red preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -1185,8 +1188,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver más opciones."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accesorio de audio no compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca para obtener más información"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para inhabilitar la depuración USB"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para inhabilitar la depuración USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de errores…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar el idioma y el diseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Mostrar sobre otras aplicaciones"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si no quieres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca la notificación para abrir los ajustes y desactivarla."</string>
@@ -1299,10 +1305,8 @@
     <string name="submit" msgid="1602335572089911941">"Enviar"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Se ha habilitado el modo coche"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca para salir del modo coche."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir Internet/Zona Wi-Fi activado"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atrás"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Siguiente"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Saltar"</string>
@@ -1388,7 +1392,7 @@
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Límite de datos móviles superado"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Límite de datos Wi-Fi superado"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Límite superado en <xliff:g id="SIZE">%s</xliff:g>"</string>
-    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Datos en segundo plano restringidos"</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Conexiones automáticas restringidas"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"Toca para quitar la restricción."</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"Certificado de seguridad"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado es válido."</string>
@@ -1623,7 +1627,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado por el administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Actualizado por el administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Eliminado por el administrador"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Para mejorar la duración de la batería, la función de ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayor parte de los datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de batería se desactiva automáticamente cuando el dispositivo se está cargando."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Para mejorar la duración de la batería, la función de ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de batería se desactiva automáticamente cuando el dispositivo se está cargando."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"El ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que permite reducir el uso de datos. Una aplicación activa podrá acceder a los datos, aunque con menos frecuencia. Esto significa que, por ejemplo, algunas imágenes no se muestren hasta que no las toques."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"¿Activar ahorro de datos?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Activar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 3c85958..c603b1d 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Teenus pole ette valmistatud."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Helistaja ID seadet ei saa muuta."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Andmesideteenus puudub"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Hädaabikõned on blokeeritud"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Hädaabiteenus pole saadaval"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Häälkõned pole saadaval"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Häälkõned/hädaabiteenus pole saadaval"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Teie asukoha mobiilsidevõrk seda teenust ajutiselt ei paku"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Teie operaator on andmesideteenuse selles asukohas ajutiselt peatanud"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Teie operaator on hädaabikõned selles asukohas ajutiselt peatanud"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Teie operaator on häälkõned selles asukohas ajutiselt peatanud"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Teie operaator on hääl- ja hädaabikõned selles asukohas ajutiselt peatanud"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Võrguga ei saa ühendust"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Vastuvõtu parandamiseks muutke valitud tüüpi jaotises Süsteem &gt; Võrk ja Internet &gt; Mobiilsidevõrgud &gt; Eelistatud võrgutüüp."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Teatised"</string>
@@ -1083,7 +1086,7 @@
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Valitud on hääletu märguanne"</string>
     <string name="volume_call" msgid="3941680041282788711">"Kõne helitugevus"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetoothi kõne helitugevus"</string>
-    <string name="volume_alarm" msgid="1985191616042689100">"Äratuse helitugevus"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Alarmi helitugevus"</string>
     <string name="volume_notification" msgid="2422265656744276715">"Teadistusheli"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Helitugevus"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetoothi maht"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI jaoks"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Puudutage lisavalikute nägemiseks."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Helitarvikut ei toetata"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Puudutage lisateabe saamiseks"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Puudutage USB-silumise keelamiseks."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Puudutage keele ja paigutuse valimiseks"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Muude rakenduste peal kuvamine"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Rakendus <xliff:g id="NAME">%s</xliff:g> kuvatakse teiste rakenduste peal"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> kuvat. teiste rakenduste peal"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Kui te ei soovi, et rakendus <xliff:g id="NAME">%s</xliff:g> seda funktsiooni kasutaks, puudutage seadete avamiseks ja lülitage see välja."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Puudutage autorežiimist väljumiseks."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või tööpunkt on aktiivne"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tagasi"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Järgmine"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Jäta vahele"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 696101c..7d0ddaa 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Zerbitzua ez da hornitu."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ezin duzu deien identifikazio-zerbitzuaren ezarpena aldatu."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ez dago datu-zerbitzurik"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Ezin da egin larrialdi-deirik"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ez dago larrialdi-zerbitzurik"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ez dago ahots-deien zerbitzurik"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ez dago ahots- edo larrialdi-deien zerbitzurik"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Zauden tokiko sare mugikorrak ez du eskaintzen aukera hori une honetan"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operadoreak aldi baterako eten du datu-zerbitzua kokapen honetan"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operadoreak aldi baterako eten ditu larrialdi-deiak kokapen honetan"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operadoreak aldi baterako eten ditu ahots-deiak kokapen honetan"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operadoreak aldi baterako eten ditu ahots- eta larrialdi-deiak kokapen honetan"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ezin da konektatu sarera"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Seinalea hobea izan dadin, aldatu hautatutako sare mota Sistema &gt; Sareak eta Internet &gt; Sare mugikorrak &gt; Sare mota hobetsia atalean."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Abisuak"</string>
@@ -247,7 +250,7 @@
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"Edukiak ezkutatuta daude"</string>
-    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Gidalerro batzuk ezkutatu dira, gidalerroei jarraikiz"</string>
+    <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Gidalerro batzuk ezkutatu dira, gidalerroei jarraiki"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teklatu birtuala"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Teklatu fisikoa"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Segurtasuna"</string>
@@ -1138,7 +1141,7 @@
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Gonbidapena bidali da"</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Konektatzeko gonbidapena"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Igorlea:"</string>
-    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Hartzailea:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Nori:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Idatzi beharrezko PINa:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PINa:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tableta Wi-Fi saretik deskonektatuko da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI modurako USBa"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB osagarri batera konektatuta"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Sakatu aukera gehiago ikusteko."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ez da onartzen audio-osagarri hori"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Informazio gehiago lortzeko, sakatu hau"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Sakatu USB arazketa desgaitzeko."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Akatsen txostena partekatzen…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Hizkuntza eta diseinua hautatzeko, sakatu hau"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Bistaratu beste aplikazioen gainean"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> aplikazioen gainean agertzea"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Besteen gainean agertzen da <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ez baduzu nahi <xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Sakatu auto modutik irteteko."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atzera"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Hurrengoa"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Saltatu"</string>
@@ -1376,7 +1381,7 @@
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB unitatea"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB memoria"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Editatu"</string>
-    <string name="data_usage_warning_title" msgid="3620440638180218181">"Datuen erabilerari buruzko abisua"</string>
+    <string name="data_usage_warning_title" msgid="3620440638180218181">"Datu-erabilerari buruzko abisua"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Sakatu erabilera eta ezarpenak ikusteko."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2-3 GB-ko mugara iritsi zara"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4 GB-ko mugara iritsi zara"</string>
@@ -1599,7 +1604,7 @@
       <item quantity="one">Saiatu berriro segundo bat igarotakoan</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Saiatu berriro geroago"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"Pantaila osoko ikuspegia"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Pantaila osoan ikusten"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Irteteko, pasatu hatza goitik behera."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Ados"</string>
     <string name="done_label" msgid="2093726099505892398">"Eginda"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7fcad41..dc8c5fd 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"سرویس دارای مجوز نیست."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"‏شما می‎توانید تنظیم شناسه تماس‌گیرنده را تغییر دهید."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"سرویس داده دردسترس نیست"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"بدون تماس اضطراری"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"سرویس اضطراری دردسترس نیست"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"سرویس صوتی دردسترس نیست"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"سرویس صوتی/اضطراری دردسترس نیست"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"موقتاً توسط شبکه داده دستگاه همراه در مکان شما ارائه نمی‌شود"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"شرکت مخابراتی شما موقتاً سرویس داده را در این مکان به حالت تعلیق درآورده است"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"شرکت مخابراتی شما موقتاً تماس‌های اضطراری را در این مکان به حالت تعلیق درآورده است"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"شرکت مخابراتی شما موقتاً تماس‌های صوتی را در این مکان به حالت تعلیق درآورده است"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"شرکت مخابراتی شما موقتاً تماس‌های صوتی و اضطراری را در این مکان به حالت تعلیق درآورده است"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"شبکه دردسترس نیست"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"برای بهبود دریافت، نوع شبکه‌ای را که انتخاب کرده‌اید در «سیستم» &gt; «شبکه‌ و اینترنت» &gt; «شبکه‌های تلفن همراه» &gt; «نوع شبکه ترجیحی» تغییر دهید."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"هشدارها"</string>
@@ -245,7 +248,7 @@
     <string name="global_action_assist" msgid="3892832961594295030">"دستیار"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
-    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"۹۹۹+"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
     <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خط‌مشی پنهان شده است"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"صفحه‌‌کلید مجازی"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB برای MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏به یک وسیله جانبی USB وصل شده است"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"برای گزینه‌های بیشتر ضربه بزنید."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"وسیله جانبی صوتی پشتیبانی نمی‌شود"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"برای اطلاعات بیشتر ضربه بزنید"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏برای غیرفعال کردن اشکال‌زدایی USB ضربه بزنید."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"نمایش روی سایر برنامه‌ها"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> روی برنامه‌های دیگر نشان داده می‌شود"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> روی برنامه‌های دیگر نشان داده می‌شود"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"اگر نمی‌خواهید <xliff:g id="NAME">%s</xliff:g> از این قابلیت استفاده کند، با ضربه زدن، تنظیمات را باز کنید و قابلیت را خاموش کنید."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"برای خروج از حالت خودرو ضربه بزنید."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"اتصال داده با سیم یا نقطه اتصال فعال"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"برای راه‌اندازی ضربه بزنید."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"اتصال به اینترنت با تلفن همراه غیرفعال شده است"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
     <string name="back_button_label" msgid="2300470004503343439">"برگشت"</string>
     <string name="next_button_label" msgid="1080555104677992408">"بعدی"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"پرش"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index dc38a7a..58783de 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Palvelua ei tarjota."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Et voi muuttaa soittajan tunnuksen asetusta."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ei datayhteyttä"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Ei hätäpuheluita"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ei hätäpuheluja"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ei äänipuheluja"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ei ääni- tai hätäpuheluja"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Sijaintisi mobiiliverkko ei tarjoa tätä tilapäisesti."</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operaattorisi on väliaikaisesti keskeyttänyt datayhteydet tässä sijainnissa."</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operaattorisi on väliaikaisesti keskeyttänyt hätäpuhelut tässä sijainnissa."</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operaattorisi on väliaikaisesti keskeyttänyt äänipuhelut tässä sijainnissa."</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operaattorisi on väliaikaisesti keskeyttänyt ääni- ja hätäpuhelut tästä sijainnista."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ei yhteyttä verkkoon"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Voit yrittää parantaa kuuluvuutta vaihtamalla tyypin asetusta. Valitse Järjestelmä &gt; Verkko &gt; Internet &gt; Mobiiliverkot &gt; Ensisijainen verkko."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ilmoitukset"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB on MIDI-tilassa"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Liitetty USB-laitteeseen"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Näet lisää vaihtoehtoja napauttamalla."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Äänilisälaitetta ei tueta."</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Saat lisätietoja napauttamalla."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Poista USB-vianetsintä käytöstä napauttamalla."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Valitse kieli ja asettelu koskettamalla."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Sovellusten päällä näkyminen"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> näkyy muiden sovellusten päällä"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> näkyy sovellusten päällä"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jos et halua, että <xliff:g id="NAME">%s</xliff:g> voi käyttää tätä ominaisuutta, avaa asetukset napauttamalla ja poista se käytöstä."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Poistu autotilasta napauttamalla."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Takaisin"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seuraava"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ohita"</string>
@@ -1413,7 +1417,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">"Tabletti"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet-laite"</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>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 491fe66..c527eba 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Ce service n\'est pas pris en charge."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Impossible de modifier le paramètre relatif au numéro de l\'appelant."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Aucun service de données"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Aucun appel d\'urgence"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Aucun service d\'urgence"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Aucun service vocal"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Aucun service vocal ou d\'urgence"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Ce service est temporairement non offert par le réseau cellulaire à l\'endroit où vous êtes"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Votre fournisseur de services a momentanément suspendu le service de données pour ce lieu"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Votre fournisseur de services a momentanément suspendu les appels d\'urgence pour ce lieu"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Votre fournisseur de services a momentanément suspendu les appels vocaux pour ce lieu"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Votre fournisseur de services a momentanément suspendu les appels vocaux et d\'urgence pour ce lieu"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible de joindre le réseau"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pour améliorer la réception, essayez de changer le type de réseau sélectionné, sous Système &gt; Réseaux et Internet &gt; Réseaux cellulaires &gt; Type de réseau préféré."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
@@ -1185,7 +1188,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB pour MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Touchez pour afficher plus d\'options."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non pris en charge"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Touchez l\'écran pour obtenir plus d\'information"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Touchez pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création d\'un rapport de bogue en cours..."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Touchez pour sélectionner la langue et la configuration du clavier"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Afficher par-dessus les autres applications"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> affiche du contenu par-dessus d\'autres applications"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> aff. contenu par-dessus applis"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalités, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Touchez pour quitter le mode Voiture."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Précédent"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Suivante"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Passer"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a77ba4e..2f5c44f 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Ce service n\'est pas pris en charge."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Impossible de modifier le paramètre relatif au numéro de l\'appelant."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Aucun service de données"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Aucun appel d\'urgence"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Aucun service d\'urgence"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Aucun service vocal"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Aucun service vocal/d\'urgence"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentanément non proposé par le réseau mobile à votre position"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Votre opérateur a momentanément suspendu le service de données pour ce lieu"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Votre opérateur a momentanément suspendu les appels d\'urgence pour ce lieu"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Votre opérateur a momentanément suspendu les appels vocaux pour ce lieu"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Votre opérateur a momentanément suspendu les appels vocaux et d\'urgence pour ce lieu"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossible d\'accéder au réseau"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pour améliorer la réception, essayez de modifier le type sélectionné sous Système &gt; Réseau et Internet &gt; Réseaux mobiles &gt; Type de réseau préféré."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertes"</string>
@@ -1093,7 +1096,7 @@
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
-    <string name="ringtone_silent" msgid="7937634392408977062">"Aucun(e)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
     <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons de l\'alarme"</string>
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notification"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB en mode MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Appuyez ici pour plus d\'options."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Appuyer pour afficher plus d\'informations"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Appuyez ici pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Appuyer pour sélectionner la langue et la disposition"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Afficher par-dessus les autres applications"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> est affichée sur les autres applications"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> s\'affiche sur autres applis"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Si vous ne voulez pas que l\'application <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalité, appuyez ici pour ouvrir les paramètres et la désactiver."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Appuyez ici pour quitter le mode Voiture."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Retour"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Suivant"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorer"</string>
@@ -1425,7 +1429,7 @@
     <string name="media_route_button_content_description" msgid="591703006349356016">"Caster"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Connexion à l\'appareil"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Caster l\'écran sur l\'appareil"</string>
-    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Recherche d\'appareils…"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Recherche d\'appareils en cours…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Paramètres"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Déconnecter"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Analyse en cours..."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 73f82b1..f733680 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Servizo non ofrecido."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Non podes cambiar a configuración do ID de chamada."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Non hai servizo de datos"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Non se poden realizar chamadas de emerxencia"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Non hai servizo de chamadas de emerxencia"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Non hai servizo de chamadas de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Non hai servizo de chamadas de emerxencia nin de voz"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"A rede de telefonía móbil non ofrece o servizo na túa localización temporalmente"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"O teu operador suspendeu temporalmente o servizo de datos nesta localización"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"O teu operador suspendeu temporalmente as chamadas de emerxencia nesta localización"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"O teu operador suspendeu temporalmente as chamadas de voz nesta localización"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"O teu operador suspendeu temporalmente as chamadas de emerxencia e de voz nesta localización"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Non se pode conectar coa rede"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para mellorar a recepción, proba a cambiar o tipo seleccionado en Sistema &gt; Rede e Internet &gt; Redes de telefonía móbil &gt; Tipo de rede preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -197,7 +200,7 @@
     <string name="silent_mode" msgid="7167703389802618663">"Modo de silencio"</string>
     <string name="turn_on_radio" msgid="3912793092339962371">"Activar a conexión sen fíos"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Desactivar a conexión sen fíos"</string>
-    <string name="screen_lock" msgid="799094655496098153">"Bloqueo de pantalla"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Bloqueo da pantalla"</string>
     <string name="power_off" msgid="4266614107412865048">"Apagar"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"Timbre desactivado"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"Timbre en vibración"</string>
@@ -221,7 +224,7 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Opcións de tableta"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"Opcións da televisión"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opcións de teléfono"</string>
-    <string name="global_action_lock" msgid="2844945191792119712">"Bloqueo de pantalla"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Bloqueo da pantalla"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Apagar"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"Emerxencias"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
@@ -471,7 +474,7 @@
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar o bloqueo da pantalla"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguranza dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguridade dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"xestionar hardware de impresión dixital"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permite que a aplicación invoque métodos para engadir e eliminar modelos de uso de impresión dixital."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"usar hardware de impresión dixital"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver máis opcións."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"O accesorio de audio non é compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca para obter máis información"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para desactivar a depuración de erros de USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración de USB."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartindo informe de erros..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar o idioma e o deseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Mostrar sobre outras aplicacións"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Mostrando <xliff:g id="NAME">%s</xliff:g> sobre outras aplicacións"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> móstrase sobre outras aplicacións"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se non queres que <xliff:g id="NAME">%s</xliff:g> utilice esta función, toca para abrir a configuración e desactívaa."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toca para saír do modo de coche."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Volver"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omitir"</string>
@@ -1600,7 +1605,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Téntao de novo máis tarde"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Vendo pantalla completa"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Para saír, pasa o dedo cara abaixo desde a parte superior."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Para saír, pasa o dedo cara abaixo desde arriba."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"De acordo"</string>
     <string name="done_label" msgid="2093726099505892398">"Feito"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Control desprazable circular das horas"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 20215c1b..341e17e 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -54,12 +54,12 @@
     <string name="serviceErased" msgid="1288584695297200972">"કાઢી નાખવું સફળ થયું હતું."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"ખોટો પાસવર્ડ"</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI પૂર્ણ."</string>
-    <string name="badPin" msgid="9015277645546710014">"તમે લખેલો જૂનો પિન સાચો નથી."</string>
+    <string name="badPin" msgid="9015277645546710014">"તમે લખેલો જૂનો PIN સાચો નથી."</string>
     <string name="badPuk" msgid="5487257647081132201">"તમે લખેલો PUK સાચો નથી."</string>
-    <string name="mismatchPin" msgid="609379054496863419">"તમે લખેલ પિન મેળ ખાતો નથી."</string>
-    <string name="invalidPin" msgid="3850018445187475377">"એક પિન લખો જે 4 થી 8 સંખ્યાનો છે."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"તમે લખેલ PIN મેળ ખાતો નથી."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"એક PIN લખો જે 4 થી 8 સંખ્યાનો છે."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"એક PUK લખો કે જે 8 અંક કે તેથી લાંબો હોય."</string>
-    <string name="needPuk" msgid="919668385956251611">"તમારો સિમ કાર્ડ, PUK-લૉક કરેલ છે. તેને અનલૉક કરવા માટે PUK કોડ લખો."</string>
+    <string name="needPuk" msgid="919668385956251611">"તમારો SIM કાર્ડ, PUK-લૉક કરેલ છે. તેને અનલૉક કરવા માટે PUK કોડ લખો."</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIM કાર્ડને અનાવરોધિત કરવા માટે PUK2 લખો."</string>
     <string name="enablePin" msgid="209412020907207950">"અસફળ, SIM/RUIM લૉક સક્ષમ કરો."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
@@ -76,7 +76,7 @@
     <string name="CwMmi" msgid="9129678056795016867">"કૉલ પ્રતીક્ષા"</string>
     <string name="BaMmi" msgid="455193067926770581">"કૉલ અવરોધન"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"પાસવર્ડમાં બદલાવ"</string>
-    <string name="PinMmi" msgid="3113117780361190304">"પિનમાં બદલાવ"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PIN માં બદલાવ"</string>
     <string name="CnipMmi" msgid="3110534680557857162">"કૉલિંગ નંબર હાજર"</string>
     <string name="CnirMmi" msgid="3062102121430548731">"કૉલ થઈ રહેલો નંબર પ્રતિબંધિત છે"</string>
     <string name="ThreeWCMmi" msgid="9051047170321190368">"ત્રણ રીતે કૉલિંગ"</string>
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"સેવાની જોગવાઈ કરી નથી."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"તમે કૉલર ID સેટિંગ બદલી શકતાં નથી."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"કોઈ ડેટા સેવા નથી"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"કટોકટીમાં કૉલ કરવાની કોઈ સુવિધા નથી"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"કોઈ કટોકટીની સેવા નથી"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"કોઈ વૉઇસ સેવા નથી"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"કોઈ વૉઇસ/કટોકટીની સેવા નથી"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"તમારા સ્થળે મોબાઇલ નેટવર્ક દ્વારા અસ્થાયીરૂપે ઑફર કરવામાં આવતી નથી"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"તમારા કૅરિઅરે આ સ્થાને ડેટાની સેવાઓ અસ્થાયી રૂપે સસ્પેન્ડ કરી છે"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"તમારા કૅરિઅરે આ સ્થાને કટોકટીના કૉલ અસ્થાયી રૂપે સસ્પેન્ડ કર્યા છે"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"તમારા કૅરિઅરે આ સ્થાને વૉઇસ કૉલ અસ્થાયી રૂપે સસ્પેન્ડ કર્યા છે"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"તમારા કૅરિઅરે આ સ્થાને વૉઇસ અને કટોકટીના કૉલ અસ્થાયી રૂપે સસ્પેન્ડ કર્યા છે"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"નેટવર્ક પર પહોંચી શકાતું નથી"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"રિસેપ્શનને બહેતર બનાવવા માટે, સિસ્ટમ &gt; નેટવર્ક અને ઇન્ટરનેટ &gt; મોબાઇલ નેટવર્ક &gt; પસંદગીનો નેટવર્ક પ્રકારમાં પસંદ કરેલો પ્રકાર બદલવાનો પ્રયાસ કરો."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ચેતવણીઓ"</string>
@@ -102,7 +105,7 @@
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"મોબાઇલ ડેટા ચેતવણીઓ"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS સંદેશા"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"વૉઇસમેઇલ સંદેશા"</string>
-    <string name="notification_channel_wfc" msgid="2130802501654254801">"વાઇ-ફાઇ કૉલિંગ"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi કૉલિંગ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"પીઅરે TTY મોડ પૂર્ણની વિનંતી કરી"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"પીઅરે TTY મોડ HCO ની વિનંતી કરી"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"પીઅરે TTY મોડ VCO ની વિનંતી કરી"</string>
@@ -129,16 +132,16 @@
     <string name="roamingText11" msgid="4154476854426920970">"રોમિંગ બેનર ચાલુ"</string>
     <string name="roamingText12" msgid="1189071119992726320">"રૉમિંગ બૅનર બંધ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"સેવા શોધી રહ્યું છે"</string>
-    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"વાઇ-ફાઇ કૉલિંગ"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi કૉલિંગ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"વાઇ-ફાઇ પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલાં તમારા કૅરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી વાઇ-ફાઇ કૉલિંગ ચાલુ કરો."</item>
+    <item msgid="2254967670088539682">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s વાઇ-ફાઇ કૉલિંગ"</item>
+    <item msgid="4397097370387921767">"%s Wi-Fi કૉલિંગ"</item>
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"બંધ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi પસંદ કર્યું"</string>
@@ -182,10 +185,10 @@
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"અજાણ તૃતીય પક્ષ દ્વારા"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"તમારી કાર્ય પ્રોફાઇલના વ્યવસ્થાપક દ્વારા"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> દ્વારા"</string>
-    <string name="work_profile_deleted" msgid="5005572078641980632">"કાર્યાલયની પ્રોફાઇલ કાઢી નાખી"</string>
-    <string name="work_profile_deleted_description" msgid="1100529432509639864">"ખૂટતી વ્યવસ્થાપક ઍપ્લિકેશનને કારણે કાર્યાલયની પ્રોફાઇલ કાઢી નાખી"</string>
-    <string name="work_profile_deleted_details" msgid="6307630639269092360">"કાર્ય પ્રોફાઇલ વ્યવસ્થાપક ઍપ્લિકેશન ખૂટે છે અથવા તો દૂષિત છે. પરિણામે, તમારી કાર્યાલયની પ્રોફાઇલ અને તે સંબંધિત ડેટા કાઢી નાખવામાં આવ્યો છે. સહાયતા માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
+    <string name="work_profile_deleted" msgid="5005572078641980632">"કાર્ય પ્રોફાઇલ કાઢી નાખી"</string>
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"ખૂટતી વ્યવસ્થાપક ઍપ્લિકેશનને કારણે કાર્ય પ્રોફાઇલ કાઢી નાખી"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"કાર્ય પ્રોફાઇલ વ્યવસ્થાપક ઍપ્લિકેશન ખૂટે છે અથવા તો દૂષિત છે. પરિણામે, તમારી કાર્ય પ્રોફાઇલ અને સંબંધિત ડેટા કાઢી નાખવામાં આવ્યો છે. સહાયતા માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"આ ઉપકરણ પર તમારી કાર્ય પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ઉપકરણ સંચાલિત છે"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string>
@@ -292,7 +295,7 @@
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો સામગ્રી પુનર્પ્રાપ્ત કરો"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"તમે જેની સાથે ક્રિયાપ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોની સામગ્રીની તપાસ કરો."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"સ્પર્શ કરીને શોધખોળ કરવું સક્ષમ કરો"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ટચ કરીને અન્વેષણ કરો સક્ષમ કરો"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"ટૅપ કરેલ આઇટમ્સ મોટેથી બોલવામાં આવશે અને હાવભાવની મદદથી સ્ક્રીનનું અન્વેષણ કરી શકાય છે."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"તમે લખો તે ટેક્સ્ટનું અવલોકન કરો"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ક્રેડિટ કાર્ડ નંબર્સ અને પાસવર્ડ્સ જેવો વ્યક્તિગત ડેટા શામેલ છે."</string>
@@ -302,12 +305,12 @@
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ફિંગરપ્રિન્ટ સંકેતો"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ઉપકરણોનાં ફિંગરપ્રિન્ટ સેન્સર પર ભજવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_statusBarService" msgid="4826835508226139688">"સ્ટેટસ બારમાં બતાવો"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"ઍપ્લિકેશનને સ્ટેટસ બારમાં બતાવવાની મંજૂરી આપે છે."</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"સ્ટેટસ બાર વિસ્તૃત કરો/સંકુકિત કરો"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ઍપ્લિકેશનને સ્ટેટસ બાર વિસ્તૃત કરવાની અને સંકુચિત કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"સ્થિતિ બાર અક્ષમ કરો અથવા સંશોધિત કરો"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"એપ્લિકેશનને સ્થિતિ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_statusBarService" msgid="4826835508226139688">"સ્થિતિ બાર થાઓ"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"એપ્લિકેશનને સ્થિતિ બાર થવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"સ્થિતિ બાર વિસ્તૃત કરો/સંકુકિત કરો"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"એપ્લિકેશનને સ્થિતિ બાર વિસ્તૃત કરવાની અને સંકુચિત કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર હોમસ્ક્રીન શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"શોર્ટકટ્સ અનઇન્સ્ટોલ કરો"</string>
@@ -464,12 +467,12 @@
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ટેબ્લેટને WiMAX નેટવર્ક્સ પર કનેક્ટ કરવાની અને ટેબ્લેટને તેનાથી ડિસ્કનેક્ટ કરવાની મંજૂરી એપ્લિકેશનને આપે છે."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"ટીવીને WiMAX નેટવર્ક્સ પર કનેક્ટ કરવાની અને ટીવીને તેનાથી ડિસ્કનેક્ટ કરવાની મંજૂરી એપ્લિકેશનને આપે છે."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ફોનને WiMAX નેટવર્ક્સ પર કનેક્ટ કરવાની અને ફોનને તેનાથી ડિસ્કનેક્ટ કરવાની મંજૂરી એપ્લિકેશનને આપે છે."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"બ્લૂટૂથ ઉપકરણો સાથે જોડાણ બનાવો"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"Bluetooth ઉપકરણો સાથે જોડી કરો"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"એપ્લિકેશનને ટેબ્લેટ પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"એપ્લિકેશનને ટીવી પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"એપ્લિકેશનને ફોન પર Bluetooth ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"ઍપ્લિકેશનને નિઅર ફીલ્ડ કમ્યુનિકેશન (NFC) ટૅગ, કાર્ડ અને રીડર સાથે સંચાર કરવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"એપ્લિકેશનને નિઅર ફીલ્ડ કમ્યુનિકેશન (NFC) ટેગ્સ, કાર્ડ્સ અને રીડર્સ સાથે સંચાર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"તમારું સ્ક્રીન લૉક અક્ષમ કરો"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"એપ્લિકેશનને કીલૉક અને કોઈપણ સંકળાયેલ પાસવર્ડ સુરક્ષા અક્ષમ કરવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, ઇનકમિંગ ફોન કૉલ પ્રાપ્ત કરતી વખતે ફોન, કીલૉકને અક્ષમ કરે છે, પછી કૉલ સમાપ્ત થઈ જવા પર કીલૉક ફરીથી સક્ષમ કરે છે."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
@@ -506,7 +509,7 @@
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"એપ્લિકેશનને તમારા SD કાર્ડની સામગ્રીઓ વાંચવાની મંજૂરી આપે છે."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"તમારા USB સંગ્રહની સામગ્રીઓ સંશોધિત કરો અથવા કાઢી નાખો"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"તમારા SD કાર્ડની સામગ્રીઓ સંશોધિત કરો અથવા કાઢી નાખો"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ઍપ્લિકેશનને USB સ્ટોરેજ પર લખવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"એપ્લિકેશનને USB સંગ્રહ પર લખવાની મંજૂરી આપે છે."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"એપ્લિકેશનને SD કાર્ડ પર લખવાની મંજૂરી આપે છે."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"SIP કૉલ્સ કરો/પ્રાપ્ત કરો"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"એપ્લિકેશનને SIP કૉલ્સ કરવા અને પ્રાપ્ત કરવાની મંજૂરી આપે છે."</string>
@@ -555,7 +558,7 @@
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"ખલેલ પાડશો નહીં ઍક્સેસ કરો"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"એપ્લિકેશનને ખલેલ પાડશો નહીં ગોઠવણી વાંચવા અને લખવાની મંજૂરી આપે છે."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"પાસવર્ડ નિયમો સેટ કરો"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"સ્ક્રીન લૉક પાસવર્ડ અને પિનમાં મંજૂર લંબાઈ અને અક્ષરોને નિયંત્રિત કરો."</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"સ્ક્રીન લૉક પાસવર્ડ્સ અને PIN માં મંજૂર લંબાઈ અને અક્ષરોને નિયંત્રિત કરો."</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"સ્ક્રીનને અનલૉક કરવાના પ્રયત્નોનું નિયમન કરો"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"સ્ક્રીનને અનલૉક કરતી વખતે લખેલા ખોટા પાસવર્ડ્સની સંખ્યાને મૉનિટર કરો અને જો ઘણા બધા ખોટા પાસવર્ડ્સ લખ્યાં છે તો ટેબ્લેટને લૉક કરો અથવા ટેબ્લેટનો તમામ ડેટા કાઢી નાખો."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"સ્ક્રીનને અનલૉક કરતી વખતે લખેલા ખોટા પાસવર્ડ્સની સંખ્યાને મૉનિટર કરો અને જો ઘણા બધા ખોટા પાસવર્ડ્સ લખ્યાં છે તો ટીવીને લૉક કરો અથવા ટીવીનો તમામ ડેટા કાઢી નાખો."</string>
@@ -578,7 +581,7 @@
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ઉપકરણ વૈશ્વિક પ્રોક્સી સેટ કરો"</string>
     <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"નીતિ સક્ષમ હોય તે વખતે ઉપયોગ કરવા માટેના ઉપકરણ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ઉપકરણના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"સ્ક્રીન લૉક પાસવર્ડ સમાપ્તિ સેટ કરો"</string>
-    <string name="policydesc_expirePassword" msgid="5367525762204416046">"કેટલા સમયાંતરે સ્ક્રીન લૉક પાસવર્ડ, પિન અથવા પૅટર્ન બદલવો આવશ્યક છે, તેને બદલો."</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"કેટલીવાર સ્ક્રીન લૉક પાસવર્ડ, PIN અથવા પેટર્ન બદલવો આવશ્યક છે તેને બદલો."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"સંગ્રહ એન્ક્રિપ્શન સેટ કરો"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"જરૂરી છે કે સંગ્રહિત ઍપ્લિકેશન એન્ક્રિપ્ટ થાય."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"કૅમેરા અક્ષમ કરો"</string>
@@ -699,21 +702,21 @@
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"કાર્યાલય"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"અન્ય"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"આ સંપર્ક જોવા માટે કોઈ ઍપ્લિકેશન મળી નથી."</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"પિન કોડ લખો"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK અને નવો પિન કોડ લખો"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN કોડ લખો"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK અને નવો PIN કોડ લખો"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK કોડ"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"નવો પિન કોડ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"નવો PIN કોડ"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"પાસવર્ડ ટાઇપ કરવા માટે ટૅપ કરો"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"અનલૉક કરવા માટે પાસવર્ડ લખો"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"અનલૉક કરવા માટે પિન લખો"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ખોટો પિન કોડ."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"અનલૉક કરવા માટે PIN લખો"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ખોટો PIN કોડ."</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"અનલૉક કરવા માટે, મેનૂ દબાવો તે પછી 0."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"ઇમરજન્સિ નંબર"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"કોઈ સેવા નથી"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"સ્ક્રીન લૉક કરી."</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"અનલૉક કરવા માટે અથવા કટોકટીનો કૉલ કરવા માટે મેનૂ દબાવો."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"અનલૉક કરવા માટે પૅટર્ન દોરો."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"અનલૉક કરવા માટે પેટર્ન દોરો."</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"કટોકટી"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"કૉલ પર પાછા ફરો"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"સાચું!"</string>
@@ -721,14 +724,14 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"ફરી પ્રયાસ કરો"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"તમામ સુવિધાઓ અને ડેટા માટે અનલૉક કરો"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"મહત્તમ ફેસ અનલૉક પ્રયાસો ઓળંગાયા"</string>
-    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"કોઈ સિમ કાર્ડ નથી"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ટૅબ્લેટમાં સિમ કાર્ડ નથી."</string>
-    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"ટીવીમાં કોઈ સિમ કાર્ડ નથી."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ફોનમાં સિમ કાર્ડ નથી."</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"એક સિમ કાર્ડ દાખલ કરો."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"સિમ કાર્ડ ખૂટે છે અથવા વાંચન યોગ્ય નથી. સિમ કાર્ડ દાખલ કરો."</string>
-    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"બિનઉપયોગી સિમ કાર્ડ."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"તમારો સિમ કાર્ડ કાયમી રૂપે અક્ષમ કરવામાં આવ્યો છે.\n બીજા સિમ કાર્ડ માટે તમારા વાયરલેસ સેવા પ્રદાતાનો સંપર્ક કરો."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"કોઈ SIM કાર્ડ નથી"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ટેબ્લેટમાં SIM કાર્ડ નથી."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"ટીવીમાં કોઈ SIM કાર્ડ નથી."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ફોનમાં SIM કાર્ડ નથી."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"એક SIM કાર્ડ દાખલ કરો."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM કાર્ડ ખૂટે છે અથવા વાંચન યોગ્ય નથી. SIM કાર્ડ દાખલ કરો."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"બિનઉપયોગી SIM કાર્ડ."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"તમારું SIM કાર્ડ કાયમીરૂપે અક્ષમ કરવામાં આવ્યું છે.\n બીજા SIM કાર્ડ માટે તમારા વાયરલેસ સેવા પ્રદાતાનો સંપર્ક કરો."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"પહેલાનો ટ્રૅક"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"આગલો ટ્રૅક"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"થોભો"</string>
@@ -738,16 +741,16 @@
     <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"ઝડપી ફોરવર્ડ કરો"</string>
     <string name="emergency_calls_only" msgid="6733978304386365407">"ફક્ત કટોકટીના કૉલ્સ"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"નેટવર્ક લૉક થયું"</string>
-    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"સિમ કાર્ડ, PUK-લૉક કરેલ છે."</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM કાર્ડ, PUK-લૉક કરેલ છે."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"વપરાશકર્તા માર્ગદર્શિકા જુઓ અથવા ગ્રાહક સંભાળનો સંપર્ક કરો."</string>
-    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"સિમ કાર્ડ લૉક કરેલ છે."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"સિમ કાર્ડ અનલૉક કરી રહ્યાં છીએ…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પૅટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM કાર્ડ લૉક કરેલ છે."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM કાર્ડ અનલૉક કરી રહ્યાં છે…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પેટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પાસવર્ડ લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પિન લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટેબ્લેટને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"તમે ટીવીને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટીવીને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -755,9 +758,9 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટીવીને અનલૉક કરવાનો પ્રયાસ કર્યો. ટીવી હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"પૅટર્ન ભૂલી ગયા છો?"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"પેટર્ન ભૂલી ગયાં છો?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"એકાઉન્ટ અનલૉક કરો"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ઘણા બધા પૅટર્ન પ્રયાસો"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ઘણા બધા પેટર્ન પ્રયાસો"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"અનલૉક કરવા માટે, તમારા Google એકાઉન્ટથી સાઇન ઇન કરો."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"વપરાશકર્તાનામ (ઇમેઇલ)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"પાસવર્ડ"</string>
@@ -768,12 +771,12 @@
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"અનલૉક કરો"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ધ્વનિ ચાલુ"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"અવાજ બંધ"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"પૅટર્ન શરૂ કરી"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"પૅટર્ન સાફ કરી"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"પેટર્ન શરૂ કરી"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"પેટર્ન સાફ કરી"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"કોષ ઉમેર્યો"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> કોષ ઉમેર્યો"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"પૅટર્ન પૂર્ણ કરી"</string>
-    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"પૅટર્ન ક્ષેત્ર."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"પેટર્ન પૂર્ણ કરી"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"પેટર્ન ક્ષેત્ર."</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d માંથી %2$d વિજેટ."</string>
     <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"વિજેટ ઉમેરો."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ખાલી"</string>
@@ -789,11 +792,11 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"વિજેટ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> કાઢી નાંખ્યું."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"અનલૉક ક્ષેત્ર વિસ્તૃત કરો."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"સ્લાઇડ અનલૉક કરો."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"પૅટર્ન અનલૉક."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"પેટર્ન અનલૉક."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ફેસ અનલૉક"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"પિન અનલૉક."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"પાસવર્ડ અનલૉક કરો."</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"પૅટર્ન ક્ષેત્ર."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"પેટર્ન ક્ષેત્ર."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"સ્લાઇડ ક્ષેત્ર."</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
@@ -862,7 +865,7 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"ક્વેરી સાફ કરો"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"ક્વેરી સબમિટ કરો"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"વૉઇસ શોધ"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"સ્પર્શ કરીને શોધખોળ કરવું સક્ષમ કરીએ?"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"ટચ કરીને અન્વેષણ કરો સક્ષમ કરીએ?"</string>
     <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ટચ દ્વારા અન્વેષણ કરવાને સક્ષમ કરવા માંગે છે. જ્યારે ટચ દ્વારા અન્વેષણ ચાલુ હોય ત્યારે તમે તમારી આંગળી નીચે જે છે તેનું વર્ણન જોઈ અથવા સાંભળી શકો છો અથવા ટેબ્લેટ સાથે ક્રિયાપ્રતિક્રિયા કરવા માટે હાવભાવ ભજવી શકો છો."</string>
     <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ટચ દ્વારા અન્વેષણ કરવાને સક્ષમ કરવા માંગે છે. જ્યારે ટચ દ્વારા અન્વેષણ ચાલુ હોય ત્યારે તમે તમારી આંગળી નીચે જે છે તેનું વર્ણન જોઈ અથવા સાંભળી શકો છો અથવા ફોન સાથે ક્રિયાપ્રતિક્રિયા કરવા માટે હાવભાવ ભજવી શકો છો."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 મહિના પહેલાં"</string>
@@ -1139,8 +1142,8 @@
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"કનેક્ટ થવા માટે આમંત્રણ"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"પ્રેષક:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"પ્રતિ:"</string>
-    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"આવશ્યક પિન લખો:"</string>
-    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"પિન:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"આવશ્યક PIN લખો:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ટેબ્લેટ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"ટીવી <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ફોન <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે Wi-Fi થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
@@ -1158,10 +1161,10 @@
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"તમે પછીથી આને સેટિંગ્સ &gt; એપ્લિકેશન્સમાં બદલી શકો છો"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"હંમેશા મંજૂરી આપો"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ક્યારેય મંજૂરી આપશો નહીં"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"સિમ કાર્ડ કાઢી નાખ્યો"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"એક માન્ય સિમ કાર્ડ દાખલ કરીને તમે પુનઃપ્રારંભ ન કરો ત્યાં સુધી મોબાઇલ નેટવર્ક અનુપલબ્ધ રહેશે."</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM કાર્ડ દૂર કર્યું"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"એક માન્ય SIM કાર્ડ દાખલ કરીને તમે પુનઃપ્રારંભ ન કરો ત્યાં સુધી મોબાઇલ નેટવર્ક અનુપલબ્ધ રહેશે."</string>
     <string name="sim_done_button" msgid="827949989369963775">"થઈ ગયું"</string>
-    <string name="sim_added_title" msgid="3719670512889674693">"સિમ કાર્ડ ઉમેર્યો"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM કાર્ડ ઉમેર્યું"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"મોબાઇલ નેટવર્કને ઍક્સેસ કરવા માટે તમારા ઉપકરણને પુનઃપ્રારંભ કરો."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"પુનઃપ્રારંભ કરો"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"તમારું નવું SIM ઠીકથી કામ કરે તે માટે, તમને તમારા કેરીઅર પરથી ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને ખોલવી પડશે."</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI માટે USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ઍક્સેસરીથી કનેક્ટ થયાં"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ઑડિયો ઍક્સેસરી સમર્થિત નથી"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"વધુ માહિતી માટે ટૅપ કરો"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ડીબગિંગ અક્ષમ કરવા માટે ટૅપ કરો."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"બગ રિપોર્ટ શેર કરી રહ્યાં છે…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"અન્ય ઍપ્લિકેશનોની ટોચે પ્રદર્શિત કરો"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનોની ઉપર પ્રદર્શિત થઈ રહ્યું છે"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનો પર દેખાઈ છે"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"જો તમે નથી ઇચ્છતા કે <xliff:g id="NAME">%s</xliff:g> આ સુવિધાનો ઉપયોગ કરે, તો સેટિંગ્સ ખોલવા માટે ટૅપ કરો અને તેને બંધ કરો."</string>
@@ -1299,10 +1306,8 @@
     <string name="submit" msgid="1602335572089911941">"સબમિટ કરો"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"કાર મોડ સક્ષમ છે"</string>
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"કાર મોડથી બહાર નીકળવા માટે ટૅપ કરો."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હોટસ્પોટ સક્રિય"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
     <string name="back_button_label" msgid="2300470004503343439">"પાછળ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"આગલું"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"છોડો"</string>
@@ -1313,7 +1318,7 @@
       <item quantity="other"><xliff:g id="TOTAL">%d</xliff:g> માંથી <xliff:g id="INDEX">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"થઈ ગયું"</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB સ્ટોરેજ ભૂસી રહ્યાં છીએ…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB સંગ્રહ કાઢી નાખી રહ્યાં છે…"</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD કાર્ડ કાઢી નાખી રહ્યાં છે…"</string>
     <string name="share" msgid="1778686618230011964">"શેર કરો"</string>
     <string name="find" msgid="4808270900322985960">"શોધો"</string>
@@ -1335,7 +1340,7 @@
     <string name="add_account_button_label" msgid="3611982894853435874">"એકાઉન્ટ ઉમેરો"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"વધારો"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"ઘટાડો"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> સ્પર્શ કરી રાખો"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> ટચ કરો અને પકડી રાખો."</string>
     <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"વધારવા માટે ઉપર અને ઘટાડવા માટે નીચે સ્લાઇડ કરો."</string>
     <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"મિનિટ વધારો"</string>
     <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"મિનિટ ઘટાડો"</string>
@@ -1362,7 +1367,7 @@
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> લોંચ કરી શકાયું નથી"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"આની સાથે શેર કરો"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> સાથે શેર કરો"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"સ્લાઇડિંગ હૅન્ડલ. સ્પર્શ કરી રાખો."</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"સ્લાઇડિંગ હેન્ડલ. ટચ કરો અને પકડો."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"અનલૉક કરવા માટે સ્વાઇપ કરો."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"હોમ પર નેવિગેટ કરો"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"ઉપર નેવિગેટ કરો"</string>
@@ -1374,7 +1379,7 @@
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD કાર્ડ"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ડ્રાઇવ"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ડ્રાઇવ"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USB સ્ટોરેજ"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB સંગ્રહ"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"સંપાદિત કરો"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"ડેટા વપરાશ ચેતવણી"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"વપરાશ અને સેટિંગ્સ જોવા ટૅપ કરો."</string>
@@ -1388,7 +1393,7 @@
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"મોબાઇલ ડેટા મર્યાદા ઓળંગાઈ"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ડેટા મર્યાદા ઓળંગાઈ"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"ઉલ્લેખિત મર્યાદાથી <xliff:g id="SIZE">%s</xliff:g> વધુ."</string>
-    <string name="data_usage_restricted_title" msgid="5965157361036321914">"બૅકગ્રાઉન્ડ ડેટા પ્રતિબંધિત"</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"પૃષ્ઠભૂમિ ડેટા પ્રતિબંધિત"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"પ્રતિબંધ દૂર કરવા માટે ટૅપ કરો."</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"સુરક્ષા પ્રમાણપત્ર"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"આ પ્રમાણપત્ર માન્ય છે."</string>
@@ -1421,7 +1426,7 @@
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"સિસ્ટમ"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ઑડિઓ"</string>
-    <string name="wireless_display_route_description" msgid="9070346425023979651">"વાયરલેસ ડિસ્પ્લે"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"બિનતારી પ્રદર્શન"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"કાસ્ટ કરો"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"ઉપકરણ સાથે કનેક્ટ કરો"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ઉપકરણ પર સ્ક્રીન કાસ્ટ કરો"</string>
@@ -1438,25 +1443,25 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ઓવરલે કરો"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", સુરક્ષિત"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"પૅટર્ન ભૂલી ગયાં"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"ખોટી પૅટર્ન"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"પેટર્ન ભૂલી ગયાં"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"ખોટી પેટર્ન"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ખોટો પાસવર્ડ"</string>
-    <string name="kg_wrong_pin" msgid="1131306510833563801">"ખોટો પિન"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"ખોટો PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="kg_pattern_instructions" msgid="398978611683075868">"તમારી પૅટર્ન દોરો"</string>
-    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"સિમ પિન દાખલ કરો"</string>
-    <string name="kg_pin_instructions" msgid="2377242233495111557">"પિન દાખલ કરો"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"તમારી પેટર્ન દોરો"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN દાખલ કરો"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN દાખલ કરો"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"પાસવર્ડ દાખલ કરો"</string>
     <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM હવે અક્ષમ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કેરીઅરનો સંપર્ક કરો."</string>
-    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"જોઈતો પિન કોડ દાખલ કરો"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"જોઈતા પિન કોડની પુષ્ટિ કરો"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"સિમ કાર્ડ અનલૉક કરી રહ્યાં છીએ…"</string>
-    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ખોટો પિન કોડ."</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"એક પિન લખો જે 4 થી 8 સંખ્યાનો છે."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"જોઈતો PIN કોડ દાખલ કરો"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"જોઈતા PIN કોડની પુષ્ટિ કરો"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM કાર્ડ અનલૉક કરી રહ્યાં છે…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ખોટો PIN કોડ."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"એક PIN લખો જે 4 થી 8 સંખ્યાનો છે."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK કોડ 8 નંબર્સનો હોવો જોઈએ."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"સાચો PUK કોડ ફરીથી દાખલ કરો. પુનરાવર્તિત પ્રયાસો SIM ને કાયમી રીતે અક્ષમ કરશે."</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"પિન કોડ મેળ ખાતા નથી"</string>
-    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ઘણા બધા પૅટર્ન પ્રયાસો"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN કોડ્સ મેળ ખાતા નથી"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ઘણા બધા પેટર્ન પ્રયાસો"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"અનલૉક કરવા માટે, તમારા Google એકાઉન્ટથી સાઇન ઇન કરો."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"વપરાશકર્તાનામ (ઇમેઇલ)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"પાસવર્ડ"</string>
@@ -1464,18 +1469,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"અમાન્ય વપરાશકર્તાનામ અથવા પાસવર્ડ"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"તમારું વપરાશકર્તાનામ અથવા પાસવર્ડ ભૂલાઈ ગયો?\n "<b>"google.com/accounts/recovery"</b>" ની મુલાકાત લો."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"એકાઉન્ટ તપાસી રહ્યું છે…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પિન લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પાસવર્ડ લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પૅટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પેટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"તમે ટીવીને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટીવીને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટેબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટેબ્લેટ હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટીવીને અનલૉક કરવાનો પ્રયાસ કર્યો. ટીવી હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી. હજી <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટેબ્લેટને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"તમે તમારી અનલૉક પેટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી. હજી <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"દૂર કરો"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
@@ -1585,15 +1590,15 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"મુદ્રણ સેવા સક્ષમ નથી"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> સેવા ઇન્સ્ટોલ કરી"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"સક્ષમ કરવા માટે ટેપ કરો"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"વ્યવસ્થાપક પિન દાખલ કરો"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"વ્યવસ્થાપક PIN દાખલ કરો"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"પિન દાખલ કરો"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"ખોટું"</string>
-    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"વર્તમાન પિન"</string>
-    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"નવો પિન"</string>
-    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"નવા પિનની પુષ્ટિ કરો"</string>
-    <string name="restr_pin_create_pin" msgid="8017600000263450337">"પ્રતિબંધો સંશોધિત કરવા માટે એક પિન બનાવો"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"પિન મેળ ખાતા નથી. ફરીથી પ્રયાસ કરો."</string>
-    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"પિન ખૂબ નાનો છે. ઓછામાં ઓછો 4 અંકનો હોવો આવશ્યક છે."</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"વર્તમાન PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"નવો PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"નવા PIN ની પુષ્ટિ કરો"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"પ્રતિબંધો સંશોધિત કરવા માટે એક PIN બનાવો"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN મેળ ખાતા નથી. ફરીથી પ્રયાસ કરો."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ખૂબ નાનો છે. ઓછામાં ઓછો 4 અંકનો હોવો આવશ્યક છે."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો</item>
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો</item>
@@ -1613,12 +1618,12 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"કાર્યાલય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="6820571533009838261">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને ઝલક બટનોને સ્પર્શ કરી રાખો"</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને વિહંગાવલોકન બટનોને ટચ કરીને દબાવી રાખો"</string>
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"આ ઍપ્લિકેશનને અનપિન કરી શકાશે નહીં"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"સ્ક્રીન પિન કરી"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"સ્ક્રીન અનપિન કરી"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"અનપિન કરતા પહેલાં પિન માટે પૂછો"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"અનપિન કરતાં પહેલાં PIN માટે પૂછો"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"અનપિન કરતા પહેલાં અનલૉક પેટર્ન માટે પૂછો"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
     <string name="package_installed_device_owner" msgid="6875717669960212648">"તમારા વ્યવસ્થાપક દ્વારા ઇન્સ્ટૉલ કરવામાં આવેલ છે"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ કરવામાં આવેલ છે"</string>
@@ -1679,7 +1684,7 @@
     <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS વિનંતીને DIAL વિનંતી પર સંશોધિત કરી."</string>
     <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS વિનંતીને USSD વિનંતી પર સંશોધિત કરી."</string>
     <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS વિનંતીને નવી SS વિનંતી પર સંશોધિત કરી."</string>
-    <string name="notification_work_profile_content_description" msgid="4600554564103770764">"કાર્યાલયની પ્રોફાઇલ"</string>
+    <string name="notification_work_profile_content_description" msgid="4600554564103770764">"કાર્ય પ્રોફાઇલ"</string>
     <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"વિસ્તૃત કરો"</string>
     <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"સંકુચિત કરો"</string>
     <string name="expand_action_accessibility" msgid="5307730695723718254">"વિસ્તરણ ટૉગલ કરો"</string>
@@ -1708,15 +1713,15 @@
     <string name="region_picker_section_all" msgid="8966316787153001779">"તમામ પ્રદેશ"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"શોધ"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"કાર્ય મોડ ચાલુ કરીએ?"</string>
-    <string name="work_mode_off_message" msgid="2961559609199223594">"આનાથી ઍપ્લિકેશનો, બૅકગ્રાઉન્ડ સિંક અને તે સંબંધિત સુવિધાઓ સહિતની તમારી કાર્યાલયની પ્રોફાઇલ ચાલુ થઈ જશે"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"આનાથી ઍપ્લિકેશનો, પૃષ્ઠભૂમિ સમન્વયન અને સંબંધિત સુવિધાઓ સહિતની તમારી કાર્ય પ્રોફાઇલ ચાલુ થઈ જશે"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"ચાલુ કરો"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"તમારી પાસે નવા સંદેશા છે"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"જોવા માટે SMS ઍપ્લિકેશન ખોલો"</string>
     <string name="user_encrypted_title" msgid="9054897468831672082">"કેટલીક કાર્યક્ષમતા મર્યાદિત હોઈ શકે છે"</string>
     <string name="user_encrypted_message" msgid="4923292604515744267">"અનલૉક કરવા માટે ટૅપ કરો"</string>
     <string name="user_encrypted_detail" msgid="5708447464349420392">"વપરાશકર્તા ડેટા લૉક કર્યો"</string>
-    <string name="profile_encrypted_detail" msgid="3700965619978314974">"કાર્યાલયની પ્રોફાઇલ લૉક કરી"</string>
-    <string name="profile_encrypted_message" msgid="6964994232310195874">"કાર્યાલયની પ્રોફાઇલ અનલૉક કરવા ટૅપ કરો"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"કાર્ય પ્રોફાઇલ લૉક કરી"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"કાર્ય પ્રોફાઇલ અનલૉક કરવા ટૅપ કરો"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> થી કનેક્ટ કરેલું છે"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ફાઇલો જોવા માટે ટૅપ કરો"</string>
     <string name="pin_target" msgid="3052256031352291362">"પિન"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2f757d7..ba658e2 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -46,7 +46,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"कनेक्‍शन समस्‍या या अमान्‍य MMI कोड."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"कार्रवाई केवल फ़िक्‍स्‍ड डायलिंग नंबर के लिए प्रतिबंधित है."</string>
-    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"आपके रोमिंग में होने पर, आपके फ़ोन से कॉल को दूसरे नंबर पर भेजने की सेटिंग नहीं बदली जा सकती."</string>
+    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"आपके रोमिंग में होने पर आपके फ़ोन से कॉल अग्रेषण की सेटिंग नहीं बदली जा सकतीं."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"सेवा अक्षम थी."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"सेवा इसके लिए सक्षम की गई थी:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"सेवा अक्षम कर दी गई है."</string>
@@ -68,8 +68,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर आईडी"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर आईडी"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर ID"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"कनेक्ट किया गया लाइन आईडी"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"कनेक्ट किया गया लाइन आईडी प्रतिबंध"</string>
     <string name="CfMmi" msgid="5123218989141573515">"कॉल आगे भेजना"</string>
@@ -83,30 +83,33 @@
     <string name="RuacMmi" msgid="7827887459138308886">"अवांछित कष्टप्रद कॉल की अस्वीकृति"</string>
     <string name="CndMmi" msgid="3116446237081575808">"कॉलिंग नंबर वितरण"</string>
     <string name="DndMmi" msgid="1265478932418334331">"परेशान न करें"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित है. अगली कॉल: सीमित"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित है. अगली कॉल: सीमित नहीं"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित नहीं है. अगली कॉल: सीमित"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित नहीं है. अगली कॉल: सीमित नहीं"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"कॉलर आईडी प्रतिबंधित पर डिफ़ॉल्‍ट है. अगली कॉल: प्रतिबंधित"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"कॉलर ID प्रतिबंधित पर डिफ़ॉल्‍ट है. अगला कॉल: प्रतिबंधित नहीं"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"कॉलर ID प्रतिबंधित नहीं पर डिफ़ॉल्‍ट है. अगला कॉल: प्रतिबंधित"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"कॉलर ID प्रतिबंधित नहीं पर डिफ़ॉल्‍ट है. अगली कॉल: प्रतिबंधित नहीं"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"सेवा प्रावधान की हुई नहीं है."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"आप कॉलर आईडी सेटिंग नहीं बदल सकते."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"कोई डेटा सेवा नहीं है"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"कोई भी आपातकालीन कॉलिंग नहीं है"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"कोई आपातकालीन सेवा नहीं है"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"कोई वॉइस सेवा नहीं है"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"कोई वॉइस/आपातकालीन सेवा नहीं है"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"आपके स्थान के मोबाइल नेटवर्क की ओर से इस समय ऑफ़र नहीं किया जा रहा है"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"आपके वाहक ने इस स्थान पर कुछ समय के लिए डेटा सेवा बंद कर दी है"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"आपके वाहक ने इस स्थान पर कुछ समय के लिए आपातकालीन कॉल बंद कर दिए हैं"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"आपके वाहक ने इस स्थान पर कुछ समय के लिए वॉइस कॉल बंद कर दिए हैं"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"आपके वाहक ने इस स्थान पर वॉइस और आपातकालीन कॉल कुछ समय के लिए बंद कर दिए हैं"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्क तक नहीं पहुंच पा रहे हैं"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन बेहतर करने के लिए, सिस्टम &gt; नेटवर्क और इंटरनेट &gt; मोबाइल नेटवर्क &gt; पसंदीदा नेटवर्क प्रकार पर जाकर, चुना गया प्रकार बदलकर देखें."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"सूचनाएं"</string>
-    <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल को दूसरे नंबर पर भेजना"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"कॉल अग्रेषण"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"आपातकालीन कॉलबैक मोड"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"मोबाइल डेटा सूचनाएं"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"वॉइसमेल संदेश"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"वाई-फ़ाई कॉलिंग"</string>
-    <string name="peerTtyModeFull" msgid="6165351790010341421">"पीयर ने टेलीटाइपराइटर (TTY) मोड फ़ुल का अनुरोध किया"</string>
-    <string name="peerTtyModeHco" msgid="5728602160669216784">"पीयर ने टेलीटाइपराइटर (TTY) मोड एचसीओ (HCO) का अनुरोध किया"</string>
-    <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने टेलीटाइपराइटर (TTY) मोड वीसीअो (VCO) का अनुरोध किया"</string>
-    <string name="peerTtyModeOff" msgid="3280819717850602205">"पीयर ने टेलीटाइपराइटर (TTY) मोड बंद का अनुरोध किया"</string>
+    <string name="peerTtyModeFull" msgid="6165351790010341421">"पीयर ने TTY मोड पूर्ण का अनुरोध किया"</string>
+    <string name="peerTtyModeHco" msgid="5728602160669216784">"पीयर ने TTY मोड HCO का अनुरोध किया"</string>
+    <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने TTY मोड VCO का अनुरोध किया"</string>
+    <string name="peerTtyModeOff" msgid="3280819717850602205">"पीयर ने TTY मोड बंद का अनुरोध किया"</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"ध्‍वनि"</string>
     <string name="serviceClassData" msgid="872456782077937893">"डेटा"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"फ़ैक्स"</string>
@@ -115,9 +118,9 @@
     <string name="serviceClassDataSync" msgid="7530000519646054776">"समन्वयन"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"पैकेट"</string>
     <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
-    <string name="roamingText0" msgid="7170335472198694945">"रोमिंग दिखाने वाला संकेत चालू है"</string>
-    <string name="roamingText1" msgid="5314861519752538922">"रोमिंग दिखाने वाला संकेत बंद है"</string>
-    <string name="roamingText2" msgid="8969929049081268115">"रोमिंग दिखाने वाला संकेत चमक रहा है"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"रोमिंग संकेतक चालू"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"रोमिंग संकेतक बंद"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"रोमिंग संकेतक स्क्रीन की रोशनी रहा है"</string>
     <string name="roamingText3" msgid="5148255027043943317">"मोहल्‍ले से बाहर"</string>
     <string name="roamingText4" msgid="8808456682550796530">"भवन से बाहर"</string>
     <string name="roamingText5" msgid="7604063252850354350">"रोमिंग - पसंदीदा सिस्‍टम"</string>
@@ -131,10 +134,10 @@
     <string name="roamingTextSearching" msgid="8360141885972279963">"सेवा खोज रहा है"</string>
     <string name="wfcRegErrorTitle" msgid="2301376280632110664">"वाई-फ़ाई कॉलिंग"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"वाई-फ़ाई से फ़ोन करने और मैसेज भेजने के लिए, सबसे पहले अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से इस सेवा को सेट अप करने के लिए कहें. उसके बाद सेटिंग से वाई-फ़ाई कॉलिंग को फिर से चालू करें."</item>
+    <item msgid="2254967670088539682">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="6177300162212449033">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी में रजिस्टर करें"</item>
+    <item msgid="6177300162212449033">"अपने वाहक के साथ पंजीकृत करें"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
@@ -194,7 +197,7 @@
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टेबलेट विकल्‍प"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"टीवी के विकल्‍प"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"फ़ोन विकल्‍प"</string>
-    <string name="silent_mode" msgid="7167703389802618663">"साइलेंट मोड (खामोश)"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"मौन मोड"</string>
     <string name="turn_on_radio" msgid="3912793092339962371">"वायरलेस चालू करें"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"वायरलेस बंद करें"</string>
     <string name="screen_lock" msgid="799094655496098153">"स्‍क्रीन लॉक"</string>
@@ -230,12 +233,12 @@
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"सहभागी रिपोर्ट"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"अधिकांश परिस्थितियों में इसका उपयोग करें. यह आपको रिपोर्ट की प्रगति ट्रैक करने देता है, समस्या के बारे में अधिक विवरण डालने देता है और स्क्रीनशॉट लेने देता है. यह आपको ऐसे कम उपयोग किए गए अनुभाग मिटाने दे सकता है जिनकी रिपोर्ट करने में अधिक समय लगता है."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"पूर्ण रिपोर्ट"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"जब आपका डिवाइस ठीक से काम नहीं कर रहा हो या बहुत धीमा हो या जब आपको रिपोर्ट के सभी भागों की ज़रूरत हो, तो सिस्टम से कम से कम रोक-टोक के लिए इस विकल्प का इस्तेमाल करें. यह आपको ज़्यादा जानकारी डालने या अतिरिक्त स्क्रीनशॉट लेने नहीं देता."</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"जब आपका डिवाइस प्रतिसाद नहीं दे रहा हो या बहुत ही धीमा हो, या जब आपको सभी रिपोर्ट अनुभागों की आवश्यकता हो, तो न्यूनतम सिस्टम हस्तक्षेप के लिए इस विकल्प का उपयोग करें. यह आपको अधिक विवरण नहीं डालने देता या अतिरिक्त स्क्रीनशॉट नहीं लेने देता."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
       <item quantity="one">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
       <item quantity="other">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
     </plurals>
-    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"साइलेंट मोड (खामोश)"</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्‍वनि बंद है"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्‍वनि चालू है"</string>
     <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"हवाई जहाज मोड"</string>
@@ -243,7 +246,7 @@
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"हवाई जहाज मोड बंद है"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"सेटिंग"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"सहायता"</string>
-    <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज़ से डिवाइस का इस्तेमाल"</string>
+    <string name="global_action_voice_assist" msgid="7751191495200504480">"वॉइस सहायक"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"छिपी हुई सामग्री"</string>
@@ -266,7 +269,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैकग्राउंड में चल रहा है"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा खर्च की जानकारी के लिए टैप करें"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा उपयोग के विवरण देखने के लिए टैप करें"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android सिस्‍टम"</string>
@@ -292,36 +295,36 @@
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री प्राप्त करें"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"उस विंडो की सामग्री का निरीक्षण करें जिससे आप सहभागिता कर रहे हैं."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"छूकर, उससे जुड़ी जानकारी सुनने की सुविधा चालू करें"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"टैप किए गए आइटम ज़ोर से बोले जाएंगे और स्क्रीन को जेस्चर के ज़रिए एक्सप्लोर किया जा सकता है."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श द्वारा एक्सप्लोर करें को चालू करें"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"टैप किए गए आइटम ज़ोर से बोले जाएंगे और स्क्रीन को हावभाव के उपयोग से एक्सप्लोर किया जा सकेगा."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आपके द्वारा लिखे हुए लेख को ध्यान से देखें"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर और पासवर्ड जैसा व्यक्तिगत डेटा शामिल होता है."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन आवर्धन नियंत्रित करें"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शन का ज़ूम स्‍तर और स्‍थिति निर्धारण नियंत्रित करें."</string>
-    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेस्चर करें"</string>
-    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"इस सेवा के ज़रिए टैप, स्वाइप, पिंच और बाकी जेस्चर किए जा सकते हैं."</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फ़िंगरप्रिंट जेस्चर"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिवाइस फ़िंगरप्रिंट सेंसर पर किए गए जेस्चर कैप्चर किए जा सकते हैं."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार को अक्षम करें या बदलें"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप को, स्टेटस बार को अक्षम करने या सिस्‍टम आइकन को जोड़ने या निकालने की अनुमति देता है."</string>
-    <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार को रहने दें"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"ऐप को स्टेटस बार बने रहने की अनुमति देता है."</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्टेटस बार खोलकर बड़ा करें/छोटा करें"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ऐप को, स्टेटस बार खोलकर बड़ा करने या उसे छोटा करने की अनुमति देता है."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"हावभाव निष्पादित करें"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"इस सेवा के द्वारा टैप किया जा सकता है, स्वाइप किया जा सकता है, पिंच किया जा सकता है और अन्य हावभाव निष्पादित किए जा सकते हैं."</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फ़िंगरप्रिंट हावभाव"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिवाइस फ़िंगरप्रिंट सेंसर पर किए गए हावभाव कैप्चर किए जा सकते हैं."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"स्‍थिति बार अक्षम या बदलें"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप्स  को स्थिति बार अक्षम करने या सिस्‍टम आइकन को जोड़ने या निकालने देता है."</string>
+    <string name="permlab_statusBarService" msgid="4826835508226139688">"स्‍थिति बार होने दें"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"ऐप्स को स्‍थिति बार होने देता है."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्‍थिति बार विस्‍तृत/संक्षिप्त करें"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"ऐप्स  को स्थिति बार को विस्तृत या संक्षिप्त करने देता है."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"शॉर्टकट इंस्‍टॉल करें"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट जोड़ने की अनुमति देता है."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट अनइंस्टॉल करें"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट निकालने की अनुमति देता है."</string>
-    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"किया जाने वाला कॉल (आउटगोइंग) कहीं और भेजें"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"एेप कॉल को किसी और नंबर पर भेजने या कॉल को पूरी तरह रद्द करने के विकल्प के साथ, किए गए कॉल (आउटगोइंग) के नंबर को देख सकता है."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"आउटगोइंग कॉल को कहीं और भेजें"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ऐप्स को किसी कॉल को भिन्न नंबर पर रिडायरेक्ट करने या पूरी तरह से कॉल निरस्त करने के विकल्प के साथ आउटगोइंग कॉल के दौरान डायल किए जा रहे नंबर को देखने की अनुमति देती है."</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"फ़ोन कॉल का जवाब दें"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ऐप्लिकेशन को किसी इनकमिंग फ़ोन कॉल का जवाब देने देती है."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"लेख संदेश (SMS) प्राप्त करें"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"ऐप्स  को SMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप्स  आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"लेख संदेश (MMS) प्राप्त करें"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"ऐप्स  को MMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि ऐप्स  आपके डिवाइस पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ें"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप को, वो सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ने देता है जो आपके डिवाइस को मिले हैं. सेल ब्रॉडकास्ट (CBC) अलर्ट कुछ स्थानों (लोकेशन) पर आपको आपातकालीन स्‍थितियों की चेतावनी देने के लिए दिए जाते हैं. आपातकालीन सेल ब्रॉडकास्ट (CBC) मिलने पर, धोखा देने वाले ऐप आपके डिवाइस के परफ़ॉर्मेंस या कार्यवाही में दखल दे सकते हैं."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण संदेश पढ़ें"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप्स को आपके डिवाइस द्वारा प्राप्त सेल प्रसारण संदेशों को पढ़ने देता है. कुछ स्‍थानों पर आपको आपातकालीन स्‍थितियों की चेतावनी देने के लिए सेल प्रसारण अलर्ट वितरित किए जाते हैं. आपातकालीन सेल प्रसारण प्राप्त होने पर दुर्भावनापूर्ण ऐप्स आपके डिवाइस के निष्‍पादन या संचालन में हस्‍तक्षेप कर सकते हैं."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता-प्राप्त फ़ीड पढ़ें"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ऐप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS संदेश भेजें और देखें"</string>
@@ -375,9 +378,9 @@
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"यह ऐप्लिकेशन आपका कॉल इतिहास पढ़ सकता है."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिखें"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टैबलेट के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टीवी के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके फ़ोन के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ऐप को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टैबलेट के कॉल लॉग में बदलाव करने देती है. दुर्भावनापूर्ण ऐप्‍स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए उसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर संवेदक एक्सेस करें (जैसे हृदय गति मॉनीटर)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्‍थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्‍सेस करने देती है."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कैलेंडर इवेंट और विवरण पढ़ें"</string>
@@ -388,8 +391,8 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"यह ऐप्लिकेशन आपके टैबलेट पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"यह ऐप्लिकेशन आपके टीवी पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"यह ऐप्लिकेशन आपके फ़ोन पर मौजूद कैलेंडर इवेंट जोड़, निकाल या बदल सकता है. यह ऐप्लिकेशन ऐसे संदेश भेज सकता है जो कैलेंडर स्वामियों से आए हुए लग सकते हैं या यह स्वामियों को सूचित किए बिना इवेंट में बदलाव कर सकता है."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"कुछ और जगह बताने वाले आदेशों का एक्सेस"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप को कुछ और जगह बताने वाले आदेशों का एक्सेस देता है. इससे ऐप GPS या और स्‍थान स्रोतों के काम में रोक-टोक कर सकता है."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्‍थान प्रदाता आदेशों में पहुंचे"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप्स को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देती है. इससे ऐप्स GPS या अन्य स्थान स्रोतों के संचालन में अवरोध पहुंचा सकता है."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"सटीक स्थान एक्सेस करें (GPS और नेटवर्क-आधारित)"</string>
     <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"यह ऐप्लिकेशन सेल टॉवर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों या GPS के आधार पर आपका स्थान पता कर सकता है. ये स्थान सेवाएं आपके फ़ोन पर चालू और उपलब्ध होनी चाहिए ताकि ऐप्लिकेशन उनका उपयोग कर सके. इससे बैटरी की खपत बढ़ सकती है."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अनुमानित स्थान एक्सेस करें (नेटवर्क-आधारित)"</string>
@@ -416,11 +419,11 @@
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करने के अनुभव को बेहतर बनाने के लिए ऐप्लिकेशन को सिस्टम के माध्यम से उसके कॉल रूट करने देती है."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फ़ोन नंबर पढ़ना"</string>
     <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"ऐप्लिकेशन को डिवाइस के फ़ोन नंबर एक्सेस करने देती है."</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को सोने (कम बैटरी मोड) से रोकें"</string>
-    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"टीवी को सोने (कम बैटरी मोड) से रोकें"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"टीवी को सोने (कम बैटरी मोड) से रोकें"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्‍क्रिय होने से रोकें"</string>
+    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"टीवी को निष्‍क्रिय होने से रोकना"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्‍क्रिय होने से रोकें"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ऐप्स  को टेबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
-    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"ऐप को टीवी को सोने (कम बैटरी मोड) से रोकने की अनुमति देता है."</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"ऐप को टीवी को निष्‍क्रिय होने से रोकने देती है."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ऐप्स  को फ़ोन को प्रयोग में नहीं होने से रोकता है."</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"इंफ़्रारेड संचारित करें"</string>
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"ऐप्लिकेशन को टेबलेट के इंफ़्रारेड ट्रांसमीटर का उपयोग करने देती है."</string>
@@ -464,7 +467,7 @@
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ऐप्स को WiMAX नेटवर्क से टेबलेट को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"ऐप को, टीवी को WiMAX नेटवर्कों से कनेक्‍ट करने और उनसे डिस्‍कनेक्‍ट करने देती है."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"ऐप्स को WiMAX नेटवर्क से फ़ोन को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटूथ डिवाइस को दूसरे डिवाइस से जोड़ें"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटूथ डिवाइस के साथ युग्मित करें"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ऐप्स को टेबलेट पर ब्लूटूथ का कॉन्‍फ़िगरेशन देखने, और युग्‍मित डिवाइस के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"ऐप को टीवी पर ब्‍लूटूथ का कॉन्‍फ़िगरेशन देखने देती है और युग्‍मित डिवाइसों के साथ कनेक्‍शन बनाने और स्‍वीकार करने देती है."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ऐप्स को फ़ोन पर ब्लूटूथ का कॉन्‍फ़िगरेशन देखने, और युग्‍मित डिवाइस के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
@@ -528,30 +531,30 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ऐप्स को नेटवर्क नीतियां प्रबंधित करने और ऐप्स-विशिष्‍ट नियमों को परिभाषित करने देता है."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब बदलें"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ऐप्स  को यह संशोधित करने देता है कि ऐप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्‍य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफ़िकेशन तक पहुंचें"</string>
-    <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स  को नोटिफ़िकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स  के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफ़िकेशन श्रवणकर्ता सेवा से जुड़ें"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफ़िकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफिकेशन तक पहुंचें"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स  को नोटिफिकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स  के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफिकेशन श्रवणकर्ता सेवा से जुड़ें"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफिकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
     <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी स्थिति प्रदाता सेवा से आबद्ध हों"</string>
     <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"धारक को किसी स्थिति प्रदाता सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_bindDreamService" msgid="4153646965978563462">"भावी सेवा से आबद्ध करें"</string>
     <string name="permdesc_bindDreamService" msgid="7325825272223347863">"धारक को किसी भावी सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
-    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी से पाया गया कॉन्फ़िगरेशन ऐप शुरु करें."</string>
-    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को मोबाइल और इंटरनेट सेवा देने वाली कंपनी से पाया गया कॉन्फ़िगरेशन ऐप शुरु करने देता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन ऐप्स  प्रारंभ करें"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन ऐप्स  प्रारंभ करने देता है. सामान्‍य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्थितियों के अवलोकनों को सुनें"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ऐप्स  को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिवाइस कैलिब्रेशन बदलें"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ऐप्स को टच स्क्रीन के कैलिब्रेशन पैरामीटर को बदलने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्र एक्सेस करें"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ऐप्लिकेशन को DRM प्रमाणपत्रों का प्रावधान और उपयोग करने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होना चाहिए."</string>
-    <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम ट्रांसफ़र की स्थिति पाएं"</string>
-    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"इस एेप को मौजूदा Android बीम ट्रांसफ़र के बारे में जानकारी पाने की अनुमति दें."</string>
+    <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android Beam ट्रांसफर स्थिति प्राप्त करें"</string>
+    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"इस ऐप्लिकेशन को वर्तमान Android Beam स्थानान्तरणों के बारे में जानकारी प्राप्त करने देती है."</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM प्रमाणपत्रों को निकाल सकता है"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"एप्‍लिकेशन को DRM प्रमाणपत्रों को निकालने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होनी चाहिए."</string>
-    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी की संदेश सेवा से जुड़ें"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी की मैसेज सेवा के सबसे बढ़िया इंटरफ़ेस से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
-    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जुड़ें"</string>
-    <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"किसी वाहक संदेश सेवा से आबद्ध करें"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"धारक को किसी वाहक संदेश सेवा के शीर्ष-स्‍तरीय इंटरफ़ेस से आबद्ध होने देती है. सामान्‍य ऐप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"वाहक सेवाओं से आबद्ध करें"</string>
+    <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"धारक को वाहक सेवाओं से आबद्ध रहने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"परेशान न करें को ऐक्सेस करें"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
@@ -568,9 +571,9 @@
     <string name="policylab_forceLock" msgid="2274085384704248431">"स्‍क्रीन लॉक करें"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"नियंत्रित करें कि स्‍क्रीन कैसे और कब लॉक हो."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"सभी डेटा हटाएं"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"फ़ैक्टरी डेटा रीसेट करके, चेतावनी दिए बिना टेबलेट का डेटा मिटाएं."</string>
-    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"फ़ैक्‍टरी डेटा रीसेट करके, चेतावनी दिए बिना टीवी का डेटा मिटाएं."</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"फ़ैक्‍टरी डेटा रीसेट करके, चेतावनी दिए बिना फ़ोन का डेटा मिटाएं."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"फ़ैक्टरी डेटा रीसेट करके, बिना चेतावनी के टेबलेट का डेटा हटाएं."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"फ़ैक्‍टरी डेटा रीसेट करके चेतावनी दिए बिना टीवी का डेटा हटाएं."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"फ़ैक्‍टरी डेटा रीसेट करके, बिना चेतावनी के फ़ोन का डेटा हटाएं."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"उपयोगकर्ता डेटा मिटाएं"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"इस टैबलेट पर मौजूद इस उपयोगकर्ता का डेटा बिना चेतावनी के मिटा दें."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"इस टीवी पर मौजूद इस उपयोगकर्ता का डेटा बिना चेतावनी के मिटा दें."</string>
@@ -644,7 +647,7 @@
     <string name="phoneTypeOtherFax" msgid="8587657145072446565">"अन्य फ़ैक्स"</string>
     <string name="phoneTypeRadio" msgid="4093738079908667513">"रेडियो"</string>
     <string name="phoneTypeTelex" msgid="3367879952476250512">"टेलेक्स"</string>
-    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"टेलीटाइपराइटर (TTY) टीडीडी (TDD)"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"कार्यालय का मोबाइल"</string>
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"कार्यालय का पेजर"</string>
     <string name="phoneTypeAssistant" msgid="5596772636128562884">"सहायक"</string>
@@ -720,7 +723,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"फिर से प्रयास करें"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"फिर से प्रयास करें"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"सभी सुविधाओं और डेटा के लिए अनलॉक करें"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"मालिक का चेहरा पहचानकर अनलॉक करने की तय सीमा खत्म हो गई"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"फेस अनलॉक के अधिकतम प्रयासों की सीमा पार हो गई"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"कोई सिम कार्ड नहीं है"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"टेबलेट में कोई सिम कार्ड नहीं है."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"टीवी में कोई SIM कार्ड नहीं है."</string>
@@ -790,7 +793,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र विस्तृत करें."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलॉक."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"आकार अनलॉक."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"मालिक का चेहरा पहचानकर अनलॉक करें."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"फेस अनलॉक."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"पिन अनलॉक."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलॉक."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"आकार क्षेत्र."</string>
@@ -849,7 +852,7 @@
     <string name="save_password_remember" msgid="6491879678996749466">"याद रखें"</string>
     <string name="save_password_never" msgid="8274330296785855105">"कभी नहीं"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"आपके पास इस पेज को खोलने की अनुमति नहीं है."</string>
-    <string name="text_copied" msgid="4985729524670131385">"लेख को क्‍लिपबोर्ड पर कॉपी किया गया."</string>
+    <string name="text_copied" msgid="4985729524670131385">"लेख की क्‍लिपबोर्ड पर प्रतिलिपि बनाई गई."</string>
     <string name="more_item_label" msgid="4650918923083320495">"अधिक"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"मेनू+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
@@ -966,12 +969,12 @@
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"सभी को चुनें"</string>
     <string name="cut" msgid="3092569408438626261">"काटें"</string>
-    <string name="copy" msgid="2681946229533511987">"कॉपी करें"</string>
+    <string name="copy" msgid="2681946229533511987">"प्रतिलिपि बनाएं"</string>
     <string name="paste" msgid="5629880836805036433">"चिपकाएं"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"सादे पाठ के रूप में चिपकाएं"</string>
     <string name="replace" msgid="5781686059063148930">"बदलें•"</string>
     <string name="delete" msgid="6098684844021697789">"हटाएं"</string>
-    <string name="copyUrl" msgid="2538211579596067402">"URL को कॉपी करें"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"URL की प्रतिलिपि बनाएं"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"लेख को चुनें"</string>
     <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="redo" msgid="7759464876566803888">"फिर से करें"</string>
@@ -1073,7 +1076,7 @@
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> प्रारंभ करें"</string>
     <string name="new_app_description" msgid="1932143598371537340">"पुराने ऐप्स को बिना सहेजे बंद करें."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> मेमोरी सीमा को पार कर गई है"</string>
-    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप का संग्रह कर लिया गया है; शेयर करने के लिए टैप करें"</string>
+    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप एकत्र कर लिया गया है; साझा करने के लिए टैप करें"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप साझा करें?"</string>
     <string name="dump_heap_text" msgid="4809417337240334941">"प्रक्रिया <xliff:g id="PROC">%1$s</xliff:g> इसकी <xliff:g id="SIZE">%2$s</xliff:g> की मेमोरी की सीमा को पार कर गई है. इसके डेवलपर से साझा करने के लिए एक हीप डंप आपके लिए उपलब्ध है. सावधान रहें: इस हीप डंप में आपकी ऐसी कोई भी व्यक्तिगत जानकारी हो सकती है जिस पर ऐप्लिकेशन की ऐक्सेस हो."</string>
     <string name="sendText" msgid="5209874571959469142">"लेख के लिए किसी क्रिया को चुनें"</string>
@@ -1084,13 +1087,13 @@
     <string name="volume_call" msgid="3941680041282788711">"कॉल के दौरान वॉल्‍यूम"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटूथ कॉल के दौरान वॉल्‍यूम"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"अलार्म वॉल्‍यूम"</string>
-    <string name="volume_notification" msgid="2422265656744276715">"नोटिफ़िकेशन वॉल्‍यूम"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"नोटिफिकेशन वॉल्‍यूम"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"आवाज़"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ब्लूटूथ वॉल्‍यूम"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"रिंगटोन वॉल्‍यूम"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"कॉल वॉल्‍यूम"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्‍यूम"</string>
-    <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफ़िकेशन वॉल्‍यूम"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफिकेशन वॉल्‍यूम"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्‍ट रिंगटोन"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"डिफ़ॉल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="7937634392408977062">"कोई नहीं"</string>
@@ -1164,7 +1167,7 @@
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोड़ा गया"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क पर पहुंचने के लिए अपना डिवाइस पुन: प्रारंभ करें."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"पुन: प्रारंभ करें"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपका नया SIM ठीक से काम करे, इसके लिए आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से कोई ऐप इंस्टॉल करना होगा और उसे खोलना होगा."</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपकी नई SIM ठीक से काम करे, इसके लिए आपको अपने वाहक से किसी ऐप को इंस्टॉल करना होगा और खोलना होगा."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ऐप प्राप्त करें"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"अभी नहीं"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नई SIM डाली गई"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI के लिए USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्‍ट कि‍या गया"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"अधिक विकल्पों के लिए टैप करें."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ऑडियो एक्सेसरी इस पर काम नहीं करती है"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"अधिक जानकारी के लिए टैप करें"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करना अक्षम करने के लिए टैप करें."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा और लेआउट चुनने के लिए टैप करें"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"दूसरे ऐप्लिकेशन के ऊपर दिखाएं"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप्लिकेशन के ऊपर दिखाई दे रहा है"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप पर दिखाई दे रहा है"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"अगर आप नहीं चाहते कि <xliff:g id="NAME">%s</xliff:g> इस सुविधा का उपयोग करे, तो सेटिंग खोलने और उसे बंद करने के लिए टैप करें."</string>
@@ -1280,7 +1286,7 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"सरल उपयोग"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"वॉलपेपर"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
-    <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफ़िकेशन श्रवणकर्ता"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफिकेशन श्रवणकर्ता"</string>
     <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string>
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"नोटिफ़िकेशन रैंकर सेवा"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोड से बाहर निकलने के लिए टैप करें."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्‍पॉट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने व्यवस्थापक से संपर्क करें"</string>
     <string name="back_button_label" msgid="2300470004503343439">"वापस जाएं"</string>
     <string name="next_button_label" msgid="1080555104677992408">"आगे"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"अभी नहीं"</string>
@@ -1335,7 +1339,7 @@
     <string name="add_account_button_label" msgid="3611982894853435874">"खाता जोड़ें"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"बढ़ाएं"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"कम करें"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> को दबाकर रखें."</string>
+    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> को स्पर्श करके रखें."</string>
     <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"बढ़ाने के लिए ऊपर और कम करने के लिए नीचे स्‍लाइड करें."</string>
     <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"मिनट बढ़ाएं"</string>
     <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"मिनट कम करें"</string>
@@ -1362,7 +1366,7 @@
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> को लॉन्च नहीं किया जा सका"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"इसके साथ साझा करें:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. दबाकर रखें."</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. स्पर्श करके रखें."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"अनलॉक करने के लिए स्‍वाइप करें."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"होम पर नेविगेट करें"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"ऊपर नेविगेट करें"</string>
@@ -1376,7 +1380,7 @@
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB डिस्‍क"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB मेमोरी"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"संपादित करें"</string>
-    <string name="data_usage_warning_title" msgid="3620440638180218181">"डेटा खर्च की चेतावनी"</string>
+    <string name="data_usage_warning_title" msgid="3620440638180218181">"डेटा उपयोग की चेतावनी"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"उपयोग व सेटिंग देखने हेतु टैप करें."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G डेटा सीमा पूर्ण हो गई"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G डेटा सीमा पूर्ण हो गई"</string>
@@ -1399,7 +1403,7 @@
     <string name="issued_by" msgid="2647584988057481566">"जारीकर्ता:"</string>
     <string name="validity_period" msgid="8818886137545983110">"मान्यता:"</string>
     <string name="issued_on" msgid="5895017404361397232">"जारी करने का दिनांक:"</string>
-    <string name="expires_on" msgid="3676242949915959821">"खत्म होने की तारीख है:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"समय समाप्ति दिनांक:"</string>
     <string name="serial_number" msgid="758814067660862493">"सीरियल नंबर:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"फ़िंगरप्रिंट:"</string>
     <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 फ़िंगरप्रिंट:"</string>
@@ -1474,7 +1478,7 @@
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास किया है. अब टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. फ़ोन अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. अगर आपने <xliff:g id="NUMBER_1">%2$d</xliff:g> बार और गलत ड्रॉ किया, तो आपको किसी ईमेल खाते के ज़रिये अपने टीवी को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"आपने अपना अनलॉक पैटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. और <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासों के बाद, आपसे अपने टीवी को किसी ईमेल पते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%2$d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"निकालें"</string>
@@ -1486,7 +1490,7 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"एक्सेस-योग्यता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू किया"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"एक्सेस-योग्यता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद किया"</string>
     <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"एक्सेस-योग्यता बटन पर टैप करते समय उपयोग की जाने वाली सुविधा चुनें:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाएं बदलने के लिए, एक्सेस-योग्यता बटन को स्पर्श करके रखें."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"आवर्धन"</string>
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1613,19 +1617,19 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्यस्थल का <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"दूसरा कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"तीसरा कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="6820571533009838261">"इस स्क्रीन को अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' के बटन को दबाकर रखें"</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"इस स्क्रीन को अनपिन करने के लिए, वापस जाएं और अवलोकन बटनों को स्पर्श करके रखें"</string>
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"इस ऐप्लिकेशन को अनपिन नहीं किया जा सकता"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"स्‍क्रीन पिन की गई"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"स्‍क्रीन अनपिन की गई"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"अनपिन करने से पहले पिन के लिए पूछें"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करने से पहले अनलॉक पैटर्न के लिए पूछें"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
     <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="data_saver_description" msgid="6015391409098303235">"डेटा खर्च, कम करने के लिए डेटा सेवर कुछ ऐप को बैकग्राउंड में डेटा भेजने या पाने से रोकता है. आप फ़िलहाल जिस एेप का इस्तेमाल कर रहे हैं वह डेटा एक्सेस कर सकता है, लेकिन ऐसा कभी-कभी ही हो पाएगा. उदाहरण के लिए, इसका मतलब है कि इमेज तब तक दिखाई नहीं देंगी जब तक कि आप उन्हें टैप नहीं करते."</string>
-    <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा बचाने की सेटिंग चालू करें?"</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>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
@@ -1671,7 +1675,7 @@
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इवेंट"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा म्यूट किया गया"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस में कोई अंदरूनी समस्या है और यह तब तक ठीक नहीं होगी जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते."</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई और यह तब तक अस्‍थिर रह सकता है, जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते हैं."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD अनुरोध को DIAL अनुरोध में बदल दिया गया है."</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD अनुरोध को SS अनुरोध में बदल दिया गया है."</string>
@@ -1696,7 +1700,7 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="5929663562028088222">"अवर्गीकृत"</string>
-    <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफ़िकेशन का महत्व सेट किया है."</string>
+    <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफिकेशन का महत्व सेट किया है."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें?"</string>
     <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें (इस खाते वाला एक उपयोगकर्ता पहले से मौजूद है) ?"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3695c67..65e6708 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -83,7 +83,7 @@
     <string name="ThreeWCMmi" msgid="9051047170321190368">"Trostrani poziv"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"Odbijanje neželjenih i neugodnih poziva"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Isporuka pozivnog broja"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"Ne ometaj"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Ne uznemiravaj"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Zadana postavka ID-a pozivatelja ima ograničenje. Sljedeći poziv: Ograničen"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Zadana postavka ID-a pozivatelja ima ograničenje. Sljedeći poziv: Nije ograničen"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Zadana postavka ID-a pozivatelja nema ograničenje. Sljedeći poziv: Ograničen"</string>
@@ -91,10 +91,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Usluga nije rezervirana."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete promijeniti postavku ID-a pozivatelja."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Podatkovna usluga nije dostupna"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nema hitnih poziva"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nema hitnih usluga"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nema glasovnih usluga"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nema glasovnih i hitnih usluga"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Trenutačno nije u ponudi mobilne mreže na vašoj lokaciji"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Vaš je mobilni operater privremeno obustavio podatkovne usluge na ovoj lokaciji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Vaš je mobilni operater privremeno obustavio hitne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Vaš je mobilni operater privremeno obustavio glasovne pozive na ovoj lokaciji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Vaš je mobilni operater privremeno obustavio glasovne i hitne pozive na ovoj lokaciji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Pristup mreži nije moguć"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Za bolji prijem pokušajte odabrati drugu vrstu mreže u odjeljku Sustav &gt; Mreža i internet &gt; Mobilne mreže &gt; Željena vrsta mreže."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozorenja"</string>
@@ -1207,6 +1210,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Spojen na USB pribor"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audiododatak nije podržan"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dodirnite za više informacija"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka USB-om"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje pogrešaka putem USB-a."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
@@ -1223,7 +1228,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste odabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Prikaz iznad drugih aplikacija"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prikazuje se preko drugih aplikacija"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Apl. <xliff:g id="NAME">%s</xliff:g> zakriva druge aplikacije"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ako ne želite da aplikacija <xliff:g id="NAME">%s</xliff:g> upotrebljava tu značajku, dodirnite da biste otvorili postavke i isključili je."</string>
@@ -1323,8 +1329,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite da biste napustili način rada u automobilu."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Natrag"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Dalje"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskoči"</string>
@@ -1624,7 +1628,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Gledanje preko cijelog zaslona"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Za izlaz prijeđite prstom od vrha prema dolje."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Za izlaz prijeđite prstom prema od vrha prema dolje."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Shvaćam"</string>
     <string name="done_label" msgid="2093726099505892398">"Gotovo"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač sati"</string>
@@ -1647,7 +1651,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao administrator"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao administrator"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao administrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, lokacijske usluge i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio podatkovni promet, Ušteda podataka onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
@@ -1693,8 +1697,8 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"Dok ne isključite \"Ne ometaj\""</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dok ne isključite \"Ne ometaj\""</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"Dok ne isključite \"Ne uznemiravaj\""</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dok ne isključite \"Ne uznemiravaj\""</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 7e71104..9e47afc 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"A szolgáltatás nincs biztosítva."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nem tudja módosítani a hívó fél azonosítója beállítást."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Adatszolgáltatás letiltva"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nincs segélyhívás"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Segélyszolgáltatás letiltva"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Hangszolgáltatás letiltva"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hang- és segélyszolgáltatás letiltva"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Az Ön tartózkodási helyén ideiglenesen nem áll rendelkezésre a mobilhálózaton"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Szolgáltatója ezen a helyen átmenetileg felfüggesztette az adatszolgáltatást"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Szolgáltatója ezen a helyen átmenetileg felfüggesztette a segélyhívásokat"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Szolgáltatója ezen a helyen átmenetileg felfüggesztette a hanghívásokat"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Szolgáltatója ezen a helyen átmenetileg felfüggesztette a hang- és segélyhívásokat"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"A hálózat nem érhető el"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"A vétel javítása érdekében próbálja módosítani a kiválasztott hálózattípust a Rendszer &gt; Hálózat és internet &gt; Mobilhálózatok &gt; Preferált hálózattípus menüben."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Értesítések"</string>
@@ -223,7 +226,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonbeállítások"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Képernyő lezárása"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Kikapcsolás"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Segélyhívás"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Vészhívás"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Programhiba bejelentése"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hibajelentés készítése"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
@@ -714,7 +717,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"A feloldáshoz vagy segélyhívás kezdeményezéséhez nyomja meg a Menü gombot."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"A feloldáshoz nyomja meg a Menü gombot."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Rajzolja le a mintát a feloldáshoz"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Segélyhívás"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Vészhívás"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Hívás folytatása"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Helyes!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Próbálja újra"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-hez"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Csatlakoztatva egy USB-kiegészítőhöz"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Koppintson a további beállítások megjelenítéséhez."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ez az audiotartozék nem támogatott"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Koppintson, ha további információra van szüksége"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Koppintson az USB fejlesztő mód kikapcsolásához."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Koppintson a nyelv és a billentyűzetkiosztás kiválasztásához"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Megjelenítés a többi alkalmazás fölött"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"A(z) <xliff:g id="NAME">%s</xliff:g> a többi alkalmazás felett jelenik meg"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> – a többi alkalmazás felett"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ha nem szeretné, hogy a(z) <xliff:g id="NAME">%s</xliff:g> használja ezt a funkciót, koppintson a beállítások megnyitásához, és kapcsolja ki."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Koppintson az autós üzemmódból való kilépéshez."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Vissza"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tovább"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Kihagyás"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 14c0451..4a11c14 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Ծառայությունը չի տրամադրվում:"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Դուք չեք կարող փոխել զանգողի ID-ի կարգավորումները:"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Տվյալների ծառայությունն անհասանելի է"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Հնարավոր չէ կատարել շտապ կանչ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Արտակարգ իրավիճակների ծառայությունն անհասանելի է"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ձայնային ծառայությունն անհասանելի է"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ձայնային/արտակարգ իրավիճակների ծառայությունն անհասանելի է"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Ձեր գտնվելու վայրում ծառայությունը ժամանակավորապես չի տրամադրվում բջջային ցանցի կողմից"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Ձեր օպերատորն այս վայրում ժամանակավորապես կասեցրել է տվյալների ծառայությունը"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Ձեր օպերատորն այս վայրում ժամանակավորապես կասեցրել է շտապ կանչերը"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Ձեր օպերատորն այս վայրում ժամանակավորապես կասեցրել է ձայնային կանչերը"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Ձեր օպերատորն այս վայրում ժամանակավորապես կասեցրել է ձայնային և շտապ կանչերը"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ցանցն անհասանելի է"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ազդանշանի ընդունման որակը բարելավելու համար փոխեք ցանցի տեսակը՝ անցնելով Համակարգ &gt; Ցանց և ինտերնետ &gt; Բջջային ցանցեր &gt; Ցանկալի ցանցի տեսակը։"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ծանուցումներ"</string>
@@ -280,7 +283,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"օգտագործել օրացույցը"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"ուղարկել և դիտել SMS-ները"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Տարածք"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Հիշողություն"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"օգտագործել լուսանկարները, մեդիա ֆայլերը և ձեր սարքում պահվող մյուս ֆայլերը"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Խոսափող"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ձայնագրել"</string>
@@ -398,7 +401,7 @@
     <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"փոխել ձեր աուդիո կարգավորումները"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ` ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"ձայնագրել աուդիո ֆայլ"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"ձայնագրել ձայնանյութ"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Այս հավելվածը ցանկացած պահի կարող է ձայնագրել խոսափողի օգնությամբ:"</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"ուղարկել հրամաններ SIM քարտին"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Թույլ է տալիս հավելվածին հրամաններ ուղարկել SIM-ին: Սա շատ վտանգավոր է:"</string>
@@ -579,8 +582,8 @@
     <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Կարգավորել, որ սարքի համընդհանուր պրոքսի-սերվերն օգտագործվի, երբ քաղաքականությունը միացված է: Միայն սարքի սեփականատերը կարող է կարգավորել համընդհանուր պրոքսի-սերվերը:"</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"Նշել էկր կողպ գաղտնաբ սպառումը"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"Փոխել էկրանի կողպման գաղտնաբառի, PIN-ի կամ նախշի փոփոխման հաճախականությունը:"</string>
-    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Կարգավորել պահոցի գաղտնագրումը"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Պահանջել, որ պահվող հավելվածների տվյալները լինեն գաղտնագրված:"</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Կարգավորել պահոցի կոդավորումը"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Պահանջել, որ պահվող հավելվածների տվյալները լինեն կոդավորված:"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"Կասեցնել տեսախցիկները"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"Կանխել բոլոր սարքերի ֆոտոխցիկների օգտագործումը:"</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Անջատել կողպման գործառույթները"</string>
@@ -1083,7 +1086,7 @@
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Սահմանվել է անձայն զանգերանգ"</string>
     <string name="volume_call" msgid="3941680041282788711">"Մուտքային զանգի ձայնի ուժգնությունը"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth-ի ներզանգի բարձրություն"</string>
-    <string name="volume_alarm" msgid="1985191616042689100">"Զարթուցիչի ձայնը"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Զարթուցիչի ձայնի ուժգնությունը"</string>
     <string name="volume_notification" msgid="2422265656744276715">"Ծանուցումների ձայնի ուժգնությունը"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Ձայն"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth-ի ձայնի ուժգնությունը"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ի USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Աուդիո սարքը չի աջակցվում"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Հպեք՝ լրացուցիչ տեղեկություններ ստանալու համար"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Հպեք՝ USB վրիպազերծումն անջատելու համար:"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Հպեք՝ լեզուն և դասավորությունն ընտրելու համար"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Ցույց տալ այլ հավելվածների վրայից"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> հավելվածը ցուցադրվում է այլ հավելվածների վերևում"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> հավելվածը ցուցադրվում է այլ հավելվածների վերևում"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Եթե չեք ցանկանում, որ <xliff:g id="NAME">%s</xliff:g>-ն օգտագործի այս գործառույթը, հպեք՝ կարգավորումները բացելու և այն անջատելու համար։"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Հպեք` մեքենայի ռեժիմից դուրս գալու համար:"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Հետ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Հաջորդը"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Բաց թողնել"</string>
@@ -1420,7 +1424,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Համակցված բարձրախոսներ"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Համակարգ"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ի աուդիո ֆայլ"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ի ձայնանյութ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Անլար էկրան"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"Հեռարձակում"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Միանալ սարքին"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 998daa6..9175507 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Layanan tidak diperlengkapi."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak dapat mengubah setelan nomor penelepon."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Tidak ada layanan data"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Tidak ada panggilan darurat"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Tidak ada layanan panggilan darurat"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Tidak ada layanan panggilan suara"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tidak ada layanan panggilan suara/darurat"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Untuk sementara tidak ditawarkan oleh jaringan seluler di lokasi Anda"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operator menangguhkan layanan data di lokasi ini untuk sementara"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operator menangguhkan panggilan darurat di lokasi ini untuk sementara"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operator menangguhkan panggilan suara di lokasi ini untuk sementara"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operator menangguhkan panggilan suara dan darurat di lokasi ini untuk sementara"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat menjangkau jaringan"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Untuk meningkatkan penerimaan sinyal, coba ubah jenis yang dipilih di Sistem &gt; Jaringan &amp; Internet &gt; Jaringan seluler &gt; Jenis jaringan pilihan."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Notifikasi"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ketuk untuk opsi lainnya."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori audio tidak didukung"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tap untuk info selengkapnya"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ketuk untuk menonaktifkan debug USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketuk untuk memilih bahasa dan tata letak"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Tampilkan di atas aplikasi lain"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ditampilkan di atas aplikasi lain"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ditampilkan di atas aplikasi lain"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, tap untuk membuka setelan dan menonaktifkannya."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ketuk untuk keluar dari mode mobil."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Kembali"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Selanjutnya"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Lewati"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9e71625..7694e9a 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Þjónustu ekki útdeilt."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Þú getur ekki breytt stillingu númerabirtingar."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Gagnasamband er ekki í boði"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Engin neyðarsímtöl"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Neyðarsímtöl eru ekki í boði"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Símtöl eru ekki í boði"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Símtöl/neyðarsímtöl eru ekki í boði"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Ekki í boði á farsímakerfinu á þínum stað eins og er"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Símafyrirtækið þitt hefur tímabundið lokað fyrir gagnasamband á þessum stað"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Símafyrirtækið þitt hefur tímabundið lokað fyrir neyðarsímtöl á þessum stað"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Símfyrirtækið þitt hefur tímabundið lokað fyrir símtöl á þessum stað"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Símafyrirtækið þitt hefur tímabundið lokað fyrir símtöl og neyðarsímtöl á þessum stað"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ekki næst samband við símkerfi"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Reyndu að breyta valinni gerð í Kerfi &gt; Netkerfi og internet > Farsímakerfi &gt; Valin símkerfistegund til að bæta móttökuskilyrðin."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Tilkynningar"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB fyrir MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tengt við USB-aukabúnað"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ýttu til að sjá fleiri valkosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Hljóðaukabúnaður er ekki studdur"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ýttu til að fá frekari upplýsingar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ýttu til að slökkva á USB-villuleit."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deilir villutilkynningu..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ýttu til að velja tungumál og útlit"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Opna ofan á öðrum forritum"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> birtist yfir öðrum forritum"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> birtist yfir öðrum forritum"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ef þú vilt ekki að <xliff:g id="NAME">%s</xliff:g> noti þennan eiginleika skaltu ýta til að opna stillingarnar og slökkva á því."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ýttu til að fara úr bílastillingu."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Til baka"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Áfram"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Sleppa"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 11c866d..e6fd76b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Servizio non fornito."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Non è possibile modificare l\'impostazione ID chiamante."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nessun servizio dati"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Chiamate di emergenza non disponibili"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nessun servizio di emergenza"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nessun servizio di telefonia"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nessun servizio di telefonia/emergenza"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Servizio temporaneamente non offerto dalla rete mobile nella tua località"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Il tuo operatore ha sospeso temporaneamente il servizio dati per questa località"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Il tuo operatore ha sospeso temporaneamente le chiamate di emergenza per questa località"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Il tuo operatore ha sospeso temporaneamente le telefonate per questa località"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Il tuo operatore ha sospeso temporaneamente le telefonate e le chiamate di emergenza per questa località"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Impossibile raggiungere la rete"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Per migliorare la ricezione, prova a modificare il tipo selezionato in Sistema &gt; Rete e Internet &gt; Reti mobili &gt; Tipo di rete preferito."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Avvisi"</string>
@@ -274,7 +277,7 @@
     <string name="managed_profile_label" msgid="5289992269827577857">"Passa al profilo di lavoro"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatti"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedere ai contatti"</string>
-    <string name="permgrouplab_location" msgid="7275582855722310164">"Geolocalizzazione"</string>
+    <string name="permgrouplab_location" msgid="7275582855722310164">"Posizione"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedere al calendario"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per la modalità MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Collegato a un accessorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tocca per altre opzioni."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessorio audio non supportato"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tocca per ulteriori informazioni"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tocca per disattivare il debug USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tocca per selezionare la lingua e il layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Mostra sopra altre app"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"App <xliff:g id="NAME">%s</xliff:g> visualizzata sopra altre app"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"App <xliff:g id="NAME">%s</xliff:g> mostrata sopra altre app"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tocca per uscire dalla modalità automobile."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Indietro"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avanti"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignora"</string>
@@ -1369,7 +1373,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="3570990907910199483">"Memoria condivisa interna"</string>
+    <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index b9b5cf9..c6336fd 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"השירות לא הוקצה."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"אינך יכול לשנות את הגדרת זיהוי המתקשר."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"חבילת הגלישה לא זמינה"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"אין גישה לשיחות חירום"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"אין אפשרות לבצע שיחות חירום"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"אין אפשרות לבצע שיחות רגילות"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"אין אפשרות לבצע שיחות חירום ושיחות קוליות רגילות"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"הרשת הסלולרית במיקום הזה חסמה את השירות באופן זמני"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"הספק השעה באופן זמני את חבילת הגלישה במיקום זה"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"הספק השעה באופן זמני את האפשרות לבצע שיחות חירום במיקום זה"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"הספק השעה באופן זמני את האפשרות לבצע שיחות רגילות במיקום זה"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"הספק שלך השעה באופן זמני את האפשרות לבצע שיחות חירום ושיחות קוליות רגילות ממיקום זה"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"לא ניתן להתחבר לרשת"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏כדי לשפר את הקליטה, נסה לשנות את הסוג הנבחר ב\'מערכת\' &gt; \'רשת ואינטרנט\' &gt; \'רשתות סלולריות\' &gt; \'סוג רשת מועדף\'."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"התראות"</string>
@@ -1229,6 +1232,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB ל-MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏מחובר לאביזר USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"הקש לקבלת אפשרויות נוספות."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"אביזר אודיו אינו נתמך"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"הקש לקבלת מידע נוסף"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏הקש כדי להשבית ניפוי באגים של USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏בחר להשבית ניפוי באגים ב-USB."</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"הקש כדי לבחור שפה ופריסה"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"הצגה מעל אפליקציות אחרות"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"תצוגה של <xliff:g id="NAME">%s</xliff:g> מעל אפליקציות אחרות"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> מוצגת מעל אפליקציות אחרות"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"אם אינך רוצה ש-<xliff:g id="NAME">%s</xliff:g> תשתמש בתכונה הזו, הקש כדי לפתוח את ההגדרות ולכבות אותה."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"הקש כדי לצאת ממצב מכונית."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string>
     <string name="back_button_label" msgid="2300470004503343439">"הקודם"</string>
     <string name="next_button_label" msgid="1080555104677992408">"הבא"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"דילוג"</string>
@@ -1648,7 +1652,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"נסה שוב מאוחר יותר"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"צפייה במסך מלא"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"כדי לצאת, פשוט מחליקים אצבע מלמעלה למטה."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"כדי לצאת, החלק מלמעלה למטה."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"הבנתי"</string>
     <string name="done_label" msgid="2093726099505892398">"בוצע"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"מחוון שעות מעגלי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 408b3b3..abfb474 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"提供可能なサービスがありません。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"発信者番号の設定は変更できません。"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"データサービス停止"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"緊急通報は利用できません"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"緊急通報サービス停止"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"音声通話サービス停止"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"音声通話 / 緊急通報サービス停止"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"現在地のモバイル ネットワークでは一時的に提供されていません"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"この場所では、携帯通信会社によりデータサービスが一時的に停止されています"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"この場所では、携帯通信会社により緊急通報が一時的に停止されています"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"この場所では、携帯通信会社により音声通話が一時的に停止されています"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"この場所では、携帯通信会社により音声通話と緊急通報が一時的に停止されています"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ネットワークにアクセスできません"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"受信状態を改善するには、[システム] &gt; [ネットワークとインターネット] &gt; [モバイル ネットワーク] &gt; [優先ネットワーク タイプ] で選択したタイプを変更してみてください。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"タップしてその他のオプションを表示します。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"オーディオ アクセサリがサポートされていません"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"タップして詳細をご確認ください"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"タップして USB デバッグを無効にします。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"タップして言語とレイアウトを選択してください"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"他のアプリの上に重ねて表示"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g>を他のアプリの上に重ねて表示"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>が他のアプリの上に表示されています"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g>でこの機能を使用しない場合は、タップして設定を開いて OFF にしてください。"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"タップして運転モードを終了します。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string>
     <string name="back_button_label" msgid="2300470004503343439">"戻る"</string>
     <string name="next_button_label" msgid="1080555104677992408">"次へ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"スキップ"</string>
@@ -1429,7 +1433,7 @@
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"設定"</string>
     <string name="media_route_controller_disconnect" msgid="8966120286374158649">"接続を解除"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"スキャン中..."</string>
-    <string name="media_route_status_connecting" msgid="6422571716007825440">"接続処理中..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"接続中..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"利用できます"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"利用できません"</string>
     <string name="media_route_status_in_use" msgid="4533786031090198063">"使用中"</string>
@@ -1600,7 +1604,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"しばらくしてから再試行"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"全画面表示"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"終了するには、上から下にスワイプします。"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"終了するには、上部から下にスワイプします。"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"OK"</string>
     <string name="done_label" msgid="2093726099505892398">"完了"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"円形スライダー(時)"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6308818..b08bfa6 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"სერვისი არ არის მიწოდებული."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"არ შეგიძლიათ აბონენტის ID პარამეტრების შეცვლა."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"მობილური ინტერნეტის სერვისი არ არის"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"გადაუდებელი ზარების სერვისი არ არის"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"გადაუდებელი ზარების სერვისი არ არის"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ხმოვანი ზარების სერვისი არ არის"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ხმოვანი/გადაუდებელი ზარების სერვისი არ არის"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"დროებით არ არის შემოთავაზებული მობილური ქსელის მიერ თქვენს მდებარეობაზე"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"მობილური ინტერნეტის სერვისი დროებით შეიზღუდა თქვენი ოპერატორის მიერ ამ მდებარეობაზე"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"გადაუდებელი ზარები დროებით შეიზღუდა თქვენი ოპერატორის მიერ ამ მდებარეობაზე"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ხმოვანი ზარები დროებით შეიზღუდა თქვენი ოპერატორის მიერ ამ მდებარეობაზე"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ხმოვანი და გადაუდებელი ზარები დროებით შეიზღუდა თქვენი ოპერატორის მიერ ამ მდებარეობაზე"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ქსელთან დაკავშირება ვერ ხერხდება"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"მიღების გასაუმჯობესებლად ცადეთ არჩეული ტიპის შეცვლა აქ: სისტემა &gt; ქსელი და ინტერნეტი &gt; მობილური ქსელები &gt; ქსელის სასურველი ტიპი."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"გაფრთხილებები"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI-სთვის"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"შეეხეთ დამატებითი ვარიანტების სანახავად."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"აუდიო აქსესუარი მხარდაუჭერელია"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"შეეხეთ დამატებითი ინფორმაციისთვის"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"შეეხეთ USB-გამართვის გასათიშად."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"შეეხეთ ენისა და განლაგების ასარჩევად"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"სხვა აპების ზემოდან გამოჩენა"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ნაჩვენებია სხვა აპების ინტერფეისის გადაფარვით"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ნაჩვენებია სხვა აპების ინტერფეისის გადაფარვით"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"თუ არ გსურთ <xliff:g id="NAME">%s</xliff:g>-ის მიერ ამ ფუნქციის გამოყენება, შეეხეთ პარამეტრების გასახსნელად და გამორთეთ."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"შეეხეთ მანქანის რეჟიმიდან გამოსასვლელად."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ინტერნეტის მიერთება ან უსადენო ქსელი აქტიურია."</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
     <string name="back_button_label" msgid="2300470004503343439">"უკან"</string>
     <string name="next_button_label" msgid="1080555104677992408">"მომდევნო"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"გამოტოვება"</string>
@@ -1623,7 +1627,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>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index c74ecef..d80fdb5 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Қызмет ұсынылмаған."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Қоңырау шалушы идентификаторы параметрін өзгерту мүмкін емес."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Деректер қызметі жоқ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Шұғыл қоңырау шалу бөгелген"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Жедел қызметке қоңыраулар қызметі жоқ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Дауыстық қоңыраулар қызметі жоқ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Дауыстық/жедел қызметке қоңыраулар қызметі жоқ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Орналасқан аймағыңызда мобильдік желі уақытша ұсынбады"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Оператор осы жерде деректер қызметін уақытша тоқтатты"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Оператор осы жерде жедел қызметке қоңырауларды уакытша тоқтатты"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Оператор осы жерде дауыстық қоңырауларды уақытша тоқтатты"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Оператор осы жерде дауыстық қоңыраулар мен жедел қызметке қоңырауларды уақытша тоқтатты"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Желіге қосылу мүмкін емес"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Қабылдауды жақсарту үшін \"Жүйе &gt; Желі және интернет &gt; Мобильдік желілер &gt; Қалаған желі түрі\" тармағынан түрді өзгертіп көріңіз."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Дабылдар"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI режиміне арналған USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB жабдығына қосылған"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Қосымша опциялар үшін түртіңіз."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио аксессуарға қолдау көрсетілмейді"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Қосымша ақпарат алу үшін түртіңіз"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB түзетуін өшіру үшін түртіңіз."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Қате туралы есеп бөлісілуде…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Басқа қолданбалардың үстінен көрсету"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> басқа қолданбалардың үстінен шықты"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> басқа қолданбалардың үстінен көрсетіледі"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> деген пайдаланушының бұл функцияны пайдалануына жол бермеу үшін параметрлерді түртіп ашыңыз да, оларды өшіріңіз."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Автокөлік режимінен шығу үшін түртіңіз."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Артқа"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Келесі"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Аттап өту"</string>
@@ -1600,7 +1605,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Кейінірек қайта әрекеттеніңіз."</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Толық экранда көру"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Шығу үшін жоғарыдан төмен қарай сипап өтіңіз."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Шығу үшін жоғарыдан төмен қарай жанап өтіңіз."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Түсіндім"</string>
     <string name="done_label" msgid="2093726099505892398">"Дайын"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Сағаттар айналымының қозғалтқышы"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 36d7c5a..1e17005 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"មិន​បាន​ផ្ដល់​សេវាកម្ម។"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"អ្នក​មិន​អាច​ប្ដូរ​ការ​កំណត់​លេខ​សម្គាល់​អ្នក​ហៅ​បានទេ។"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"គ្មាន​សេវាកម្ម​ទិន្នន័យ​ទេ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"មិនមាន​ការហៅបន្ទាន់ទេ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"គ្មាន​សេវាកម្ម​សង្រ្គោះបន្ទាន់​ទេ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"គ្មាន​សេវាកម្ម​ជា​សំឡេង​ទេ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"គ្មាន​សេវាកម្ម​សំឡេង/សង្រ្គោះបន្ទាន់​ទេ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"​មិន​បាន​ផ្តល់​ជូន​ដោយ​បណ្តាញចល័តនៅ​ទីកន្លែងរបស់អ្នកជា​បណ្តោះ​អាសន្ន"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ក្រុមហ៊ុន​បម្រើ​សេវាទូរសព្ទ​របស់​អ្នក​បានផ្អាក​សេវាកម្ម​ទិន្នន័យ​ជាបណ្តោះអាសន្ន​នៅ​ទីតាំង​នេះ"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ក្រុមហ៊ុន​បម្រើ​សេវាទូរសព្ទ​របស់អ្នក​បានផ្អាក​ការហៅ​បន្ទាន់​ជាបណ្តោះអាសន្ន​នៅទី​តាំង​នេះ"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ក្រុមហ៊ុន​បម្រើសេវា​ទូរសព្ទ​របស់អ្នក​បានផ្អាក​ការហៅ​ដោយ​សំឡេង​ជាបណ្តោះអាសន្ន​នៅទី​តាំងនេះ"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់អ្នក​បានផ្អាក​ការហៅ​ដោយ​សំឡេង និង​ការហៅ​បន្ទាន់​ជា​បណ្តោះអាសន្ន​នៅទី​តាំង​នេះ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"មិន​អាច​ភ្ជាប់​ទៅ​បណ្តាញ​បានទេ​"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ដើម្បីកែលម្អការទទួលយក សាកល្បងប្តូរប្រភេទដែលបានជ្រើសរើសនៅ ប្រព័ន្ធ &gt; បណ្តាញ និងអ៊ីនធឺណិត &gt; បណ្តាញទូរសព្ទចល័ត &gt; ប្រភេទបណ្តាញដែលចង់ប្រើ។"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ការជូនដំណឹង"</string>
@@ -1187,6 +1190,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB សម្រាប់ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"មិនស្គាល់គ្រឿងបរិក្ខារសំឡេងទេ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ចុចដើម្បីទទួលព័ត៌មានបន្ថែម"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុសយូអេសប៊ី"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស​ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
@@ -1203,7 +1208,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ប៉ះដើម្បីជ្រើសភាសា និងប្លង់"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"បង្ហាញនៅលើកម្មវិធីផ្សេងទៀត"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> កំពុង​បង្ហាញពីលើ​កម្មវិធី​ផ្សេង​ទៀត"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> កំពុង​បង្ហាញ​ពីលើ​កម្មវិធី​ផ្សេង​ទៀត"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"ប្រសិនបើ​អ្នក​មិន​ចង់​ឲ្យ <xliff:g id="NAME">%s</xliff:g> ប្រើ​មុខងារ​នេះ​ទេ សូមចុច​ដើម្បី​បើក​ការកំណត់ រួច​បិទ​វា។"</string>
@@ -1303,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ប៉ះដើម្បីចាកចេញពីរបៀបរថយន្ត"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នកសម្រាប់​ព័ត៌មានលម្អិត"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់​"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 8b71aec..db06af7 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ಸೇವೆಯನ್ನು ಪೂರೈಸಲಾಗಿಲ್ಲ."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"ನೀವು ಕಾಲರ್‌ ID ಸೆಟ್ಟಿಂಗ್‌ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ಡೇಟಾ ಸೇವೆ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ಯಾವುದೇ ತುರ್ತು ಕರೆ ಮಾಡಲಾಗುವುದಿಲ್ಲ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ತುರ್ತು ಸೇವೆ ಇಲ್ಲ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ಧ್ವನಿ ಸೇವೆಯಿಲ್ಲ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ಧ್ವನಿ/ತುರ್ತು ಸೇವೆ ಇಲ್ಲ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"ತಾತ್ಕಾಲಿಕವಾಗಿ ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ನಿಂದ ನಿಮ್ಮ ಸ್ಥಳದಲ್ಲಿ ಒದಗಿಸುತ್ತಿಲ್ಲ"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ನಿಮ್ಮ ವಾಹಕವು ಈ ಸ್ಥಳದಲ್ಲಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ಡೇಟಾ ಸೇವೆಯನ್ನು ಅಮಾನತ್ತುಗೊಳಿಸಿದೆ"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ನಿಮ್ಮ ವಾಹಕವು ಈ ಸ್ಥಳದಲ್ಲಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ತುರ್ತು ಕರೆಗಳನ್ನು ಅಮಾನತ್ತುಗೊಳಿಸಿದೆ"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ನಿಮ್ಮ ವಾಹಕವು  ಈ ಸ್ಥಳದಲ್ಲಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ಧ್ವನಿ ಕರೆಗಳನ್ನು ಅಮಾನತ್ತುಗೊಳಿಸಿದೆ"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ನಿಮ್ಮ ವಾಹಕವು ಈ ಸ್ಥಳದಲ್ಲಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ಧ್ವನಿ ಮತ್ತು ತುರ್ತು ಕರೆಗಳನ್ನು ಅಮಾನತ್ತುಗೊಳಿಸಿದೆ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ನೆಟ್‌ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕ ಪಡೆಯುವುದನ್ನು ಸುಧಾರಿಸಲು, ಆಯ್ಕೆ ಮಾಡಿರುವ ವಿಧವನ್ನು ಸಿಸ್ಟಂ &gt; ನೆಟ್‌ವರ್ಕ್ ಮತ್ತು ಇಂಟರ್ನೆಟ್ &gt; ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು &gt; ಆದ್ಯತೆಯ ನೆಟ್‌ವರ್ಕ್ ವಿಧದಲ್ಲಿ ಬದಲಿಸಿ ನೋಡಿ."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ಎಚ್ಚರಿಕೆಗಳು"</string>
@@ -230,7 +233,7 @@
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸಿ. ಇದು ವರದಿಯ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು, ಸಮಸ್ಯೆ ಕುರಿತು ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಮತ್ತು ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ವರದಿ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುವಂತಹ ಕೆಲವು ಕಡಿಮೆ ಬಳಸಲಾದ ವಿಭಾಗಗಳನ್ನು ತ್ಯಜಿಸಬಹುದು."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"ಪೂರ್ಣ ವರದಿ"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ನಿಮ್ಮ ಸಾಧನವು ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲದಿರುವಾಗ ಅಥವಾ ತುಂಬಾ ನಿಧಾನವಾಗಿರುವಾಗ ಕನಿಷ್ಠ ಹಸ್ತಕ್ಷೇಪಕ್ಕಾಗಿ ಅಥವಾ ನಿಮಗೆ ಎಲ್ಲಾ ವಿಭಾಗಗಳೂ ಅಗತ್ಯವಿರುವಾಗ ಈ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ. ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಅಥವಾ ಹೆಚ್ಚುವರಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ನಿಮ್ಮ ಸಾಧನವು ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲದಿರುವಾಗ ಅಥವಾ ತುಂಬಾ ನಿಧಾನವಾಗಿರುವಾಗ ಕನಿಷ್ಟ ಹಸ್ತಕ್ಷೇಪಕ್ಕಾಗಿ ಅಥವಾ ನಿಮಗೆ ಎಲ್ಲಾ ವಿಭಾಗಗಳೂ ಅಗತ್ಯವಿರುವಾಗ ಈ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ. ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಅಥವಾ ಹೆಚ್ಚುವರಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
       <item quantity="one">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
       <item quantity="other">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ಗೆ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ಪರಿಕರಕ್ಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ಆಡಿಯೋ ಪರಿಕರಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚುವುದೇ?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ಇತರ ಅಪ್ಲಿಕೇಶನ್ ಮೇಲೆ ಡಿಸ್‌ಪ್ಲೇ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೂಲಕ ಪ್ರದರ್ಶಿಸುತ್ತಿದೆ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ಇತರವುಗಳ ಮೇಲೆ ಪ್ರದರ್ಶಿಸುತ್ತಿದೆ"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆದು, ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ಕಾರು ಮೋಡ್‍ನಿಂದ ನಿರ್ಗಮಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ಹಿಂದೆ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ಮುಂದಿನದು"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ಸ್ಕಿಪ್‌"</string>
@@ -1423,7 +1428,7 @@
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"ವಯರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"ಪಾತ್ರ"</string>
-    <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುವ ಪರದೆ"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
     <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
@@ -1593,7 +1598,7 @@
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ಹೊಸ ಪಿನ್‌ ದೃಢೀಕರಿಸಿ"</string>
     <string name="restr_pin_create_pin" msgid="8017600000263450337">"ನಿರ್ಬಂಧಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಪಿನ್‌ ರಚಿಸಿ"</string>
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ಪಿನ್‌ ಗಳು ಹೊಂದಿಕೆಯಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ಪಿನ್‌ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಠ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ಪಿನ್‌ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಟ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</item>
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fd56280..1fdfb91 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"서비스가 준비되지 않았습니다."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"발신자 번호 설정을 변경할 수 없습니다."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"데이터 서비스를 이용할 수 없음"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"긴급 전화 차단됨"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"긴급 서비스를 이용할 수 없음"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"음성 서비스를 이용할 수 없음"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"음성/긴급 서비스를 이용할 수 없음"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"현재 위치에서 모바일 네트워크가 서비스 제공을 일시적으로 중단했습니다."</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"이동통신사에서 이 위치에서의 데이터 서비스를 일시적으로 정지했습니다."</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"이동통신사에서 이 위치에서의 긴급 통화를 일시적으로 정지했습니다."</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"이동통신사에서 이 위치에서의 음성 통화를 일시적으로 정지했습니다."</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"이동통신사에서 이 위치에서의 음성 및 긴급 통화를 일시적으로 정지했습니다."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"네트워크에 연결할 수 없습니다."</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"수신 상태를 개선하려면 시스템 &gt; 네트워크 및 인터넷 &gt; 모바일 네트워크 &gt; 기본 네트워크 유형에서 선택된 유형을 변경해 보세요."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"알림"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI용 USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"옵션을 더 보려면 탭하세요."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"지원되지 않는 오디오 액세서리"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"자세한 내용은 탭하여 확인하세요."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB 디버깅을 사용하지 않으려면 탭하세요."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"탭하여 언어와 레이아웃을 선택하세요."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"다른 앱 위에 표시"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g>이(가) 다른 앱 위에 표시됨"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>이(가) 다른 앱 위에 표시됨"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g>에서 이 기능이 사용되는 것을 원하지 않는 경우 탭하여 설정을 열고 기능을 사용 중지하세요."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"운전 모드를 종료하려면 탭하세요."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string>
     <string name="back_button_label" msgid="2300470004503343439">"뒤로"</string>
     <string name="next_button_label" msgid="1080555104677992408">"다음"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"건너뛰기"</string>
@@ -1599,7 +1603,7 @@
       <item quantity="one">1초 후에 다시 시도하세요.</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"나중에 다시 시도"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"전체 화면 보기 중"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"전체 화면 보기"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"종료하려면 위에서 아래로 스와이프합니다."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"확인"</string>
     <string name="done_label" msgid="2093726099505892398">"완료"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7c4c1fa..b744f98 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Кызмат камсыздалган эмес."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Чалуучунун далдаштырма дайындары жөндөөлөрүн өзгөртө албайсыз."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Мобилдик туташуу кызматы жок"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Шашылыш чалуу бөгөттөлгөн"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Өзгөчө кырдаалдагы кызматтар бөгөттөлгөн"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Аудио чалуу кызматы бөгөттөлгөн"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Бардык чалуулар жана кызматтар бөгөттөлгөн"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Өзгөчө кырдаалдагы кызматтар сиз жайгашкан жердеги мобилдик тармак тарабынан убактылуу бөгөттөлгөн"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Операторуңуз бул аймактагы мобилдик туташуу кызматын убактылуу токтотуп койду"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Операторуңуз өзгөчө кырдаалдагы чалууларды бул аймактан убактылуу токтотуп койду"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Операторуңуз аудио чалууларды бул аймактан убактылуу токтотуп койду"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Операторуңуз аудио чалууларды жана өзгөчө кырдаалдагы чалууларды бул аймактан убактылуу токтотуп койду"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Тармакка туташпай жатат"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Кабыл алуу мүмкүнчүлүгүн жакшыртуу үчүн Тутум &gt; Тармак жана Интернет &gt; Мобилдик тармактар &gt; Тандалган тармак бөлүмүнөн тармактын түрүн өзгөртүп көрүңүз."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Эскертүүлөр"</string>
@@ -1078,18 +1081,18 @@
     <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> процесси өзүнүн <xliff:g id="SIZE">%2$s</xliff:g> процесс чегинен ашып кетти. Үймө дамп сиз үчүн иштеп чыгуучу менен бөлүшүүгө даяр. Абайлаңыз: бул үймө дампта колдонмонун уруксаты бар жеке маалыматыңыз камтылышы мүмкүн."</string>
     <string name="sendText" msgid="5209874571959469142">"Текст үчүн аракет тандаңыз"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Коңгуроонун үн көлөмү"</string>
-    <string name="volume_music" msgid="5421651157138628171">"Мультимедианын үнү"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Медианын үн көлөмү"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth аркылуу ойнотулууда"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Үнсүз рингтон орнотулду"</string>
     <string name="volume_call" msgid="3941680041282788711">"Чалуудагы үн көлөмү"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth чалуудагы үн көлөмү"</string>
-    <string name="volume_alarm" msgid="1985191616042689100">"Ойготкучтун үнү"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Ойготкучтун үн көлөмү"</string>
     <string name="volume_notification" msgid="2422265656744276715">"Эскертме үн көлөмү"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Үн көлөмү"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth үнүнүн деңгээли"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Коңгуроо үнүнүн деңгээли"</string>
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"Чалуунун үн деңгээли"</string>
-    <string name="volume_icon_description_media" msgid="4217311719665194215">"Мультимедианын үнү"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа үнүнүн деңгээли"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Эскертме үнүнүн деңгээли"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Демейки шыңгыр"</string>
     <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Демейки шыңгыр (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI үчүн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB аксессуарга байланышты"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио шайманы колдоого алынбайт"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Мүчүлштктрдү USB аркл оңдну өчр үчн тийп коюңуз."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1202,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тил жана калып тандоо үчүн таптап коюңуз"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Башка терезелердин үстүнөн көрсөтүү"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> колдонмосун башка терезелердин үстүнөн көрсөтүү"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>: башка колдонмолордун үстүнөн"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
@@ -1302,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Унаа режиминен чыгуу үчүн таптап коюңуз."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Артка"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Кийинки"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Өткөрүп жиберүү"</string>
@@ -1600,7 +1604,7 @@
       <item quantity="one">1 секунддан кийин кайталаңыз</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Кийинчерээк кайталаңыз"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"Толук экран режими"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Толук экранды көрүүдө"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Чыгуу үчүн, жогурдан төмөн сүрүңүз."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Түшүндүм"</string>
     <string name="done_label" msgid="2093726099505892398">"Даяр"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 390a60d..58872dc 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ບໍ່ໄດ້ເປີດໃຊ້ບໍລິການ."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"ທ່ານບໍ່ສາມາດປ່ຽນແປງການຕັ້ງຄ່າ Caller ID"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ບໍ່ມີບໍລິການອິນເຕີເນັດ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ບໍ່ສາມາດໂທສຸກເສີນໄດ້"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ບໍ່ມີບໍລິການໂທສຸກເສີນ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ບໍ່ມີບໍລິການໂທສຽງ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ບໍ່ມີບໍລິການສຽງ/ສຸກເສີນ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"ເຄືອຂ່າຍຂອງທ່ານບໍ່ໄດ້ໃຫ້ບໍລິການຢູ່ສະຖານທີ່ນີ້ເປັນການຊົ່ວຄາວ"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານໄດ້ລະງັບບໍລິການອິນເຕີເນັດຢູ່ບ່ອນນີ້ໄວ້ຊົ່ວຄາວ"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານໄດ້ລະງັບການໂທສຸກເສີນຢູ່ບ່ອນນີ້ໄວ້ຊົ່ວຄາວ"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານໄດ້ລະງັບການໂທສຽງຢູ່ບ່ອນນີ້ໄວ້ຊົ່ວຄາວ"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ຜູ້ໃຫ້ບໍລິການຂອງທ່ານໄດ້ລະງັບການນຳໃຊ້ການໂທສຽງ ແລະ ການໂທສຸກເສີນຢູ່ບ່ອນນີ້ໄວ້ຊົ່ວຄາວ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Can’t reach network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ເພື່ອປັບປຸງການຮັບສັນຍານ, ໃຫ້ລອງປ່ຽນປະເພດທີ່ເລືອກໄວ້ທີ່ ລະບົບ &gt; ເຄືອຂ່າຍ ແລະ ອິນເຕີເນັດ &gt; ເຄືອຂ່າຍມືຖື &gt; ປະເພດເຄືອຂ່າຍທີ່ຕ້ອງການ."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ການເຕືອນ"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB ສຳ​ລັບ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ບໍ່ຮອງຮັບອຸປະກອນເສີມສຽງ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"ແຕະເພື່ອປິດການດີບັກຜ່ານ USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ແຕະເພື່ອເລືອກພາສາ ແລະ ໂຄງແປ້ນພິມ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ສະແດງແອັບບັງແອັບອື່ນ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ກຳລັງສະແດງຜົນຢູເທິງແອັບອື່ນຢູ່"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ກຳລັງສະແດງຜົນບັງແອັບອື່ນຢູ່"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"ຫາກທ່ານບໍ່ຕ້ອງການ <xliff:g id="NAME">%s</xliff:g> ໃຫ້ໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ແຕະເພື່ອເປີດການຕັ້ງຄ່າ ແລ້ວປິດມັນໄວ້."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ແຕະເພື່ອອອກຈາກໂໝດລົດ."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດ​ການ​ປ່ອຍ​ສັນຍານ ຫຼື​ຮັອດສະປອດ​ແລ້ວ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ກັບຄືນ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ຕໍ່ໄປ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ຂ້າມ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4b2699a..c53e5ba 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Paslauga neteikiama."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Negalima pakeisti skambinančiojo ID nustatymo."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Duomenų paslauga neteikiama"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nėra skambučių pagalbos numeriu paslaugos"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Skambučių pagalbos numeriais paslauga neteikiama"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Balso skambučių paslauga neteikiama"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Balso skambučių / skambučių pagalbos numeriais paslauga neteikiama"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Laikinai nesiūloma mobiliojo ryšio tinkle jūsų vietovėje"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Jūsų operatorius laikinai sustabdė duomenų paslaugą šioje vietovėje"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Jūsų operatorius laikinai sustabdė skambučius pagalbos numeriais šioje vietovėje"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Jūsų operatorius laikinai sustabdė balso skambučius šioje vietovėje"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Jūsų operatorius laikinai sustabdė balso skambučius ir skambučius pagalbos numeriais šioje vietovėje"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepavyko pasiekti tinklo"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Kad pagerintumėte ryšį, pabandykite pakeisti tipą, pasirinktą skiltyje „Nustatymai“ &gt; „Tinklas ir internetas“ &gt; „Mobiliojo ryšio tinklai“ &gt; „Pageidaujamas tinklo tipas“."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Įspėjimai"</string>
@@ -1229,6 +1232,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB (MIDI)"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Prijungta prie USB priedo"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Garso įrašo priedas nepalaikomas"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Palieskite, kad išjungtumėte USB derinimą."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Palieskite, kad pasirinktumėte kalbą ir išdėstymą"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Rodoma virš kitų programų"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> rodomi virš kitų programų"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> rodomi virš kitų programų."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jei nenorite, kad <xliff:g id="NAME">%s</xliff:g> naudotų šią funkciją, palietę atidarykite nustatymus ir išjunkite ją."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Palieskite, kad išeitumėte iš automobilio režimo."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atgal"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Kitas"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Praleisti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index bbffbf8..a3a91eb 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -91,10 +91,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Pakalpojums netiek nodrošināts."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Zvanītāja ID iestatījumu nevar mainīt."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nav datu pakalpojuma"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Nav ārkārtas izsaukumu"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ārkārtas izsaukumu pakalpojums nedarbojas"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Balss izsaukumu pakalpojums nedarbojas"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Balss un ārkārtas izsaukumu pakalpojums nedarbojas"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Pagaidām netiek piedāvāts mobilajā tīklā jūsu atrašanās vietā"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Jūsu mobilo sakaru operators uz laiku apturēja datu pakalpojuma darbību šajā atrašanās vietā."</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Jūsu mobilo sakaru operators uz laiku apturēja ārkārtas izsaukumus šajā atrašanās vietā."</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Jūsu mobilo sakaru operators uz laiku apturēja balss izsaukumus šajā atrašanās vietā."</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Jūsu mobilo sakaru operators uz laiku apturēja balss un ārkārtas izsaukumus šajā atrašanās vietā."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nevar sasniegt tīklu"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Lai uzlabotu uztveršanu, mainiet atlasīto veidu sadaļā Sistēma &gt; Tīkls un internets &gt; Mobilie tīkli &gt; Ieteicamais tīkla veids."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Brīdinājumi"</string>
@@ -1207,6 +1210,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB savienojums MIDI režīmā"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Pieskarieties, lai skatītu citas iespējas."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio piederums netiek atbalstīts"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Pieskarieties, lai uzzinātu vairāk"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
@@ -1223,7 +1228,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Pieskarieties, lai atlasītu valodu un izkārtojumu"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Rādīt pāri citām lietotnēm"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Lietotne <xliff:g id="NAME">%s</xliff:g> tiek rādīta pāri citām lietotnēm"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Lietotne <xliff:g id="NAME">%s</xliff:g> pāri citām lietotnēm"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ja nevēlaties lietotnē <xliff:g id="NAME">%s</xliff:g> izmantot šo funkciju, pieskarieties, lai atvērtu iestatījumus un to izslēgtu."</string>
@@ -1323,8 +1329,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Pieskarieties, lai izietu no automašīnas režīma."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Atpakaļ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tālāk"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Izlaist"</string>
diff --git a/core/res/res/values-mcc262-mnc02/strings.xml b/core/res/res/values-mcc262-mnc02/strings.xml
new file mode 100644
index 0000000..2b89401
--- /dev/null
+++ b/core/res/res/values-mcc262-mnc02/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2017, Google Inc.
+ *
+ * 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+     <!-- Do not translate. Template for showing mobile network operator name while WFC is active -->
+     <string-array name="wfcSpnFormats">
+         <item>%s</item>
+         <item>%s Wi-Fi Calling</item>
+     </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 422f7c9..9a3d736 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -38,19 +38,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.telusmobility.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=3</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml
index 1444250..007fd04 100644
--- a/core/res/res/values-mcc302-mnc221/config.xml
+++ b/core/res/res/values-mcc302-mnc221/config.xml
@@ -36,19 +36,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.telusmobility.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=3</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index 4876a8ae..28cca62 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -35,23 +35,17 @@
     -->
     <integer name="config_mobile_mtu">1410</integer>
 
-  <!-- Values for GPS configuration (Rogers) -->
+    <!-- Values for GPS configuration (Rogers) -->
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc370/strings.xml b/core/res/res/values-mcc302-mnc370/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml
index 8ac8f4c..232f149 100644
--- a/core/res/res/values-mcc302-mnc610/config.xml
+++ b/core/res/res/values-mcc302-mnc610/config.xml
@@ -26,18 +26,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml
index cba8eed..1d2e625 100644
--- a/core/res/res/values-mcc302-mnc640/config.xml
+++ b/core/res/res/values-mcc302-mnc640/config.xml
@@ -22,18 +22,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index dff3678..c322bb9 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -37,23 +37,17 @@
     -->
     <integer name="config_mobile_mtu">1430</integer>
 
-  <!-- Values for GPS configuration (Rogers) -->
+    <!-- Values for GPS configuration (Rogers) -->
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin</item>
-        <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
-        <item>SUPL_MODE=1</item>
         <item>SUPL_VER=0x20000</item>
-        <item>LPP_PROFILE=2</item>
-        <item>NMEA_PROVIDER=0</item>
-        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
-        <item>ERR_ESTIMATE=0</item>
-        <item>INTERMEDIATE_POS=0</item>
-        <item>GPS_LOCK=0</item>
+        <item>SUPL_MODE=1</item>
         <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=2</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720/strings.xml b/core/res/res/values-mcc302-mnc720/strings.xml
new file mode 100644
index 0000000..f5b8496
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Template for showing mobile network operator name while WFC is active -->
+    <string-array name="wfcSpnFormats">
+        <item>%s</item>
+        <item>%s Wi-Fi</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc030-af/strings.xml b/core/res/res/values-mcc310-mnc030-af/strings.xml
deleted file mode 100644
index 0b666c2..0000000
--- a/core/res/res/values-mcc310-mnc030-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-am/strings.xml b/core/res/res/values-mcc310-mnc030-am/strings.xml
deleted file mode 100644
index 08c5e32..0000000
--- a/core/res/res/values-mcc310-mnc030-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ar/strings.xml b/core/res/res/values-mcc310-mnc030-ar/strings.xml
deleted file mode 100644
index 5d6a53d..0000000
--- a/core/res/res/values-mcc310-mnc030-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-az/strings.xml b/core/res/res/values-mcc310-mnc030-az/strings.xml
deleted file mode 100644
index 194d189..0000000
--- a/core/res/res/values-mcc310-mnc030-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-bg/strings.xml b/core/res/res/values-mcc310-mnc030-bg/strings.xml
deleted file mode 100644
index a7c014a..0000000
--- a/core/res/res/values-mcc310-mnc030-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ca/strings.xml b/core/res/res/values-mcc310-mnc030-ca/strings.xml
deleted file mode 100644
index af25f9b..0000000
--- a/core/res/res/values-mcc310-mnc030-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-cs/strings.xml b/core/res/res/values-mcc310-mnc030-cs/strings.xml
deleted file mode 100644
index ee0f90c..0000000
--- a/core/res/res/values-mcc310-mnc030-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-da/strings.xml b/core/res/res/values-mcc310-mnc030-da/strings.xml
deleted file mode 100644
index 8539f7a..0000000
--- a/core/res/res/values-mcc310-mnc030-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-de/strings.xml b/core/res/res/values-mcc310-mnc030-de/strings.xml
deleted file mode 100644
index ad797b5..0000000
--- a/core/res/res/values-mcc310-mnc030-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-el/strings.xml b/core/res/res/values-mcc310-mnc030-el/strings.xml
deleted file mode 100644
index 62aa97f..0000000
--- a/core/res/res/values-mcc310-mnc030-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
deleted file mode 100644
index 1a50ac6..0000000
--- a/core/res/res/values-mcc310-mnc030-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
deleted file mode 100644
index 1a50ac6..0000000
--- a/core/res/res/values-mcc310-mnc030-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
deleted file mode 100644
index 1a50ac6..0000000
--- a/core/res/res/values-mcc310-mnc030-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
deleted file mode 100644
index 87226ac..0000000
--- a/core/res/res/values-mcc310-mnc030-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-es/strings.xml b/core/res/res/values-mcc310-mnc030-es/strings.xml
deleted file mode 100644
index c13f5f8..0000000
--- a/core/res/res/values-mcc310-mnc030-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-et/strings.xml b/core/res/res/values-mcc310-mnc030-et/strings.xml
deleted file mode 100644
index 07229ab..0000000
--- a/core/res/res/values-mcc310-mnc030-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-eu/strings.xml b/core/res/res/values-mcc310-mnc030-eu/strings.xml
deleted file mode 100644
index 024fbab..0000000
--- a/core/res/res/values-mcc310-mnc030-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-fa/strings.xml b/core/res/res/values-mcc310-mnc030-fa/strings.xml
deleted file mode 100644
index e754032..0000000
--- a/core/res/res/values-mcc310-mnc030-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-fi/strings.xml b/core/res/res/values-mcc310-mnc030-fi/strings.xml
deleted file mode 100644
index 3b9c2ab..0000000
--- a/core/res/res/values-mcc310-mnc030-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
deleted file mode 100644
index 31644b7..0000000
--- a/core/res/res/values-mcc310-mnc030-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-fr/strings.xml b/core/res/res/values-mcc310-mnc030-fr/strings.xml
deleted file mode 100644
index 9c690e7..0000000
--- a/core/res/res/values-mcc310-mnc030-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-gl/strings.xml b/core/res/res/values-mcc310-mnc030-gl/strings.xml
deleted file mode 100644
index 59be216..0000000
--- a/core/res/res/values-mcc310-mnc030-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-gu/strings.xml b/core/res/res/values-mcc310-mnc030-gu/strings.xml
deleted file mode 100644
index ac57a85..0000000
--- a/core/res/res/values-mcc310-mnc030-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-hi/strings.xml b/core/res/res/values-mcc310-mnc030-hi/strings.xml
deleted file mode 100644
index 244d175..0000000
--- a/core/res/res/values-mcc310-mnc030-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-hr/strings.xml b/core/res/res/values-mcc310-mnc030-hr/strings.xml
deleted file mode 100644
index a37043c..0000000
--- a/core/res/res/values-mcc310-mnc030-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-hu/strings.xml b/core/res/res/values-mcc310-mnc030-hu/strings.xml
deleted file mode 100644
index b26b2b2..0000000
--- a/core/res/res/values-mcc310-mnc030-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-hy/strings.xml b/core/res/res/values-mcc310-mnc030-hy/strings.xml
deleted file mode 100644
index 0d052f3..0000000
--- a/core/res/res/values-mcc310-mnc030-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-in/strings.xml b/core/res/res/values-mcc310-mnc030-in/strings.xml
deleted file mode 100644
index f8f6613..0000000
--- a/core/res/res/values-mcc310-mnc030-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-is/strings.xml b/core/res/res/values-mcc310-mnc030-is/strings.xml
deleted file mode 100644
index 1033965..0000000
--- a/core/res/res/values-mcc310-mnc030-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-it/strings.xml b/core/res/res/values-mcc310-mnc030-it/strings.xml
deleted file mode 100644
index fb74a97..0000000
--- a/core/res/res/values-mcc310-mnc030-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-iw/strings.xml b/core/res/res/values-mcc310-mnc030-iw/strings.xml
deleted file mode 100644
index 50bd517..0000000
--- a/core/res/res/values-mcc310-mnc030-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ja/strings.xml b/core/res/res/values-mcc310-mnc030-ja/strings.xml
deleted file mode 100644
index 78cd78c..0000000
--- a/core/res/res/values-mcc310-mnc030-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ka/strings.xml b/core/res/res/values-mcc310-mnc030-ka/strings.xml
deleted file mode 100644
index 04d6a7d..0000000
--- a/core/res/res/values-mcc310-mnc030-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-kk/strings.xml b/core/res/res/values-mcc310-mnc030-kk/strings.xml
deleted file mode 100644
index aad588c..0000000
--- a/core/res/res/values-mcc310-mnc030-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-km/strings.xml b/core/res/res/values-mcc310-mnc030-km/strings.xml
deleted file mode 100644
index bd99927..0000000
--- a/core/res/res/values-mcc310-mnc030-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ស៊ីមកាត​មិនត្រូវបាន​ផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាត​ទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-kn/strings.xml b/core/res/res/values-mcc310-mnc030-kn/strings.xml
deleted file mode 100644
index 39e9b070..0000000
--- a/core/res/res/values-mcc310-mnc030-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ko/strings.xml b/core/res/res/values-mcc310-mnc030-ko/strings.xml
deleted file mode 100644
index 67e45b0..0000000
--- a/core/res/res/values-mcc310-mnc030-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ky/strings.xml b/core/res/res/values-mcc310-mnc030-ky/strings.xml
deleted file mode 100644
index 837ff98..0000000
--- a/core/res/res/values-mcc310-mnc030-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-lo/strings.xml b/core/res/res/values-mcc310-mnc030-lo/strings.xml
deleted file mode 100644
index b41bf91..0000000
--- a/core/res/res/values-mcc310-mnc030-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-lt/strings.xml b/core/res/res/values-mcc310-mnc030-lt/strings.xml
deleted file mode 100644
index 59c66be..0000000
--- a/core/res/res/values-mcc310-mnc030-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-lv/strings.xml b/core/res/res/values-mcc310-mnc030-lv/strings.xml
deleted file mode 100644
index 685c9b8..0000000
--- a/core/res/res/values-mcc310-mnc030-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-mk/strings.xml b/core/res/res/values-mcc310-mnc030-mk/strings.xml
deleted file mode 100644
index ce24e25..0000000
--- a/core/res/res/values-mcc310-mnc030-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ml/strings.xml b/core/res/res/values-mcc310-mnc030-ml/strings.xml
deleted file mode 100644
index bc87cbd..0000000
--- a/core/res/res/values-mcc310-mnc030-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-mn/strings.xml b/core/res/res/values-mcc310-mnc030-mn/strings.xml
deleted file mode 100644
index 6ff2d5e..0000000
--- a/core/res/res/values-mcc310-mnc030-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-mr/strings.xml b/core/res/res/values-mcc310-mnc030-mr/strings.xml
deleted file mode 100644
index afc40a1..0000000
--- a/core/res/res/values-mcc310-mnc030-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ms/strings.xml b/core/res/res/values-mcc310-mnc030-ms/strings.xml
deleted file mode 100644
index 9a54b04..0000000
--- a/core/res/res/values-mcc310-mnc030-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-my/strings.xml b/core/res/res/values-mcc310-mnc030-my/strings.xml
deleted file mode 100644
index 79a0791..0000000
--- a/core/res/res/values-mcc310-mnc030-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-nb/strings.xml b/core/res/res/values-mcc310-mnc030-nb/strings.xml
deleted file mode 100644
index 7c06dba..0000000
--- a/core/res/res/values-mcc310-mnc030-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ne/strings.xml b/core/res/res/values-mcc310-mnc030-ne/strings.xml
deleted file mode 100644
index 3ef06ab..0000000
--- a/core/res/res/values-mcc310-mnc030-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-nl/strings.xml b/core/res/res/values-mcc310-mnc030-nl/strings.xml
deleted file mode 100644
index 861385d..0000000
--- a/core/res/res/values-mcc310-mnc030-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-pl/strings.xml b/core/res/res/values-mcc310-mnc030-pl/strings.xml
deleted file mode 100644
index 84ff351..0000000
--- a/core/res/res/values-mcc310-mnc030-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
deleted file mode 100644
index 2679f93..0000000
--- a/core/res/res/values-mcc310-mnc030-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
deleted file mode 100644
index 2679f93..0000000
--- a/core/res/res/values-mcc310-mnc030-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-pt/strings.xml b/core/res/res/values-mcc310-mnc030-pt/strings.xml
deleted file mode 100644
index 2679f93..0000000
--- a/core/res/res/values-mcc310-mnc030-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ro/strings.xml b/core/res/res/values-mcc310-mnc030-ro/strings.xml
deleted file mode 100644
index 5bae0c0..0000000
--- a/core/res/res/values-mcc310-mnc030-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ru/strings.xml b/core/res/res/values-mcc310-mnc030-ru/strings.xml
deleted file mode 100644
index 658badf..0000000
--- a/core/res/res/values-mcc310-mnc030-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-si/strings.xml b/core/res/res/values-mcc310-mnc030-si/strings.xml
deleted file mode 100644
index 635ffa4..0000000
--- a/core/res/res/values-mcc310-mnc030-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sk/strings.xml b/core/res/res/values-mcc310-mnc030-sk/strings.xml
deleted file mode 100644
index 2a046b6..0000000
--- a/core/res/res/values-mcc310-mnc030-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sl/strings.xml b/core/res/res/values-mcc310-mnc030-sl/strings.xml
deleted file mode 100644
index 7321e4d..0000000
--- a/core/res/res/values-mcc310-mnc030-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sq/strings.xml b/core/res/res/values-mcc310-mnc030-sq/strings.xml
deleted file mode 100644
index e553f01..0000000
--- a/core/res/res/values-mcc310-mnc030-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sr/strings.xml b/core/res/res/values-mcc310-mnc030-sr/strings.xml
deleted file mode 100644
index 945e2fc..0000000
--- a/core/res/res/values-mcc310-mnc030-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sv/strings.xml b/core/res/res/values-mcc310-mnc030-sv/strings.xml
deleted file mode 100644
index 5f0cc46..0000000
--- a/core/res/res/values-mcc310-mnc030-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-sw/strings.xml b/core/res/res/values-mcc310-mnc030-sw/strings.xml
deleted file mode 100644
index fbd2076..0000000
--- a/core/res/res/values-mcc310-mnc030-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ta/strings.xml b/core/res/res/values-mcc310-mnc030-ta/strings.xml
deleted file mode 100644
index 6fc3df6..0000000
--- a/core/res/res/values-mcc310-mnc030-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-th/strings.xml b/core/res/res/values-mcc310-mnc030-th/strings.xml
deleted file mode 100644
index 9a8ee74..0000000
--- a/core/res/res/values-mcc310-mnc030-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-tl/strings.xml b/core/res/res/values-mcc310-mnc030-tl/strings.xml
deleted file mode 100644
index 6408f4e..0000000
--- a/core/res/res/values-mcc310-mnc030-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-tr/strings.xml b/core/res/res/values-mcc310-mnc030-tr/strings.xml
deleted file mode 100644
index 361ee9c..0000000
--- a/core/res/res/values-mcc310-mnc030-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-uk/strings.xml b/core/res/res/values-mcc310-mnc030-uk/strings.xml
deleted file mode 100644
index efee94e..0000000
--- a/core/res/res/values-mcc310-mnc030-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-ur/strings.xml b/core/res/res/values-mcc310-mnc030-ur/strings.xml
deleted file mode 100644
index a0e5fd6..0000000
--- a/core/res/res/values-mcc310-mnc030-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-uz/strings.xml b/core/res/res/values-mcc310-mnc030-uz/strings.xml
deleted file mode 100644
index 7eb641a..0000000
--- a/core/res/res/values-mcc310-mnc030-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-vi/strings.xml b/core/res/res/values-mcc310-mnc030-vi/strings.xml
deleted file mode 100644
index 362ee6a..0000000
--- a/core/res/res/values-mcc310-mnc030-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
deleted file mode 100644
index efa43f5..0000000
--- a/core/res/res/values-mcc310-mnc030-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
deleted file mode 100644
index c163544..0000000
--- a/core/res/res/values-mcc310-mnc030-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
deleted file mode 100644
index c163544..0000000
--- a/core/res/res/values-mcc310-mnc030-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc030-zu/strings.xml b/core/res/res/values-mcc310-mnc030-zu/strings.xml
deleted file mode 100644
index 720fa82..0000000
--- a/core/res/res/values-mcc310-mnc030-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6575159319460304530">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1930079814544869756">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-af/strings.xml b/core/res/res/values-mcc310-mnc170-af/strings.xml
deleted file mode 100644
index 4256d3a..0000000
--- a/core/res/res/values-mcc310-mnc170-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-am/strings.xml b/core/res/res/values-mcc310-mnc170-am/strings.xml
deleted file mode 100644
index 311d9e1..0000000
--- a/core/res/res/values-mcc310-mnc170-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ar/strings.xml b/core/res/res/values-mcc310-mnc170-ar/strings.xml
deleted file mode 100644
index a80ff2e..0000000
--- a/core/res/res/values-mcc310-mnc170-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-az/strings.xml b/core/res/res/values-mcc310-mnc170-az/strings.xml
deleted file mode 100644
index a690668..0000000
--- a/core/res/res/values-mcc310-mnc170-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-bg/strings.xml b/core/res/res/values-mcc310-mnc170-bg/strings.xml
deleted file mode 100644
index 1158b3b..0000000
--- a/core/res/res/values-mcc310-mnc170-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ca/strings.xml b/core/res/res/values-mcc310-mnc170-ca/strings.xml
deleted file mode 100644
index 9abeeb7..0000000
--- a/core/res/res/values-mcc310-mnc170-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-cs/strings.xml b/core/res/res/values-mcc310-mnc170-cs/strings.xml
deleted file mode 100644
index 2d4d2fb..0000000
--- a/core/res/res/values-mcc310-mnc170-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-da/strings.xml b/core/res/res/values-mcc310-mnc170-da/strings.xml
deleted file mode 100644
index ae2155f..0000000
--- a/core/res/res/values-mcc310-mnc170-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-de/strings.xml b/core/res/res/values-mcc310-mnc170-de/strings.xml
deleted file mode 100644
index f7c5eec..0000000
--- a/core/res/res/values-mcc310-mnc170-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-el/strings.xml b/core/res/res/values-mcc310-mnc170-el/strings.xml
deleted file mode 100644
index 68b7008..0000000
--- a/core/res/res/values-mcc310-mnc170-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
deleted file mode 100644
index fd16620..0000000
--- a/core/res/res/values-mcc310-mnc170-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
deleted file mode 100644
index fd16620..0000000
--- a/core/res/res/values-mcc310-mnc170-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
deleted file mode 100644
index fd16620..0000000
--- a/core/res/res/values-mcc310-mnc170-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
deleted file mode 100644
index 50d3c12..0000000
--- a/core/res/res/values-mcc310-mnc170-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-es/strings.xml b/core/res/res/values-mcc310-mnc170-es/strings.xml
deleted file mode 100644
index 7191d04..0000000
--- a/core/res/res/values-mcc310-mnc170-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-et/strings.xml b/core/res/res/values-mcc310-mnc170-et/strings.xml
deleted file mode 100644
index 7159bf9..0000000
--- a/core/res/res/values-mcc310-mnc170-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
deleted file mode 100644
index 797f988..0000000
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-fa/strings.xml b/core/res/res/values-mcc310-mnc170-fa/strings.xml
deleted file mode 100644
index 968f952..0000000
--- a/core/res/res/values-mcc310-mnc170-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-fi/strings.xml b/core/res/res/values-mcc310-mnc170-fi/strings.xml
deleted file mode 100644
index c0523f4..0000000
--- a/core/res/res/values-mcc310-mnc170-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
deleted file mode 100644
index 5600fa4..0000000
--- a/core/res/res/values-mcc310-mnc170-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-fr/strings.xml b/core/res/res/values-mcc310-mnc170-fr/strings.xml
deleted file mode 100644
index 73b4f0e..0000000
--- a/core/res/res/values-mcc310-mnc170-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-gl/strings.xml b/core/res/res/values-mcc310-mnc170-gl/strings.xml
deleted file mode 100644
index fe13211..0000000
--- a/core/res/res/values-mcc310-mnc170-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-gu/strings.xml b/core/res/res/values-mcc310-mnc170-gu/strings.xml
deleted file mode 100644
index 60eba5b..0000000
--- a/core/res/res/values-mcc310-mnc170-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-hi/strings.xml b/core/res/res/values-mcc310-mnc170-hi/strings.xml
deleted file mode 100644
index eb350b0..0000000
--- a/core/res/res/values-mcc310-mnc170-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-hr/strings.xml b/core/res/res/values-mcc310-mnc170-hr/strings.xml
deleted file mode 100644
index d5cf025..0000000
--- a/core/res/res/values-mcc310-mnc170-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-hu/strings.xml b/core/res/res/values-mcc310-mnc170-hu/strings.xml
deleted file mode 100644
index e05e700..0000000
--- a/core/res/res/values-mcc310-mnc170-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-hy/strings.xml b/core/res/res/values-mcc310-mnc170-hy/strings.xml
deleted file mode 100644
index 90a5f6d..0000000
--- a/core/res/res/values-mcc310-mnc170-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-in/strings.xml b/core/res/res/values-mcc310-mnc170-in/strings.xml
deleted file mode 100644
index fc1bd0a..0000000
--- a/core/res/res/values-mcc310-mnc170-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-is/strings.xml b/core/res/res/values-mcc310-mnc170-is/strings.xml
deleted file mode 100644
index eef786c..0000000
--- a/core/res/res/values-mcc310-mnc170-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-it/strings.xml b/core/res/res/values-mcc310-mnc170-it/strings.xml
deleted file mode 100644
index eaf0abc..0000000
--- a/core/res/res/values-mcc310-mnc170-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-iw/strings.xml b/core/res/res/values-mcc310-mnc170-iw/strings.xml
deleted file mode 100644
index edee703..0000000
--- a/core/res/res/values-mcc310-mnc170-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ja/strings.xml b/core/res/res/values-mcc310-mnc170-ja/strings.xml
deleted file mode 100644
index 6942641..0000000
--- a/core/res/res/values-mcc310-mnc170-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ka/strings.xml b/core/res/res/values-mcc310-mnc170-ka/strings.xml
deleted file mode 100644
index 6f6c4aa..0000000
--- a/core/res/res/values-mcc310-mnc170-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-kk/strings.xml b/core/res/res/values-mcc310-mnc170-kk/strings.xml
deleted file mode 100644
index 210fb31..0000000
--- a/core/res/res/values-mcc310-mnc170-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-km/strings.xml b/core/res/res/values-mcc310-mnc170-km/strings.xml
deleted file mode 100644
index 79acf48..0000000
--- a/core/res/res/values-mcc310-mnc170-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-kn/strings.xml b/core/res/res/values-mcc310-mnc170-kn/strings.xml
deleted file mode 100644
index e11523b..0000000
--- a/core/res/res/values-mcc310-mnc170-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ko/strings.xml b/core/res/res/values-mcc310-mnc170-ko/strings.xml
deleted file mode 100644
index 22d7e35..0000000
--- a/core/res/res/values-mcc310-mnc170-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ky/strings.xml b/core/res/res/values-mcc310-mnc170-ky/strings.xml
deleted file mode 100644
index 988c40a..0000000
--- a/core/res/res/values-mcc310-mnc170-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-lo/strings.xml b/core/res/res/values-mcc310-mnc170-lo/strings.xml
deleted file mode 100644
index 3073000..0000000
--- a/core/res/res/values-mcc310-mnc170-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-lt/strings.xml b/core/res/res/values-mcc310-mnc170-lt/strings.xml
deleted file mode 100644
index 127e69f..0000000
--- a/core/res/res/values-mcc310-mnc170-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-lv/strings.xml b/core/res/res/values-mcc310-mnc170-lv/strings.xml
deleted file mode 100644
index da2ff7c..0000000
--- a/core/res/res/values-mcc310-mnc170-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-mk/strings.xml b/core/res/res/values-mcc310-mnc170-mk/strings.xml
deleted file mode 100644
index 3bc8194..0000000
--- a/core/res/res/values-mcc310-mnc170-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ml/strings.xml b/core/res/res/values-mcc310-mnc170-ml/strings.xml
deleted file mode 100644
index 8d36412..0000000
--- a/core/res/res/values-mcc310-mnc170-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-mn/strings.xml b/core/res/res/values-mcc310-mnc170-mn/strings.xml
deleted file mode 100644
index 59f24ec..0000000
--- a/core/res/res/values-mcc310-mnc170-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-mr/strings.xml b/core/res/res/values-mcc310-mnc170-mr/strings.xml
deleted file mode 100644
index 938207c..0000000
--- a/core/res/res/values-mcc310-mnc170-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ms/strings.xml b/core/res/res/values-mcc310-mnc170-ms/strings.xml
deleted file mode 100644
index 36be774..0000000
--- a/core/res/res/values-mcc310-mnc170-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-my/strings.xml b/core/res/res/values-mcc310-mnc170-my/strings.xml
deleted file mode 100644
index 61f1a67..0000000
--- a/core/res/res/values-mcc310-mnc170-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-nb/strings.xml b/core/res/res/values-mcc310-mnc170-nb/strings.xml
deleted file mode 100644
index 3f213da..0000000
--- a/core/res/res/values-mcc310-mnc170-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ne/strings.xml b/core/res/res/values-mcc310-mnc170-ne/strings.xml
deleted file mode 100644
index d7febc4..0000000
--- a/core/res/res/values-mcc310-mnc170-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-nl/strings.xml b/core/res/res/values-mcc310-mnc170-nl/strings.xml
deleted file mode 100644
index b1f9ba8..0000000
--- a/core/res/res/values-mcc310-mnc170-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-pl/strings.xml b/core/res/res/values-mcc310-mnc170-pl/strings.xml
deleted file mode 100644
index d1ecd5d..0000000
--- a/core/res/res/values-mcc310-mnc170-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
deleted file mode 100644
index fc31e9e..0000000
--- a/core/res/res/values-mcc310-mnc170-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
deleted file mode 100644
index fc31e9e..0000000
--- a/core/res/res/values-mcc310-mnc170-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-pt/strings.xml b/core/res/res/values-mcc310-mnc170-pt/strings.xml
deleted file mode 100644
index fc31e9e..0000000
--- a/core/res/res/values-mcc310-mnc170-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ro/strings.xml b/core/res/res/values-mcc310-mnc170-ro/strings.xml
deleted file mode 100644
index 1ee5080..0000000
--- a/core/res/res/values-mcc310-mnc170-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ru/strings.xml b/core/res/res/values-mcc310-mnc170-ru/strings.xml
deleted file mode 100644
index 0e00909..0000000
--- a/core/res/res/values-mcc310-mnc170-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-si/strings.xml b/core/res/res/values-mcc310-mnc170-si/strings.xml
deleted file mode 100644
index bbd1e4c..0000000
--- a/core/res/res/values-mcc310-mnc170-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sk/strings.xml b/core/res/res/values-mcc310-mnc170-sk/strings.xml
deleted file mode 100644
index e5f9376..0000000
--- a/core/res/res/values-mcc310-mnc170-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sl/strings.xml b/core/res/res/values-mcc310-mnc170-sl/strings.xml
deleted file mode 100644
index 2d4c7dd..0000000
--- a/core/res/res/values-mcc310-mnc170-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sq/strings.xml b/core/res/res/values-mcc310-mnc170-sq/strings.xml
deleted file mode 100644
index df5b537..0000000
--- a/core/res/res/values-mcc310-mnc170-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sr/strings.xml b/core/res/res/values-mcc310-mnc170-sr/strings.xml
deleted file mode 100644
index 6bfbbb2..0000000
--- a/core/res/res/values-mcc310-mnc170-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sv/strings.xml b/core/res/res/values-mcc310-mnc170-sv/strings.xml
deleted file mode 100644
index 1a28db1..0000000
--- a/core/res/res/values-mcc310-mnc170-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-sw/strings.xml b/core/res/res/values-mcc310-mnc170-sw/strings.xml
deleted file mode 100644
index 0852115..0000000
--- a/core/res/res/values-mcc310-mnc170-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ta/strings.xml b/core/res/res/values-mcc310-mnc170-ta/strings.xml
deleted file mode 100644
index 0277cc2..0000000
--- a/core/res/res/values-mcc310-mnc170-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-th/strings.xml b/core/res/res/values-mcc310-mnc170-th/strings.xml
deleted file mode 100644
index e5d02c8..0000000
--- a/core/res/res/values-mcc310-mnc170-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-tl/strings.xml b/core/res/res/values-mcc310-mnc170-tl/strings.xml
deleted file mode 100644
index e285759..0000000
--- a/core/res/res/values-mcc310-mnc170-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-tr/strings.xml b/core/res/res/values-mcc310-mnc170-tr/strings.xml
deleted file mode 100644
index b5102ef..0000000
--- a/core/res/res/values-mcc310-mnc170-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-uk/strings.xml b/core/res/res/values-mcc310-mnc170-uk/strings.xml
deleted file mode 100644
index 37e3118..0000000
--- a/core/res/res/values-mcc310-mnc170-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-ur/strings.xml b/core/res/res/values-mcc310-mnc170-ur/strings.xml
deleted file mode 100644
index ea8b93e..0000000
--- a/core/res/res/values-mcc310-mnc170-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-uz/strings.xml b/core/res/res/values-mcc310-mnc170-uz/strings.xml
deleted file mode 100644
index 0bb3f52..0000000
--- a/core/res/res/values-mcc310-mnc170-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-vi/strings.xml b/core/res/res/values-mcc310-mnc170-vi/strings.xml
deleted file mode 100644
index a37f48f..0000000
--- a/core/res/res/values-mcc310-mnc170-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
deleted file mode 100644
index f072b28..0000000
--- a/core/res/res/values-mcc310-mnc170-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
deleted file mode 100644
index db14b90..0000000
--- a/core/res/res/values-mcc310-mnc170-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
deleted file mode 100644
index db14b90..0000000
--- a/core/res/res/values-mcc310-mnc170-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc170-zu/strings.xml b/core/res/res/values-mcc310-mnc170-zu/strings.xml
deleted file mode 100644
index 282f403..0000000
--- a/core/res/res/values-mcc310-mnc170-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="210168420192421012">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1130721094178658338">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-af/strings.xml b/core/res/res/values-mcc310-mnc260-af/strings.xml
deleted file mode 100644
index ee051c5..0000000
--- a/core/res/res/values-mcc310-mnc260-af/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreer by jou diensverskaffer"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-oproep"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-am/strings.xml b/core/res/res/values-mcc310-mnc260-am/strings.xml
deleted file mode 100644
index 74f711a..0000000
--- a/core/res/res/values-mcc310-mnc260-am/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"የ%s Wi-Fi ጥሪ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ar/strings.xml b/core/res/res/values-mcc310-mnc260-ar/strings.xml
deleted file mode 100644
index 5a84295..0000000
--- a/core/res/res/values-mcc310-mnc260-ar/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"التسجيل لدى مشغّل شبكة الجوّال"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-az/strings.xml b/core/res/res/values-mcc310-mnc260-az/strings.xml
deleted file mode 100644
index 32d21c5..0000000
--- a/core/res/res/values-mcc310-mnc260-az/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Operatorla qeydiyyatdan keçin"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Zəngi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
deleted file mode 100644
index 6750940..0000000
--- a/core/res/res/values-mcc310-mnc260-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrujte se kod mobilnog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-be/strings.xml b/core/res/res/values-mcc310-mnc260-be/strings.xml
deleted file mode 100644
index 497366b..0000000
--- a/core/res/res/values-mcc310-mnc260-be/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Каб рабіць выклікі і адпраўляць паведамленні па Wi-Fi, спачатку папрасіце свайго аператара наладзіць гэту паслугу. Затым зноў уключыце Wi-Fi-тэлефанію ў меню Налады."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Зарэгіструйцеся ў свайго аператара"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-тэлефанія %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bg/strings.xml b/core/res/res/values-mcc310-mnc260-bg/strings.xml
deleted file mode 100644
index a671120..0000000
--- a/core/res/res/values-mcc310-mnc260-bg/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Регистриране с оператора ви"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s – обаждания през Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bn/strings.xml b/core/res/res/values-mcc310-mnc260-bn/strings.xml
deleted file mode 100644
index 67955d5..0000000
--- a/core/res/res/values-mcc310-mnc260-bn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi কলিং"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-bs/strings.xml b/core/res/res/values-mcc310-mnc260-bs/strings.xml
deleted file mode 100644
index 64e4862..0000000
--- a/core/res/res/values-mcc310-mnc260-bs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrirajte se kod svog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi pozivanje preko operatera %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ca/strings.xml b/core/res/res/values-mcc310-mnc260-ca/strings.xml
deleted file mode 100644
index 8ce8dc8..0000000
--- a/core/res/res/values-mcc310-mnc260-ca/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registra\'t amb el teu operador de telefonia mòbil"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Trucada de Wi-Fi de: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-cs/strings.xml b/core/res/res/values-mcc310-mnc260-cs/strings.xml
deleted file mode 100644
index 61ba268..0000000
--- a/core/res/res/values-mcc310-mnc260-cs/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrace u operátora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Volání přes Wi-Fi: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-da/strings.xml b/core/res/res/values-mcc310-mnc260-da/strings.xml
deleted file mode 100644
index 0c612e5..0000000
--- a/core/res/res/values-mcc310-mnc260-da/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrer dig hos dit mobilselskab"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-opkald"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-de/strings.xml b/core/res/res/values-mcc310-mnc260-de/strings.xml
deleted file mode 100644
index b9cbb48..0000000
--- a/core/res/res/values-mcc310-mnc260-de/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registriere dich bei deinem Mobilfunkanbieter."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Anrufe über WLAN"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-el/strings.xml b/core/res/res/values-mcc310-mnc260-el/strings.xml
deleted file mode 100644
index b4cd123..0000000
--- a/core/res/res/values-mcc310-mnc260-el/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Κλήση Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rAU/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rGB/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
deleted file mode 100644
index 1d300ea..0000000
--- a/core/res/res/values-mcc310-mnc260-en-rIN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Register with your operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Calling"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
deleted file mode 100644
index 6398c02..0000000
--- a/core/res/res/values-mcc310-mnc260-es-rUS/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regístrate con tu proveedor."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada por Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-es/strings.xml b/core/res/res/values-mcc310-mnc260-es/strings.xml
deleted file mode 100644
index e959116..0000000
--- a/core/res/res/values-mcc310-mnc260-es/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regístrate con tu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Llamada Wi-Fi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-et/strings.xml b/core/res/res/values-mcc310-mnc260-et/strings.xml
deleted file mode 100644
index 2310130..0000000
--- a/core/res/res/values-mcc310-mnc260-et/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreeruge operaatori juures"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WiFi kaudu helistamine"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-eu/strings.xml b/core/res/res/values-mcc310-mnc260-eu/strings.xml
deleted file mode 100644
index 8fb03d4..0000000
--- a/core/res/res/values-mcc310-mnc260-eu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Erregistratu operadorearekin"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi bidezko deiak"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fa/strings.xml b/core/res/res/values-mcc310-mnc260-fa/strings.xml
deleted file mode 100644
index 659a0dd..0000000
--- a/core/res/res/values-mcc310-mnc260-fa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ثبت نام با شرکت مخابراتی شما"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏تماس ‪%s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fi/strings.xml b/core/res/res/values-mcc310-mnc260-fi/strings.xml
deleted file mode 100644
index 1eecb61..0000000
--- a/core/res/res/values-mcc310-mnc260-fi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Rekisteröidy operaattorisi asiakkaaksi."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi-puhelut: %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
deleted file mode 100644
index c767039..0000000
--- a/core/res/res/values-mcc310-mnc260-fr-rCA/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Inscrivez-vous auprès de votre fournisseur de services"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-fr/strings.xml b/core/res/res/values-mcc310-mnc260-fr/strings.xml
deleted file mode 100644
index 1de93ca..0000000
--- a/core/res/res/values-mcc310-mnc260-fr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Inscrivez-vous auprès de votre opérateur."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Appels Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gl/strings.xml b/core/res/res/values-mcc310-mnc260-gl/strings.xml
deleted file mode 100644
index 2747ab3..0000000
--- a/core/res/res/values-mcc310-mnc260-gl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Rexístrate co teu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas wifi de %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-gu/strings.xml b/core/res/res/values-mcc310-mnc260-gu/strings.xml
deleted file mode 100644
index d02d5ad..0000000
--- a/core/res/res/values-mcc310-mnc260-gu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi કૉલિંગ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hi/strings.xml b/core/res/res/values-mcc310-mnc260-hi/strings.xml
deleted file mode 100644
index a19f51a..0000000
--- a/core/res/res/values-mcc310-mnc260-hi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"अपने वाहक के साथ पंजीकृत करें"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाई-फ़ाई कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hr/strings.xml b/core/res/res/values-mcc310-mnc260-hr/strings.xml
deleted file mode 100644
index dc48a1e..0000000
--- a/core/res/res/values-mcc310-mnc260-hr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrirajte se kod mobilnog operatera"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi pozivanje"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hu/strings.xml b/core/res/res/values-mcc310-mnc260-hu/strings.xml
deleted file mode 100644
index ef6a2fc..0000000
--- a/core/res/res/values-mcc310-mnc260-hu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regisztráljon a szolgáltatójánál"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-hívás"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-hy/strings.xml b/core/res/res/values-mcc310-mnc260-hy/strings.xml
deleted file mode 100644
index 0a37df2..0000000
--- a/core/res/res/values-mcc310-mnc260-hy/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Գրանցվեք օպերատորի մոտ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi զանգեր"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-in/strings.xml b/core/res/res/values-mcc310-mnc260-in/strings.xml
deleted file mode 100644
index 4da068e..0000000
--- a/core/res/res/values-mcc310-mnc260-in/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Harap daftarkan ke operator"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-is/strings.xml b/core/res/res/values-mcc310-mnc260-is/strings.xml
deleted file mode 100644
index 1fd14d4..0000000
--- a/core/res/res/values-mcc310-mnc260-is/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Skráðu þig hjá símafyrirtækinu"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi símtöl"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-it/strings.xml b/core/res/res/values-mcc310-mnc260-it/strings.xml
deleted file mode 100644
index 6a7dec5..0000000
--- a/core/res/res/values-mcc310-mnc260-it/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrati con il tuo operatore"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chiamata Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-iw/strings.xml b/core/res/res/values-mcc310-mnc260-iw/strings.xml
deleted file mode 100644
index 1bcce94..0000000
--- a/core/res/res/values-mcc310-mnc260-iw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"הירשם אצל הספק"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏שיחות Wi-Fi של %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ja/strings.xml b/core/res/res/values-mcc310-mnc260-ja/strings.xml
deleted file mode 100644
index 05a333b..0000000
--- a/core/res/res/values-mcc310-mnc260-ja/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"携帯通信会社に登録してください"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi通話(%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ka/strings.xml b/core/res/res/values-mcc310-mnc260-ka/strings.xml
deleted file mode 100644
index dbb2822..0000000
--- a/core/res/res/values-mcc310-mnc260-ka/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s დარეკვა Wi-Fi-ს მეშვეობით"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kk/strings.xml b/core/res/res/values-mcc310-mnc260-kk/strings.xml
deleted file mode 100644
index 80eebfc..0000000
--- a/core/res/res/values-mcc310-mnc260-kk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Жабдықтаушыңыз арқылы тіркелу"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi арқылы қоңырау шалу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-km/strings.xml b/core/res/res/values-mcc310-mnc260-km/strings.xml
deleted file mode 100644
index e3cd1b2..0000000
--- a/core/res/res/values-mcc310-mnc260-km/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"ការហៅតាមរយៈ Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-kn/strings.xml b/core/res/res/values-mcc310-mnc260-kn/strings.xml
deleted file mode 100644
index 0a9d58d..0000000
--- a/core/res/res/values-mcc310-mnc260-kn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ Wi-Fi ಆನ್‌ ಮಾಡಿ."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ko/strings.xml b/core/res/res/values-mcc310-mnc260-ko/strings.xml
deleted file mode 100644
index 5581235..0000000
--- a/core/res/res/values-mcc310-mnc260-ko/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"이동통신사에 등록"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 통화"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ky/strings.xml b/core/res/res/values-mcc310-mnc260-ky/strings.xml
deleted file mode 100644
index 775542d..0000000
--- a/core/res/res/values-mcc310-mnc260-ky/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Операторуңузга катталыңыз"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Чалуу"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lo/strings.xml b/core/res/res/values-mcc310-mnc260-lo/strings.xml
deleted file mode 100644
index 49f79016..0000000
--- a/core/res/res/values-mcc310-mnc260-lo/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"ການ​ໂທ %s Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lt/strings.xml b/core/res/res/values-mcc310-mnc260-lt/strings.xml
deleted file mode 100644
index 4c3ebb7..0000000
--- a/core/res/res/values-mcc310-mnc260-lt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Užregistruokite pas operatorių"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"„%s“ „Wi-Fi“ skambinimas"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-lv/strings.xml b/core/res/res/values-mcc310-mnc260-lv/strings.xml
deleted file mode 100644
index 23d8ca0..0000000
--- a/core/res/res/values-mcc310-mnc260-lv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi zvani"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mk/strings.xml b/core/res/res/values-mcc310-mnc260-mk/strings.xml
deleted file mode 100644
index 878b7af..0000000
--- a/core/res/res/values-mcc310-mnc260-mk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Регистрирајте се со операторот"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Повикување преку Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ml/strings.xml b/core/res/res/values-mcc310-mnc260-ml/strings.xml
deleted file mode 100644
index a94680d..0000000
--- a/core/res/res/values-mcc310-mnc260-ml/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s വൈഫൈ കോളിംഗ്"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mn/strings.xml b/core/res/res/values-mcc310-mnc260-mn/strings.xml
deleted file mode 100644
index 4c97e2e..0000000
--- a/core/res/res/values-mcc310-mnc260-mn/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Операторт бүртгүүлэх"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi Дуудлага"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-mr/strings.xml b/core/res/res/values-mcc310-mnc260-mr/strings.xml
deleted file mode 100644
index 06eceff..0000000
--- a/core/res/res/values-mcc310-mnc260-mr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"आपल्या वाहकासह नोंदणी करा"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s वाय-फाय कॉलिंग"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ms/strings.xml b/core/res/res/values-mcc310-mnc260-ms/strings.xml
deleted file mode 100644
index dafb3bd..0000000
--- a/core/res/res/values-mcc310-mnc260-ms/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Daftar dengan pembawa anda"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Panggilan Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-my/strings.xml b/core/res/res/values-mcc310-mnc260-my/strings.xml
deleted file mode 100644
index 25ea191..0000000
--- a/core/res/res/values-mcc310-mnc260-my/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"ဝိုင်ဖိုင်သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်စေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် ဝိုင်ဖိုင် ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ဝိုင်ဖိုင် ခေါ်ဆိုမှု"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nb/strings.xml b/core/res/res/values-mcc310-mnc260-nb/strings.xml
deleted file mode 100644
index 9918996..0000000
--- a/core/res/res/values-mcc310-mnc260-nb/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrer deg hos operatøren din"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-anrop"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ne/strings.xml b/core/res/res/values-mcc310-mnc260-ne/strings.xml
deleted file mode 100644
index 6fb7b50..0000000
--- a/core/res/res/values-mcc310-mnc260-ne/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi कलिङ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
deleted file mode 100644
index ac4961c..0000000
--- a/core/res/res/values-mcc310-mnc260-nl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registreren bij je provider"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Bellen via wifi van %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pa/strings.xml b/core/res/res/values-mcc310-mnc260-pa/strings.xml
deleted file mode 100644
index 0026681..0000000
--- a/core/res/res/values-mcc310-mnc260-pa/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pl/strings.xml b/core/res/res/values-mcc310-mnc260-pl/strings.xml
deleted file mode 100644
index b7f512d..0000000
--- a/core/res/res/values-mcc310-mnc260-pl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Zarejestruj u operatora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Połączenia przez Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
deleted file mode 100644
index 18e3801..0000000
--- a/core/res/res/values-mcc310-mnc260-pt-rPT/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registar-se junto do seu operador"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Chamadas por Wi-Fi da %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-pt/strings.xml b/core/res/res/values-mcc310-mnc260-pt/strings.xml
deleted file mode 100644
index bad49c3..0000000
--- a/core/res/res/values-mcc310-mnc260-pt/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Faça registro na sua operadora"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ro/strings.xml b/core/res/res/values-mcc310-mnc260-ro/strings.xml
deleted file mode 100644
index 6b865a2..0000000
--- a/core/res/res/values-mcc310-mnc260-ro/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Înregistrați-vă la operatorul dvs."</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Apelare prin Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ru/strings.xml b/core/res/res/values-mcc310-mnc260-ru/strings.xml
deleted file mode 100644
index 829c477..0000000
--- a/core/res/res/values-mcc310-mnc260-ru/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Укажите оператора и зарегистрируйтесь"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Звонки по Wi-Fi (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-si/strings.xml b/core/res/res/values-mcc310-mnc260-si/strings.xml
deleted file mode 100644
index de00901..0000000
--- a/core/res/res/values-mcc310-mnc260-si/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi අමතමින්"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sk/strings.xml b/core/res/res/values-mcc310-mnc260-sk/strings.xml
deleted file mode 100644
index eb8b5f8..0000000
--- a/core/res/res/values-mcc310-mnc260-sk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrujte sa so svojím operátorom"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Volanie siete Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sl/strings.xml b/core/res/res/values-mcc310-mnc260-sl/strings.xml
deleted file mode 100644
index ae30c5a..0000000
--- a/core/res/res/values-mcc310-mnc260-sl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registracija pri operaterju"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Klicanje prek Wi-Fi-ja (%s)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sq/strings.xml b/core/res/res/values-mcc310-mnc260-sq/strings.xml
deleted file mode 100644
index 84ac153..0000000
--- a/core/res/res/values-mcc310-mnc260-sq/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Regjistrohu me operatorin tënd celular"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Telefonatat me Wi-Fi nga %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sr/strings.xml b/core/res/res/values-mcc310-mnc260-sr/strings.xml
deleted file mode 100644
index 92c6f35..0000000
--- a/core/res/res/values-mcc310-mnc260-sr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Региструјте се код мобилног оператера"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Wi-Fi позивање преко оператера %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sv/strings.xml b/core/res/res/values-mcc310-mnc260-sv/strings.xml
deleted file mode 100644
index 632a2ce..0000000
--- a/core/res/res/values-mcc310-mnc260-sv/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrera dig hos operatören"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi-samtal"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-sw/strings.xml b/core/res/res/values-mcc310-mnc260-sw/strings.xml
deleted file mode 100644
index eecf6d2..0000000
--- a/core/res/res/values-mcc310-mnc260-sw/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Jisajili na mtoa huduma wako"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Upigaji Simu kwa Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ta/strings.xml b/core/res/res/values-mcc310-mnc260-ta/strings.xml
deleted file mode 100644
index 144bc95..0000000
--- a/core/res/res/values-mcc310-mnc260-ta/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s வைஃபை அழைப்பு"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-te/strings.xml b/core/res/res/values-mcc310-mnc260-te/strings.xml
deleted file mode 100644
index ef94c4c..0000000
--- a/core/res/res/values-mcc310-mnc260-te/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi కాలింగ్"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-th/strings.xml b/core/res/res/values-mcc310-mnc260-th/strings.xml
deleted file mode 100644
index dd026cc..0000000
--- a/core/res/res/values-mcc310-mnc260-th/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"ลงทะเบียนกับผู้ให้บริการ"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"กำลังเรียก Wi-Fi ของ %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tl/strings.xml b/core/res/res/values-mcc310-mnc260-tl/strings.xml
deleted file mode 100644
index 5557835..0000000
--- a/core/res/res/values-mcc310-mnc260-tl/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Magparehistro sa iyong carrier"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Pagtawag sa Pamamagitan ng Wi-Fi ng %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-tr/strings.xml b/core/res/res/values-mcc310-mnc260-tr/strings.xml
deleted file mode 100644
index 7cfd9c1..0000000
--- a/core/res/res/values-mcc310-mnc260-tr/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Operatörünüze kaydolun"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Kablosuz Çağrı"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uk/strings.xml b/core/res/res/values-mcc310-mnc260-uk/strings.xml
deleted file mode 100644
index 0c21309..0000000
--- a/core/res/res/values-mcc310-mnc260-uk/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Зареєструйтеся в оператора"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Дзвінок через Wi-Fi від оператора %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-ur/strings.xml b/core/res/res/values-mcc310-mnc260-ur/strings.xml
deleted file mode 100644
index 5e93fa7..0000000
--- a/core/res/res/values-mcc310-mnc260-ur/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"‏‎%s Wi-Fi کالنگ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-uz/strings.xml b/core/res/res/values-mcc310-mnc260-uz/strings.xml
deleted file mode 100644
index 19c8f2e..0000000
--- a/core/res/res/values-mcc310-mnc260-uz/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi qo‘ng‘iroqlar"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-vi/strings.xml b/core/res/res/values-mcc310-mnc260-vi/strings.xml
deleted file mode 100644
index 7b249c8..0000000
--- a/core/res/res/values-mcc310-mnc260-vi/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"Gọi điện qua Wi-Fi %s"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
deleted file mode 100644
index 7624e91..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rCN/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的运营商注册"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s WLAN 通话功能"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
deleted file mode 100644
index 1aea15a..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rHK/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的流動網絡供應商註冊"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
deleted file mode 100644
index b0c7834..0000000
--- a/core/res/res/values-mcc310-mnc260-zh-rTW/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"向您的行動通訊業者註冊"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Wi-Fi 通話"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc260-zu/strings.xml b/core/res/res/values-mcc310-mnc260-zu/strings.xml
deleted file mode 100644
index cc32b1e..0000000
--- a/core/res/res/values-mcc310-mnc260-zu/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 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 my 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.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="7239039348648848288">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-FI, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-FI futhi kusukela kuzilungiselelo."</item>
-  </string-array>
-  <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
-  </string-array>
-    <string name="wfcSpnFormat" msgid="4982938551498609442">"%s ukushaya kwe-Wi-Fi"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-af/strings.xml b/core/res/res/values-mcc310-mnc280-af/strings.xml
deleted file mode 100644
index a761881..0000000
--- a/core/res/res/values-mcc310-mnc280-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-am/strings.xml b/core/res/res/values-mcc310-mnc280-am/strings.xml
deleted file mode 100644
index 6750a71..0000000
--- a/core/res/res/values-mcc310-mnc280-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ar/strings.xml b/core/res/res/values-mcc310-mnc280-ar/strings.xml
deleted file mode 100644
index a77d78e..0000000
--- a/core/res/res/values-mcc310-mnc280-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-az/strings.xml b/core/res/res/values-mcc310-mnc280-az/strings.xml
deleted file mode 100644
index b7ee114..0000000
--- a/core/res/res/values-mcc310-mnc280-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-bg/strings.xml b/core/res/res/values-mcc310-mnc280-bg/strings.xml
deleted file mode 100644
index a320898..0000000
--- a/core/res/res/values-mcc310-mnc280-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ca/strings.xml b/core/res/res/values-mcc310-mnc280-ca/strings.xml
deleted file mode 100644
index 9a9e309..0000000
--- a/core/res/res/values-mcc310-mnc280-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-cs/strings.xml b/core/res/res/values-mcc310-mnc280-cs/strings.xml
deleted file mode 100644
index 99e2bdb..0000000
--- a/core/res/res/values-mcc310-mnc280-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-da/strings.xml b/core/res/res/values-mcc310-mnc280-da/strings.xml
deleted file mode 100644
index 4f444a1..0000000
--- a/core/res/res/values-mcc310-mnc280-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-de/strings.xml b/core/res/res/values-mcc310-mnc280-de/strings.xml
deleted file mode 100644
index 063c75b..0000000
--- a/core/res/res/values-mcc310-mnc280-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-el/strings.xml b/core/res/res/values-mcc310-mnc280-el/strings.xml
deleted file mode 100644
index 1161a7d..0000000
--- a/core/res/res/values-mcc310-mnc280-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
deleted file mode 100644
index e9c9eba..0000000
--- a/core/res/res/values-mcc310-mnc280-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
deleted file mode 100644
index e9c9eba..0000000
--- a/core/res/res/values-mcc310-mnc280-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
deleted file mode 100644
index e9c9eba..0000000
--- a/core/res/res/values-mcc310-mnc280-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
deleted file mode 100644
index 86ad4fd..0000000
--- a/core/res/res/values-mcc310-mnc280-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-es/strings.xml b/core/res/res/values-mcc310-mnc280-es/strings.xml
deleted file mode 100644
index 2c7aa93..0000000
--- a/core/res/res/values-mcc310-mnc280-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-et/strings.xml b/core/res/res/values-mcc310-mnc280-et/strings.xml
deleted file mode 100644
index 7305d18..0000000
--- a/core/res/res/values-mcc310-mnc280-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
deleted file mode 100644
index 3c7296d..0000000
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-fa/strings.xml b/core/res/res/values-mcc310-mnc280-fa/strings.xml
deleted file mode 100644
index cd7ce85..0000000
--- a/core/res/res/values-mcc310-mnc280-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-fi/strings.xml b/core/res/res/values-mcc310-mnc280-fi/strings.xml
deleted file mode 100644
index b2ccc50..0000000
--- a/core/res/res/values-mcc310-mnc280-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
deleted file mode 100644
index 29bb9a0..0000000
--- a/core/res/res/values-mcc310-mnc280-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-fr/strings.xml b/core/res/res/values-mcc310-mnc280-fr/strings.xml
deleted file mode 100644
index ce2f931..0000000
--- a/core/res/res/values-mcc310-mnc280-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-gl/strings.xml b/core/res/res/values-mcc310-mnc280-gl/strings.xml
deleted file mode 100644
index e941341..0000000
--- a/core/res/res/values-mcc310-mnc280-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-gu/strings.xml b/core/res/res/values-mcc310-mnc280-gu/strings.xml
deleted file mode 100644
index a3763be..0000000
--- a/core/res/res/values-mcc310-mnc280-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-hi/strings.xml b/core/res/res/values-mcc310-mnc280-hi/strings.xml
deleted file mode 100644
index ce866af..0000000
--- a/core/res/res/values-mcc310-mnc280-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-hr/strings.xml b/core/res/res/values-mcc310-mnc280-hr/strings.xml
deleted file mode 100644
index 0021474..0000000
--- a/core/res/res/values-mcc310-mnc280-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-hu/strings.xml b/core/res/res/values-mcc310-mnc280-hu/strings.xml
deleted file mode 100644
index 864faff..0000000
--- a/core/res/res/values-mcc310-mnc280-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-hy/strings.xml b/core/res/res/values-mcc310-mnc280-hy/strings.xml
deleted file mode 100644
index 6d027c3..0000000
--- a/core/res/res/values-mcc310-mnc280-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-in/strings.xml b/core/res/res/values-mcc310-mnc280-in/strings.xml
deleted file mode 100644
index a4f3486..0000000
--- a/core/res/res/values-mcc310-mnc280-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-is/strings.xml b/core/res/res/values-mcc310-mnc280-is/strings.xml
deleted file mode 100644
index 30bbea4..0000000
--- a/core/res/res/values-mcc310-mnc280-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-it/strings.xml b/core/res/res/values-mcc310-mnc280-it/strings.xml
deleted file mode 100644
index f83921b..0000000
--- a/core/res/res/values-mcc310-mnc280-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-iw/strings.xml b/core/res/res/values-mcc310-mnc280-iw/strings.xml
deleted file mode 100644
index f3f87ff..0000000
--- a/core/res/res/values-mcc310-mnc280-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ja/strings.xml b/core/res/res/values-mcc310-mnc280-ja/strings.xml
deleted file mode 100644
index a1cfd8b..0000000
--- a/core/res/res/values-mcc310-mnc280-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ka/strings.xml b/core/res/res/values-mcc310-mnc280-ka/strings.xml
deleted file mode 100644
index 91c434f..0000000
--- a/core/res/res/values-mcc310-mnc280-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-kk/strings.xml b/core/res/res/values-mcc310-mnc280-kk/strings.xml
deleted file mode 100644
index 44440d3..0000000
--- a/core/res/res/values-mcc310-mnc280-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-km/strings.xml b/core/res/res/values-mcc310-mnc280-km/strings.xml
deleted file mode 100644
index a016601..0000000
--- a/core/res/res/values-mcc310-mnc280-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-kn/strings.xml b/core/res/res/values-mcc310-mnc280-kn/strings.xml
deleted file mode 100644
index 1d9e353..0000000
--- a/core/res/res/values-mcc310-mnc280-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ko/strings.xml b/core/res/res/values-mcc310-mnc280-ko/strings.xml
deleted file mode 100644
index e7bb9bb..0000000
--- a/core/res/res/values-mcc310-mnc280-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ky/strings.xml b/core/res/res/values-mcc310-mnc280-ky/strings.xml
deleted file mode 100644
index 4d364d8..0000000
--- a/core/res/res/values-mcc310-mnc280-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-lo/strings.xml b/core/res/res/values-mcc310-mnc280-lo/strings.xml
deleted file mode 100644
index 9415089..0000000
--- a/core/res/res/values-mcc310-mnc280-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-lt/strings.xml b/core/res/res/values-mcc310-mnc280-lt/strings.xml
deleted file mode 100644
index b5ff1b9..0000000
--- a/core/res/res/values-mcc310-mnc280-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-lv/strings.xml b/core/res/res/values-mcc310-mnc280-lv/strings.xml
deleted file mode 100644
index 4034bc1..0000000
--- a/core/res/res/values-mcc310-mnc280-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-mk/strings.xml b/core/res/res/values-mcc310-mnc280-mk/strings.xml
deleted file mode 100644
index a93cb79..0000000
--- a/core/res/res/values-mcc310-mnc280-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ml/strings.xml b/core/res/res/values-mcc310-mnc280-ml/strings.xml
deleted file mode 100644
index d14743b8..0000000
--- a/core/res/res/values-mcc310-mnc280-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-mn/strings.xml b/core/res/res/values-mcc310-mnc280-mn/strings.xml
deleted file mode 100644
index 54b8190..0000000
--- a/core/res/res/values-mcc310-mnc280-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-mr/strings.xml b/core/res/res/values-mcc310-mnc280-mr/strings.xml
deleted file mode 100644
index cb343cb..0000000
--- a/core/res/res/values-mcc310-mnc280-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ms/strings.xml b/core/res/res/values-mcc310-mnc280-ms/strings.xml
deleted file mode 100644
index 27da747..0000000
--- a/core/res/res/values-mcc310-mnc280-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-my/strings.xml b/core/res/res/values-mcc310-mnc280-my/strings.xml
deleted file mode 100644
index 40cdc63..0000000
--- a/core/res/res/values-mcc310-mnc280-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-nb/strings.xml b/core/res/res/values-mcc310-mnc280-nb/strings.xml
deleted file mode 100644
index 7666c3e..0000000
--- a/core/res/res/values-mcc310-mnc280-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ne/strings.xml b/core/res/res/values-mcc310-mnc280-ne/strings.xml
deleted file mode 100644
index 8735605..0000000
--- a/core/res/res/values-mcc310-mnc280-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-nl/strings.xml b/core/res/res/values-mcc310-mnc280-nl/strings.xml
deleted file mode 100644
index 7d7bfa7..0000000
--- a/core/res/res/values-mcc310-mnc280-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-pl/strings.xml b/core/res/res/values-mcc310-mnc280-pl/strings.xml
deleted file mode 100644
index 52410f4..0000000
--- a/core/res/res/values-mcc310-mnc280-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
deleted file mode 100644
index 03d0efb..0000000
--- a/core/res/res/values-mcc310-mnc280-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
deleted file mode 100644
index 03d0efb..0000000
--- a/core/res/res/values-mcc310-mnc280-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-pt/strings.xml b/core/res/res/values-mcc310-mnc280-pt/strings.xml
deleted file mode 100644
index 03d0efb..0000000
--- a/core/res/res/values-mcc310-mnc280-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ro/strings.xml b/core/res/res/values-mcc310-mnc280-ro/strings.xml
deleted file mode 100644
index d60ea0c..0000000
--- a/core/res/res/values-mcc310-mnc280-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ru/strings.xml b/core/res/res/values-mcc310-mnc280-ru/strings.xml
deleted file mode 100644
index 308c353..0000000
--- a/core/res/res/values-mcc310-mnc280-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-si/strings.xml b/core/res/res/values-mcc310-mnc280-si/strings.xml
deleted file mode 100644
index 5bd6d1f..0000000
--- a/core/res/res/values-mcc310-mnc280-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sk/strings.xml b/core/res/res/values-mcc310-mnc280-sk/strings.xml
deleted file mode 100644
index 4098ac7..0000000
--- a/core/res/res/values-mcc310-mnc280-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sl/strings.xml b/core/res/res/values-mcc310-mnc280-sl/strings.xml
deleted file mode 100644
index faa78ad..0000000
--- a/core/res/res/values-mcc310-mnc280-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sq/strings.xml b/core/res/res/values-mcc310-mnc280-sq/strings.xml
deleted file mode 100644
index 48fba2d..0000000
--- a/core/res/res/values-mcc310-mnc280-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sr/strings.xml b/core/res/res/values-mcc310-mnc280-sr/strings.xml
deleted file mode 100644
index 30c9df3..0000000
--- a/core/res/res/values-mcc310-mnc280-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sv/strings.xml b/core/res/res/values-mcc310-mnc280-sv/strings.xml
deleted file mode 100644
index cb5b9f32..0000000
--- a/core/res/res/values-mcc310-mnc280-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-sw/strings.xml b/core/res/res/values-mcc310-mnc280-sw/strings.xml
deleted file mode 100644
index 15a1a36..0000000
--- a/core/res/res/values-mcc310-mnc280-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ta/strings.xml b/core/res/res/values-mcc310-mnc280-ta/strings.xml
deleted file mode 100644
index c3911d4..0000000
--- a/core/res/res/values-mcc310-mnc280-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-th/strings.xml b/core/res/res/values-mcc310-mnc280-th/strings.xml
deleted file mode 100644
index 9810ba6..0000000
--- a/core/res/res/values-mcc310-mnc280-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-tl/strings.xml b/core/res/res/values-mcc310-mnc280-tl/strings.xml
deleted file mode 100644
index 600ad05..0000000
--- a/core/res/res/values-mcc310-mnc280-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-tr/strings.xml b/core/res/res/values-mcc310-mnc280-tr/strings.xml
deleted file mode 100644
index ea90bdb..0000000
--- a/core/res/res/values-mcc310-mnc280-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-uk/strings.xml b/core/res/res/values-mcc310-mnc280-uk/strings.xml
deleted file mode 100644
index 68a34fd..0000000
--- a/core/res/res/values-mcc310-mnc280-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-ur/strings.xml b/core/res/res/values-mcc310-mnc280-ur/strings.xml
deleted file mode 100644
index d61a5dc..0000000
--- a/core/res/res/values-mcc310-mnc280-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-uz/strings.xml b/core/res/res/values-mcc310-mnc280-uz/strings.xml
deleted file mode 100644
index 324d364..0000000
--- a/core/res/res/values-mcc310-mnc280-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-vi/strings.xml b/core/res/res/values-mcc310-mnc280-vi/strings.xml
deleted file mode 100644
index 6806e39..0000000
--- a/core/res/res/values-mcc310-mnc280-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
deleted file mode 100644
index add3f920..0000000
--- a/core/res/res/values-mcc310-mnc280-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
deleted file mode 100644
index 856297c..0000000
--- a/core/res/res/values-mcc310-mnc280-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
deleted file mode 100644
index 856297c..0000000
--- a/core/res/res/values-mcc310-mnc280-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc280-zu/strings.xml b/core/res/res/values-mcc310-mnc280-zu/strings.xml
deleted file mode 100644
index 6c5147c..0000000
--- a/core/res/res/values-mcc310-mnc280-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6638755728961013003">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="5562215652599183258">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-af/strings.xml b/core/res/res/values-mcc310-mnc380-af/strings.xml
deleted file mode 100644
index 7dfadad..0000000
--- a/core/res/res/values-mcc310-mnc380-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-am/strings.xml b/core/res/res/values-mcc310-mnc380-am/strings.xml
deleted file mode 100644
index dd9dbac..0000000
--- a/core/res/res/values-mcc310-mnc380-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ar/strings.xml b/core/res/res/values-mcc310-mnc380-ar/strings.xml
deleted file mode 100644
index 381749e..0000000
--- a/core/res/res/values-mcc310-mnc380-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-az/strings.xml b/core/res/res/values-mcc310-mnc380-az/strings.xml
deleted file mode 100644
index aeb1c79..0000000
--- a/core/res/res/values-mcc310-mnc380-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-bg/strings.xml b/core/res/res/values-mcc310-mnc380-bg/strings.xml
deleted file mode 100644
index bdce855..0000000
--- a/core/res/res/values-mcc310-mnc380-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ca/strings.xml b/core/res/res/values-mcc310-mnc380-ca/strings.xml
deleted file mode 100644
index e30fd81..0000000
--- a/core/res/res/values-mcc310-mnc380-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-cs/strings.xml b/core/res/res/values-mcc310-mnc380-cs/strings.xml
deleted file mode 100644
index 62fe37c..0000000
--- a/core/res/res/values-mcc310-mnc380-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-da/strings.xml b/core/res/res/values-mcc310-mnc380-da/strings.xml
deleted file mode 100644
index 7dda72c..0000000
--- a/core/res/res/values-mcc310-mnc380-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-de/strings.xml b/core/res/res/values-mcc310-mnc380-de/strings.xml
deleted file mode 100644
index ca03926..0000000
--- a/core/res/res/values-mcc310-mnc380-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-el/strings.xml b/core/res/res/values-mcc310-mnc380-el/strings.xml
deleted file mode 100644
index 07d0db4..0000000
--- a/core/res/res/values-mcc310-mnc380-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc380-en-rAU/strings.xml
deleted file mode 100644
index faf6df8..0000000
--- a/core/res/res/values-mcc310-mnc380-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc380-en-rGB/strings.xml
deleted file mode 100644
index faf6df8..0000000
--- a/core/res/res/values-mcc310-mnc380-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc380-en-rIN/strings.xml
deleted file mode 100644
index faf6df8..0000000
--- a/core/res/res/values-mcc310-mnc380-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc380-es-rUS/strings.xml
deleted file mode 100644
index 2335661..0000000
--- a/core/res/res/values-mcc310-mnc380-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-es/strings.xml b/core/res/res/values-mcc310-mnc380-es/strings.xml
deleted file mode 100644
index 028c265..0000000
--- a/core/res/res/values-mcc310-mnc380-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-et/strings.xml b/core/res/res/values-mcc310-mnc380-et/strings.xml
deleted file mode 100644
index c25b128..0000000
--- a/core/res/res/values-mcc310-mnc380-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-eu/strings.xml b/core/res/res/values-mcc310-mnc380-eu/strings.xml
deleted file mode 100644
index 73bcd35..0000000
--- a/core/res/res/values-mcc310-mnc380-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-fa/strings.xml b/core/res/res/values-mcc310-mnc380-fa/strings.xml
deleted file mode 100644
index b2b1126..0000000
--- a/core/res/res/values-mcc310-mnc380-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-fi/strings.xml b/core/res/res/values-mcc310-mnc380-fi/strings.xml
deleted file mode 100644
index dfb9b5f..0000000
--- a/core/res/res/values-mcc310-mnc380-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc380-fr-rCA/strings.xml
deleted file mode 100644
index 432c7a3..0000000
--- a/core/res/res/values-mcc310-mnc380-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-fr/strings.xml b/core/res/res/values-mcc310-mnc380-fr/strings.xml
deleted file mode 100644
index 2041d89..0000000
--- a/core/res/res/values-mcc310-mnc380-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-gl/strings.xml b/core/res/res/values-mcc310-mnc380-gl/strings.xml
deleted file mode 100644
index f224b92..0000000
--- a/core/res/res/values-mcc310-mnc380-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-gu/strings.xml b/core/res/res/values-mcc310-mnc380-gu/strings.xml
deleted file mode 100644
index 13df8d3..0000000
--- a/core/res/res/values-mcc310-mnc380-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-hi/strings.xml b/core/res/res/values-mcc310-mnc380-hi/strings.xml
deleted file mode 100644
index 76247af..0000000
--- a/core/res/res/values-mcc310-mnc380-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-hr/strings.xml b/core/res/res/values-mcc310-mnc380-hr/strings.xml
deleted file mode 100644
index 21263b2..0000000
--- a/core/res/res/values-mcc310-mnc380-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-hu/strings.xml b/core/res/res/values-mcc310-mnc380-hu/strings.xml
deleted file mode 100644
index bf4a40c..0000000
--- a/core/res/res/values-mcc310-mnc380-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-hy/strings.xml b/core/res/res/values-mcc310-mnc380-hy/strings.xml
deleted file mode 100644
index 1fbf283..0000000
--- a/core/res/res/values-mcc310-mnc380-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-in/strings.xml b/core/res/res/values-mcc310-mnc380-in/strings.xml
deleted file mode 100644
index 0b0ad54..0000000
--- a/core/res/res/values-mcc310-mnc380-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-is/strings.xml b/core/res/res/values-mcc310-mnc380-is/strings.xml
deleted file mode 100644
index 9df1007..0000000
--- a/core/res/res/values-mcc310-mnc380-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-it/strings.xml b/core/res/res/values-mcc310-mnc380-it/strings.xml
deleted file mode 100644
index 3800d83..0000000
--- a/core/res/res/values-mcc310-mnc380-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-iw/strings.xml b/core/res/res/values-mcc310-mnc380-iw/strings.xml
deleted file mode 100644
index 0602cb3..0000000
--- a/core/res/res/values-mcc310-mnc380-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ja/strings.xml b/core/res/res/values-mcc310-mnc380-ja/strings.xml
deleted file mode 100644
index 93aeee0..0000000
--- a/core/res/res/values-mcc310-mnc380-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ka/strings.xml b/core/res/res/values-mcc310-mnc380-ka/strings.xml
deleted file mode 100644
index 773f2ab..0000000
--- a/core/res/res/values-mcc310-mnc380-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-kk/strings.xml b/core/res/res/values-mcc310-mnc380-kk/strings.xml
deleted file mode 100644
index 8e003c2..0000000
--- a/core/res/res/values-mcc310-mnc380-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-km/strings.xml b/core/res/res/values-mcc310-mnc380-km/strings.xml
deleted file mode 100644
index eaadc8b..0000000
--- a/core/res/res/values-mcc310-mnc380-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-kn/strings.xml b/core/res/res/values-mcc310-mnc380-kn/strings.xml
deleted file mode 100644
index 3d43e9a..0000000
--- a/core/res/res/values-mcc310-mnc380-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ko/strings.xml b/core/res/res/values-mcc310-mnc380-ko/strings.xml
deleted file mode 100644
index be4f15d..0000000
--- a/core/res/res/values-mcc310-mnc380-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ky/strings.xml b/core/res/res/values-mcc310-mnc380-ky/strings.xml
deleted file mode 100644
index eb81f69..0000000
--- a/core/res/res/values-mcc310-mnc380-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-lo/strings.xml b/core/res/res/values-mcc310-mnc380-lo/strings.xml
deleted file mode 100644
index 01cd13c..0000000
--- a/core/res/res/values-mcc310-mnc380-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-lt/strings.xml b/core/res/res/values-mcc310-mnc380-lt/strings.xml
deleted file mode 100644
index e719839..0000000
--- a/core/res/res/values-mcc310-mnc380-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-lv/strings.xml b/core/res/res/values-mcc310-mnc380-lv/strings.xml
deleted file mode 100644
index ecbc518..0000000
--- a/core/res/res/values-mcc310-mnc380-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-mk/strings.xml b/core/res/res/values-mcc310-mnc380-mk/strings.xml
deleted file mode 100644
index 0cec5ab..0000000
--- a/core/res/res/values-mcc310-mnc380-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ml/strings.xml b/core/res/res/values-mcc310-mnc380-ml/strings.xml
deleted file mode 100644
index a0a84d9..0000000
--- a/core/res/res/values-mcc310-mnc380-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-mn/strings.xml b/core/res/res/values-mcc310-mnc380-mn/strings.xml
deleted file mode 100644
index a0534ce..0000000
--- a/core/res/res/values-mcc310-mnc380-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-mr/strings.xml b/core/res/res/values-mcc310-mnc380-mr/strings.xml
deleted file mode 100644
index 0541893..0000000
--- a/core/res/res/values-mcc310-mnc380-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ms/strings.xml b/core/res/res/values-mcc310-mnc380-ms/strings.xml
deleted file mode 100644
index 545ff3f..0000000
--- a/core/res/res/values-mcc310-mnc380-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-my/strings.xml b/core/res/res/values-mcc310-mnc380-my/strings.xml
deleted file mode 100644
index a375b04..0000000
--- a/core/res/res/values-mcc310-mnc380-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-nb/strings.xml b/core/res/res/values-mcc310-mnc380-nb/strings.xml
deleted file mode 100644
index 7fc96f0..0000000
--- a/core/res/res/values-mcc310-mnc380-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ne/strings.xml b/core/res/res/values-mcc310-mnc380-ne/strings.xml
deleted file mode 100644
index 28cdcba..0000000
--- a/core/res/res/values-mcc310-mnc380-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-nl/strings.xml b/core/res/res/values-mcc310-mnc380-nl/strings.xml
deleted file mode 100644
index 33bc4b6..0000000
--- a/core/res/res/values-mcc310-mnc380-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-pl/strings.xml b/core/res/res/values-mcc310-mnc380-pl/strings.xml
deleted file mode 100644
index df5b5d2..0000000
--- a/core/res/res/values-mcc310-mnc380-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc380-pt-rBR/strings.xml
deleted file mode 100644
index 06bc55a..0000000
--- a/core/res/res/values-mcc310-mnc380-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc380-pt-rPT/strings.xml
deleted file mode 100644
index 06bc55a..0000000
--- a/core/res/res/values-mcc310-mnc380-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-pt/strings.xml b/core/res/res/values-mcc310-mnc380-pt/strings.xml
deleted file mode 100644
index 06bc55a..0000000
--- a/core/res/res/values-mcc310-mnc380-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ro/strings.xml b/core/res/res/values-mcc310-mnc380-ro/strings.xml
deleted file mode 100644
index 218dec4..0000000
--- a/core/res/res/values-mcc310-mnc380-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ru/strings.xml b/core/res/res/values-mcc310-mnc380-ru/strings.xml
deleted file mode 100644
index ab3bb21..0000000
--- a/core/res/res/values-mcc310-mnc380-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-si/strings.xml b/core/res/res/values-mcc310-mnc380-si/strings.xml
deleted file mode 100644
index be471a3..0000000
--- a/core/res/res/values-mcc310-mnc380-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sk/strings.xml b/core/res/res/values-mcc310-mnc380-sk/strings.xml
deleted file mode 100644
index 91454e6..0000000
--- a/core/res/res/values-mcc310-mnc380-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sl/strings.xml b/core/res/res/values-mcc310-mnc380-sl/strings.xml
deleted file mode 100644
index 1d29a78..0000000
--- a/core/res/res/values-mcc310-mnc380-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sq/strings.xml b/core/res/res/values-mcc310-mnc380-sq/strings.xml
deleted file mode 100644
index c50b1dc..0000000
--- a/core/res/res/values-mcc310-mnc380-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sr/strings.xml b/core/res/res/values-mcc310-mnc380-sr/strings.xml
deleted file mode 100644
index e43d25f..0000000
--- a/core/res/res/values-mcc310-mnc380-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sv/strings.xml b/core/res/res/values-mcc310-mnc380-sv/strings.xml
deleted file mode 100644
index 213d26e..0000000
--- a/core/res/res/values-mcc310-mnc380-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-sw/strings.xml b/core/res/res/values-mcc310-mnc380-sw/strings.xml
deleted file mode 100644
index 249dcb3..0000000
--- a/core/res/res/values-mcc310-mnc380-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ta/strings.xml b/core/res/res/values-mcc310-mnc380-ta/strings.xml
deleted file mode 100644
index d673f22..0000000
--- a/core/res/res/values-mcc310-mnc380-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-th/strings.xml b/core/res/res/values-mcc310-mnc380-th/strings.xml
deleted file mode 100644
index 06bfa56..0000000
--- a/core/res/res/values-mcc310-mnc380-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-tl/strings.xml b/core/res/res/values-mcc310-mnc380-tl/strings.xml
deleted file mode 100644
index 52e6edb..0000000
--- a/core/res/res/values-mcc310-mnc380-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-tr/strings.xml b/core/res/res/values-mcc310-mnc380-tr/strings.xml
deleted file mode 100644
index c59a8b5..0000000
--- a/core/res/res/values-mcc310-mnc380-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-uk/strings.xml b/core/res/res/values-mcc310-mnc380-uk/strings.xml
deleted file mode 100644
index c1b5a02..0000000
--- a/core/res/res/values-mcc310-mnc380-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-ur/strings.xml b/core/res/res/values-mcc310-mnc380-ur/strings.xml
deleted file mode 100644
index 1e68214..0000000
--- a/core/res/res/values-mcc310-mnc380-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-uz/strings.xml b/core/res/res/values-mcc310-mnc380-uz/strings.xml
deleted file mode 100644
index 89de07c..0000000
--- a/core/res/res/values-mcc310-mnc380-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-vi/strings.xml b/core/res/res/values-mcc310-mnc380-vi/strings.xml
deleted file mode 100644
index 200da73..0000000
--- a/core/res/res/values-mcc310-mnc380-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc380-zh-rCN/strings.xml
deleted file mode 100644
index b150645..0000000
--- a/core/res/res/values-mcc310-mnc380-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc380-zh-rHK/strings.xml
deleted file mode 100644
index 7a7f225..0000000
--- a/core/res/res/values-mcc310-mnc380-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc380-zh-rTW/strings.xml
deleted file mode 100644
index 7a7f225..0000000
--- a/core/res/res/values-mcc310-mnc380-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc380-zu/strings.xml b/core/res/res/values-mcc310-mnc380-zu/strings.xml
deleted file mode 100644
index e795a46..0000000
--- a/core/res/res/values-mcc310-mnc380-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="6933439408719203102">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="6367773216941648568">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-af/strings.xml b/core/res/res/values-mcc310-mnc410-af/strings.xml
deleted file mode 100644
index 81688f1..0000000
--- a/core/res/res/values-mcc310-mnc410-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-am/strings.xml b/core/res/res/values-mcc310-mnc410-am/strings.xml
deleted file mode 100644
index 176a628..0000000
--- a/core/res/res/values-mcc310-mnc410-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ar/strings.xml b/core/res/res/values-mcc310-mnc410-ar/strings.xml
deleted file mode 100644
index 884e18e..0000000
--- a/core/res/res/values-mcc310-mnc410-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-az/strings.xml b/core/res/res/values-mcc310-mnc410-az/strings.xml
deleted file mode 100644
index 178451c..0000000
--- a/core/res/res/values-mcc310-mnc410-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-bg/strings.xml b/core/res/res/values-mcc310-mnc410-bg/strings.xml
deleted file mode 100644
index fc6f3e5..0000000
--- a/core/res/res/values-mcc310-mnc410-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ca/strings.xml b/core/res/res/values-mcc310-mnc410-ca/strings.xml
deleted file mode 100644
index 19ab945b..0000000
--- a/core/res/res/values-mcc310-mnc410-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-cs/strings.xml b/core/res/res/values-mcc310-mnc410-cs/strings.xml
deleted file mode 100644
index 3e36325..0000000
--- a/core/res/res/values-mcc310-mnc410-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-da/strings.xml b/core/res/res/values-mcc310-mnc410-da/strings.xml
deleted file mode 100644
index e99ab57..0000000
--- a/core/res/res/values-mcc310-mnc410-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-de/strings.xml b/core/res/res/values-mcc310-mnc410-de/strings.xml
deleted file mode 100644
index c5f64f4..0000000
--- a/core/res/res/values-mcc310-mnc410-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-el/strings.xml b/core/res/res/values-mcc310-mnc410-el/strings.xml
deleted file mode 100644
index 128d1bf..0000000
--- a/core/res/res/values-mcc310-mnc410-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
deleted file mode 100644
index eb56351..0000000
--- a/core/res/res/values-mcc310-mnc410-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
deleted file mode 100644
index eb56351..0000000
--- a/core/res/res/values-mcc310-mnc410-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
deleted file mode 100644
index eb56351..0000000
--- a/core/res/res/values-mcc310-mnc410-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
deleted file mode 100644
index 85b0344..0000000
--- a/core/res/res/values-mcc310-mnc410-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-es/strings.xml b/core/res/res/values-mcc310-mnc410-es/strings.xml
deleted file mode 100644
index 248069e..0000000
--- a/core/res/res/values-mcc310-mnc410-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-et/strings.xml b/core/res/res/values-mcc310-mnc410-et/strings.xml
deleted file mode 100644
index 6ef7802..0000000
--- a/core/res/res/values-mcc310-mnc410-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
deleted file mode 100644
index 966511b..0000000
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-fa/strings.xml b/core/res/res/values-mcc310-mnc410-fa/strings.xml
deleted file mode 100644
index 82f6272..0000000
--- a/core/res/res/values-mcc310-mnc410-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-fi/strings.xml b/core/res/res/values-mcc310-mnc410-fi/strings.xml
deleted file mode 100644
index c5a4ef6..0000000
--- a/core/res/res/values-mcc310-mnc410-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
deleted file mode 100644
index cec2491..0000000
--- a/core/res/res/values-mcc310-mnc410-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-fr/strings.xml b/core/res/res/values-mcc310-mnc410-fr/strings.xml
deleted file mode 100644
index f715e71..0000000
--- a/core/res/res/values-mcc310-mnc410-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-gl/strings.xml b/core/res/res/values-mcc310-mnc410-gl/strings.xml
deleted file mode 100644
index c3aba8e..0000000
--- a/core/res/res/values-mcc310-mnc410-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-gu/strings.xml b/core/res/res/values-mcc310-mnc410-gu/strings.xml
deleted file mode 100644
index 26898f4..0000000
--- a/core/res/res/values-mcc310-mnc410-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-hi/strings.xml b/core/res/res/values-mcc310-mnc410-hi/strings.xml
deleted file mode 100644
index a01845a..0000000
--- a/core/res/res/values-mcc310-mnc410-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-hr/strings.xml b/core/res/res/values-mcc310-mnc410-hr/strings.xml
deleted file mode 100644
index 47062c4..0000000
--- a/core/res/res/values-mcc310-mnc410-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-hu/strings.xml b/core/res/res/values-mcc310-mnc410-hu/strings.xml
deleted file mode 100644
index 194d865..0000000
--- a/core/res/res/values-mcc310-mnc410-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-hy/strings.xml b/core/res/res/values-mcc310-mnc410-hy/strings.xml
deleted file mode 100644
index 85129cc..0000000
--- a/core/res/res/values-mcc310-mnc410-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-in/strings.xml b/core/res/res/values-mcc310-mnc410-in/strings.xml
deleted file mode 100644
index c065221..0000000
--- a/core/res/res/values-mcc310-mnc410-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-is/strings.xml b/core/res/res/values-mcc310-mnc410-is/strings.xml
deleted file mode 100644
index a40a643..0000000
--- a/core/res/res/values-mcc310-mnc410-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-it/strings.xml b/core/res/res/values-mcc310-mnc410-it/strings.xml
deleted file mode 100644
index ab5c731..0000000
--- a/core/res/res/values-mcc310-mnc410-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-iw/strings.xml b/core/res/res/values-mcc310-mnc410-iw/strings.xml
deleted file mode 100644
index b675f64..0000000
--- a/core/res/res/values-mcc310-mnc410-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ja/strings.xml b/core/res/res/values-mcc310-mnc410-ja/strings.xml
deleted file mode 100644
index 1961a75b..0000000
--- a/core/res/res/values-mcc310-mnc410-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ka/strings.xml b/core/res/res/values-mcc310-mnc410-ka/strings.xml
deleted file mode 100644
index 5216e8f..0000000
--- a/core/res/res/values-mcc310-mnc410-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-kk/strings.xml b/core/res/res/values-mcc310-mnc410-kk/strings.xml
deleted file mode 100644
index 137c73a..0000000
--- a/core/res/res/values-mcc310-mnc410-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-km/strings.xml b/core/res/res/values-mcc310-mnc410-km/strings.xml
deleted file mode 100644
index 94babe1..0000000
--- a/core/res/res/values-mcc310-mnc410-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-kn/strings.xml b/core/res/res/values-mcc310-mnc410-kn/strings.xml
deleted file mode 100644
index b003dcc..0000000
--- a/core/res/res/values-mcc310-mnc410-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ko/strings.xml b/core/res/res/values-mcc310-mnc410-ko/strings.xml
deleted file mode 100644
index 7824d1e6..0000000
--- a/core/res/res/values-mcc310-mnc410-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ky/strings.xml b/core/res/res/values-mcc310-mnc410-ky/strings.xml
deleted file mode 100644
index 66cc98e..0000000
--- a/core/res/res/values-mcc310-mnc410-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-lo/strings.xml b/core/res/res/values-mcc310-mnc410-lo/strings.xml
deleted file mode 100644
index 9684e7a..0000000
--- a/core/res/res/values-mcc310-mnc410-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-lt/strings.xml b/core/res/res/values-mcc310-mnc410-lt/strings.xml
deleted file mode 100644
index c4a646a..0000000
--- a/core/res/res/values-mcc310-mnc410-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-lv/strings.xml b/core/res/res/values-mcc310-mnc410-lv/strings.xml
deleted file mode 100644
index e95d62b..0000000
--- a/core/res/res/values-mcc310-mnc410-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-mk/strings.xml b/core/res/res/values-mcc310-mnc410-mk/strings.xml
deleted file mode 100644
index 76bba96..0000000
--- a/core/res/res/values-mcc310-mnc410-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ml/strings.xml b/core/res/res/values-mcc310-mnc410-ml/strings.xml
deleted file mode 100644
index 03a4b7a..0000000
--- a/core/res/res/values-mcc310-mnc410-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-mn/strings.xml b/core/res/res/values-mcc310-mnc410-mn/strings.xml
deleted file mode 100644
index 2667aab..0000000
--- a/core/res/res/values-mcc310-mnc410-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-mr/strings.xml b/core/res/res/values-mcc310-mnc410-mr/strings.xml
deleted file mode 100644
index e7b0644..0000000
--- a/core/res/res/values-mcc310-mnc410-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ms/strings.xml b/core/res/res/values-mcc310-mnc410-ms/strings.xml
deleted file mode 100644
index 85b8621..0000000
--- a/core/res/res/values-mcc310-mnc410-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-my/strings.xml b/core/res/res/values-mcc310-mnc410-my/strings.xml
deleted file mode 100644
index faa80ec..0000000
--- a/core/res/res/values-mcc310-mnc410-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-nb/strings.xml b/core/res/res/values-mcc310-mnc410-nb/strings.xml
deleted file mode 100644
index 79be7af..0000000
--- a/core/res/res/values-mcc310-mnc410-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ne/strings.xml b/core/res/res/values-mcc310-mnc410-ne/strings.xml
deleted file mode 100644
index e270c7c..0000000
--- a/core/res/res/values-mcc310-mnc410-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-nl/strings.xml b/core/res/res/values-mcc310-mnc410-nl/strings.xml
deleted file mode 100644
index 2995beb..0000000
--- a/core/res/res/values-mcc310-mnc410-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-pl/strings.xml b/core/res/res/values-mcc310-mnc410-pl/strings.xml
deleted file mode 100644
index 8677ad6..0000000
--- a/core/res/res/values-mcc310-mnc410-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
deleted file mode 100644
index 4f41e5e..0000000
--- a/core/res/res/values-mcc310-mnc410-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
deleted file mode 100644
index 4f41e5e..0000000
--- a/core/res/res/values-mcc310-mnc410-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-pt/strings.xml b/core/res/res/values-mcc310-mnc410-pt/strings.xml
deleted file mode 100644
index 4f41e5e..0000000
--- a/core/res/res/values-mcc310-mnc410-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ro/strings.xml b/core/res/res/values-mcc310-mnc410-ro/strings.xml
deleted file mode 100644
index fea0609..0000000
--- a/core/res/res/values-mcc310-mnc410-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ru/strings.xml b/core/res/res/values-mcc310-mnc410-ru/strings.xml
deleted file mode 100644
index a00e59c..0000000
--- a/core/res/res/values-mcc310-mnc410-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-si/strings.xml b/core/res/res/values-mcc310-mnc410-si/strings.xml
deleted file mode 100644
index 8f66f3d..0000000
--- a/core/res/res/values-mcc310-mnc410-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sk/strings.xml b/core/res/res/values-mcc310-mnc410-sk/strings.xml
deleted file mode 100644
index e4d4bc6..0000000
--- a/core/res/res/values-mcc310-mnc410-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sl/strings.xml b/core/res/res/values-mcc310-mnc410-sl/strings.xml
deleted file mode 100644
index 2d03b04..0000000
--- a/core/res/res/values-mcc310-mnc410-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sq/strings.xml b/core/res/res/values-mcc310-mnc410-sq/strings.xml
deleted file mode 100644
index 51626d7..0000000
--- a/core/res/res/values-mcc310-mnc410-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sr/strings.xml b/core/res/res/values-mcc310-mnc410-sr/strings.xml
deleted file mode 100644
index b4a9006..0000000
--- a/core/res/res/values-mcc310-mnc410-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sv/strings.xml b/core/res/res/values-mcc310-mnc410-sv/strings.xml
deleted file mode 100644
index c270b04..0000000
--- a/core/res/res/values-mcc310-mnc410-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-sw/strings.xml b/core/res/res/values-mcc310-mnc410-sw/strings.xml
deleted file mode 100644
index a6e6018..0000000
--- a/core/res/res/values-mcc310-mnc410-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ta/strings.xml b/core/res/res/values-mcc310-mnc410-ta/strings.xml
deleted file mode 100644
index 4ac46ce..0000000
--- a/core/res/res/values-mcc310-mnc410-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-th/strings.xml b/core/res/res/values-mcc310-mnc410-th/strings.xml
deleted file mode 100644
index cf51029..0000000
--- a/core/res/res/values-mcc310-mnc410-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-tl/strings.xml b/core/res/res/values-mcc310-mnc410-tl/strings.xml
deleted file mode 100644
index b2aa68a..0000000
--- a/core/res/res/values-mcc310-mnc410-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-tr/strings.xml b/core/res/res/values-mcc310-mnc410-tr/strings.xml
deleted file mode 100644
index 9e5c38e..0000000
--- a/core/res/res/values-mcc310-mnc410-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-uk/strings.xml b/core/res/res/values-mcc310-mnc410-uk/strings.xml
deleted file mode 100644
index 5d74f80..0000000
--- a/core/res/res/values-mcc310-mnc410-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-ur/strings.xml b/core/res/res/values-mcc310-mnc410-ur/strings.xml
deleted file mode 100644
index 8cf16e4..0000000
--- a/core/res/res/values-mcc310-mnc410-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-uz/strings.xml b/core/res/res/values-mcc310-mnc410-uz/strings.xml
deleted file mode 100644
index 4618525..0000000
--- a/core/res/res/values-mcc310-mnc410-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-vi/strings.xml b/core/res/res/values-mcc310-mnc410-vi/strings.xml
deleted file mode 100644
index e6fc334..0000000
--- a/core/res/res/values-mcc310-mnc410-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
deleted file mode 100644
index a00316a..0000000
--- a/core/res/res/values-mcc310-mnc410-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
deleted file mode 100644
index 66a622e..0000000
--- a/core/res/res/values-mcc310-mnc410-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
deleted file mode 100644
index 66a622e..0000000
--- a/core/res/res/values-mcc310-mnc410-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc410-zu/strings.xml b/core/res/res/values-mcc310-mnc410-zu/strings.xml
deleted file mode 100644
index a52049f..0000000
--- a/core/res/res/values-mcc310-mnc410-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="376893116792604964">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="1593063035884873292">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-af/strings.xml b/core/res/res/values-mcc310-mnc560-af/strings.xml
deleted file mode 100644
index ecbb954..0000000
--- a/core/res/res/values-mcc310-mnc560-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-am/strings.xml b/core/res/res/values-mcc310-mnc560-am/strings.xml
deleted file mode 100644
index 297c059..0000000
--- a/core/res/res/values-mcc310-mnc560-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ar/strings.xml b/core/res/res/values-mcc310-mnc560-ar/strings.xml
deleted file mode 100644
index 12a06fa..0000000
--- a/core/res/res/values-mcc310-mnc560-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-az/strings.xml b/core/res/res/values-mcc310-mnc560-az/strings.xml
deleted file mode 100644
index 9acc2c1..0000000
--- a/core/res/res/values-mcc310-mnc560-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-bg/strings.xml b/core/res/res/values-mcc310-mnc560-bg/strings.xml
deleted file mode 100644
index 49c2d2f..0000000
--- a/core/res/res/values-mcc310-mnc560-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ca/strings.xml b/core/res/res/values-mcc310-mnc560-ca/strings.xml
deleted file mode 100644
index 1eac589..0000000
--- a/core/res/res/values-mcc310-mnc560-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-cs/strings.xml b/core/res/res/values-mcc310-mnc560-cs/strings.xml
deleted file mode 100644
index 4701f99..0000000
--- a/core/res/res/values-mcc310-mnc560-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-da/strings.xml b/core/res/res/values-mcc310-mnc560-da/strings.xml
deleted file mode 100644
index 2c63d87..0000000
--- a/core/res/res/values-mcc310-mnc560-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-de/strings.xml b/core/res/res/values-mcc310-mnc560-de/strings.xml
deleted file mode 100644
index e8fec2c..0000000
--- a/core/res/res/values-mcc310-mnc560-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-el/strings.xml b/core/res/res/values-mcc310-mnc560-el/strings.xml
deleted file mode 100644
index efd81f7..0000000
--- a/core/res/res/values-mcc310-mnc560-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
deleted file mode 100644
index c218c64..0000000
--- a/core/res/res/values-mcc310-mnc560-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
deleted file mode 100644
index c218c64..0000000
--- a/core/res/res/values-mcc310-mnc560-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
deleted file mode 100644
index c218c64..0000000
--- a/core/res/res/values-mcc310-mnc560-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
deleted file mode 100644
index 62d61ba..0000000
--- a/core/res/res/values-mcc310-mnc560-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-es/strings.xml b/core/res/res/values-mcc310-mnc560-es/strings.xml
deleted file mode 100644
index dbd71d5..0000000
--- a/core/res/res/values-mcc310-mnc560-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-et/strings.xml b/core/res/res/values-mcc310-mnc560-et/strings.xml
deleted file mode 100644
index b269ace..0000000
--- a/core/res/res/values-mcc310-mnc560-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-eu/strings.xml b/core/res/res/values-mcc310-mnc560-eu/strings.xml
deleted file mode 100644
index cee0106..0000000
--- a/core/res/res/values-mcc310-mnc560-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-fa/strings.xml b/core/res/res/values-mcc310-mnc560-fa/strings.xml
deleted file mode 100644
index b4683c7..0000000
--- a/core/res/res/values-mcc310-mnc560-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-fi/strings.xml b/core/res/res/values-mcc310-mnc560-fi/strings.xml
deleted file mode 100644
index 54c80ed..0000000
--- a/core/res/res/values-mcc310-mnc560-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
deleted file mode 100644
index 8b6c4ec..0000000
--- a/core/res/res/values-mcc310-mnc560-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-fr/strings.xml b/core/res/res/values-mcc310-mnc560-fr/strings.xml
deleted file mode 100644
index b52eaf7..0000000
--- a/core/res/res/values-mcc310-mnc560-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-gl/strings.xml b/core/res/res/values-mcc310-mnc560-gl/strings.xml
deleted file mode 100644
index a8c04d2..0000000
--- a/core/res/res/values-mcc310-mnc560-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-gu/strings.xml b/core/res/res/values-mcc310-mnc560-gu/strings.xml
deleted file mode 100644
index c3892da..0000000
--- a/core/res/res/values-mcc310-mnc560-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-hi/strings.xml b/core/res/res/values-mcc310-mnc560-hi/strings.xml
deleted file mode 100644
index 4e07e4f..0000000
--- a/core/res/res/values-mcc310-mnc560-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-hr/strings.xml b/core/res/res/values-mcc310-mnc560-hr/strings.xml
deleted file mode 100644
index dc6653e..0000000
--- a/core/res/res/values-mcc310-mnc560-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-hu/strings.xml b/core/res/res/values-mcc310-mnc560-hu/strings.xml
deleted file mode 100644
index 1a7a6b3..0000000
--- a/core/res/res/values-mcc310-mnc560-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-hy/strings.xml b/core/res/res/values-mcc310-mnc560-hy/strings.xml
deleted file mode 100644
index c398877..0000000
--- a/core/res/res/values-mcc310-mnc560-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-in/strings.xml b/core/res/res/values-mcc310-mnc560-in/strings.xml
deleted file mode 100644
index c3c7df3..0000000
--- a/core/res/res/values-mcc310-mnc560-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-is/strings.xml b/core/res/res/values-mcc310-mnc560-is/strings.xml
deleted file mode 100644
index 4a59abd..0000000
--- a/core/res/res/values-mcc310-mnc560-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-it/strings.xml b/core/res/res/values-mcc310-mnc560-it/strings.xml
deleted file mode 100644
index d2c966c..0000000
--- a/core/res/res/values-mcc310-mnc560-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-iw/strings.xml b/core/res/res/values-mcc310-mnc560-iw/strings.xml
deleted file mode 100644
index 68f0aa9..0000000
--- a/core/res/res/values-mcc310-mnc560-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ja/strings.xml b/core/res/res/values-mcc310-mnc560-ja/strings.xml
deleted file mode 100644
index 0429996..0000000
--- a/core/res/res/values-mcc310-mnc560-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ka/strings.xml b/core/res/res/values-mcc310-mnc560-ka/strings.xml
deleted file mode 100644
index b0371f0..0000000
--- a/core/res/res/values-mcc310-mnc560-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-kk/strings.xml b/core/res/res/values-mcc310-mnc560-kk/strings.xml
deleted file mode 100644
index 2015f8c..0000000
--- a/core/res/res/values-mcc310-mnc560-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-km/strings.xml b/core/res/res/values-mcc310-mnc560-km/strings.xml
deleted file mode 100644
index a13ca7d..0000000
--- a/core/res/res/values-mcc310-mnc560-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-kn/strings.xml b/core/res/res/values-mcc310-mnc560-kn/strings.xml
deleted file mode 100644
index da75904..0000000
--- a/core/res/res/values-mcc310-mnc560-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ko/strings.xml b/core/res/res/values-mcc310-mnc560-ko/strings.xml
deleted file mode 100644
index ee71a09c..0000000
--- a/core/res/res/values-mcc310-mnc560-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ky/strings.xml b/core/res/res/values-mcc310-mnc560-ky/strings.xml
deleted file mode 100644
index 00fc1c4..0000000
--- a/core/res/res/values-mcc310-mnc560-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-lo/strings.xml b/core/res/res/values-mcc310-mnc560-lo/strings.xml
deleted file mode 100644
index 702470e..0000000
--- a/core/res/res/values-mcc310-mnc560-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-lt/strings.xml b/core/res/res/values-mcc310-mnc560-lt/strings.xml
deleted file mode 100644
index c3c5a9e..0000000
--- a/core/res/res/values-mcc310-mnc560-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-lv/strings.xml b/core/res/res/values-mcc310-mnc560-lv/strings.xml
deleted file mode 100644
index dcf7805..0000000
--- a/core/res/res/values-mcc310-mnc560-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-mk/strings.xml b/core/res/res/values-mcc310-mnc560-mk/strings.xml
deleted file mode 100644
index cf0ae7e..0000000
--- a/core/res/res/values-mcc310-mnc560-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ml/strings.xml b/core/res/res/values-mcc310-mnc560-ml/strings.xml
deleted file mode 100644
index 379d438..0000000
--- a/core/res/res/values-mcc310-mnc560-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-mn/strings.xml b/core/res/res/values-mcc310-mnc560-mn/strings.xml
deleted file mode 100644
index 0bf1599..0000000
--- a/core/res/res/values-mcc310-mnc560-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-mr/strings.xml b/core/res/res/values-mcc310-mnc560-mr/strings.xml
deleted file mode 100644
index 69e81ad..0000000
--- a/core/res/res/values-mcc310-mnc560-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ms/strings.xml b/core/res/res/values-mcc310-mnc560-ms/strings.xml
deleted file mode 100644
index cd0aed7..0000000
--- a/core/res/res/values-mcc310-mnc560-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-my/strings.xml b/core/res/res/values-mcc310-mnc560-my/strings.xml
deleted file mode 100644
index 58fba87..0000000
--- a/core/res/res/values-mcc310-mnc560-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-nb/strings.xml b/core/res/res/values-mcc310-mnc560-nb/strings.xml
deleted file mode 100644
index bc90ae1..0000000
--- a/core/res/res/values-mcc310-mnc560-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ne/strings.xml b/core/res/res/values-mcc310-mnc560-ne/strings.xml
deleted file mode 100644
index 75c493d..0000000
--- a/core/res/res/values-mcc310-mnc560-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-nl/strings.xml b/core/res/res/values-mcc310-mnc560-nl/strings.xml
deleted file mode 100644
index 7241627..0000000
--- a/core/res/res/values-mcc310-mnc560-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-pl/strings.xml b/core/res/res/values-mcc310-mnc560-pl/strings.xml
deleted file mode 100644
index f844db6..0000000
--- a/core/res/res/values-mcc310-mnc560-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
deleted file mode 100644
index 4c10ef9..0000000
--- a/core/res/res/values-mcc310-mnc560-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
deleted file mode 100644
index 4c10ef9..0000000
--- a/core/res/res/values-mcc310-mnc560-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-pt/strings.xml b/core/res/res/values-mcc310-mnc560-pt/strings.xml
deleted file mode 100644
index 4c10ef9..0000000
--- a/core/res/res/values-mcc310-mnc560-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ro/strings.xml b/core/res/res/values-mcc310-mnc560-ro/strings.xml
deleted file mode 100644
index e24b74c..0000000
--- a/core/res/res/values-mcc310-mnc560-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ru/strings.xml b/core/res/res/values-mcc310-mnc560-ru/strings.xml
deleted file mode 100644
index 35bf36f..0000000
--- a/core/res/res/values-mcc310-mnc560-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-si/strings.xml b/core/res/res/values-mcc310-mnc560-si/strings.xml
deleted file mode 100644
index 4c60ce4..0000000
--- a/core/res/res/values-mcc310-mnc560-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sk/strings.xml b/core/res/res/values-mcc310-mnc560-sk/strings.xml
deleted file mode 100644
index ad4aba4..0000000
--- a/core/res/res/values-mcc310-mnc560-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sl/strings.xml b/core/res/res/values-mcc310-mnc560-sl/strings.xml
deleted file mode 100644
index 7855987..0000000
--- a/core/res/res/values-mcc310-mnc560-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sq/strings.xml b/core/res/res/values-mcc310-mnc560-sq/strings.xml
deleted file mode 100644
index 527430e..0000000
--- a/core/res/res/values-mcc310-mnc560-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sr/strings.xml b/core/res/res/values-mcc310-mnc560-sr/strings.xml
deleted file mode 100644
index ec5a2b6..0000000
--- a/core/res/res/values-mcc310-mnc560-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sv/strings.xml b/core/res/res/values-mcc310-mnc560-sv/strings.xml
deleted file mode 100644
index d113989..0000000
--- a/core/res/res/values-mcc310-mnc560-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-sw/strings.xml b/core/res/res/values-mcc310-mnc560-sw/strings.xml
deleted file mode 100644
index 4e3df8b..0000000
--- a/core/res/res/values-mcc310-mnc560-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ta/strings.xml b/core/res/res/values-mcc310-mnc560-ta/strings.xml
deleted file mode 100644
index 78f8243..0000000
--- a/core/res/res/values-mcc310-mnc560-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-th/strings.xml b/core/res/res/values-mcc310-mnc560-th/strings.xml
deleted file mode 100644
index 7896973..0000000
--- a/core/res/res/values-mcc310-mnc560-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-tl/strings.xml b/core/res/res/values-mcc310-mnc560-tl/strings.xml
deleted file mode 100644
index ac87cb5..0000000
--- a/core/res/res/values-mcc310-mnc560-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-tr/strings.xml b/core/res/res/values-mcc310-mnc560-tr/strings.xml
deleted file mode 100644
index 5ea1d80..0000000
--- a/core/res/res/values-mcc310-mnc560-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-uk/strings.xml b/core/res/res/values-mcc310-mnc560-uk/strings.xml
deleted file mode 100644
index 7ee6b88..0000000
--- a/core/res/res/values-mcc310-mnc560-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-ur/strings.xml b/core/res/res/values-mcc310-mnc560-ur/strings.xml
deleted file mode 100644
index 609d3e8..0000000
--- a/core/res/res/values-mcc310-mnc560-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-uz/strings.xml b/core/res/res/values-mcc310-mnc560-uz/strings.xml
deleted file mode 100644
index 4157041..0000000
--- a/core/res/res/values-mcc310-mnc560-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-vi/strings.xml b/core/res/res/values-mcc310-mnc560-vi/strings.xml
deleted file mode 100644
index b2284e1..0000000
--- a/core/res/res/values-mcc310-mnc560-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
deleted file mode 100644
index 050ea01..0000000
--- a/core/res/res/values-mcc310-mnc560-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
deleted file mode 100644
index 43cfc01..0000000
--- a/core/res/res/values-mcc310-mnc560-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
deleted file mode 100644
index 43cfc01..0000000
--- a/core/res/res/values-mcc310-mnc560-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc560-zu/strings.xml b/core/res/res/values-mcc310-mnc560-zu/strings.xml
deleted file mode 100644
index e1b7abb..0000000
--- a/core/res/res/values-mcc310-mnc560-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="2976453378311251765">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2519618694918727742">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-af/strings.xml b/core/res/res/values-mcc310-mnc950-af/strings.xml
deleted file mode 100644
index 19ae78d..0000000
--- a/core/res/res/values-mcc310-mnc950-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-am/strings.xml b/core/res/res/values-mcc310-mnc950-am/strings.xml
deleted file mode 100644
index e81745d..0000000
--- a/core/res/res/values-mcc310-mnc950-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ar/strings.xml b/core/res/res/values-mcc310-mnc950-ar/strings.xml
deleted file mode 100644
index 1aab01c..0000000
--- a/core/res/res/values-mcc310-mnc950-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-az/strings.xml b/core/res/res/values-mcc310-mnc950-az/strings.xml
deleted file mode 100644
index 26d91ef..0000000
--- a/core/res/res/values-mcc310-mnc950-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-bg/strings.xml b/core/res/res/values-mcc310-mnc950-bg/strings.xml
deleted file mode 100644
index 761b439..0000000
--- a/core/res/res/values-mcc310-mnc950-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ca/strings.xml b/core/res/res/values-mcc310-mnc950-ca/strings.xml
deleted file mode 100644
index 9b77ce7..0000000
--- a/core/res/res/values-mcc310-mnc950-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-cs/strings.xml b/core/res/res/values-mcc310-mnc950-cs/strings.xml
deleted file mode 100644
index 3f8b8aa..0000000
--- a/core/res/res/values-mcc310-mnc950-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-da/strings.xml b/core/res/res/values-mcc310-mnc950-da/strings.xml
deleted file mode 100644
index 6cd8306..0000000
--- a/core/res/res/values-mcc310-mnc950-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-de/strings.xml b/core/res/res/values-mcc310-mnc950-de/strings.xml
deleted file mode 100644
index 70e3068..0000000
--- a/core/res/res/values-mcc310-mnc950-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-el/strings.xml b/core/res/res/values-mcc310-mnc950-el/strings.xml
deleted file mode 100644
index 1a2542c..0000000
--- a/core/res/res/values-mcc310-mnc950-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
deleted file mode 100644
index 7ef6605..0000000
--- a/core/res/res/values-mcc310-mnc950-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
deleted file mode 100644
index 7ef6605..0000000
--- a/core/res/res/values-mcc310-mnc950-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
deleted file mode 100644
index 7ef6605..0000000
--- a/core/res/res/values-mcc310-mnc950-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
deleted file mode 100644
index 31a863c..0000000
--- a/core/res/res/values-mcc310-mnc950-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-es/strings.xml b/core/res/res/values-mcc310-mnc950-es/strings.xml
deleted file mode 100644
index ba8c78b..0000000
--- a/core/res/res/values-mcc310-mnc950-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-et/strings.xml b/core/res/res/values-mcc310-mnc950-et/strings.xml
deleted file mode 100644
index 013243a..0000000
--- a/core/res/res/values-mcc310-mnc950-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
deleted file mode 100644
index 097e423..0000000
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-fa/strings.xml b/core/res/res/values-mcc310-mnc950-fa/strings.xml
deleted file mode 100644
index 3281bb5..0000000
--- a/core/res/res/values-mcc310-mnc950-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-fi/strings.xml b/core/res/res/values-mcc310-mnc950-fi/strings.xml
deleted file mode 100644
index 01e04f7..0000000
--- a/core/res/res/values-mcc310-mnc950-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
deleted file mode 100644
index a310f82..0000000
--- a/core/res/res/values-mcc310-mnc950-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-fr/strings.xml b/core/res/res/values-mcc310-mnc950-fr/strings.xml
deleted file mode 100644
index 7b0fb2c..0000000
--- a/core/res/res/values-mcc310-mnc950-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-gl/strings.xml b/core/res/res/values-mcc310-mnc950-gl/strings.xml
deleted file mode 100644
index 55ff461..0000000
--- a/core/res/res/values-mcc310-mnc950-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-gu/strings.xml b/core/res/res/values-mcc310-mnc950-gu/strings.xml
deleted file mode 100644
index a6e1a83..0000000
--- a/core/res/res/values-mcc310-mnc950-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-hi/strings.xml b/core/res/res/values-mcc310-mnc950-hi/strings.xml
deleted file mode 100644
index 41b9bc9..0000000
--- a/core/res/res/values-mcc310-mnc950-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-hr/strings.xml b/core/res/res/values-mcc310-mnc950-hr/strings.xml
deleted file mode 100644
index 1c39a09..0000000
--- a/core/res/res/values-mcc310-mnc950-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-hu/strings.xml b/core/res/res/values-mcc310-mnc950-hu/strings.xml
deleted file mode 100644
index 6b8ee76..0000000
--- a/core/res/res/values-mcc310-mnc950-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-hy/strings.xml b/core/res/res/values-mcc310-mnc950-hy/strings.xml
deleted file mode 100644
index 63dfa46..0000000
--- a/core/res/res/values-mcc310-mnc950-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-in/strings.xml b/core/res/res/values-mcc310-mnc950-in/strings.xml
deleted file mode 100644
index a7c0232..0000000
--- a/core/res/res/values-mcc310-mnc950-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-is/strings.xml b/core/res/res/values-mcc310-mnc950-is/strings.xml
deleted file mode 100644
index ceee15a..0000000
--- a/core/res/res/values-mcc310-mnc950-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-it/strings.xml b/core/res/res/values-mcc310-mnc950-it/strings.xml
deleted file mode 100644
index 21e2a4a..0000000
--- a/core/res/res/values-mcc310-mnc950-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-iw/strings.xml b/core/res/res/values-mcc310-mnc950-iw/strings.xml
deleted file mode 100644
index 041408f..0000000
--- a/core/res/res/values-mcc310-mnc950-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ja/strings.xml b/core/res/res/values-mcc310-mnc950-ja/strings.xml
deleted file mode 100644
index 97f697e..0000000
--- a/core/res/res/values-mcc310-mnc950-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ka/strings.xml b/core/res/res/values-mcc310-mnc950-ka/strings.xml
deleted file mode 100644
index 4d8c8a8..0000000
--- a/core/res/res/values-mcc310-mnc950-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-kk/strings.xml b/core/res/res/values-mcc310-mnc950-kk/strings.xml
deleted file mode 100644
index 899a9a2..0000000
--- a/core/res/res/values-mcc310-mnc950-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-km/strings.xml b/core/res/res/values-mcc310-mnc950-km/strings.xml
deleted file mode 100644
index 3c80d9f..0000000
--- a/core/res/res/values-mcc310-mnc950-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-kn/strings.xml b/core/res/res/values-mcc310-mnc950-kn/strings.xml
deleted file mode 100644
index 1c7ab20..0000000
--- a/core/res/res/values-mcc310-mnc950-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ko/strings.xml b/core/res/res/values-mcc310-mnc950-ko/strings.xml
deleted file mode 100644
index 2419c2a..0000000
--- a/core/res/res/values-mcc310-mnc950-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ky/strings.xml b/core/res/res/values-mcc310-mnc950-ky/strings.xml
deleted file mode 100644
index fb7efbb..0000000
--- a/core/res/res/values-mcc310-mnc950-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-lo/strings.xml b/core/res/res/values-mcc310-mnc950-lo/strings.xml
deleted file mode 100644
index b69536f..0000000
--- a/core/res/res/values-mcc310-mnc950-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-lt/strings.xml b/core/res/res/values-mcc310-mnc950-lt/strings.xml
deleted file mode 100644
index 8ef0869..0000000
--- a/core/res/res/values-mcc310-mnc950-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-lv/strings.xml b/core/res/res/values-mcc310-mnc950-lv/strings.xml
deleted file mode 100644
index 2a491c0..0000000
--- a/core/res/res/values-mcc310-mnc950-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-mk/strings.xml b/core/res/res/values-mcc310-mnc950-mk/strings.xml
deleted file mode 100644
index a1da44b..0000000
--- a/core/res/res/values-mcc310-mnc950-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ml/strings.xml b/core/res/res/values-mcc310-mnc950-ml/strings.xml
deleted file mode 100644
index 4a04194..0000000
--- a/core/res/res/values-mcc310-mnc950-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-mn/strings.xml b/core/res/res/values-mcc310-mnc950-mn/strings.xml
deleted file mode 100644
index 2d4b5f5..0000000
--- a/core/res/res/values-mcc310-mnc950-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-mr/strings.xml b/core/res/res/values-mcc310-mnc950-mr/strings.xml
deleted file mode 100644
index eca7dca..0000000
--- a/core/res/res/values-mcc310-mnc950-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ms/strings.xml b/core/res/res/values-mcc310-mnc950-ms/strings.xml
deleted file mode 100644
index 4f5c781..0000000
--- a/core/res/res/values-mcc310-mnc950-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-my/strings.xml b/core/res/res/values-mcc310-mnc950-my/strings.xml
deleted file mode 100644
index ecf9f61..0000000
--- a/core/res/res/values-mcc310-mnc950-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-nb/strings.xml b/core/res/res/values-mcc310-mnc950-nb/strings.xml
deleted file mode 100644
index 907482e..0000000
--- a/core/res/res/values-mcc310-mnc950-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ne/strings.xml b/core/res/res/values-mcc310-mnc950-ne/strings.xml
deleted file mode 100644
index 380f01c..0000000
--- a/core/res/res/values-mcc310-mnc950-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-nl/strings.xml b/core/res/res/values-mcc310-mnc950-nl/strings.xml
deleted file mode 100644
index a01896c..0000000
--- a/core/res/res/values-mcc310-mnc950-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-pl/strings.xml b/core/res/res/values-mcc310-mnc950-pl/strings.xml
deleted file mode 100644
index ce40c22..0000000
--- a/core/res/res/values-mcc310-mnc950-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
deleted file mode 100644
index 1f89e47..0000000
--- a/core/res/res/values-mcc310-mnc950-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
deleted file mode 100644
index 1f89e47..0000000
--- a/core/res/res/values-mcc310-mnc950-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-pt/strings.xml b/core/res/res/values-mcc310-mnc950-pt/strings.xml
deleted file mode 100644
index 1f89e47..0000000
--- a/core/res/res/values-mcc310-mnc950-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ro/strings.xml b/core/res/res/values-mcc310-mnc950-ro/strings.xml
deleted file mode 100644
index 7fb3f2e..0000000
--- a/core/res/res/values-mcc310-mnc950-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ru/strings.xml b/core/res/res/values-mcc310-mnc950-ru/strings.xml
deleted file mode 100644
index 16deeed..0000000
--- a/core/res/res/values-mcc310-mnc950-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-si/strings.xml b/core/res/res/values-mcc310-mnc950-si/strings.xml
deleted file mode 100644
index dd512d9..0000000
--- a/core/res/res/values-mcc310-mnc950-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sk/strings.xml b/core/res/res/values-mcc310-mnc950-sk/strings.xml
deleted file mode 100644
index 6a8e6f0..0000000
--- a/core/res/res/values-mcc310-mnc950-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sl/strings.xml b/core/res/res/values-mcc310-mnc950-sl/strings.xml
deleted file mode 100644
index 391ee78..0000000
--- a/core/res/res/values-mcc310-mnc950-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sq/strings.xml b/core/res/res/values-mcc310-mnc950-sq/strings.xml
deleted file mode 100644
index ebc978c..0000000
--- a/core/res/res/values-mcc310-mnc950-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sr/strings.xml b/core/res/res/values-mcc310-mnc950-sr/strings.xml
deleted file mode 100644
index 4f3f86f..0000000
--- a/core/res/res/values-mcc310-mnc950-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sv/strings.xml b/core/res/res/values-mcc310-mnc950-sv/strings.xml
deleted file mode 100644
index 4739f06..0000000
--- a/core/res/res/values-mcc310-mnc950-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-sw/strings.xml b/core/res/res/values-mcc310-mnc950-sw/strings.xml
deleted file mode 100644
index 903b4a5..0000000
--- a/core/res/res/values-mcc310-mnc950-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ta/strings.xml b/core/res/res/values-mcc310-mnc950-ta/strings.xml
deleted file mode 100644
index 8838aed..0000000
--- a/core/res/res/values-mcc310-mnc950-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-th/strings.xml b/core/res/res/values-mcc310-mnc950-th/strings.xml
deleted file mode 100644
index 3feb1f6..0000000
--- a/core/res/res/values-mcc310-mnc950-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-tl/strings.xml b/core/res/res/values-mcc310-mnc950-tl/strings.xml
deleted file mode 100644
index 55e0bfd..0000000
--- a/core/res/res/values-mcc310-mnc950-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-tr/strings.xml b/core/res/res/values-mcc310-mnc950-tr/strings.xml
deleted file mode 100644
index 7a274a4..0000000
--- a/core/res/res/values-mcc310-mnc950-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-uk/strings.xml b/core/res/res/values-mcc310-mnc950-uk/strings.xml
deleted file mode 100644
index bf5e6411..0000000
--- a/core/res/res/values-mcc310-mnc950-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-ur/strings.xml b/core/res/res/values-mcc310-mnc950-ur/strings.xml
deleted file mode 100644
index 35857cd..0000000
--- a/core/res/res/values-mcc310-mnc950-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-uz/strings.xml b/core/res/res/values-mcc310-mnc950-uz/strings.xml
deleted file mode 100644
index e31c7b6..0000000
--- a/core/res/res/values-mcc310-mnc950-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-vi/strings.xml b/core/res/res/values-mcc310-mnc950-vi/strings.xml
deleted file mode 100644
index b9360b5..0000000
--- a/core/res/res/values-mcc310-mnc950-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
deleted file mode 100644
index 3b4ba0a..0000000
--- a/core/res/res/values-mcc310-mnc950-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
deleted file mode 100644
index 763e498..0000000
--- a/core/res/res/values-mcc310-mnc950-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
deleted file mode 100644
index 763e498..0000000
--- a/core/res/res/values-mcc310-mnc950-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc310-mnc950-zu/strings.xml b/core/res/res/values-mcc310-mnc950-zu/strings.xml
deleted file mode 100644
index 1c29754..0000000
--- a/core/res/res/values-mcc310-mnc950-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="94675382531896663">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="2418195136279399212">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-af/strings.xml b/core/res/res/values-mcc311-mnc180-af/strings.xml
deleted file mode 100644
index ead8992..0000000
--- a/core/res/res/values-mcc311-mnc180-af/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM is nie opgestel nie MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM word nie toegelaat nie MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-am/strings.xml b/core/res/res/values-mcc311-mnc180-am/strings.xml
deleted file mode 100644
index a7d0d1d..0000000
--- a/core/res/res/values-mcc311-mnc180-am/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ሲም አልቀረበም MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"ሲም አይፈቀድም MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ar/strings.xml b/core/res/res/values-mcc311-mnc180-ar/strings.xml
deleted file mode 100644
index f5412bd..0000000
--- a/core/res/res/values-mcc311-mnc180-ar/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏لم يتم توفير SIM ‏MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏غير مسموح باستخدام SIM ‏MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-az/strings.xml b/core/res/res/values-mcc311-mnc180-az/strings.xml
deleted file mode 100644
index c2c06be..0000000
--- a/core/res/res/values-mcc311-mnc180-az/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 təmin etmir"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 dəstəkləmir"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-bg/strings.xml b/core/res/res/values-mcc311-mnc180-bg/strings.xml
deleted file mode 100644
index faf5a42..0000000
--- a/core/res/res/values-mcc311-mnc180-bg/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картата не е обезпечена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картата не е разрешена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ca/strings.xml b/core/res/res/values-mcc311-mnc180-ca/strings.xml
deleted file mode 100644
index e33a901..0000000
--- a/core/res/res/values-mcc311-mnc180-ca/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"La SIM no està proporcionada a MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"La SIM no és compatible a MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-cs/strings.xml b/core/res/res/values-mcc311-mnc180-cs/strings.xml
deleted file mode 100644
index 653a55a..0000000
--- a/core/res/res/values-mcc311-mnc180-cs/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta není poskytována (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta není povolena (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-da/strings.xml b/core/res/res/values-mcc311-mnc180-da/strings.xml
deleted file mode 100644
index 04c89a5..0000000
--- a/core/res/res/values-mcc311-mnc180-da/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort leveres ikke MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort er ikke tilladt MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-de/strings.xml b/core/res/res/values-mcc311-mnc180-de/strings.xml
deleted file mode 100644
index 8fef081..0000000
--- a/core/res/res/values-mcc311-mnc180-de/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-Karte nicht eingerichtet MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-Karte nicht zulässig MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-el/strings.xml b/core/res/res/values-mcc311-mnc180-el/strings.xml
deleted file mode 100644
index 795f48f..0000000
--- a/core/res/res/values-mcc311-mnc180-el/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Δεν παρέχεται κάρτα SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Η κάρτα SIM δεν επιτρέπεται MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml b/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
deleted file mode 100644
index 9c972bc..0000000
--- a/core/res/res/values-mcc311-mnc180-en-rAU/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml b/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
deleted file mode 100644
index 9c972bc..0000000
--- a/core/res/res/values-mcc311-mnc180-en-rGB/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml b/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
deleted file mode 100644
index 9c972bc..0000000
--- a/core/res/res/values-mcc311-mnc180-en-rIN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM not provisioned MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM not allowed MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml b/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
deleted file mode 100644
index 694cd76..0000000
--- a/core/res/res/values-mcc311-mnc180-es-rUS/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no provista MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no permitida MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-es/strings.xml b/core/res/res/values-mcc311-mnc180-es/strings.xml
deleted file mode 100644
index 605e314..0000000
--- a/core/res/res/values-mcc311-mnc180-es/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM no proporcionada (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM no admitida (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-et/strings.xml b/core/res/res/values-mcc311-mnc180-et/strings.xml
deleted file mode 100644
index 39dfa1b..0000000
--- a/core/res/res/values-mcc311-mnc180-et/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kaart on ette valmistamata MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kaart pole lubatud MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
deleted file mode 100644
index 84732c9..0000000
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ez dago SIM txartelik MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Ez da onartzen SIM txartela MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-fa/strings.xml b/core/res/res/values-mcc311-mnc180-fa/strings.xml
deleted file mode 100644
index 902d821..0000000
--- a/core/res/res/values-mcc311-mnc180-fa/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏سیم‌کارت مجوز لازم را ندارد MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏سیم‌کارت مجاز نیست MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-fi/strings.xml b/core/res/res/values-mcc311-mnc180-fi/strings.xml
deleted file mode 100644
index 004e645..0000000
--- a/core/res/res/values-mcc311-mnc180-fi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortti ei käyttäjien hallinnassa MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortti estetty MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml b/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
deleted file mode 100644
index c0aaf99..0000000
--- a/core/res/res/values-mcc311-mnc180-fr-rCA/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non configurée, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-fr/strings.xml b/core/res/res/values-mcc311-mnc180-fr/strings.xml
deleted file mode 100644
index b9adf79..0000000
--- a/core/res/res/values-mcc311-mnc180-fr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Carte SIM non provisionnée MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Carte SIM non autorisée MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-gl/strings.xml b/core/res/res/values-mcc311-mnc180-gl/strings.xml
deleted file mode 100644
index cb59c97..0000000
--- a/core/res/res/values-mcc311-mnc180-gl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Non se introduciu ningunha tarxeta SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Non se admite a tarxeta SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-gu/strings.xml b/core/res/res/values-mcc311-mnc180-gu/strings.xml
deleted file mode 100644
index 556416e..0000000
--- a/core/res/res/values-mcc311-mnc180-gu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIMને MM#2ની જોગવાઈ નથી"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIMને MM#3 કરવાની મંજૂરી નથી"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-hi/strings.xml b/core/res/res/values-mcc311-mnc180-hi/strings.xml
deleted file mode 100644
index da1f9e1..0000000
--- a/core/res/res/values-mcc311-mnc180-hi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM काम नहीं कर रहा है MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM की अनुमति नहीं है MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-hr/strings.xml b/core/res/res/values-mcc311-mnc180-hr/strings.xml
deleted file mode 100644
index a1f0b0e..0000000
--- a/core/res/res/values-mcc311-mnc180-hr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Ne pruža se usluga za SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM nije dopušten MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-hu/strings.xml b/core/res/res/values-mcc311-mnc180-hu/strings.xml
deleted file mode 100644
index 917c2ee9..0000000
--- a/core/res/res/values-mcc311-mnc180-hu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Nem engedélyezett SIM-kártya (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"A SIM-kártya nem engedélyezett (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-hy/strings.xml b/core/res/res/values-mcc311-mnc180-hy/strings.xml
deleted file mode 100644
index a832d02..0000000
--- a/core/res/res/values-mcc311-mnc180-hy/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM քարտը նախապատրաստված չէ (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM քարտի օգտագործումն արգելված է (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-in/strings.xml b/core/res/res/values-mcc311-mnc180-in/strings.xml
deleted file mode 100644
index bdc8d20..0000000
--- a/core/res/res/values-mcc311-mnc180-in/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak di-provisioning MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak diizinkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-is/strings.xml b/core/res/res/values-mcc311-mnc180-is/strings.xml
deleted file mode 100644
index 35966f7..0000000
--- a/core/res/res/values-mcc311-mnc180-is/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-korti ekki úthlutað MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort ekki leyft MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-it/strings.xml b/core/res/res/values-mcc311-mnc180-it/strings.xml
deleted file mode 100644
index 25f301b..0000000
--- a/core/res/res/values-mcc311-mnc180-it/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Scheda SIM non predisposta MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Scheda SIM non consentita MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-iw/strings.xml b/core/res/res/values-mcc311-mnc180-iw/strings.xml
deleted file mode 100644
index c6bdc14..0000000
--- a/core/res/res/values-mcc311-mnc180-iw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏כרטיס ה-SIM לא הופעל MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏כרטיס ה-SIM לא מורשה לשימוש ברשת הסלולרית MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ja/strings.xml b/core/res/res/values-mcc311-mnc180-ja/strings.xml
deleted file mode 100644
index 6d30808..0000000
--- a/core/res/res/values-mcc311-mnc180-ja/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM には対応していません(MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM は許可されていません(MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ka/strings.xml b/core/res/res/values-mcc311-mnc180-ka/strings.xml
deleted file mode 100644
index b86ce07..0000000
--- a/core/res/res/values-mcc311-mnc180-ka/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ბარათი უზრუნველყოფილი არ არის (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ბარათი დაუშვებელია (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-kk/strings.xml b/core/res/res/values-mcc311-mnc180-kk/strings.xml
deleted file mode 100644
index 539fbe4..0000000
--- a/core/res/res/values-mcc311-mnc180-kk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картасы қарастырылмаған MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картасына рұқсат етілмеген MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-km/strings.xml b/core/res/res/values-mcc311-mnc180-km/strings.xml
deleted file mode 100644
index 970532e..0000000
--- a/core/res/res/values-mcc311-mnc180-km/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ស៊ីមកាត​មិនត្រូវបានផ្ដល់ជូនទេ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"មិនអនុញ្ញាត​ចំពោះស៊ីមកាតទេ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-kn/strings.xml b/core/res/res/values-mcc311-mnc180-kn/strings.xml
deleted file mode 100644
index 53a0419..0000000
--- a/core/res/res/values-mcc311-mnc180-kn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 ಗೆ ಸಿಮ್‌ ಸಿದ್ಧವಾಗಿಲ್ಲ"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"ಸಿಮ್‌ MM#3 ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ko/strings.xml b/core/res/res/values-mcc311-mnc180-ko/strings.xml
deleted file mode 100644
index 01d6fec..0000000
--- a/core/res/res/values-mcc311-mnc180-ko/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM이 프로비저닝되지 않음 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM이 허용되지 않음 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ky/strings.xml b/core/res/res/values-mcc311-mnc180-ky/strings.xml
deleted file mode 100644
index d8d58d9..0000000
--- a/core/res/res/values-mcc311-mnc180-ky/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM карта таанылган жок MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картаны колдонууга тыюу салынган MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-lo/strings.xml b/core/res/res/values-mcc311-mnc180-lo/strings.xml
deleted file mode 100644
index 5cbd1c8..0000000
--- a/core/res/res/values-mcc311-mnc180-lo/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ບໍ່ໄດ້ເປີດໃຊ້ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ບໍ່ອະນຸຍາດ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-lt/strings.xml b/core/res/res/values-mcc311-mnc180-lt/strings.xml
deleted file mode 100644
index 40a7e4a..0000000
--- a/core/res/res/values-mcc311-mnc180-lt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM kortelė neteikiama (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM kortelė neleidžiama (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-lv/strings.xml b/core/res/res/values-mcc311-mnc180-lv/strings.xml
deleted file mode 100644
index 74b6818..0000000
--- a/core/res/res/values-mcc311-mnc180-lv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karte netiek nodrošināta: MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karti nav atļauts izmantot: MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-mk/strings.xml b/core/res/res/values-mcc311-mnc180-mk/strings.xml
deleted file mode 100644
index 7db80fa..0000000
--- a/core/res/res/values-mcc311-mnc180-mk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Не е обезбедена SIM-картичка, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Не е дозволена SIM-картичка, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ml/strings.xml b/core/res/res/values-mcc311-mnc180-ml/strings.xml
deleted file mode 100644
index c31b9a7..0000000
--- a/core/res/res/values-mcc311-mnc180-ml/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM, MM#3 പ്രൊവിഷൻ ചെയ്‌തിട്ടില്ല"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM, MM#3 അനുവദിക്കുന്നില്ല"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-mn/strings.xml b/core/res/res/values-mcc311-mnc180-mn/strings.xml
deleted file mode 100644
index 1be055c..0000000
--- a/core/res/res/values-mcc311-mnc180-mn/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-г идэвхжүүлээгүй байна MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-г зөвшөөрөөгүй байна MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-mr/strings.xml b/core/res/res/values-mcc311-mnc180-mr/strings.xml
deleted file mode 100644
index f8e08ae..0000000
--- a/core/res/res/values-mcc311-mnc180-mr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM ने MM#2 ची तरतूद केलेली नाही"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM ने MM#3 ला परवानगी दिली नाही"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ms/strings.xml b/core/res/res/values-mcc311-mnc180-ms/strings.xml
deleted file mode 100644
index 305a10d..0000000
--- a/core/res/res/values-mcc311-mnc180-ms/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM tidak diperuntukkan MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM tidak dibenarkan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-my/strings.xml b/core/res/res/values-mcc311-mnc180-my/strings.xml
deleted file mode 100644
index 306c0dd..0000000
--- a/core/res/res/values-mcc311-mnc180-my/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ဆင်းမ်ကို ထောက်ပံ့မထားပါ MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"ဆင်းမ်ကို ခွင့်မပြုပါ MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-nb/strings.xml b/core/res/res/values-mcc311-mnc180-nb/strings.xml
deleted file mode 100644
index e1296f4..0000000
--- a/core/res/res/values-mcc311-mnc180-nb/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kortet er ikke klargjort, MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kortet er ikke tillatt, MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ne/strings.xml b/core/res/res/values-mcc311-mnc180-ne/strings.xml
deleted file mode 100644
index 6177a83..0000000
--- a/core/res/res/values-mcc311-mnc180-ne/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM को प्रावधान छैन MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM लाई अनुमति छैन MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-nl/strings.xml b/core/res/res/values-mcc311-mnc180-nl/strings.xml
deleted file mode 100644
index 3f12e64..0000000
--- a/core/res/res/values-mcc311-mnc180-nl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Simkaart niet geregistreerd MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Simkaart niet toegestaan MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-pl/strings.xml b/core/res/res/values-mcc311-mnc180-pl/strings.xml
deleted file mode 100644
index 0744491..0000000
--- a/core/res/res/values-mcc311-mnc180-pl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"MM#2 – karta SIM nieobsługiwana"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"MM#3 – niedozwolona karta SIM"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
deleted file mode 100644
index c4d2240..0000000
--- a/core/res/res/values-mcc311-mnc180-pt-rBR/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml b/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
deleted file mode 100644
index c4d2240..0000000
--- a/core/res/res/values-mcc311-mnc180-pt-rPT/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-pt/strings.xml b/core/res/res/values-mcc311-mnc180-pt/strings.xml
deleted file mode 100644
index c4d2240..0000000
--- a/core/res/res/values-mcc311-mnc180-pt/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM não aprovisionado MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM não permitido MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ro/strings.xml b/core/res/res/values-mcc311-mnc180-ro/strings.xml
deleted file mode 100644
index 68cab29..0000000
--- a/core/res/res/values-mcc311-mnc180-ro/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Cardul SIM nu este activat MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Cardul SIM nu este permis MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ru/strings.xml b/core/res/res/values-mcc311-mnc180-ru/strings.xml
deleted file mode 100644
index 90a3a09..0000000
--- a/core/res/res/values-mcc311-mnc180-ru/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карта не активирована (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Использование SIM-карты запрещено (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-si/strings.xml b/core/res/res/values-mcc311-mnc180-si/strings.xml
deleted file mode 100644
index 1907d3e..0000000
--- a/core/res/res/values-mcc311-mnc180-si/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3 ඉඩ නොදේ"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sk/strings.xml b/core/res/res/values-mcc311-mnc180-sk/strings.xml
deleted file mode 100644
index a456431..0000000
--- a/core/res/res/values-mcc311-mnc180-sk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta nie je k dispozícii – MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta je zakázaná – MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sl/strings.xml b/core/res/res/values-mcc311-mnc180-sl/strings.xml
deleted file mode 100644
index 454a1cd..0000000
--- a/core/res/res/values-mcc311-mnc180-sl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Kartica SIM ni omogočena za uporabo MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Kartica SIM ni dovoljena MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sq/strings.xml b/core/res/res/values-mcc311-mnc180-sq/strings.xml
deleted file mode 100644
index 23da1a3..0000000
--- a/core/res/res/values-mcc311-mnc180-sq/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Karta SIM nuk është dhënë MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Karta SIM nuk lejohet MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sr/strings.xml b/core/res/res/values-mcc311-mnc180-sr/strings.xml
deleted file mode 100644
index 182a7bc..0000000
--- a/core/res/res/values-mcc311-mnc180-sr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM картица није подешена MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM картица није дозвољена MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sv/strings.xml b/core/res/res/values-mcc311-mnc180-sv/strings.xml
deleted file mode 100644
index fee7a1f..0000000
--- a/core/res/res/values-mcc311-mnc180-sv/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-kort tillhandahålls inte MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-kort tillåts inte MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-sw/strings.xml b/core/res/res/values-mcc311-mnc180-sw/strings.xml
deleted file mode 100644
index e49b3d1..0000000
--- a/core/res/res/values-mcc311-mnc180-sw/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM haitumiki MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM hairuhusiwi MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ta/strings.xml b/core/res/res/values-mcc311-mnc180-ta/strings.xml
deleted file mode 100644
index 6c11c4f..0000000
--- a/core/res/res/values-mcc311-mnc180-ta/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"சிம் அமைக்கப்படவில்லை MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"சிம் அனுமதிக்கப்படவில்லை MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-th/strings.xml b/core/res/res/values-mcc311-mnc180-th/strings.xml
deleted file mode 100644
index be4b08e..0000000
--- a/core/res/res/values-mcc311-mnc180-th/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"ไม่มีการจัดสรรซิม MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"ไม่อนุญาตให้ใช้ซิม MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-tl/strings.xml b/core/res/res/values-mcc311-mnc180-tl/strings.xml
deleted file mode 100644
index 6aacf16..0000000
--- a/core/res/res/values-mcc311-mnc180-tl/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"Hindi na-provision ang SIM MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"Hindi pinapahintulutan ang SIM MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-tr/strings.xml b/core/res/res/values-mcc311-mnc180-tr/strings.xml
deleted file mode 100644
index cf4fd77..0000000
--- a/core/res/res/values-mcc311-mnc180-tr/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM, MM#2\'nin temel hazırlığını yapamadı"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM MM#3\'e izin vermiyor"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-uk/strings.xml b/core/res/res/values-mcc311-mnc180-uk/strings.xml
deleted file mode 100644
index fae40ac..0000000
--- a/core/res/res/values-mcc311-mnc180-uk/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM-карту не надано (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM-карта заборонена (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-ur/strings.xml b/core/res/res/values-mcc311-mnc180-ur/strings.xml
deleted file mode 100644
index ebceb5e..0000000
--- a/core/res/res/values-mcc311-mnc180-ur/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"‏SIM فراہم کردہ نہیں ہے MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"‏SIM کی اجازت نہیں ہے MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-uz/strings.xml b/core/res/res/values-mcc311-mnc180-uz/strings.xml
deleted file mode 100644
index ebcdd3b..0000000
--- a/core/res/res/values-mcc311-mnc180-uz/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM karta ishlatish taqiqlangan (MM#2)"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM karta ishlatish taqiqlangan (MM#3)"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-vi/strings.xml b/core/res/res/values-mcc311-mnc180-vi/strings.xml
deleted file mode 100644
index 0d7ff96..0000000
--- a/core/res/res/values-mcc311-mnc180-vi/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"SIM không được cấp phép MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM không được phép MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
deleted file mode 100644
index d8ff182..0000000
--- a/core/res/res/values-mcc311-mnc180-zh-rCN/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未配置的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"不被允许的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
deleted file mode 100644
index 14332bf..0000000
--- a/core/res/res/values-mcc311-mnc180-zh-rHK/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"SIM 卡不允許 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml b/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
deleted file mode 100644
index 775a70b..0000000
--- a/core/res/res/values-mcc311-mnc180-zh-rTW/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"未佈建的 SIM 卡 MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"不支援的 SIM 卡 MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc311-mnc180-zu/strings.xml b/core/res/res/values-mcc311-mnc180-zu/strings.xml
deleted file mode 100644
index a66760f..0000000
--- a/core/res/res/values-mcc311-mnc180-zu/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, 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 xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="531930017979728896">"I-SIM ayinikezelwe MM#2"</string>
-    <string name="mmcc_illegal_ms" msgid="97745044956236881">"I-SIM ayivunyelwe MM#3"</string>
-</resources>
diff --git a/core/res/res/values-mcc404/config.xml b/core/res/res/values-mcc404/config.xml
index 6b77e9c..4cadef7 100644
--- a/core/res/res/values-mcc404/config.xml
+++ b/core/res/res/values-mcc404/config.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values-mcc724/config.xml b/core/res/res/values-mcc724/config.xml
new file mode 100644
index 0000000..98f70d5
--- /dev/null
+++ b/core/res/res/values-mcc724/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d1b3916..9d9a2fe 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услугата не е предвидена."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Не може да го промените поставувањето за ID на повикувач."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Нема услуга за интернет"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Нема итни повици"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Нема услуга за итни повици"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Нема услуга за говорни повици"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Нема услуга за говорни/итни повици"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено не се нуди од мобилната мрежа на вашата локација"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Вашиот оператор привремено ја суспендираше услугата за интернет на локацијава"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Вашиот оператор привремено ги суспендираше итните повици на локацијава"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Вашиот оператор привремено ги суспендираше говорните повици на локацијава"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Вашиот оператор привремено ги суспендираше говорните и итните повици на локацијава"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не може да се дојде до мрежата"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"За подобрување на приемот, обидете се да го промените избраниот тип во: Систем &gt; Мрежа и интернет &gt; Мобилни мрежи &gt; Претпочитан тип мрежа."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Предупредувања"</string>
@@ -280,7 +283,7 @@
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапува до календарот"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"испраќа и прикажува SMS-пораки"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Капацитет"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Меморија"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"пристапува до фотографии, аудио-видео и датотеки на уредот"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снима аудио"</string>
@@ -1041,7 +1044,7 @@
     <string name="anr_application_process" msgid="6417199034861140083">"<xliff:g id="APPLICATION">%1$s</xliff:g> не реагира"</string>
     <string name="anr_process" msgid="6156880875555921105">"Процесот <xliff:g id="PROCESS">%1$s</xliff:g> не реагира"</string>
     <string name="force_close" msgid="8346072094521265605">"Во ред"</string>
-    <string name="report" msgid="4060218260984795706">"Пријави"</string>
+    <string name="report" msgid="4060218260984795706">"Извештај"</string>
     <string name="wait" msgid="7147118217226317732">"Почекај"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Страницата не реагира.\n\nДали сакате да ја затворите?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Пренасочена апликација"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за МИДИ"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со USB додаток"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Допрете за повеќе опции."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиододатокот не е поддржан"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Допрете за повеќе информации"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Се споделува извештај за грешки…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Допрете за избирање јазик и распоред"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Прикажувај врз други апликации"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> се прикажува врз други апликации"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> се прикажува врз апликации"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ако не сакате <xliff:g id="NAME">%s</xliff:g> да ја користи функцијава, допрете за да ги отворите поставките и исклучете ја."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Допрете за да излезете од автомобилски режим."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Следно"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Прескокни"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 41b073d..92cfb6b 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -46,7 +46,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"കണക്ഷൻ പ്രശ്‌നം അല്ലെങ്കിൽ MMI കോഡ് അസാധുവാണ്."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"നിശ്ചയിച്ചുറപ്പിച്ച ഡയൽ ചെയ്യൽ നമ്പറുകൾക്ക് മാത്രമായി പ്രവർത്തനം പരിമിതപ്പെടുത്തിയിരിക്കുന്നു."</string>
-    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"റോമിംഗിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോണിൽ നിന്ന് കോൾ കൈമാറ്റ ക്രമീകരണം സാധിക്കില്ല."</string>
+    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"റോമിംഗിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോണിൽ നിന്ന് കോൾ കൈമാറൽ ക്രമീകരണം മാറ്റാൻ കഴിയില്ല."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"സേവനം പ്രവർത്തനക്ഷമമാക്കി."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"സേവനം ഇവയ്‌ക്കായി പ്രവർത്തനക്ഷമമാക്കി:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"സേവനം പ്രവർത്തനരഹിതമാക്കി."</string>
@@ -68,8 +68,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"ഇൻകമിംഗ് വിളിച്ച നമ്പർ"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"ഔട്ട്ഗോയിംഗ് വിളിച്ച നമ്പർ"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"ഇൻകമിംഗ് കോളർ ഐഡി"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ഔട്ട്ഗോയിംഗ് കോളർ ഐഡി"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"കണക്‌റ്റുചെയ്‌തിരിക്കുന്ന ലൈൻ ഐഡി"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"കണക്‌റ്റുചെയ്‌തിരിക്കുന്ന ലൈൻ ഐഡി നിയന്ത്രണം"</string>
     <string name="CfMmi" msgid="5123218989141573515">"കോൾ ഫോർവേഡിംഗ്"</string>
@@ -88,12 +88,15 @@
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"നിയന്ത്രിക്കേണ്ടതല്ലാത്ത സ്ഥിര കോളർ ഐഡികൾ. അടുത്ത കോൾ: നിയന്ത്രിച്ചിട്ടുണ്ട്"</string>
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"നിയന്ത്രിക്കേണ്ടതല്ലാത്ത സ്ഥിര കോളർ ഐഡികൾ. അടുത്ത കോൾ: നിയന്ത്രിച്ചിട്ടില്ല"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"സേവനം വ്യവസ്ഥ ചെയ്‌തിട്ടില്ല."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"വിളിച്ച നമ്പർ ക്രമീകരണം നിങ്ങൾക്ക് മാറ്റാനാവില്ല."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"നിങ്ങൾക്ക് കോളർ ഐഡി ക്രമീകരണം മാറ്റാനാവില്ല."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ഡാറ്റ ‌സേവനം ലഭ്യമല്ല"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"എമർജൻസി കോളിംഗ് സാധ്യമല്ല"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"അടിയന്തിര സേവനമില്ല"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"വോയ്സ് സേവനമില്ല"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"വോയ്സ്/അടിയന്തിര സേവനമില്ല"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"നിങ്ങളുടെ ലൊക്കേഷനിൽ മൊബൈൽ നെറ്റ്‌വര്‍ക്ക് താൽക്കാലികമായി ലഭ്യമല്ല"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"നിങ്ങളുടെ കാരിയർ ഈ ലൊക്കേഷനിൽ ഡാറ്റാ സേവനം തൽക്കാലം നിർത്തിവച്ചിരിക്കുകയാണ്"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"നിങ്ങളുടെ കാരിയർ ഈ ലൊക്കേഷനിൽ അടിയന്തിര കോളുകൾ തൽക്കാലം നിർത്തിവച്ചിരിക്കുകയാണ്"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"നിങ്ങളുടെ കാരിയർ ഈ ലൊക്കേഷനിൽ വോയ്സ് കോളുകൾ തൽക്കാലം നിർത്തിവച്ചിരിക്കുകയാണ്"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ഈ ലൊക്കേഷനിൽ നിങ്ങളുടെ കാരിയർ വോയ്സ് കോളുകളും അടിയന്തിര കോളുകളും തൽക്കാലം നിർത്തിവച്ചിരിക്കുകയാണ്"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റുചെയ്യാനാവുന്നില്ല"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"സ്വീകരണം മെച്ചപ്പെടുത്തുന്നതിന് സിസ്റ്റം &gt; നെറ്റ്‌വർക്കും ഇന്റർനെറ്റും &gt; മൊബൈൽ നെറ്റ്‌വർക്കുകൾ &gt; തിരഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് തരം എന്നതിൽ തിരഞ്ഞെടുത്തിരിക്കുന്ന തരം മാറ്റിക്കൊണ്ട് ശ്രമിച്ചുനോക്കുക."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"അലേർട്ടുകൾ"</string>
@@ -294,7 +297,7 @@
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"സ്‌പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക ഓൺ ചെയ്യുക"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"ടാപ്പുചെയ്ത ഇനങ്ങൾ ഉച്ചത്തിൽ പറയപ്പെടും, ജെസ്റ്ററുകൾ ഉപയോഗിച്ച് സ്‌ക്രീൻ അടുത്തറിയാവുന്നതാണ്."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"നിങ്ങൾ ടൈപ്പ് ചെയ്യുന്ന ടെക്സ്റ്റ് നിരീക്ഷിക്കുക"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"നിങ്ങൾ ടൈപ്പുചെയ്യുന്ന വാചകം നിരീക്ഷിക്കുക"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ക്രെഡിറ്റ് കാർഡ് നമ്പറുകളും പാസ്‌വേഡുകളും പോലുള്ള വ്യക്തിഗത ഡാറ്റ ഉൾപ്പെടുന്നു."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ഡിസ്പ്ലേ മാഗ്നിഫിക്കേഷൻ നിയന്ത്രിക്കുക"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ഡിസ്പ്ലേയുടെ സൂം നിലയും പൊസിഷനിംഗും നിയന്ത്രിക്കുക."</string>
@@ -366,18 +369,18 @@
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"സ്റ്റിക്കി പ്രക്ഷേപണങ്ങൾ അയയ്‌ക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു, പ്രക്ഷേപണം അവസാനിച്ചതിനുശേഷവും അത് നിലനിൽക്കുന്നു. അമിതോപയോഗം വളരെയധികം മെമ്മറി ഉപയോഗിക്കുന്നതിനാൽ, അത് ഫോണിന്റെ പ്രവർത്തനത്തെ മന്ദഗതിയിലാക്കുകയോ അസ്ഥിരമാക്കുകയോ ചെയ്യാം."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ റീഡുചെയ്യുക"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"നിശ്ചിത ആളുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ,  നിങ്ങളുടെ ടാബ്‌ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൺടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ഈ അനുമതി അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ അറിവില്ലാതെ കോൺടാക്റ്റ് ഡാറ്റ പങ്കിടാനിടയുണ്ട്."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങള്‍ വഴി നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നും അവർക്ക് എത്ര ഇമെയിൽ അയച്ചിട്ടുണ്ടെന്നും ആശയവിനിമയത്തെ സംബന്ധിച്ചുള്ളതും ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന കോൺടാക്‌റ്റുകളെ കുറിച്ചുള്ള വിവരവും ഉള്‍പ്പെടെ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.കോൾ ചരിത്ര ഡാറ്റകള്‍ സംരക്ഷിക്കാന്‍ അപ്ലിക്കേഷന് ഇൗ അനുമതി കാരണമാകും ഒപ്പം കോൾ ചരിത്ര ഡാറ്റകള്‍ നിങ്ങളറിയാതെ ദോഷകരമായ അപ്ലിക്കേഷനുകൾ പങ്കിട്ടേയ്ക്കാം."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന കോൺടാക്‌റ്റുകളെക്കുറിച്ചുള്ള വിവരം റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൾ ലോഗ് വിവരത്തെ സംരക്ഷിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു ഒപ്പം നിങ്ങളുടെ അറിവില്ലാതെ കോൾ ലോഗ് വിവരം ദോഷകരമായ അപ്ലിക്കേഷനുകൾ പങ്കിട്ടേക്കാം."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"നിശ്ചിത ആളുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ,  നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൺടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ഈ അനുമതി അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ അറിവില്ലാതെ കോൺടാക്റ്റ് ഡാറ്റ പങ്കിടാനിടയുണ്ട്."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ പരിഷ്‌ക്കരിക്കുക"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ടാബ്‌ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള വിവരം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൺടാക്റ്റ് വിവരം ഇല്ലാതാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്‌തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
-    <string name="permlab_readCallLog" msgid="3478133184624102739">"കോൾ ചരിത്രം റീഡ് ചെയ്യുക"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"കോൾ ലോഗ് റീഡുചെയ്യുക"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"ഈ ആപ്പിന് നിങ്ങളുടെ കോൾ ചരിത്രം വായിക്കാൻ കഴിയും."</string>
-    <string name="permlab_writeCallLog" msgid="8552045664743499354">"കോൾ ചരിത്രം റൈറ്റ് ചെയ്യുക"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ടാബ്‌ലെറ്റിന്‍റെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്‌ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ടിവിയുടെ കോള്‍ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്‌ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ഫോണിന്‍റെ കോൾ ചരിത്രം പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്‌ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"കോൾ ലോഗ് റൈറ്റുചെയ്യുക"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടുന്ന, നിങ്ങളുടെ ടാബ്‌ലെറ്റിന്റെ കോൾ ലോഗ് പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള വിവരമുൾപ്പെടുന്ന, നിങ്ങളുടെ ടിവിയുടെ കോൾ ലോഗ് പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ദോഷകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടുന്ന, നിങ്ങളുടെ ഫോണിന്റെ കോൾ ലോഗ് പരിഷ്‌ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ കോൾ ലോഗ് മായ്‌ക്കാനോ പരിഷ്‌ക്കരിക്കാനോ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"ശരീര സെൻസറുകൾ (ഹൃദയമിടിപ്പ് നിരക്ക് മോണിറ്ററുകൾ പോലെ) ആക്സസ് ചെയ്യുക"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"നിങ്ങളുടെ ഹൃദയമിടിപ്പ് പോലുള്ള ശാരീരികാവസ്ഥ നിരീക്ഷിക്കാൻ സെൻസറുകളിൽ നിന്ന് വിവരം ആക്‌സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"കലണ്ടർ ഇവന്റുകളും വിശദാംശങ്ങളും വായിക്കുക"</string>
@@ -577,7 +580,7 @@
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"മുന്നറിയിപ്പൊന്നും നൽകാതെ ഈ ഫോണിലെ ഈ ഉപയോക്താവിന്റെ ഡാറ്റ മായ്‌ക്കുക."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ഉപകരണ ഗ്ലോബൽ പ്രോക്‌സി സജ്ജീകരിക്കുക"</string>
     <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"നയം പ്രവർത്തനക്ഷമമാക്കിയിരിക്കുമ്പോൾ ഉപകരണ ഗ്ലോബൽ പ്രോക്‌സി ഉപയോഗിക്കുന്നത് സജ്ജമാക്കുക. ഉപകരണ ഉടമയ്‌ക്ക് മാത്രമേ ഗ്ലോബൽ പ്രോക്‌സി സജ്ജമാക്കാനാകൂ."</string>
-    <string name="policylab_expirePassword" msgid="5610055012328825874">"സ്‌ക്രീൻ ലോക്ക് പാസ്‌വേഡിന് സമയപരിധി നിശ്ചയിക്കുക"</string>
+    <string name="policylab_expirePassword" msgid="5610055012328825874">"സ്‌ക്രീൻ ലോക്ക് പാസ്‌വേഡ് കാലഹരണപ്പെടൽ സജ്ജമാക്കുക"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"സ്‌ക്രീൻ ലോക്ക് പാസ്‌വേഡ്, PIN അല്ലെങ്കിൽ പാറ്റേൺ എപ്പോഴൊക്കെ മാറ്റണമെന്നത് നിയന്ത്രിക്കുക."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"സംഭരണ എൻക്രിപ്‌ഷൻ സജ്ജീകരിക്കുക"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"സംഭരിച്ച അപ്ലിക്കേഷൻ ഡാറ്റ എൻക്രിപ്റ്റുചെയ്യേണ്ടതുണ്ട്."</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-യ്‌ക്കായുള്ള USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ഒരു USB ആക്‌സസ്സറി കണക്റ്റുചെയ്‌തു"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ഓഡിയോ ആക്‌സസറി പ്രവർത്തിക്കുകയില്ല"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പുചെയ്യുക"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നു…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ഭാഷയും ലേഔട്ടും തിരഞ്ഞെടുക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"മറ്റ് ആപ്‌സിന് മുകളിൽ പ്രദർശിപ്പിക്കുക"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ഈ ഫീച്ചർ ഉപയോഗിക്കുന്നതിൽ നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ടാപ്പുചെയ്‌ത് ക്രമീകരണം തുറന്ന് അത് ഓഫാക്കുക."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"കാർ മോഡിൽ നിന്ന് പുറത്തുകടക്കാൻ ടാപ്പുചെയ്യുക."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
     <string name="back_button_label" msgid="2300470004503343439">"മടങ്ങുക"</string>
     <string name="next_button_label" msgid="1080555104677992408">"അടുത്തത്"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ഒഴിവാക്കുക"</string>
@@ -1623,7 +1628,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>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index cd561a7..cfdd9be 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Үйлчилгээ провишн хийгдээгүй ."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Та дуудлага хийгчийн ID тохиргоог солиж чадахгүй."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Дата үйлчилгээ алга"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Яаралтай дуудлага хийх боломжгүй"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Яаралтай үйлчилгээ алга"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Дуу хоолойны үйлчилгээ алга"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Дуу хоолой/яаралтай үйлчилгээ алга"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Таны байршилд таны мобайл сүлжээнээс түр хугацаанд блоклосон"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Таны оператор компани энэ байршилд дата үйлчилгээг түр хаасан байна"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Таны оператор компани энэ байршилд яаралтай дуудлагыг түр хаасан байна"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Таны оператор компани энэ байршилд дуу хоолойн дуудлагыг түр хаасан байна"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Таны оператор компани энэ байршилд дуу хоолой, яаралтай дуудлагыг түр хаасан байна"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сүлжээнд холбогдох боломжгүй байна"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Хүлээн авалтыг сайжруулахын тулд систем, сүлжээ, интернэт, мобайл сүлжээнд сонгосон сүлжээний төрлийг өөрчилнө үү."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сануулга"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ийн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Бусад сонголтыг харахын тулд товшино уу."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио хэрэгслийг дэмжээгүй байна"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Дэлгэрэнгүйг үзэхийн тулд товшино уу"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB-н алдаа засварлахыг идэвхгүй болгохын тулд товшино уу."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Бусад апп дээр харуулах"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Бусад апп дээгүүр <xliff:g id="NAME">%s</xliff:g>-г харуулж байна"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>-г бусад апп дээр харуулж байна"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Та <xliff:g id="NAME">%s</xliff:g>-д энэ онцлогийг ашиглахыг хүсэхгүй байгаа бол тохиргоог нээгээд, унтраана уу."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Машины горимоос гарахын тулд товшино уу."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Буцах"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Дараах"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Алгасах"</string>
@@ -1623,7 +1627,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>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 832cd44..e43a3c9 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -46,7 +46,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"कनेक्शन समस्या किंवा अवैध MMI कोड."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"कार्य फक्त निश्चित डायलिंग नंबरसाठी प्रतिबंधित आहे."</string>
-    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"आपण रोमिंगमध्ये असताना आपल्या फोनवरील कॉल फॉरवर्डिंग सेटिंंग्ज बदलू शकत नाही."</string>
+    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"आपण रोमिंगमध्ये असताना आपल्या फोनवरील कॉल अग्रेषण सेटिंंग्ज बदलू शकत नाही."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"सेवा सक्षम केली."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"सेवा यासाठी सक्षम केली:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"सेवा अक्षम केली गेली आहे."</string>
@@ -72,7 +72,7 @@
     <string name="ClirMmi" msgid="7784673673446833091">"केला जाणारा कॉलर आयडी"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"कनेक्ट केलेला रेखा आयडी"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"कनेक्ट केलेला रेखा आयडी प्रतिबंध"</string>
-    <string name="CfMmi" msgid="5123218989141573515">"कॉल फॉरवर्डिंग"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"कॉल अग्रेषण"</string>
     <string name="CwMmi" msgid="9129678056795016867">"कॉल प्रतीक्षा"</string>
     <string name="BaMmi" msgid="455193067926770581">"कॉल सोडून"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"संकेतशब्द बदल"</string>
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"सेवेची तरतूद केलेली नाही."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"आपण कॉलर आयडी सेटिंग बदलू शकत नाही."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"डेटा सेवा नाही"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"आणीबाणीत कॉल करू शकत नाही"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"आणीबाणी सेवा नाही"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"व्हॉइस सेवा नाही"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"व्हॉइस/आणीबाणी सेवा नाही"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"तुम्‍ही असलेल्‍या स्‍थानी मोबाइल नेटवर्क तात्‍पुरते उपलब्‍ध नाही"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"आपल्या वाहकाने या स्थानावर डेटा सेवा तात्पुरती निलंबित केली आहे"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"आपल्या वाहकाने या स्थानावर आणीबाणी कॉल तात्पुरते निलंबित केले आहेत"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"आपल्या वाहकाने या स्थानावर व्हॉइस कॉल तात्पुरते निलंबित केले आहेत"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"आपल्या वाहकाने या स्थानावर व्हॉइस आणि आणीबाणी कॉल तात्पुरते निलंबित केले आहेत"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कवर पोहोचूू शकत नाही"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्शन सुधारण्यासाठी प्रणाली &gt; नेटवर्क आणि इंटरनेट &gt; मोबाइल नेटवर्क &gt; प्राधान्य दिलेला नेटवर्क प्रकार येथे निवडलेला प्रकार बदलून पहा."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्ट"</string>
@@ -159,10 +162,10 @@
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रॉक्सी सर्व्हरद्वारे प्रमाणीकरण यशस्वी झाले."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"सर्व्हरशी कनेक्ट करू शकलो नाही."</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"या सर्व्हरशी संप्रेषण करू शकलो नाही. नंतर पुन्हा प्रयत्न करा."</string>
-    <string name="httpErrorTimeout" msgid="4743403703762883954">"सर्व्हरवरील कनेक्शन टाइमआउट झाले."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"सर्व्हरवरील कनेक्शन कालबाह्य झाले."</string>
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"पृष्ठामध्ये बरीच सर्व्हर पुनर्निर्देशने आहेत."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"प्रोटोकॉल समर्थित नाही."</string>
-    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"सुरक्षित कनेक्शन इंस्टॉल करू शकलो नाही."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"सुरक्षित कनेक्शन स्थापित करू शकलो नाही."</string>
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL अवैध असल्यामुळे पृष्ठ उघडू शकलो नाही."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"फायलीवर प्रवेश करू शकलो नाही."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"विनंती केलेली फाईल शोधू शकलो नाही."</string>
@@ -176,8 +179,8 @@
     <string name="low_memory" product="tv" msgid="516619861191025923">"टीव्ही संचयन भरले आहे. स्थान मोकळे करण्यासाठी काही फायली हटवा."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"फोन संचयन पूर्ण भरले आहे. स्थान मोकळे करण्यासाठी काही फायली हटवा."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
-      <item quantity="one">प्रमाणपत्र अधिकार इंस्टॉल केला</item>
-      <item quantity="other">प्रमाणपत्र अधिकार इंस्टॉल केले</item>
+      <item quantity="one">प्रमाणपत्र अधिकार स्थापित केला</item>
+      <item quantity="other">प्रमाणपत्र अधिकार स्थापित केले</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"एका अज्ञात तृतीय पक्षाद्वारे"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"आपल्या कार्य प्रोफाइल प्रशासकाद्वारे"</string>
@@ -186,10 +189,10 @@
     <string name="work_profile_deleted_description" msgid="1100529432509639864">"प्रशासक अॅप गहाळ असल्यामुळे कार्य प्रोफाइल हटवले गेले"</string>
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा दूषित आहे. परिणामी, आपले कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"आपले कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्‍ध नाही"</string>
-    <string name="network_logging_notification_title" msgid="6399790108123704477">"डीव्हाइस व्यवस्थापित केले आहे"</string>
-    <string name="network_logging_notification_text" msgid="7930089249949354026">"आपली संस्था हे डीव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"तुमचे डीव्हाइस मिटविले जाईल"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"हे प्रशासक अ‍ॅप वापरले जाऊ शकत नाही. तुमचे डीव्हाइस आता मिटवले जाईल.\n\nतुम्हाला प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="network_logging_notification_title" msgid="6399790108123704477">"डिव्हाइस व्यवस्थापित केले आहे"</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"आपली संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"आपले डिव्हाइस मिटविले जाईल"</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"हे प्रशासक अ‍ॅप वापरले जाऊ शकत नाही. आपले डिव्हाइस आता मिटवले जाईल.\n\nआपल्याला प्रश्न असल्यास, आपल्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
     <string name="me" msgid="6545696007631404292">"मी"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टॅबलेट पर्याय"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"टीव्ही पर्याय"</string>
@@ -202,20 +205,20 @@
     <string name="silent_mode_silent" msgid="319298163018473078">"रिंगर बंद"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"रिंगर कंपन"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"रिंगर चालू"</string>
-    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टम अपडेट"</string>
-    <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अपडेट करण्याची तयारी करत आहे…"</string>
-    <string name="reboot_to_update_package" msgid="3871302324500927291">"अपडेट पॅकेज प्रक्रिया करत आहे…"</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टीम अद्यतन"</string>
+    <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अद्यतनित करण्यासाठी तयार करीत आहे…"</string>
+    <string name="reboot_to_update_package" msgid="3871302324500927291">"अद्यतन पॅकेजची प्रक्रिया करीत आहे…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"रीस्टार्ट करीत आहे..."</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"फॅक्‍टरी डेटा रीसेट"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"रीस्टार्ट करीत आहे..."</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"बंद होत आहे…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"आपला टॅबलेट बंद होईल."</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"आपला टीव्ही बंद होईल."</string>
-    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"तुमचे घड्याळ बंद होईल."</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"आपले घड्याळ बंद होईल."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"आपला फोन बंद होईल."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"आपण बंद करू इच्छिता?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"सुरक्षित मोडमध्ये रीबूट करा"</string>
-    <string name="reboot_safemode_confirm" msgid="55293944502784668">"आपण सुरक्षित मोडमध्ये रीबूट करू इच्छिता? हे आपण इंस्टॉल केलेले सर्व तृतीय पक्ष अॅप्लिकेशन अक्षम करेल. आपण पुन्हा रीबूट करता तेव्हा ते पुनर्संचयित केले जातील."</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"आपण सुरक्षित मोडमध्ये रीबूट करू इच्छिता? हे आपण स्थापित केलेले सर्व तृतीय पक्ष अनुप्रयोग अक्षम करेल. आपण पुन्हा रीबूट करता तेव्हा ते पुनर्संचयित केले जातील."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"अलीकडील"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"अलीकडील कोणतेही अॅप्स नाहीत."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"टॅबलेट पर्याय"</string>
@@ -226,11 +229,11 @@
     <string name="global_action_emergency" msgid="7112311161137421166">"आणीबाणी"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"दोष अहवाल"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"दोष अहवाल घ्या"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डीव्हाइस स्थितीविषयी माहिती संकलित करेल. दोष अहवाल सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे आपल्या वर्तमान डिव्हाइस स्थितीविषयी माहिती संकलित करेल. दोष अहवाल प्रारंभ करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"परस्परसंवादी अहवाल"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"बहुतांश प्रसंगांमध्ये याचा वापर करा. ते आपल्याला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील प्रविष्ट करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते."</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"संपूर्ण अहवाल"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"तुमचे डीव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते किंवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"आपले डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे होते किंवा आपल्याला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टीम हस्तक्षेपासाठी या पर्यायाचा वापर करा. आपल्याला आणखी तपशील प्रविष्ट करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
       <item quantity="one">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदामध्‍ये स्क्रीनशॉट घेत आहे.</item>
       <item quantity="other">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्‍ये स्क्रीनशॉट घेत आहे.</item>
@@ -254,14 +257,14 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"कार मोड"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"खाते स्थिती"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"विकसक संदेश"</string>
-    <string name="notification_channel_updates" msgid="4794517569035110397">"अपडेट"</string>
+    <string name="notification_channel_updates" msgid="4794517569035110397">"अद्यतने"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्क स्थिती"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क सूचना"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"नेटवर्क उपलब्ध"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN स्थिती"</string>
-    <string name="notification_channel_device_admin" msgid="1568154104368069249">"डीव्हाइस प्रशासन"</string>
+    <string name="notification_channel_device_admin" msgid="1568154104368069249">"डिव्हाइस प्रशासन"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचना"</string>
-    <string name="notification_channel_retail_mode" msgid="6088920674914038779">"रीटेल डेमो"</string>
+    <string name="notification_channel_retail_mode" msgid="6088920674914038779">"किरकोळ डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्‍शन"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"अॅप्‍स बॅकग्राउंडमध्‍ये चालू आहेत"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅकग्राउंडमध्‍ये चालू आहे"</string>
@@ -281,7 +284,7 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS संदेश पाठवणे आणि पाहणे हे"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"संचयन"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"तुमच्या डीव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अॅक्सेस"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"आपल्‍या डिव्‍हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये प्रवेश"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"मायक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडिओ रेकॉर्ड"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"कॅमेरा"</string>
@@ -333,9 +336,9 @@
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"मजकूर संदेश प्राप्त करा (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP संदेश प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अॅप ला अनुमती देते. ही परवानगी आपल्याला पाठविलेले संदेश आपल्याला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अॅप्स पुनर्प्राप्त करा"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अॅप्लिकेशन वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अॅप ला अनुमती देऊ शकतात."</string>
-    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डीव्हाइस मालक व्यवस्थापित करा"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डीव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अनुप्रयोग वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अॅप ला अनुमती देऊ शकतात."</string>
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डिव्हाइस मालक व्यवस्थापित करा"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डिव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अॅप्स पुनर्क्रमित करा"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अॅप ला अनुमती देते. अॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करा"</string>
@@ -384,7 +387,7 @@
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"हा अॅप आपल्या टॅब्लेटवर संचयित केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि सामायिक करू शकतो किंवा आपला कॅलेंडर डेटा जतन करू शकतो."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"हा अॅप आपल्या टीव्हीवर संचयित केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि सामायिक करू शकतो किंवा आपला कॅलेंडर डेटा जतन करू शकतो."</string>
     <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"हा अॅप आपल्या फोनवर संचयित केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि सामायिक करू शकतो किंवा आपला कॅलेंडर डेटा जतन करू शकतो."</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"कॅलेंडर इव्हेंट जोडा किंवा बदला आणि मालकाला न कळवता अतिथींना ईमेल पाठवा"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"कॅलेंडर इव्हेंट जोडा किंवा सुधारित करा आणि मालकांच्या माहितीशिवाय अतिथींना ईमेल पाठवा"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"हा अॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"हा अॅप आपल्या टीव्हीवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"हा अॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे संदेश पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
@@ -411,7 +414,7 @@
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवेमध्‍ये प्रवेश करा"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"आपल्‍या हस्तक्षेपाशिवाय अ‍ॅपला कॉल करण्‍यासाठी IMS सेवा वापरण्याची अनुमती देते."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिती आणि ओळख वाचा"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डीव्हाइस च्या फोन वैशिष्ट्यांवर अॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डीव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रीमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइसच्या फोन वैशिष्ट्यांवर प्रवेश करण्यास अॅप ला अनुमती देते. ही परवानगी कॉल सक्रिय असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रीमोट नंबर निर्धारित करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करण्याचा अनुभव सुधारण्यासाठी अॅपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"फोन नंबर वाचा"</string>
@@ -435,13 +438,13 @@
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"टीव्हीचा टाईम झोन बदलण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"फोनचा टाइम झोन बदलण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"डिव्हाइसवरील खाती शोधा"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"टॅब्लेटद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात आपण इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट होऊ शकतात."</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"टीव्हीद्वारे ज्ञात खात्यांची सूची मिळविण्यासाठी अॅपला अनुमती देतो. यात आपण इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट असू शकतात."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात आपण इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट करू शकतात."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"टॅब्लेटद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात आपण स्थापित केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट होऊ शकतात."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"टीव्हीद्वारे ज्ञात खात्यांची सूची मिळविण्यासाठी अॅपला अनुमती देतो. यात आपण स्थापित केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट असू शकतात."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात आपण स्थापित केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट करू शकतात."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क कनेक्शन पहा"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"कोणती नेटवर्क अस्तित्वात आहेत आणि कनेक्ट केलेली आहेत यासारख्या नेटवर्क कनेक्शनविषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"पूर्ण नेटवर्क प्रवेश आहे"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सॉकेट तयार करण्यासाठी आणि सानुकूल नेटवर्क प्रोटोकॉल वापरण्यासाठी अॅप ला अनुमती देते. ब्राउझर आणि अन्य अॅप्लिकेशन म्हणजे इंटरनेटवर डेटा पाठवण्याचा मार्ग, म्हणजे इंटरनेटवर डेटा पाठविण्यासाठी परवानगीची आवश्यकता नसते."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सॉकेट तयार करण्यासाठी आणि सानुकूल नेटवर्क प्रोटोकॉल वापरण्यासाठी अॅप ला अनुमती देते. ब्राउझर आणि अन्य अनुप्रयोग म्हणजे इंटरनेटवर डेटा पाठवण्याचा मार्ग, म्हणजे इंटरनेटवर डेटा पाठविण्यासाठी परवानगीची आवश्यकता नसते."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"नेटवर्क कनेक्टिव्हिटी बदला"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"टिथर केलेली कनेक्टिव्हिटी बदला"</string>
@@ -449,7 +452,7 @@
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"वाय-फाय कनेक्शन पहा"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डिव्हाइसेसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाय-फाय वरून कनेक्ट करा आणि डिस्कनेक्ट करा"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डीव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय प्रवेश बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डिव्हाइस कॉन्फिगरेशनमध्ये बदल करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाय-फाय मल्‍टिकास्‍ट रिसेप्‍शनला अनुमती द्या"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त आपल्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डिव्हाइसेसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे गैर-मल्टिकास्ट मोडपेक्षा अधिक पॉवर वापरते."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"केवळ आपला टीव्ही न वापरता, एकाधिक पत्ते वापरून एका वाय-फाय नेटवकवरील सर्व डिव्हाइसवर पाठविलेली पॅकेट प्राप्त करण्यासाठी अॅपला अनुमती देते."</string>
@@ -464,12 +467,12 @@
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"WiMAX नेटवर्कवर टॅबलेट कनेक्ट करण्यास आणि त्यावरून टॅबलेट डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"WiMAX नेटवर्कवरून टीव्ही कनेक्ट करण्यासाठी आणि त्यावरून टीव्ही डिस्कनेक्ट करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX नेटवर्कवर फोन कनेक्ट करण्यास आणि त्यावरून फोन डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लुटूथ डीव्हाइससह जोडा"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटुथ डिव्हाइसेससह जोडा"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"टॅब्लेटवर ब्लूटुथ चे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"टीव्हीवर ब्लूटुथचे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"फोनवर ब्लूटुथ चे कॉन्फिगरेशन पाहण्यासाठी आणि जोडलेल्या डिव्हाइसेससह कनेक्शन करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"फील्ड जवळील संप्रेषण नियंत्रित करा"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"फील्ड जवळील संप्रेषण (NFC) टॅग, कार्ड आणि वाचक यांच्यासह संप्रेषण करण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"आपले स्क्रीन लॉक अक्षम करा"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"कीलॉक आणि कोणतीही संबद्ध संकेतशब्द सुरक्षितता अक्षम करण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, येणारा फोन कॉल प्राप्त करताना फोन कीलॉक अक्षम करतो, नंतर जेव्हा कॉल समाप्त होतो तेव्हा तो कीलॉक पुन्हा-सक्षम करतो."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string>
@@ -485,7 +488,7 @@
   </string-array>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"फिंगरप्रिंट हार्डवेअर उपलब्‍ध नाही."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"फिंगरप्रिंट संचयित केले जाऊ शकत नाही. कृपया विद्यमान फिंगरप्रिंट काढा."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट टाइमआउट झाले. पुन्हा प्रयत्न करा."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट कालबाह्य झाले. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"खूप प्रयत्न करून झाले. फिंगरप्रिंट सेंसर बंद आहे."</string>
@@ -540,7 +543,7 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"होल्‍डरला वाहकद्वारे-प्रदान केलेल्या कॉन्फिगरेशन अ‍ॅपची विनंती करण्‍याची अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्‍थितींवरील निरीक्षणांसाठी ऐका"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
-    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डीव्हाइस कॅलिब्रेशन बदला"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रांवर प्रवेश करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
@@ -548,8 +551,8 @@
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM प्रमाणपत्रे काढा"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यकता नसते."</string>
-    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"एका वाहक मेसेजिंग सेवेसाठी प्रतिबद्ध"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"वाहक मेसेजिंग सेवेचा शीर्ष-स्तर इंटरफेस बाइंड करण्यासाठी होल्डरला अनुमती देतो. सामान्‍य अ‍ॅप्‍सकरिता हे कधीही आवश्‍यक नसते."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"एका वाहक संदेशन सेवेसाठी प्रतिबद्ध"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"वाहक संदेशन सेवेचा शीर्ष-स्तर इंटरफेस प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्‍य अ‍ॅप्‍सकरिता कधीही आवश्‍यक नसते."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"वाहक सेवांवर प्रतिबद्ध करा"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"वाहक सेवांवर प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसावी."</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"व्यत्यय आणू नका मध्ये प्रवेश करा"</string>
@@ -575,14 +578,14 @@
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या टॅब्लेटवरील डेटा मिटवा."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या टीव्ही वरील डेटा मिटवा."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"कोणत्याही चेतावणी शिवाय या वापरकर्त्याचा या फोनवरील डेटा मिटवा."</string>
-    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"डीव्हाइस समग्र प्रॉक्सी सेट करा"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"धोरण सक्षम असताना वापरण्यासाठी डीव्हाइस समग्र प्रॉक्सी सेट करा. फक्त डीव्हाइस मालक समग्र प्रॉक्सी सेट करु शकतो."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"डिव्हाइस समग्र प्रॉक्सी सेट करा"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"धोरण सक्षम असताना वापरण्यासाठी डिव्हाइस समग्र प्रॉक्सी सेट करा. फक्त डिव्हाइस मालक समग्र प्रॉक्सी सेट करु शकतो."</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"स्क्रीन लॉक संकेतशब्द कालबाह्यता सेट करा"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"लॉक-स्क्रीन संकेतशब्द किती वारंवार बदलणे आवश्यक आहे ते बदला."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"संचयन कूटबद्धीकरण सेट करा"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"संचयित अॅप डेटा कूटबद्ध केला जाणे आवश्यक आहे."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"कॅमेरे अक्षम करा"</string>
-    <string name="policydesc_disableCamera" msgid="2306349042834754597">"सर्व डीव्हाइस कॅमेर्‍यांचा वापर प्रतिबंधित करा."</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"सर्व डिव्हाइस कॅमेर्‍यांचा वापर प्रतिबंधित करा."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"काही स्क्रीन लॉक वैशिष्‍ट्ये अक्षम करा"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"काही स्क्रीन लॉक वैशिष्‍ट्यांचा वापर प्रतिबंधित करा."</string>
   <string-array name="phoneTypes">
@@ -695,10 +698,10 @@
     <string name="relationTypeSister" msgid="1735983554479076481">"बहिण"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"पती/पत्नी"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"सानुकूल"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"घर"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"मुख्‍यपृष्‍ठ"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"कार्य"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
-    <string name="quick_contacts_not_available" msgid="746098007828579688">"हा संपर्क पाहण्‍यासाठी कोणतीही अॅक्टिव्हिटी आढळली नाही."</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"हा संपर्क पाहण्‍यासाठी कोणताही क्रियाकलाप आढळला नाही."</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"पिन कोड टाइप करा"</string>
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK आणि नवीन पिन कोड टाइप करा"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
@@ -713,7 +716,7 @@
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"स्क्रीन लॉक केली."</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"अनलॉक करण्‍यासाठी मेनू दाबा किंवा आणीबाणीचा कॉल करा."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"अनलॉक करण्यासाठी मेनू दाबा."</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"अनलॉक करण्यासाठी पॅटर्न काढा"</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"अनलॉक करण्यासाठी नमुना काढा"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"आणीबाणी"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"कॉलवर परत या"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"अचूक!"</string>
@@ -742,12 +745,12 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"वापरकर्ता मार्गदर्शक पहा किंवा कस्टमर केअरशी संपर्क साधा."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"सिम कार्ड लॉक केलेले आहे."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"सिम कार्ड अनलॉक करत आहे…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपण आपला पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीचा रेखांकित केला आहे. <xliff:g id="NUMBER_1">%2$d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, तुमच्याला आपले Google साइन इन वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"तुम्ही <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा आपला अनलॉक पॅटर्न अयोग्यरीत्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला आपले Google साइन इन वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे रेखांकित केला आहे. <xliff:g id="NUMBER_1">%2$d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, तुमच्याला आपले Google साइन इन वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीचा रेखांकित केला आहे. <xliff:g id="NUMBER_1">%2$d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला टॅबलेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा आपला अनलॉक नमुना अयोग्यरित्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीचा रेखांकित केला आहे. <xliff:g id="NUMBER_1">%2$d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा टॅबलेट अनलॉक करण्याचे चुकीचे प्रयत्न केले. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, टॅबलेट फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावला जाईल."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, टीव्ही फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावेल."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा फोन अनलॉक करण्याचे चुकीचे प्रयत्न केले. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, फोन फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावला जाईल."</string>
@@ -755,9 +758,9 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. टीव्ही आता फॅक्टरी डीफॉल्टवर रीसेट केला जाईल."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा फोन अनलॉक करण्याचे चुकीचे प्रयत्न केले. फोन आता फॅक्टरी डीफॉल्टवर रीसेट केला जाईल."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"पॅटर्न विसरलात?"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"नमुना विसरलात?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"खाते अनलॉक करा"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"बरेच पॅटर्न प्रयत्न"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"बरेच नमुना प्रयत्न"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"वापरकर्तानाव (ईमेल)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"संकेतशब्द"</string>
@@ -768,12 +771,12 @@
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"अनलॉक करा"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ध्वनी सुरु"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ध्वनी बंद"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"पॅटर्न सुरू केला"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"पॅटर्न साफ केला"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"नमुना प्रारंभ झाला"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"नमुना साफ केला"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"सेल जोडला"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> सेल जोडला"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"पॅटर्न पूर्ण केला"</string>
-    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"पॅटर्न क्षेत्र."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"नमुना पूर्ण केला"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"नमुना क्षेत्र."</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d पैकी %2$d विजेट."</string>
     <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोडा."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string>
@@ -789,11 +792,11 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> हटविले."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र विस्तृत करा."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्‍लाइड अनलॉक."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"पॅटर्न अनलॉक."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"नमुना अनलॉक."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"चेहरा अनलॉक."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"पिन अनलॉक."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"संकेतशब्द अनलॉक."</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"पॅटर्न क्षेत्र."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"नमुना क्षेत्र."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र."</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
@@ -803,7 +806,7 @@
     <string name="granularity_label_link" msgid="5815508880782488267">"दुवा"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"रेखा"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फॅक्टरी चाचणी अयशस्वी"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अॅप मध्ये इंस्टॉल केलेल्या पॅकेजसाठी समर्थित आहे."</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अॅप मध्ये स्थापित केलेल्या पॅकेजसाठी समर्थित आहे."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST क्रिया प्रदान करणारे कोणतेही पॅकेज आढळले नाही."</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करा"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" वरील पृष्ठ हे म्हणते:"</string>
@@ -839,7 +842,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"आपल्या टीव्हीवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅपला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅपला अनुमती देऊ शकते. टीप: या परवानगीची अंमलबजावणी वेब ब्राउझिंग क्षमता असलेल्या तृतीय-पक्ष ब्राउझरद्वारे किंवा इतर अनुप्रयोगांद्वारे केली जाऊ शकत नाही."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"आपल्या फोनवर संचयित केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अनुप्रयोगांद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करा"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"इंस्टॉल केलेल्या अलार्म घड्याळ अॅपमध्ये अलार्म सेट करण्यासाठी अॅपला अनुमती देते. काही अलार्म घड्याळ अॅप्समध्ये हे वैशिष्ट्य नसू शकते."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"स्थापित केलेल्या अलार्म घड्याळ अॅपमध्ये अलार्म सेट करण्यासाठी अॅप ला अनुमती देते. काही अलार्म घड्याळ अॅप्स हे वैशिष्ट्य लागू करू शकत नाहीत."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"व्हॉइसमेल जोडा"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"आपल्या व्हॉइसमेल इनबॉक्समध्ये संदेश जोडण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउझर भौगोलिक स्थान परवानग्या सुधारित करा"</string>
@@ -863,8 +866,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करा"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"व्हॉइस शोध"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"स्पर्श करून एक्सप्लोर करा सक्षम करायचे?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा टॅब्लेटसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा फोनसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा आपण आपल्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा टॅब्लेटसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा आपण आपल्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा फोनसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 महिन्यापूर्वी"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 महिन्यापूर्वी"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -977,7 +980,7 @@
     <string name="redo" msgid="7759464876566803888">"पुन्हा करा"</string>
     <string name="autofill" msgid="3035779615680565188">"स्वयं-भरण"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"मजकूर निवड"</string>
-    <string name="addToDictionary" msgid="4352161534510057874">"डिक्शनरीत जोडा"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोशात जोडा"</string>
     <string name="deleteText" msgid="6979668428458199034">"हटवा"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट पद्धत"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"मजकूर क्रिया"</string>
@@ -1013,8 +1016,8 @@
     <string name="whichSendToApplication" msgid="8272422260066642057">"वापरून पाठवा"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s वापरून पाठवा"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"पाठवा"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"होम अ‍ॅप निवडा"</string>
-    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"होम म्हणून %1$s वापरा"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"मुख्‍यपृष्‍ठ अ‍ॅप निवडा"</string>
+    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"मुख्यपृष्ठ म्हणून %1$s वापरा"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"प्रतिमा कॅप्चर करा"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"यासह प्रतिमा कॅप्चर करा"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s सह प्रतिमा कॅप्चर करा"</string>
@@ -1032,7 +1035,7 @@
     <string name="aerr_restart" msgid="7581308074153624475">"अॅप पुन्हा उघडा"</string>
     <string name="aerr_report" msgid="5371800241488400617">"अभिप्राय पाठवा"</string>
     <string name="aerr_close" msgid="2991640326563991340">"बंद करा"</string>
-    <string name="aerr_mute" msgid="1974781923723235953">"डीव्हाइस रीस्टार्ट होईपर्यंत म्युट करा"</string>
+    <string name="aerr_mute" msgid="1974781923723235953">"डिव्हाइस रीस्टार्ट होईपर्यंत नि:शब्द करा"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"प्रतीक्षा करा"</string>
     <string name="aerr_close_app" msgid="3269334853724920302">"अॅप बंद करा"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
@@ -1057,7 +1060,7 @@
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android श्रेणीसुधारित होत आहे..."</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android प्रारंभ करत आहे…"</string>
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"संचयन ऑप्टिमाइझ करत आहे."</string>
-    <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android अपडेट संपवत आहे..."</string>
+    <string name="android_upgrading_notification_title" msgid="8428357096969413169">"Android अद्यतन समाप्त करीत आहे..."</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"श्रेणीसुधारणा पूर्ण होईपर्यंत काही अॅप्स योग्यरित्या कार्य करणार नाहीत"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> श्रेणीसुधारित करीत आहे…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप ऑप्टिमाइझ करत आहे."</string>
@@ -1075,7 +1078,7 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ने मेमेरी मर्यादा वाढविली"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप संकलित केला गेला आहे; सामायिक करण्यासाठी टॅप करा"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप सामायिक करायचे?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> प्रक्रियेने त्याची <xliff:g id="SIZE">%2$s</xliff:g> ची प्रक्रिया मेमरी मर्यादा ओलांडली आहे. त्याच्या विकासकासह सामायिक करण्यासाठी आपल्याकरिता हीप डंप उपलब्ध आहे. सावधगिरी बाळगा: या हीप डंपमध्ये आपली कोणतीही वैयक्तिक माहिती असू शकते ज्यात अॅप्लिकेशन प्रवेश करू शकतो."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> प्रक्रियेने त्याची <xliff:g id="SIZE">%2$s</xliff:g> ची प्रक्रिया मेमरी मर्यादा ओलांडली आहे. त्याच्या विकासकासह सामायिक करण्यासाठी आपल्याकरिता हीप डंप उपलब्ध आहे. सावधगिरी बाळगा: या हीप डंपमध्ये आपली कोणतीही वैयक्तिक माहिती असू शकते ज्यात अनुप्रयोग प्रवेश करू शकतो."</string>
     <string name="sendText" msgid="5209874571959469142">"मजकुरासाठी क्रिया निवडा"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर व्हॉल्यूम"</string>
     <string name="volume_music" msgid="5421651157138628171">"मीडिया व्हॉल्यूम"</string>
@@ -1113,7 +1116,7 @@
     <string name="wifi_no_internet" msgid="8451173622563841546">"वाय-फायवरून इंटरनेटवर प्रवेश नाही"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"पर्यायांसाठी टॅप करा"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेट अॅक्सेस नसताना डीव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरतो. शुल्क लागू शकेल."</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेट प्रवेश नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरतो. शुल्क लागू शकतील."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"मोबाइल डेटा"</item>
@@ -1126,8 +1129,8 @@
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाय-फाय ला कनेक्ट करू शकलो नाही"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" खराब इंटरनेट कनेक्शन आहे."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"कनेक्शनला अनुमती द्यायची?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s अॅप्लिकेशन %2$s वायफाय नेटवर्कशी कनेक्ट करू इच्छित आहे"</string>
-    <string name="wifi_connect_default_application" msgid="7143109390475484319">"अॅप्लिकेशन"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s अनुप्रयोग %2$s वायफाय नेटवर्कशी कनेक्ट करू इच्छित आहे"</string>
+    <string name="wifi_connect_default_application" msgid="7143109390475484319">"अनुप्रयोग"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"वाय-फाय थेट"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"वाय-फाय थेट प्रारंभ करा. हे वाय-फाय क्लायंट/हॉटस्पॉट बंद करेल."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"वाय-फाय थेट प्रारंभ करू शकलो नाही."</string>
@@ -1162,9 +1165,9 @@
     <string name="sim_removed_message" msgid="2333164559970958645">"आपण एक वैध सिम कार्ड घालून प्रारंभ करेपर्यंत मोबाईल नेटवर्क अनुपलब्ध असेल."</string>
     <string name="sim_done_button" msgid="827949989369963775">"पूर्ण झाले"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोडले"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अॅक्सेस करण्यासाठी तुमचे डीव्हाइस रीस्टार्ट करा."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर प्रवेश करण्यासाठी आपला डिव्हाइस रीस्टार्ट करा."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"रीस्टार्ट"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपल्या नवीन सिमने योग्यरित्या कार्य करण्यासाठी, आपल्याला अॅप इंस्टॉल करण्याची आणि तो आपल्या वाहकामधून उघडण्याची आवश्यकता असेल."</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"आपल्या नवीन सिमने योग्यरित्या कार्य करण्यासाठी, आपल्याला अॅप स्थापित करण्याची आणि तो आपल्या वाहकामधून उघडण्याची आवश्यकता असेल."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"अ‍ॅप मिळवा"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"आता नाही"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नवीन सिम घाला"</string>
@@ -1178,16 +1181,19 @@
     <string name="no_permissions" msgid="7283357728219338112">"परवानग्या आवश्यक नाहीत"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"यासाठी आपले पैसे खर्च होऊ शकतात"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ठीक"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB हे डीव्हाइस चार्ज करत आहे"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"USB हे डिव्हाइस चार्ज करीत आहे"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"USB संलग्न केलेल्या डिव्हाइसला पॉवरचा पुरवठा करीत आहे"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"स्थानांतरणासाठी USB"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"फोटो स्थानांतरणासाठी USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI साठी USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB उपसाधनावर कनेक्ट केले"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"अधिक पर्यायांसाठी टॅप करा."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ऑडिओ अॅक्‍सेसरी समर्थित नाही"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"आणखी माहितीसाठी येथे टॅप करा"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करणे अक्षम करण्यासाठी टॅप करा."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"दोष अहवाल घेत आहे..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल सामायिक करायचा?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"दोष अहवाल सामायिक करीत आहे..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"इतर अ‍ॅप्सवर दाखवा"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> इतर अॅप्सवर प्रदर्शित करीत आहे"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्‍य अॅप्सवर प्रदर्शित करीत आहे"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ने हे वैशिष्ट्य वापरू नये असे आपण इच्छित असल्यास, सेटिंग्ज उघडण्यासाठी टॅप करा आणि ते बंद करा."</string>
@@ -1214,8 +1221,8 @@
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> दूषित आहे. निराकरण करण्यासाठी टॅप करा."</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> दूषित आहे. निश्चित करण्यासाठी निवडा."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> असमर्थित"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"हे डीव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी टॅप करा."</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"हे डीव्हाइस <xliff:g id="NAME">%s</xliff:g> ला सपोर्ट करत नाही. सपोर्ट असलेल्या फॉरमॅटमध्ये सेट करण्यासाठी निवडा."</string>
+    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> ला समर्थन देत नाही. समर्थित स्वरूपनामध्ये सेट करण्यासाठी टॅप करा."</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"हे डिव्हाइस <xliff:g id="NAME">%s</xliff:g> चे समर्थन करत नाही. समर्थित स्वरूपनामध्ये सेट करण्यासाठी निवडा."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> अनपेक्षितरित्या काढले"</string>
     <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"डेटा गमावणे टाळण्‍यासाठी काढण्‍यापूर्वी <xliff:g id="NAME">%s</xliff:g> अनमाउंट करा"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> काढले"</string>
@@ -1226,7 +1233,7 @@
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"बाहेर काढा"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"एक्सप्लोर करा"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> गहाळ आहे"</string>
-    <string name="ext_media_missing_message" msgid="5761133583368750174">"हे डीव्हाइस पुन्हा घाला"</string>
+    <string name="ext_media_missing_message" msgid="5761133583368750174">"हे डिव्हाइस पुन्हा घाला"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> हलवित आहे"</string>
     <string name="ext_media_move_title" msgid="1022809140035962662">"डेटा हलवित आहे"</string>
     <string name="ext_media_move_success_title" msgid="8575300932957954671">"हलविणे पूर्ण"</string>
@@ -1244,12 +1251,12 @@
     <string name="ext_media_status_ejecting" msgid="5463887263101234174">"बाहेर काढत आहे…"</string>
     <string name="ext_media_status_formatting" msgid="1085079556538644861">"फॉर्मेट करीत आहे..."</string>
     <string name="ext_media_status_missing" msgid="5638633895221670766">"घातले नाही"</string>
-    <string name="activity_list_empty" msgid="1675388330786841066">"कोणत्याही जुळणाऱ्या अॅक्टिव्हिटी आढळल्या नाहीत."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"कोणतेही जुळणारे क्रियाकलाप आढळले नाहीत."</string>
     <string name="permlab_route_media_output" msgid="6243022988998972085">"मीडिया आउटपुट मार्गस्थ करा"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"अन्य बाह्य डिव्हाइसेसवरील रूट मीडिया आउटपुट वर अनुप्रयोगास अनुमती देते."</string>
     <string name="permlab_readInstallSessions" msgid="3713753067455750349">"स्‍थापना सत्र वाचा"</string>
     <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"अनुप्रयोगास स्‍थापना सत्र वाचण्‍याची अनुमती देते. हे सक्रिय पॅकेज स्‍थापनांविषयी तपशील पाहाण्‍याची यास अनुमती देते."</string>
-    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"पॅकेज इंस्टॉल करण्यासाठी विनंती करा"</string>
+    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"पॅकेज स्थापित करण्यासाठी विनंती करा"</string>
     <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"पॅकेजच्या स्थापना करण्यासाठी अनुप्रयोगास अनुमती देते."</string>
     <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"पॅकेज हटवण्याची विनंती"</string>
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"अनुप्रयोगास पॅकेज हटवण्यासाठी विनंती करण्याची अनुमती देते."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोडमधून बाहेर पडण्यासाठी टॅप करा."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टिथरिंग किंवा हॉटस्पॉट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string>
     <string name="back_button_label" msgid="2300470004503343439">"परत"</string>
     <string name="next_button_label" msgid="1080555104677992408">"पुढील"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"वगळा"</string>
@@ -1313,7 +1318,7 @@
       <item quantity="other"><xliff:g id="TOTAL">%d</xliff:g> पैकी <xliff:g id="INDEX">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"पूर्ण केले"</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB स्टोरेज मिटवत आहे…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB संचयन मिटवत आहे…"</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD कार्ड मिटवत आहे…"</string>
     <string name="share" msgid="1778686618230011964">"सामायिक करा"</string>
     <string name="find" msgid="4808270900322985960">"शोधा"</string>
@@ -1364,7 +1369,7 @@
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> सह सामायिक करा"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लायडिंग हँडल. स्पर्श करा आणि धरुन ठेवा."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"अनलॉक करण्यासाठी स्वाइप करा."</string>
-    <string name="action_bar_home_description" msgid="5293600496601490216">"होम स्क्रीनवर नेव्‍हिगेट करा"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"मुख्‍यपृष्‍ठ नेव्‍हिगेट करा"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"वर नेव्‍हिगेट करा"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक पर्याय"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
@@ -1374,7 +1379,7 @@
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD कार्ड"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ड्राइव्‍ह"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ड्राइव्‍ह"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USB स्टोरेज"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB संचयन"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"संपादित करा"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"डेटा वापर सूचना"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"वापर आणि सेटिंग्ज पाहण्यासाठी टॅप करा."</string>
@@ -1388,7 +1393,7 @@
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"मोबाईल डेटा मर्यादा ओलांडली"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"वाय-फाय डेटा मर्यादा ओलांडली"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"निर्दिष्ट केलेल्या मर्यादेबाहेर <xliff:g id="SIZE">%s</xliff:g>."</string>
-    <string name="data_usage_restricted_title" msgid="5965157361036321914">"पार्श्वभूमीवरील डेटा प्रतिबंधित केला"</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"पार्श्वभूमी डेटा प्रतिबंधित केला"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"प्रतिबंध काढण्यासाठी टॅप करा."</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"सुरक्षितता प्रमाणपत्र"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"हे प्रमाणपत्र वैध आहे."</string>
@@ -1399,13 +1404,13 @@
     <string name="issued_by" msgid="2647584988057481566">"द्वारे जारी:"</string>
     <string name="validity_period" msgid="8818886137545983110">"वैधता:"</string>
     <string name="issued_on" msgid="5895017404361397232">"रोजी जारी:"</string>
-    <string name="expires_on" msgid="3676242949915959821">"रोजी मुदत संपेल:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"रोजी कालबाह्य होते:"</string>
     <string name="serial_number" msgid="758814067660862493">"अनुक्रमांक:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"फिंगरप्रिंट:"</string>
     <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 फिंगरप्रिंट:"</string>
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 फिंगरप्रिंट:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"सर्व पहा"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"अॅक्टिव्हिटी निवडा"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"क्रियाकलाप निवडा"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"यांच्यासह सामायिक करा"</string>
     <string name="sending" msgid="3245653681008218030">"पाठवित आहे..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउझर लाँच करायचा?"</string>
@@ -1421,7 +1426,7 @@
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्टम"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ब्लूटुथ ऑडिओ"</string>
-    <string name="wireless_display_route_description" msgid="9070346425023979651">"वायरलेस डिस्प्ले"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"वायरलेस प्रदर्शन"</string>
     <string name="media_route_button_content_description" msgid="591703006349356016">"कास्‍ट करा"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"डिव्हाइसला कनेक्ट करा"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"डिव्‍हाइसवर स्क्रीन कास्‍ट करा"</string>
@@ -1438,12 +1443,12 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"आच्छादन #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"पॅटर्न विसरलात"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"चुकीचा पॅटर्न"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"नमुना विसरलात"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"चुकीचा नमुना"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"चुकीचा संकेतशब्द"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"चुकीचा पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_pattern_instructions" msgid="398978611683075868">"आपला पॅटर्न काढा"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"आपला नमुना काढा"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम पिन प्रविष्ट करा"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"पिन प्रविष्ट करा"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"संकेतशब्द प्रविष्ट करा"</string>
@@ -1456,7 +1461,7 @@
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK कोड 8 संख्‍येचा असावा."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"योग्य PUK कोड पुन्हा-प्रविष्ट करा. परत प्रयत्न करणे सिम कायमचे अक्षम करेल."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड जुळत नाहीत"</string>
-    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बरेच पॅटर्न प्रयत्न"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बरेच नमुना प्रयत्न"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करण्यासाठी, आपल्या Google खात्यासह साइन इन करा."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"वापरकर्तानाव (ईमेल)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"संकेतशब्द"</string>
@@ -1466,16 +1471,16 @@
     <string name="kg_login_checking_password" msgid="1052685197710252395">"खाते तपासत आहे…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला आहे. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा टॅबलेट अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. <xliff:g id="NUMBER_1">%2$d</xliff:g> आणखी अयशस्वी प्रयत्नांनंतर, टॅबलेट फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि वापरकर्ता डेटा गमावेल."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, टीव्ही फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावेल."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा फोन अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. <xliff:g id="NUMBER_1">%2$d</xliff:g> आणखी अयशस्वी प्रयत्नांनंतर, फोन फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि वापरकर्ता डेटा गमावेल."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा टॅबलेट अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. टॅबलेट आता फॅक्टरी डीफॉल्ट वर रीसेट केला जाईल."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. टीव्ही आता फॅक्टरी डीफॉल्टवर रीसेट केला जाईल."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा फोन अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. फोन आता फॅक्टरी डीफॉल्ट वर रीसेट केला जाईल."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला ईमेल खाते वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"तुम्ही <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा आपला अनलॉक पॅटर्न अयोग्यरीत्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला ईमेल खाते वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुमच्याला ईमेल खाते वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला टॅबलेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"आपण <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा आपला अनलॉक नमुना अयोग्यरित्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"काढा"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"शिफारस केलेल्‍या पातळीच्या वर आवाज वाढवायचा?\n\nउच्च आवाजात दीर्घ काळ ऐकण्‍याने आपल्‍या श्रवणशक्तीची हानी होऊ शकते."</string>
@@ -1494,7 +1499,7 @@
     <string name="owner_name" msgid="2716755460376028154">"मालक"</string>
     <string name="error_message_title" msgid="4510373083082500195">"त्रुटी"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"या बदलास आपल्या प्रशासकाद्वारे अनुमती नाही"</string>
-    <string name="app_not_found" msgid="3429141853498927379">"ही क्रिया हाताळण्यासाठी कोणताही अॅप्लिकेशन आढळला नाही"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ही क्रिया हाताळण्यासाठी कोणताही अनुप्रयोग आढळला नाही"</string>
     <string name="revoke" msgid="5404479185228271586">"मागे घ्‍या"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
@@ -1613,17 +1618,17 @@
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="lock_to_app_toast" msgid="6820571533009838261">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि अवलोकन बटणांना स्पर्श करून धरून ठेवा"</string>
+    <string name="lock_to_app_toast" msgid="6820571533009838261">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि विहंगावलोकन बटणांना स्पर्श करून धरून ठेवा"</string>
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"हे अ‍ॅप अनपिन केले जाऊ शकत नाही"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन केली"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रीन अनपिन केली"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"अनपिन करण्‍यापूर्वी पिन साठी विचारा"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"अनपिन करण्‍यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करण्‍यापूर्वी संकेतशब्दासाठी विचारा"</string>
-    <string name="package_installed_device_owner" msgid="6875717669960212648">"आपल्या प्रशासकाने इंस्टॉल केले"</string>
-    <string name="package_updated_device_owner" msgid="1847154566357862089">"आपल्या प्रशासकाने अपडेट केले"</string>
+    <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>
@@ -1666,7 +1671,7 @@
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"व्यत्यय आणू नका"</string>
-    <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"डाउनटाइम"</string>
+    <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"कार्य न करण्याचा कालावधी"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"आठवड्याची शेवटची रात्र"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"आठवड्याच्या शेवटी"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इव्‍हेंट"</string>
@@ -1723,11 +1728,11 @@
     <string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string>
     <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"डीव्हाइस रीसेट करायचे?"</string>
-    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"डीव्हाइस रीसेट करण्यासाठी टॅप करा"</string>
+    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"डिव्हाइस रीसेट करायचे?"</string>
+    <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"डिव्हाइस रीसेट करण्यासाठी टॅप करा"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ करत आहे..."</string>
-    <string name="demo_restarting_message" msgid="952118052531642451">"डीव्हाइस रीसेट करत आहे..."</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"डीव्हाइस रीसेट करायचे?"</string>
+    <string name="demo_restarting_message" msgid="952118052531642451">"डिव्हाइस रीसेट करत आहे..."</string>
+    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"डिव्हाइस रीसेट करायचे?"</string>
     <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"आपण कोणतेही बदल गमवाल आणि डेमो पुन्हा <xliff:g id="TIMEOUT">%1$s</xliff:g> सेकंदांमध्ये प्रारंभ होईल..."</string>
     <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"रद्द करा"</string>
     <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"आता रीसेट करा"</string>
@@ -1742,7 +1747,7 @@
     <string name="app_category_news" msgid="7496506240743986873">"बातम्‍या आणि मासिके"</string>
     <string name="app_category_maps" msgid="5878491404538024367">"नकाशे आणि नेव्हिगेशन"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"उत्पादनक्षमता"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डीव्हाइस स्टोरेज"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डिव्‍हाइस संचय"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB डीबगिंग"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"तास"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"मिनिट"</string>
@@ -1750,7 +1755,7 @@
     <string name="time_picker_input_error" msgid="7574999942502513765">"वैध वेळ प्रविष्‍ट करा"</string>
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"वेळ टाइप करा"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"वेळ इनपुटसाठी मजकूर इनपुट मोडवर स्विच करा."</string>
-    <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"वेळेच्या इनपुटसाठी घड्याळ मोडवर स्विच करा."</string>
+    <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"वेळ इनपुटसाठी घड्याळ मोडवर स्विच करा."</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"स्वयं-भरण पर्याय"</string>
     <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"स्वत: भरण्यासाठी सेव्ह करा"</string>
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"सामग्रींची स्‍वयं-भरणा करता येणार नाही"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index fd53735..267dd2f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Perkhidmatan yang tidak diuntukkan."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak boleh mengubah tetapan ID pemanggil."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Tiada perkhidmatan data"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Tiada panggilan kecemasan"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Tiada perkhidmatan kecemasan"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Tiada perkhidmatan suara"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tiada perkhidmatan suara/kecemasan"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Tidak ditawarkan oleh rangkaian mudah alih di lokasi anda untuk sementara waktu"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Pembawa anda telah menggantung perkhidmatan data di lokasi ini untuk sementara waktu"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Pembawa anda telah menggantung panggilan kecemasan di lokasi ini untuk sementara waktu"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Pembawa anda telah menggantung panggilan suara di lokasi ini untuk sementara waktu"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Pembawa anda telah menggantung panggilan suara dan kecemasan di lokasi ini untuk sementara waktu"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tidak dapat mencapai rangkaian"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Untuk memperbaik penerimaan, cuba tukar jenis rangkaian yang dipilih di Sistem &gt; Rangkaian &amp; Internet &gt; Rangkaian mudah alih &gt; Jenis rangkaian pilihan."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Makluman"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ketik untuk mendapatkan lagi pilihan."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori audio tidak disokong"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ketik untuk mendapatkan maklumat lanjut"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ketik untuk melumpuhkan penyahpepijatan USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketik untuk memilih bahasa dan susun atur"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Paparkan di atas apl lain"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikannya."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Ketik untuk keluar daripada mod kereta."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Kembali"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seterusnya"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Langkau"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 36f8db8..a1e7558 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ဝန်ဆောင်မှုအား ကန့်သတ်မထားပါ"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"သင်သည် ခေါ်ဆိုသူ ID ဆက်တင်ကို မပြောင်းလဲနိုင်ပါ။"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ဒေတာချိတ်ဆက်ရန် ဝန်ဆောင်မှု မရှိပါ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"အရေးပေါ်ဖုန်းခေါ်ခြင်းများ မရရှိနိုင်ပါ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"အရေးပေါ်ဝန်ဆောင်မှု မရရှိနိုင်ပါ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ဖုန်းဝန်ဆောင်မှု မရှိပါ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ဖုန်း/အရေးပေါ် ဝန်ဆောင်မှုများမရရှိနိုင်ပါ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"သင်၏ ဒေသတွင် မိုဘိုင်းကွန်ရက် ယာယီမရရှိနိုင်ပါ"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"သင်၏ ဝန်ဆောင်မှုပေးသူသည် ဤတည်နေရာအတွက် ဒေတာဝန်ဆောင်မှုများကို ခေတ္တရပ်ဆိုင်းထားပါသည်"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"သင်၏ ဝန်ဆောင်မှုပေးသူသည် ဤတည်နေရာအတွက် အရေးပေါ်ဖုန်းခေါ်ဆိုမှုများကို ခေတ္တရပ်ဆိုင်းထားပါသည်"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"သင်၏ ဝန်ဆောင်မှုပေးသူသည် ဤနေရာအတွက် ဖုန်းခေါ်ဆိုမှုများကို ခေတ္တရပ်ဆိုင်းထားပါသည်"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"သင်၏ ဝန်ဆောင်မှုပေးသူသည် ဤတည်နေရာအတွက် ဖုန်းခေါ်ဆိုမှု နှင့် အရေးပေါ်ခေါ်ဆိုမှုများကို ခေတ္တရပ်ဆိုင်းထားပါသည်"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ကွန်ရက်ကို ချိတ်ဆက်၍မရပါ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"လိုင်းဖမ်းယူမှု ကောင်းမွန်စေရန် စနစ် &gt; ကွန်ရက်နှင့် အင်တာနက် &gt; မိုဘိုင်းကွန်ရက်များ &gt; အသုံးပြုလိုသည့် ကွန်ရက်အမျိုးအစားတွင် ရွေးချယ်ထားသည့် အမျိုးအစားကို ပြောင်းကြည့်ပါ။"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"သတိပေးချက်များ"</string>
@@ -110,7 +113,7 @@
     <string name="serviceClassVoice" msgid="1258393812335258019">"အသံ"</string>
     <string name="serviceClassData" msgid="872456782077937893">"ဒေတာ"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"ဖက်စ်"</string>
-    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS စာတိုစနစ်"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"စာတိုစနစ်"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
     <string name="serviceClassDataSync" msgid="7530000519646054776">"ထပ်တူ ကိုက်ညီခြင်း"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"Packet"</string>
@@ -278,7 +281,7 @@
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ဤစက်ပစ္စည်း၏ တည်နေရာကို ရယူရန်"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
-    <string name="permgrouplab_sms" msgid="228308803364967808">"SMS စာတိုစနစ်"</string>
+    <string name="permgrouplab_sms" msgid="228308803364967808">"စာတိုစနစ်"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"သိုလှောင်မှုများ"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များအား ဝင်သုံးပါ"</string>
@@ -1166,7 +1169,7 @@
     <string name="sim_restart_button" msgid="4722407842815232347">"အစက ပြန်စရန်"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"သင့် SIM အသစ်ပုံမှန် အလုပ်လုပ်ရန်၊ သင်အသုံးပြုသည့် မိုဘိုင်းဝန်ဆောင်မှုမှ အက်ပ်တစ်ခုထည့်သွင်း၍ ဖွင့်ရန်လိုအပ်ပါသည်။"</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"အက်ပ်ကို ရယူပါ"</string>
-    <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ယခုမလုပ်ပါ"</string>
+    <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ယခုမဟုတ်သေးပါ"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"SIM အသစ်ထည့်သွင်းလိုက်ပါသည်"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"၎င်းကိုတပ်ဆင်ရန် တို့ပါ"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"အချိန်သတ်မှတ်ရန်"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI အတွက် USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBတွဲဖက်ပစ္စည်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"အသံ ဆက်စပ်ပစ္စည်းကို မပံ့ပိုးပါ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"နောက်ထပ် အချက်အလက်များအတွက် တို့ပါ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ဆက်သွယ်ရေးစနစ်ကို ပိတ်ရန် တို့ပါ။"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ချွတ်ယွင်းချက် အစီရင်ခံစာပြုစုနေသည်..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို မျှဝေမလား။"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ချွတ်ယွင်းမှုအစီရင်ခံစာ မျှဝေနေသည်…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"အခြားအက်ပ်များအပေါ်တွင် ပြသခြင်း"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> သည် အခြားအက်ပ်များအပေါ်တွင် ပြပါသည်"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ကို အခြားအက်ပ်များပေါ်တွင် မြင်နေရပါသည်။"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ကို ဤဝန်ဆောင်မှုအား အသုံးမပြုစေလိုလျှင် ဆက်တင်ကို တို့၍ ဖွင့်ပြီး ၎င်းကို ပိတ်လိုက်ပါ။"</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ကားမောင်းနှင်ခြင်းမုဒ်မှ ထွက်ရန် တို့ပါ။"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"နောက်သို့"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ရှေ့သို့"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ကျော်ရန်"</string>
@@ -1600,7 +1605,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"နောက်မှ ပြန်ကြိုးစားပါ"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"မျက်နှာပြင်အပြည့် ကြည့်နေစဉ်"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"ထွက်ရန် အပေါ်မှ အောက်သို့ ဆွဲချပါ။"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"ထွက်ရန်၊ ထိပ်ဘက်မှ အောက်ဘက်သို့ ဆွဲချပါ။"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"ရပါပြီ"</string>
     <string name="done_label" msgid="2093726099505892398">"ပြီးပါပြီ"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"နာရီရွေးချက်စရာ"</string>
@@ -1668,7 +1673,7 @@
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"မနှောင့်ယှက်ရ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ကျချိန်"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ကြားရက်ည"</string>
-    <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"စနေ၊ တနင်္ဂနွေ"</string>
+    <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"စနေ၊တနင်္ဂနွေ"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ဖြစ်ရပ်"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> အသံပိတ်သည်"</string>
     <string name="system_error_wipe_data" msgid="6608165524785354962">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f6f9f3c..aafa411 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"SIM-kortet er ikke tilrettelagt for tjenesten."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Du kan ikke endre innstillingen for anrops-ID."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ingen datatjeneste"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Ingen nødanrop"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ingen nødtjeneste"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ingen taletjeneste"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ingen tale-/nødtjeneste"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Tilbys midlertidig ikke gjennom mobilnettverket der du er"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operatøren din har midlertidig suspendert datatjeneste på dette stedet"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operatøren din har midlertidig suspendert nødanrop på dette stedet"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operatøren din har midlertidig suspendert taleanrop på dette stedet"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operatøren din har midlertidig suspendert tale- og nødanrop på dette stedet"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Får ikke kontakt med nettverket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"For å forbedre signalet, prøv å endre valgt nettverkstype i System &gt; Nettverk og Internett &gt; Mobilnettverk &gt; Foretrukket nettverkstype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Varsler"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trykk for å få flere alternativ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret støttes ikke"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trykk for mer informasjon"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trykk for å slå av feilsøking via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trykk for å velge språk og layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Vis over andre apper"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> vises over andre apper"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> vises over andre apper"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Hvis du ikke vil at <xliff:g id="NAME">%s</xliff:g> skal bruke denne funksjonen, kan du trykke for å åpne innstillingene og slå den av."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Trykk for avslutte bilmodus."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tilbake"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Neste"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Hopp over"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 029957b..826a424 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"सेवाको व्यवस्था छैन।"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"तपाईं कलर ID सेटिङ परिवर्तन गर्न सक्नुहुन्न।"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"कुनै पनि डेटा सेवा छैन"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"कुनै पनि आपतकालीन कल सेवा उपलब्ध छैन"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"कुनै पनि आपतकालीन सेवा उपलब्ध छैन"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"कुनै पनि भ्वाइस सेवा उपलब्ध छैन"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"कुनै पनि भ्वाइस/आपतकालीन सेवा उपलब्ध छैन"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"तपाईंको स्थानमा सञ्चालन भइरहेको मोबाइल नेटवर्कले अस्थायी रूपमा यो सुविधा प्रदान गर्दैन"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"तपाईंको सेवा प्रदायकले अस्थायी रूपमा यस स्थानमा डेटा सेवा निलम्बित गरेको छ"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"तपाईंको सेवा प्रदायकले अस्थायी रूपमा यस स्थानमा आपतकालीन कलहरू निलम्बित गरेको छ"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"तपाईंको सेवा प्रदायकले अस्थायी रूपमा यस स्थानमा भ्वाइस कलहरू निलम्बित गरेको छ"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"तपाईंको सेवा प्रदायकले अस्थायी रूपमा यस स्थानमा भ्वाइस तथा आपतकालीन कलहरू निलम्बित गरेको छ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"नेटवर्कमाथि पहुँच राख्न सकिँदैन"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"रिसेप्सनमा सुधार गर्न, प्रणाली &gt; नेटवर्क र इन्टरनेट &gt; मोबाइल नेटवर्कहरू &gt; रुचाइएको नेटवर्कको प्रकार मा गएर चयन गरिएको प्रकार परिवर्तन गरी हेर्नुहोस्।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"अलर्टहरू"</string>
@@ -361,9 +364,9 @@
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"अनुप्रयोगलाई अनुमति दिन्छ प्रणालीले बुटिङ सकेपछि आफै सुरूवात हुन। यसले TV सुरू गर्न लामो समय लिन सक्छ र अनुप्रयोगहरूलाई अनुमति दिन सक्छ सँधै सञ्चालन भई समग्र रूपमा ट्याब्लेटलाई ढिलो गराएर।"</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"अनुप्रयोगलाई प्रणाली बुट गरी सकेपछि जति सक्दो चाँडो आफैंमा सुरु गर्न अनुमति दिन्छ। यसले फोन सुरु गर्नमा ढिला गर्न सक्दछ र अनप्रयोगलाई समग्रमा फोन सधैँ चालु गरेर ढिला बनाउँदछ।"</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"स्टिकि प्रसारण पठाउनुहोस्"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"औपचारिक प्रसारणलाई पठाउनको लागि एउटा अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले ट्याब्लेटलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"औपचारिक प्रसारणलाई पठाउनको लागि एउटा अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्याधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले ट्याब्लेटलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"अनुप्रयोगलाई टाँसिने प्रसारणहरू पठाउन अनुमति दिन्छ, जुन प्रसारण पछि पनि रहन्छ। अत्यन्य धेरै मेमोरी प्रयोग गर्ने बनाएर अत्यधिक प्रयोगले TV लाई ढिलो वा अस्थिर बनाउन सक्छ ।"</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"औपचारिक प्रसारणलाई पठाउनको लागि एक अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"औपचारिक प्रसारणलाई पठाउनको लागि एक अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्याधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"अनुप्रयोगलाई निर्दिष्ट व्यक्तिगतसँग अन्य तरिकाहरूबाट कल गर्नु भएका, इमेल गर्नु भएका वा अन्तर्क्रिया गर्नुभएका आवृतिसहितको तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्कहरूको डेटा पढ्न अनुमति दिन्छ। यो अनुमतिले तपाईंको सम्पर्क डेटा बचत गर्न अनुमति दिन्छ, र खराब अनुप्रयोगहरूले तपाईंको जानकारी बिना सम्पर्क डेटा साझेदारी गर्न सक्दछन्।"</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"अनुप्रयोगलाई अनुमति दिन्छ तपाईँको TV मा भण्डारण गरिएका तपाईँका सम्पर्कका डेटा, तपाईँको कल, इमेलको बारम्बारता, वा अन्य तरीकाले खास व्यक्तिहरूसँग गरिएको सञ्चार लगायत, पढ्न।यस अनुमतिले अनुप्रयोगलाई अनुमति दिन्छ तपाईँको सम्पर्क डेटा सुरक्षित गर्न र दुस्प्रभावी अनुप्रयोगहरूले तपाईँको ज्ञान बिना सम्पर्क डेटा साझेदारी गर्न सक्छन्।"</string>
@@ -720,7 +723,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"फेरि प्रयास गर्नुहोस्"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"फेरि प्रयास गर्नुहोस्"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"सबै सुविधाहरू र डेटाका लागि अनलक गर्नुहोस्"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"अत्यधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"अत्याधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM कार्ड छैन"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"TV मा कुनै SIM कार्ड छैन।"</string>
@@ -1191,9 +1194,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI को लागि USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"अडियोको सहायक सामग्रीलाई समर्थन छैन"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"थप जानकारीका लागि ट्याप गर्नुहोस्"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डिबगिङलाई असक्षम गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङ असक्षम पार्न चयन गर्नुहोस्।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट लिँदै..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्टलाई साझेदारी गर्ने हो?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्टलाई साझेदारी गर्दै ..."</string>
@@ -1207,7 +1212,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"अन्य अनुप्रयोगहरूको माथिपट्टि देखाउनुहोस्"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> अन्य अनुप्रयोगहरूमा देखिँदैछ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> अन्य अनुप्रयोगहरूमा देखिँदैछ"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले यो विशेषता प्रयोग नगरेको चाहनुहुन्न भने सेटिङहरू खोली यसलाई निष्क्रिय पार्न ट्याप गर्नुहोस्।"</string>
@@ -1307,8 +1313,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"कार मोडबाट बाहिर निस्कन ट्याप गर्नुहोस्।"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट अप गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
     <string name="back_button_label" msgid="2300470004503343439">"पछाडि"</string>
     <string name="next_button_label" msgid="1080555104677992408">"अर्को"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"छोड्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c2fcb3f..ed38f62 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service niet voorzien."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"U kunt de instelling voor de beller-ID niet wijzigen."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Geen gegevensservice"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Geen noodoproepen"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Geen service voor noodoproepen"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Geen service voor spraakoproepen"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Geen service voor spraak-/noodoproepen"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Tijdelijk niet aangeboden door het mobiele netwerk op je locatie"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Je provider heeft de gegevensservice tijdelijk opgeschort op deze locatie"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Je provider heeft noodoproepen tijdelijk opgeschort op deze locatie"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Je provider heeft spraakoproepen tijdelijk opgeschort op deze locatie"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Je provider heeft spraak- en noodoproepen tijdelijk opgeschort op deze locatie"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Kan netwerk niet bereiken"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Als je de ontvangst wilt verbeteren, kun je het netwerktype wijzigen dat is geselecteerd bij Systeem &gt; Netwerk en internet &gt; Mobiele netwerken &gt; Voorkeursnetwerktype."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Meldingen"</string>
@@ -1155,7 +1158,7 @@
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Verzenden"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Annuleren"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mijn keuze onthouden"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"U kunt dit later wijzigen in Instellingen &gt; Apps"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"U kunt dit later wijzigen in \'Instellingen\' &gt; \'Apps\'"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Altijd toestaan"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nooit toestaan"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"Simkaart verwijderd"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB voor MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Aangesloten op een USB-accessoire"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tik voor meer opties."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audioaccessoire niet ondersteund"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tik voor meer informatie"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-foutopsporing uit te schakelen."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om een taal en indeling te selecteren"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Weergeven vóór andere apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven over andere apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven over apps"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en schakel je de functie uit."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tik om de automodus te sluiten."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Vorige"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Volgende"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Overslaan"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 599ea83..c456e2f 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -54,10 +54,10 @@
     <string name="serviceErased" msgid="1288584695297200972">"ਮਿਟਾਉਣਾ ਸਫ਼ਲ ਰਿਹਾ ਸੀ।"</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"ਗ਼ਲਤ ਪਾਸਵਰਡ।"</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI ਪੂਰਾ।"</string>
-    <string name="badPin" msgid="9015277645546710014">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਪੁਰਾਣਾ ਪਿੰਨ ਠੀਕ ਨਹੀਂ ਹੈ।"</string>
+    <string name="badPin" msgid="9015277645546710014">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ ਪੁਰਾਣਾ PIN ਠੀਕ ਨਹੀਂ ਹੈ।"</string>
     <string name="badPuk" msgid="5487257647081132201">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤਾ PUK ਠੀਕ ਨਹੀਂ ਹੈ।"</string>
-    <string name="mismatchPin" msgid="609379054496863419">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੇ ਪਿੰਨ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ।"</string>
-    <string name="invalidPin" msgid="3850018445187475377">"ਇੱਕ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੈ।"</string>
+    <string name="mismatchPin" msgid="609379054496863419">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੇ PIN ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ।"</string>
+    <string name="invalidPin" msgid="3850018445187475377">"ਇੱਕ PIN ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੈ।"</string>
     <string name="invalidPuk" msgid="8761456210898036513">"ਇੱਕ PUK ਕੋਡ ਟਾਈਪ ਕਰੋ ਜੋ 8 ਜਾਂ ਵੱਧ ਸੰਖਿਆਵਾਂ ਦਾ ਹੋਵੇ।"</string>
     <string name="needPuk" msgid="919668385956251611">"ਤੁਹਾਡਾ SIM ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ। ਇਸਨੂੰ ਅਨਲੌਕ ਕਰਨ ਲਈ PUK ਕੋਡ ਟਾਈਪ ਕਰੋ।"</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIM ਕਾਰਡ ਅਨਬਲੌਕ ਕਰਨ ਲਈ PUK2 ਟਾਈਪ ਕਰੋ।"</string>
@@ -68,41 +68,44 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"ਇਨਕਮਿੰਗ ਕਾਲਰ ਆਈ.ਡੀ."</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"ਆਊਟਗੋਇੰਗ ਕਾਲਰ ਆਈ.ਡੀ."</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"ਇਨਕਮਿੰਗ ਕਾਲਰ ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ਆਊਟਗੋਇੰਗ ਕਾਲਰ ID"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ID"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"ਕਨੈਕਟ ਕੀਤੀ ਲਾਈਨ ID ਪ੍ਰਤਿਬੰਧ"</string>
     <string name="CfMmi" msgid="5123218989141573515">"ਕਾਲ ਫੌਰਵਾਰਡਿੰਗ"</string>
     <string name="CwMmi" msgid="9129678056795016867">"ਕਾਲ ਉਡੀਕ ਵਿੱਚ"</string>
     <string name="BaMmi" msgid="455193067926770581">"ਕਾਲ ਬੈਰਿੰਗ"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"ਪਾਸਵਰਡ ਬਦਲੋ"</string>
-    <string name="PinMmi" msgid="3113117780361190304">"ਪਿੰਨ ਬਦਲਣਾ"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PIN ਬਦਲੋ"</string>
     <string name="CnipMmi" msgid="3110534680557857162">"ਕਾਲਿੰਗ ਨੰਬਰ ਮੌਜੂਦ ਹੈ"</string>
     <string name="CnirMmi" msgid="3062102121430548731">"ਕਾਲਿੰਗ ਨੰਬਰ ਪ੍ਰਤਿਬੰਧਿਤ"</string>
     <string name="ThreeWCMmi" msgid="9051047170321190368">"ਥ੍ਰੀ ਵੇ ਕਾਲਿੰਗ"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"ਅਣਇੱਛਿਤ ਪਰੇਸ਼ਾਨ ਕਰਨ ਵਾਲੀਆਂ ਕਾਲਾਂ ਦੀ ਅਸਵੀਕ੍ਰਿਤੀ"</string>
     <string name="CndMmi" msgid="3116446237081575808">"ਕਾਲਿੰਗ ਨੰਬਰ ਡਿਲੀਵਰੀ"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ID ਡਿਫੌਲਟਸ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ID ਡਿਫੌਲਟਸ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ID ਡਿਫੌਲਟਸ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ID ਡਿਫੌਲਟਸ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ਸੇਵਾ ਪ੍ਰਬੰਧਿਤ ਨਹੀਂ ਹੈ।"</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"ਤੁਸੀਂ ਕਾਲਰ ਆਈ.ਡੀ. ਸੈਟਿੰਗ ਨਹੀਂ ਬਦਲ ਸਕਦੇ।"</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"ਤੁਸੀਂ ਕਾਲਰ ID ਸੈਟਿੰਗ ਨਹੀਂ ਬਦਲ ਸਕਦੇ।"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ਕੋਈ ਡੈਟਾ ਸੇਵਾ ਨਹੀਂ"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ਸੰਕਟਕਾਲ ਵਿੱਚ ਕੋਈ ਕਾਲ ਨਹੀਂ"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ਕੋਈ ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ਕੋਈ ਆਵਾਜ਼ੀ ਸੇਵਾ ਨਹੀਂ"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ਕੋਈ ਆਵਾਜ਼ੀ/ਸੰਕਟਕਾਲੀਨ ਸੇਵਾ ਨਹੀਂ"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"ਤੁਹਾਡੇ ਟਿਕਾਣੇ \'ਤੇ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਵੱਲੋਂ ਉਪਲਬਧ ਨਹੀਂ ਕਰਵਾਈ ਗਈ"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਡੈਟਾ ਸੇਵਾ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਆਵਾਜ਼ੀ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਇਸ ਟਿਕਾਣੇ \'ਤੇ ਆਵਾਜ਼ੀ ਅਤੇ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਮੁਅੱਤਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ਸਿਗਨਲ ਪ੍ਰਾਪਤੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਸਿਸਟਮ &gt; ਨੈੱਟਵਰਕ ਅਤੇ ਇੰਟਰਨੈੱਟ &gt; ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ &gt; ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ \'ਤੇ ਚੁਣੀ ਗਈ ਕਿਸਮ ਨੂੰ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ਸੁਚੇਤਨਾਵਾਂ"</string>
-    <string name="notification_channel_call_forward" msgid="2419697808481833249">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"ਕਾਲ ਫਾਰਵਾਰਡਿੰਗ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
     <string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"ਮੋਬਾਈਲ ਡੈਟਾ ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ਵੌਇਸਮੇਲ ਸੁਨੇਹੇ"</string>
-    <string name="notification_channel_wfc" msgid="2130802501654254801">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
+    <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi‑Fi ਕਾਲਿੰਗ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"ਪੀਅਰ ਨੇ TTY Mode FULL ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ਪੀਅਰ ਨੇ TTY Mode HCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ਪੀਅਰ ਨੇ TTY Mode VCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
@@ -129,16 +132,16 @@
     <string name="roamingText11" msgid="4154476854426920970">"ਰੋਮਿੰਗ ਬੈਨਰ ਚਾਲੂ"</string>
     <string name="roamingText12" msgid="1189071119992726320">"ਰੋਮਿੰਗ ਬੈਨਰ ਬੰਦ"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"ਸੇਵਾ ਦੀ ਖੋਜ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ਕਾਲਿੰਗ"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="2254967670088539682">"ਵਾਈ-ਫਾਈ ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
+    <item msgid="2254967670088539682">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="6177300162212449033">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
   </string-array>
   <string-array name="wfcSpnFormats">
     <item msgid="6830082633573257149">"%s"</item>
-    <item msgid="4397097370387921767">"%s ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</item>
+    <item msgid="4397097370387921767">"%s Wi-Fi ਕਾਲਿੰਗ"</item>
   </string-array>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ਬੰਦ"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ Wi-Fi"</string>
@@ -188,8 +191,8 @@
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਮਿਟਾਈ ਜਾਏਗੀ"</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦਾ ਡੈਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="me" msgid="6545696007631404292">"ਮੈਂ"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ਟੈਬਲੇਟ ਚੋਣਾਂ"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV ਚੋਣਾਂ"</string>
@@ -206,7 +209,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"ਅਪਡੇਟ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"ਅਪਡੇਟ ਪੈਕੇਜ ਦੀ ਕਾਰਵਾਈ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"ਰੀਸਟਾਰਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"ਫੈਕਟਰੀ ਡੈਟਾ ਰੀਸੈੱਟ"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"ਰੀਸਟਾਰਟ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਬੰਦ ਕੀਤੀ ਜਾਏਗੀ।"</string>
@@ -226,11 +229,11 @@
     <string name="global_action_emergency" msgid="7112311161137421166">"ਸੰਕਟਕਾਲ"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"ਬਗ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ਬਗ ਰਿਪੋਰਟ ਲਓ"</string>
-    <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੇ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਠੀ ਕਰੇਗਾ। ਬਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈ-ਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੀ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਤਰ ਕਰੇਗਾ। ਬਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ਅੰਤਰਕਿਰਿਆਤਮਕ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ਜ਼ਿਆਦਾਤਰ ਹਾਲਾਤਾਂ ਵਿੱਚ ਇਸ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਤੁਹਾਨੂੰ ਰਿਪੋਰਟ ਦੀ ਪ੍ਰਗਤੀ ਨੂੰ ਟਰੈਕ ਕਰਨ, ਸਮੱਸਿਆ ਬਾਰੇ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ, ਅਤੇ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦਿੰਦਾ ਹੈ। ਇਹ ਉਹਨਾਂ ਘੱਟ-ਵਰਤੇ ਗਏ ਕੁਝ ਭਾਗਾਂ ਨੂੰ ਨਜ਼ਰ-ਅੰਦਾਜ਼ ਕਰ ਸਕਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਦੀ ਰਿਪੋਰਟ ਕਰਨ ਵਿੱਚ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ।"</string>
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"ਪੂਰੀ ਰਿਪੋਰਟ"</string>
-    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ਜਦੋਂ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਪ੍ਰਤਿਕਿਰਿਆ ਨਾ ਕਰ ਰਿਹਾ ਹੋਵੇ ਜਾਂ ਬਹੁਤ ਹੀ ਹੌਲੀ ਹੋਵੇ, ਜਾਂ ਜਦੋਂ ਤੁਹਾਨੂੰ ਸਾਰੇ ਰਿਪੋਰਟ ਭਾਗਾਂ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸ ਚੋਣ ਦੀ ਵਰਤੋਂ ਘੱਟ-ਘੱਟ ਸਿਸਟਮ ਦਖ਼ਲ ਲਈ ਕਰੋ। ਤੁਹਾਨੂੰ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ ਜਾਂ ਵਾਧੂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲੈਣ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="bugreport_option_full_summary" msgid="7210859858969115745">"ਜਦੋਂ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਪ੍ਰਤਿਕਿਰਿਆ ਨਾ ਕਰ ਰਹੀ ਹੋਵੇ ਜਾਂ ਬਹੁਤ ਹੀ ਹੌਲੀ ਹੋਵੇ, ਜਾਂ ਜਦੋਂ ਤੁਹਾਨੂੰ ਸਾਰੇ ਰਿਪੋਰਟ ਭਾਗਾਂ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸ ਚੋਣ ਦੀ ਵਰਤੋਂ ਘੱਟ-ਤੋਂ-ਘੱਟ ਸਿਸਟਮ ਦਖ਼ਲ ਲਈ ਕਰੋ। ਤੁਹਾਨੂੰ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ ਜਾਂ ਵਾਧੂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲੈਣ ਦਿੰਦਾ ਹੈ।"</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
       <item quantity="one">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
       <item quantity="other">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
@@ -243,7 +246,7 @@
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"ਏਅਰਪਲੇਨ ਮੋਡ ਬੰਦ ਹੈ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"ਸਹਾਇਤਾ ਕਰੋ"</string>
-    <string name="global_action_voice_assist" msgid="7751191495200504480">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
+    <string name="global_action_voice_assist" msgid="7751191495200504480">"ਵੌਇਸ ਅਸਿਸਟ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ ਲੌਕ ਕਰੋ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"ਸਮੱਗਰੀਆਂ ਲੁਕਾਈਆਂ ਗਈਆਂ"</string>
@@ -266,7 +269,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਹਨ"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ਬੈਟਰੀ ਅਤੇ ਡਾਟਾ ਵਰਤੋਂ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
@@ -275,13 +278,13 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ਟਿਕਾਣਾ"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਿਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚੋ"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ਸਟੋਰੇਜ"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨਾ"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"ਆਪਣੀ ਡੀਵਾਈਸ ’ਤੇ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"ਮਾਈਕ੍ਰੋਫੋਨ"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"ਕੈਮਰਾ"</string>
@@ -317,11 +320,11 @@
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦਿਓ"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ਐਪ ਨੂੰ ਆਉਣ ਵਾਲੀ ਫ਼ੋਨ ਕਾਲ ਦਾ ਜਵਾਬ ਦੇਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"ਟੈਕਸਟ ਸੁਨੇਹੇ (SMS) ਪ੍ਰਾਪਤ ਕਰੋ"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"ਟੈਕਸਟ ਸੁਨੇਹੇ (MMS) ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"ਐਪ ਨੂੰ MMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"ਐਪ ਨੂੰ MMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਸੰਕਟਕਾਲੀਨ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਿਤ ਟਿਕਾਣਿਆਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੀਆਂ ਹਨ ਜਦੋਂ ਇੱਕ ਸੰਕਟਕਾਲੀਨ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈਲ ਪ੍ਰਸਾਰਨ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਐਮਰਜੈਂਸੀ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖ਼ਰਾਬ ਐਪਸ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੇ ਹਨ ਜਦੋਂ ਇੱਕ ਐਮਰਜੈਂਸੀ ਸੈਲ ਪ੍ਰਸਾਰਨ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ਸਬਸਕ੍ਰਾਈਬ ਕੀਤੇ ਫੀਡਸ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਸਿੰਕ ਕੀਤੇ ਫੀਡਸ ਬਾਰੇ ਵੇਰਵੇ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ"</string>
@@ -331,11 +334,11 @@
     <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ SMS (ਲਿਖਤ) ਸੁਨੇਹਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ SMS (ਲਿਖਤ) ਸੁਨੇਹਿਆਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"ਟੈਕਸਟ ਸੁਨੇਹੇ (WAP) ਪ੍ਰਾਪਤ ਕਰੋ"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ਐਪ ਨੂੰ WAP ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਅਨੁਮਤੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਐਪ ਦੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀ ਸਮਰੱਥਾ।"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ਐਪ ਨੂੰ WAP ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸ ਅਨੁਮਤੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਐਪ ਦੀ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰਨ ਅਤੇ ਮਿਟਾਉਣ ਦੀ ਸਮਰੱਥਾ।"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ਚੱਲ ਰਹੇ ਐਪਸ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ਐਪ ਨੂੰ ਵਰਤਮਾਨ ਵਿੱਚ ਅਤੇ ਹੁਣੇ ਜਿਹੇ ਚੱਲ ਰਹੇ ਕੰਮਾਂ ਬਾਰੇ ਵਿਸਤ੍ਰਿਤ ਜਾਣਕਾਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਇਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਖੋਜਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ ਕਿ ਡੀਵਾਈਸ ਤੇ ਕਿਹੜੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਰਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ।"</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"ਪ੍ਰੋਫ਼ਾਈਲ ਅਤੇ ਡੀਵਾਈਸ ਮਾਲਕਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ਪ੍ਰੋਫ਼ਾਈਲ ਦੇ ਮਾਲਕ ਅਤੇ ਡੀਵਾਈਸ ਦੇ ਮਾਲਕ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਐਪਾਂ ਨੂੰ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ਪ੍ਰੋਫ਼ਾਈਲ ਦੇ ਮਾਲਕ ਅਤੇ ਡੀਵਾਈਸ ਦਾ ਮਾਲਕ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਐਪਸ ਨੂੰ ਅਨੁਮਤੀ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ਚੱਲ ਰਹੇ ਐਪਸ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ਐਪ ਨੂੰ ਕੰਮਾਂ ਨੂੰ ਅਗਲੇ ਭਾਗ ਅਤੇ ਪਿਛੋਕੜ ਵਿੱਚ ਮੂਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਐਪ ਤੁਹਾਡੇ ਇਨਪੁਟ ਤੋਂ ਬਿਨਾਂ ਇਹ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ਕਾਰ ਮੋਡ ਸਮਰੱਥ ਬਣਾਓ"</string>
@@ -347,7 +350,7 @@
     <string name="permlab_runInBackground" msgid="7365290743781858803">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਓ"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਸਕਦੀ ਹੈ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਵਧੇਰੇ ਤੇਜ਼ੀ ਨਾਲ ਖਤਮ ਹੋ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
-    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟੇ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀ ਹੈ। ਇਸ ਨਾਲ ਡਾਟਾ ਵਰਤੋਂ ਵਧ ਸਕਦੀ ਹੈ।"</string>
+    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀ ਹੈ। ਇਸ ਨਾਲ ਡੈਟਾ ਉਪਯੋਗ ਵਧ ਸਕਦਾ ਹੈ।"</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"ਐਪ ਨੂੰ ਹਮੇਸ਼ਾਂ ਰਨ ਕਰੋ"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਟੈਬਲੇਟ ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਸ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"ਐਪ ਨੂੰ ਮੈਮਰੀ ਵਿੱਚ ਖੁਦ ਦੇ ਭਾਗਾਂ ਨੂੰ ਸਥਾਈ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ TV ਨੂੰ ਹੌਲੀ ਕਰਦੇ ਹੋਏ ਹੋਰਾਂ ਐਪਸ ਤੇ ਉਪਲਬਧ ਮੈਮਰੀ ਨੂੰ ਸੀਮਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
@@ -411,7 +414,7 @@
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS ਕਾਲ ਸੇਵਾ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਨ ਲਈ IMS ਸੇਵਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ਫੋਨ ਸਥਿਤੀ ਅਤੇ ਪਛਾਣ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੀਆਂ ਫ਼ੋਨ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਅਨੁਮਤੀ ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੰਬਰ ਅਤੇ ਡੀਵਾਈਸ ਆਈ.ਡੀ. ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ, ਇੱਕ ਕਾਲ ਕਿਰਿਆਸ਼ੀਲ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਰਿਮੋਟ ਨੰਬਰ ਇੱਕ ਕਾਲ ਨਾਲ ਕਨੈਕਟ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ਐਪ ਨੂੰ ਡੀਵਾਈਸ ਦੀਆਂ ਫੋਨ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਅਨੁਮਤੀ ਐਪ ਨੂੰ ਫ਼ੋਨ ਨੰਬਰ ਅਤੇ ਡੀਵਾਈਸ ID ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ, ਇੱਕ ਕਾਲ ਸਕਿਰਿਆ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਰਿਮੋਟ ਨੰਬਰ ਇੱਕ ਕਾਲ ਨਾਲ ਕਨੈਕਟ ਹੈ ਜਾਂ ਨਹੀਂ।"</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"ਸਿਸਟਮ ਰਾਹੀਂ ਕਾਲਾਂ ਰੂਟ ਕਰੋ"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"ਕਾਲ ਕਰਨ ਦੇ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਐਪ ਨੂੰ ਇਸਦੀਆਂ ਕਾਲਾਂ ਨੂੰ ਸਿਸਟਮ ਰਾਹੀਂ ਰੂਟ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"ਫ਼ੋਨ ਨੰਬਰ ਪੜ੍ਹੋ"</string>
@@ -449,7 +452,7 @@
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi ਕਨੈਕਸ਼ਨ ਦੇਖੋ"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ਐਪ ਨੂੰ Wi-Fi ਨੈਟਵਰਕਿੰਗ ਬਾਰੇ ਜਾਣਕਾਰੀ ਦੇਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਵੇਂ Wi-Fi ਸਮਰਥਿਤ ਹੈ ਜਾਂ ਨਹੀਂ ਅਤੇ ਕਨੈਕਟ ਕੀਤੀਆਂ Wi-Fi ਡਿਵਾਈਸਾਂ ਦਾ ਨਾਮ।"</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi ਤੋਂ ਕਨੈਕਟ ਅਤੇ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ਐਪ ਨੂੰ ਵਾਈ-ਫਾਈ ਪਹੁੰਚ ਬਿੰਦੂਆਂ ਤੇ ਕਨੈਕਟ ਅਤੇ ਇਹਨਾਂ ਤੋਂ ਡਿਸਕਨੈਕਟ ਕਰਨ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈਟਵਰਕਾਂ ਲਈ ਡੀਵਾਈਸ ਸੰਰੂਪਣ ਵਿੱਚ ਬਦਲਾਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ਐਪ ਨੂੰ Wi-Fi ਪਹੁੰਚ ਬਿੰਦੂਆਂ ਤੇ ਕਨੈਕਟ ਅਤੇ ਇਹਨਾਂ ਤੋਂ ਡਿਸਕਨੈਕਟ ਕਰਨ ਅਤੇ Wi-Fi ਨੈਟਵਰਕਾਂ ਲਈ ਡੀਵਾਈਸ ਕੌਂਫਿਗਰੇਸ਼ਨ ਵਿੱਚ ਬਦਲਾਵ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi ਮਲਟੀਕਾਸਟ ਰਿਸੈਪਸ਼ਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ Wi-Fi ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ਐਪ ਨੂੰ ਮਲਟੀਕਾਸਟ ਪਤੇ ਵਰਤਦੇ ਹੋਏ ਇੱਕ Wi-Fi ਨੈੱਟਵਰਕ ਤੇ ਸਾਰੀਆਂ ਡਿਵਾਈਸਾਂ ਤੇ ਭੇਜੇ ਗਏ ਪੈਕੇਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਕੇਵਲ ਤੁਹਾਡਾ TV ਨਹੀਂ। ਇਹ ਗ਼ੈਰ-ਮਲਟੀਕਾਸਟ ਮੋਡ ਦੇ ਮੁਕਾਬਲੇ ਵੱਧ ਪਾਵਰ ਵਰਤਦਾ ਹੈ।"</string>
@@ -540,7 +543,7 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ਹੋਲਡਰ ਨੂੰ ਕੈਰੀਅਰ-ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤੇ ਕੌਂਫਿਗਰੇਸ਼ਨ ਐਪ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ਨੈੱਟਵਰਕ ਸਥਿਤੀਆਂ ਤੇ ਟਿੱਪਣੀਆਂ ਸੁਣੋ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ਇੱਕ ਐਪਲੀਸ਼ਨ ਨੂੰ ਨੈੱਟਵਰਕ ਸਥਿਤੀਆਂ ਤੇ ਟਿੱਪਣੀਆਂ ਸੁਣਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
-    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ਇਨਪੁੱਟ ਡੀਵਾਈਸ ਕੈਲੀਬ੍ਰੇਸ਼ਨ ਬਦਲੋ"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ਇਨਪੁਟ ਡੀਵਾਈਸ ਕੈਲੀਬ੍ਰੇਸ਼ਨ ਬਦਲੋ"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ਐਪ ਨੂੰ ਟਚ ਸਕ੍ਰੀਨ ਦੇ ਕੈਲੀਬ੍ਰੇਸ਼ਨ ਪੈਰਾਮੀਟਰਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM ਸਰਟੀਫਿਕੇਟਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਿਵਸਥਾ ਕਰਨ ਅਤੇ DRM ਸਰਟੀਫਿਕੇਟ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
@@ -555,7 +558,7 @@
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡਾਂ ਅਤੇ PIN ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"ਸਕ੍ਰੀਨ ਅਨਲੌਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ ਟੈਬਲੇਟ ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ ਟੈਬਲੇਟ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਲੌਕ ਕਰਦੇ ਸਮੇਂ ਟਾਈਪ ਕੀਤੇ ਗ਼ਲਤ ਪਾਸਵਰਡਾਂ ਦੀ ਸੰਖਿਆ ਦਾ ਨਿਰੀਖਣ ਕਰੋ ਅਤੇ TV ਨੂੰ ਲੌਕ ਕਰੋ ਜਾਂ TV ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ ਜੇਕਰ ਬਹੁਤ ਜ਼ਿਆਦਾ ਗ਼ਲਤ ਪਾਸਵਰਡ ਟਾਈਪ ਕੀਤੇ ਹਨ।"</string>
@@ -568,17 +571,17 @@
     <string name="policylab_forceLock" msgid="2274085384704248431">"ਸਕ੍ਰੀਨ ਲੌਕ ਕਰੋ"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"ਇਸਤੇ ਨਿਯੰਤਰਣ ਪਾਓ ਕਿ ਸਕ੍ਰਿਨ ਕਿਵੇਂ ਅਤੇ ਕਦੋਂ ਲੌਕ ਹੁੰਦੀ ਹੈ।"</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੈਬਲੇਟ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੀਵੀ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"ਇੱਕ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫੋਨ ਦਾ ਡਾਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ਇੱਕ ਫੈਕਟਰੀ ਡੈਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਟੈਬਲੇਟ ਦਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"ਇੱਕ ਫੈਕਟਰੀ ਡੈਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ TV ਦਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"ਇੱਕ ਫੈਕਟਰੀ ਡੈਟਾ ਰੀਸੈੱਟ ਕਰਕੇ ਚਿਤਾਵਨੀ ਤੋਂ ਬਿਨਾਂ ਫੋਨ ਦਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"ਉਪਭੋਗਤਾ ਡੈਟਾ ਮਿਟਾਓ"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਟੈਬਲੇਟ ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ TV ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"ਬਿਨਾਂ ਚਿਤਾਵਨੀ ਦੇ ਇਸ ਫੋਨ ਤੇ ਮੌਜੂਦ ਇਸ ਉਪਭੋਗਤਾ ਦਾ ਸਾਰਾ ਡੈਟਾ ਮਿਟਾਓ।"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"ਜਦੋਂ ਨੀਤੀ ਸਮਰਥਿਤ ਹੋਵੇ ਤਾਂ ਵਰਤੇ ਜਾਣ ਲਈ ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ। ਕੇਵਲ ਡੀਵਾਈਸ ਮਾਲਕ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"ਜਦੋਂ ਪਾੱਲਿਸੀ ਸਮਰਥਿਤ ਹੋਵੇ ਤਾਂ ਵਰਤੇ ਜਾਣ ਲਈ ਡੀਵਾਈਸ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈੱਟ ਕਰੋ। ਕੇਵਲ ਡੀਵਾਈਸ ਮਾਲਡ ਗਲੋਬਲ ਪ੍ਰੌਕਸੀ ਸੈਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡ ਸਮਾਪਤੀ ਮਿਆਦ ਸੈੱਟ ਕਰੋ"</string>
-    <string name="policydesc_expirePassword" msgid="5367525762204416046">"ਇਸ ਵਿੱਚ ਬਦਲਾਵ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡ, ਪਿੰਨ ਜਾਂ ਪੈਟਰਨ ਨੂੰ ਕਿੰਨੀ ਵਾਰ ਬਦਲਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"ਇਸ ਵਿੱਚ ਬਦਲਾਵ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲੌਕ ਪਾਸਵਰਡ, PIN ਜਾਂ ਪੈਟਰਨ ਨੂੰ ਕਿੰਨੀ ਵਾਰ ਬਦਲਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ਸਟੋਰੇਜ ਇਨਕ੍ਰਿਪਸ਼ਨ ਸੈੱਟ ਕਰੋ"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ਲੋੜ ਹੈ ਕਿ ਸਟੋਰ ਕੀਤਾ ਐਪ ਡੈਟਾ ਇਨਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾਏ।"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"ਕੈਮਰੇ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
@@ -699,14 +702,14 @@
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"ਕੰਮ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ਹੋਰ"</string>
     <string name="quick_contacts_not_available" msgid="746098007828579688">"ਇਸ ਸੰਪਰਕ ਨੂੰ ਦੇਖਣ ਲਈ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਮਿਲੇ।"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ਪਿੰਨ ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ਅਤੇ ਨਵਾਂ ਪਿੰਨ ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ਅਤੇ ਨਵਾਂ PIN ਕੋਡ ਟਾਈਪ ਕਰੋ"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK ਕੋਡ"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ਨਵਾਂ ਪਿੰਨ ਕੋਡ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ਨਵਾਂ PIN ਕੋਡ"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"ਪਾਸਵਰਡ ਟਾਈਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਪਿੰਨ ਟਾਈਪ ਕਰੋ"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ਗ਼ਲਤ ਪਿੰਨ ਕੋਡ।"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ਅਨਲੌਕ ਕਰਨ ਲਈ PIN ਟਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ਗ਼ਲਤ PIN ਕੋਡ।"</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"ਅਨਲੌਕ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਮੀਨੂ ਫਿਰ 0 ਦਬਾਓ।"</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"ਐਮਰਜੈਂਸੀ ਨੰਬਰ"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"ਕੋਈ ਸੇਵਾ ਨਹੀਂ"</string>
@@ -744,7 +747,7 @@
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM ਕਾਰਡ ਅਨਲੌਕ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ਤੁਸੀਂ ਆਪਣਾ PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n  <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -791,7 +794,7 @@
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ਅਨਲੌਕ ਸਲਾਈਡ ਕਰੋ।"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ਪੈਟਰਨ ਅਨਲੌਕ।"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ਚਿਹਰਾ ਅਨਲੌਕ।"</string>
-    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ਪਿੰਨ ਅਨਲੌਕ।"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin ਅਨਲੌਕ।"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ਪਾਸਵਰਡ ਅਨਲੌਕ।"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ਪੈਟਰਨ ਖੇਤਰ।"</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ਖੇਤਰ ਸਲਾਈਡ ਕਰੋ।"</string>
@@ -833,7 +836,7 @@
     <string name="autofill_area" msgid="3547409050889952423">"ਖੇਤਰ"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"ਅਮੀਰਾਤ"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"ਆਪਣੇ ਵੈਬ ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ ਪੜ੍ਹੋ"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ਐਪ ਨੂੰ ਸਾਰੇ URL ਜਿਨ੍ਹਾਂ ਤੇ ਬ੍ਰਾਊਜ਼ਰ ਨੇ ਵਿਜਿਟ ਕੀਤਾ ਹੈ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਸਾਰੇ ਬੁੱਕਮਾਰਕਾਂ, ਦਾ ਇਤਿਹਾਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਾ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ਐਪ ਨੂੰ ਸਾਰੇ URL ਜਿਹਨਾਂ ਤੇ ਬ੍ਰਾਊਜ਼ਰ ਨੇ ਵਿਜਿਟ ਕੀਤਾ ਹੈ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਦੇ ਸਾਰੇ ਬੁੱਕਮਾਰਕਸ, ਦਾ ਇਤਿਹਾਸ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਾਂ ਵਾਲੇ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"ਵੈਬ ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ ਲਿਖੋ"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੀ ਟੈਬਲੇਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡੈਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਇਤਿਹਾਸ ਅਤੇ ਤੁਹਾਡੇ TV ਤੇ ਸਟੋਰ ਕੀਤੇ ਬੁੱਕਮਾਰਕਾਂ ਨੂੰ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ ਬ੍ਰਾਊਜ਼ਰ ਡੈਟਾ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ। ਨੋਟ: ਇਹ ਅਨੁਮਤੀ ਤੀਜੀ-ਪਾਰਟੀ ਬ੍ਰਾਊਜ਼ਰਾਂ ਜਾਂ ਵੈਬ ਬ੍ਰਾਊਜ਼ਿੰਗ ਸਮਰੱਥਤਾਵਂ ਵਾਲੀਆਂ ਹੋਰਾਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵੱਲੋਂ ਲਾਗੂ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
@@ -1113,7 +1116,7 @@
     <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi ਦੀ ਕੋਈ ਇੰਟਰਨੈਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"ਮੋਬਾਈਲ ਡੈਟਾ"</item>
@@ -1139,8 +1142,8 @@
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"ਕਨੈਕਟ ਕਰਨ ਲਈ ਸੱਦਾ"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"ਇਸ ਤੋਂ:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"ਵੱਲ:"</string>
-    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ਲੋੜੀਂਦਾ ਪਿੰਨ ਟਾਈਪ ਕਰੋ:"</string>
-    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ਪਿੰਨ:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ਲੁੜੀਂਦਾ PIN ਟਾਈਪ ਕਰੋ:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ਟੈਬਲੇਟ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗੀ"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ਫੋਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ Wi-Fi ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
@@ -1162,7 +1165,7 @@
     <string name="sim_removed_message" msgid="2333164559970958645">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਅਣਉਪਲਬਧ ਹੋਵੇਗਾ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰਮਾਣਿਕ SIM ਕਾਰਡ ਪਾ ਕੇ ਰੀਸਟਾਰਟ ਨਹੀਂ ਕਰਦੇ।"</string>
     <string name="sim_done_button" msgid="827949989369963775">"ਹੋ ਗਿਆ"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM ਕਾਰਡ ਜੋੜਿਆ ਗਿਆ"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਲਈ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮੁੜ-ਚਾਲੂ ਕਰੋ।"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਲਈ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਰੀਸਟਾਰਟ ਕਰੋ।"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ਰੀਸਟਾਰਟ ਕਰੋ"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"ਤੁਹਾਡੀ ਨਵੀਂ SIM ਦੇ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਤੋਂ ਇੱਕ ਐਪ ਸਥਾਪਤ ਕਰਨ ਅਤੇ ਖੋਲ੍ਹਣ ਦੀ ਲੋੜ ਪਵੇਗੀ।"</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ਐਪ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
@@ -1178,20 +1181,23 @@
     <string name="no_permissions" msgid="7283357728219338112">"ਕੋਈ ਅਨੁਮਤੀਆਂ ਲੁੜੀਂਦੀਆਂ ਨਹੀਂ"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"ਇਸ ਨਾਲ ਤੁਹਾਨੂੰ ਖ਼ਰਚਾ ਪੈ ਸਕਦਾ ਹੈ"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ਠੀਕ"</string>
-    <string name="usb_charging_notification_title" msgid="6895185153353640787">"ਇਹ ਡੀਵਾਈਸ USB ਰਾਹੀਂ ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="usb_supplying_notification_title" msgid="5310642257296510271">"ਨੱਥੀ ਕੀਤੇ ਡੀਵਾਈਸ ਨੂੰ USB ਰਾਹੀਂ ਪਾਵਰ ਮਿਲ ਰਹੀ ਹੈ"</string>
+    <string name="usb_charging_notification_title" msgid="6895185153353640787">"ਇਹ ਡੀਵਾਈਸ USB ਰਾਹੀਂ ਚਾਰਜ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <string name="usb_supplying_notification_title" msgid="5310642257296510271">"ਨੱਥੀ ਕੀਤੀ ਡੀਵਾਈਸ ਨੂੰ USB ਰਾਹੀਂ ਪਾਵਰ ਮਿਲ ਰਹੀ ਹੈ"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"ਫ਼ਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਲਈ USB"</string>
     <string name="usb_ptp_notification_title" msgid="1347328437083192112">"ਫ਼ੋਟੋ ਟ੍ਰਾਂਸਫ਼ਰ ਲਈ USB"</string>
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ਲਈ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ਇੱਕ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ਔਡੀਓ ਉਪਸਾਧਨ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਇਸ ਡੀਵਾਈਸ ਦੀ ਸਮੱਸਿਆ ਨੂੰ ਠੀਕ ਕਰਨ ਵਿੱਚ ਮਦਦ ਲਈ ਬੱਗ ਰਿਪੋਰਟ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ। ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਇਸ ਡੀਵਾਈਸ ਦੀ ਸਮੱਸਿਆ ਨੂੰ ਠੀਕ ਕਰਨ ਵਿੱਚ ਮਦਦ ਲਈ ਬੱਗ ਰਿਪੋਰਟ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ। ਐਪਾਂ ਅਤੇ ਡੈਟੇ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ਕੀ-ਬੋਰਡ ਬਦਲੋ"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਪਰ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰ ਐਪਾਂ ਦੇ ਉੱਤੇ ਹੈ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰਾਂ ਐਪਾਂ ਦੇ ਉੱਤੇ ਹੈ।"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"ਜੇ ਤੁਸੀਂ ਨਹੀਂ ਚਾਹੁੰਦੇ ਕਿ <xliff:g id="NAME">%s</xliff:g> ਐਪ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਦੀ ਵਰਤੋਂ ਕਰੇ, ਤਾਂ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
@@ -1214,8 +1221,8 @@
     <string name="ext_media_unmountable_notification_message" msgid="2343202057122495773">"<xliff:g id="NAME">%s</xliff:g> ਗ਼ਲਤ ਹੈ। ਠੀਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> ਖਰਾਬ ਹੈ। ਠੀਕ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"ਅਸਮਰਥਿਤ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫੌਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਵੰਨਗੀ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
+    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਫੌਰਮੈਟ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"ਇਹ ਡੀਵਾਈਸ ਇਸ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ। ਕਿਸੇ ਸਮਰਥਿਤ ਵੰਨਗੀ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> ਨੂੰ ਅਚਨਚੇਤ ਹਟਾਇਆ ਗਿਆ"</string>
     <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"ਡੇਟਾ ਦੇ ਨੁਕਸਾਨ ਤੋਂ ਬੱਚਣ ਲਈ ਹਟਾਉਣ ਤੋਂ ਪਹਿਲਾਂ <xliff:g id="NAME">%s</xliff:g> ਅਨਮਾਊਂਟ ਕਰੋ"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"ਹਟਾਇਆ <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"ਕਾਰ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੀਥਰਿਗ ਜਾਂ ਹੌਟਸਪੌਟ ਸਕਿਰਿਆ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ਪਿੱਛੇ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ਅੱਗੇ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ਛੱਡੋ"</string>
@@ -1441,21 +1446,21 @@
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ਗ਼ਲਤ ਪੈਟਰਨ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ਗ਼ਲਤ ਪਾਸਵਰਡ"</string>
-    <string name="kg_wrong_pin" msgid="1131306510833563801">"ਗ਼ਲਤ ਪਿੰਨ"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"ਗ਼ਲਤ PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"ਆਪਣਾ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string>
-    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_pin_instructions" msgid="2377242233495111557">"ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ਹੁਣ ਅਸਮਰਥਿਤ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ਲੋੜੀਂਦਾ ਪਿੰਨ ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ਲੋੜੀਂਦੇ ਪਿੰਨ ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ਲੁੜੀਂਦਾ PIN ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ਲੁੜੀਂਦੇ PIN ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ਕਾਰਡ ਅਨਲੌਕ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ਗ਼ਲਤ ਪਿੰਨ ਕੋਡ।"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ਇੱਕ ਪਿੰਨ ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੈ।"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ਗ਼ਲਤ PIN ਕੋਡ।"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ਇੱਕ PIN ਟਾਈਪ ਕਰੋ ਜੋ 4 ਤੋਂ 8 ਨੰਬਰਾਂ ਦਾ ਹੈ।"</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK ਕੋਡ 8 ਸੰਖਿਆਵਾਂ ਦਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"ਲਹੀ PUK ਕੋਡ ਮੁੜ-ਦਾਖਲ ਕਰੋ। ਦੁਹਰਾਈਆਂ ਗਈਆਂ ਕੋਸ਼ਿਸ਼ਾਂ SIM ਨੂੰ ਸਥਾਈ ਤੌਰ ਤੇ ਅਸਮਰੱਥ ਬਣਾ ਦੇਵੇਗਾ।"</string>
-    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ਪਿੰਨ ਕੋਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ਕੋਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਪੈਟਰਨ ਕੋਸ਼ਿਸ਼ਾਂ"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"ਅਨਲੌਕ ਕਰਨ ਲਈ, ਆਪਣੇ Google ਖਾਤੇ ਨਾਲ ਸਾਈਨ ਇਨ ਕਰੋ।"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"ਵਰਤੋਂਕਾਰ ਨਾਮ (ਈਮੇਲ)"</string>
@@ -1464,7 +1469,7 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ਅਪ੍ਰਮਾਣਿਕ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਵਰਤੋਂਕਾਰ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਹੋ?\n"<b>"google.com/accounts/recovery"</b>" ਤੇ ਜਾਓ।"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"ਖਾਤੇ ਦੀ ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ਤੁਸੀਂ ਆਪਣਾ ਪਿੰਨ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ਤੁਸੀਂ ਆਪਣਾ PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
@@ -1585,15 +1590,15 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"ਪ੍ਰਿੰਟ ਸੇਵਾ ਸਮਰਥਿਤ ਨਹੀਂ"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> ਸੇਵਾ ਇੰਸਟੌਲ ਕੀਤੀ"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"ਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"ਪ੍ਰਸ਼ਾਸਕ ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
-    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"ਪ੍ਰਸ਼ਾਸਕ PIN ਦਾਖਲ ਕਰੋ"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN ਦਾਖਲ ਕਰੋ"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"ਗ਼ਲਤ"</string>
-    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ਮੌਜੂਦਾ ਪਿੰਨ"</string>
-    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ਨਵਾਂ ਪਿੰਨ"</string>
-    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ਨਵੇਂ ਪਿੰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
-    <string name="restr_pin_create_pin" msgid="8017600000263450337">"ਪ੍ਰਤਿਬੰਧ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਇੱਕ ਪਿੰਨ ਬਣਾਓ"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ਪਿੰਨ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ਪਿੰਨ ਬਹੁਤ ਜ਼ਿਆਦਾ ਛੋਟਾ ਹੈ। ਘੱਟੋ-ਘੱਟ 4 ਅੰਕ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ।"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ਮੌਜੂਦਾ PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ਨਵਾਂ PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ਨਵੇਂ PIN ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"ਪ੍ਰਤਿਬੰਧ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਇੱਕ PIN ਬਣਾਓ"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ਬਹੁਤ ਜ਼ਿਆਦਾ ਛੋਟਾ ਹੈ। ਘੱਟੋ-ਘੱਟ 4 ਅੰਕ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ।"</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="one"> <xliff:g id="COUNT">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</item>
       <item quantity="other"> <xliff:g id="COUNT">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</item>
@@ -1617,15 +1622,15 @@
     <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"ਇਸ ਐਪ ਨੂੰ ਅਨਪਿੰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"ਸਕ੍ਰੀਨ ਅਨਪਿਨ ਕੀਤੀ"</string>
-    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ PIN ਮੰਗੋ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਨਲੌਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
     <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="data_saver_description" msgid="6015391409098303235">"ਡਾਟਾ ਵਰਤੋਂ ਘਟਾਉਣ ਵਿੱਚ ਮਦਦ ਲਈ, ਡਾਟਾ ਸੇਵਰ ਕੁਝ ਐਪਾਂ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਟਾ ਭੇਜਣ ਜਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਵਰਤਮਾਨ ਤੌਰ \'ਤੇ ਵਰਤੀ ਜਾ ਰਹੀ ਐਪ ਡਾਟੇ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਉਹ ਇੰਝ ਕਦੇ-ਕਦਾਈਂ ਕਰ ਸਕਦੀ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸ ਦਾ ਮਤਲਬ ਇਹ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਚਿੱਤਰ ਤਦ ਤੱਕ ਨਹੀਂ ਦਿਖਾਏ ਜਾਂਦੇ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ \'ਤੇ ਟੈਪ ਨਹੀਂ ਕਰਦੇ।"</string>
-    <string name="data_saver_enable_title" msgid="4674073932722787417">"ਕੀ ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</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>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d ਮਿੰਟਾਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ) </item>
@@ -1661,18 +1666,18 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ (ਅਗਲਾ ਅਲਾਰਮ)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੇਵਾ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ \'ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੇਵਾ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"ਨਸ਼ਟ ਕਰੋ"</string>
-    <string name="zen_mode_feature_name" msgid="5254089399895895004">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ਡਾਊਨਟਾਈਮ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ਵੀਕਨਾਈਟ"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ਹਫ਼ਤੇ ਦਾ ਅੰਤਲਾ ਦਿਨ"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ਇਵੈਂਟ"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਵੱਲੋਂ ਮਿਊਟ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string>
-    <string name="system_error_manufacturer" msgid="8086872414744210668">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਸੀ। ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਨਿਰਮਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡੈਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਸੀ। ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਨਿਰਮਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD ਬੇਨਤੀ DIAL ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD ਬੇਨਤੀ SS ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD ਬੇਨਤੀ ਨਵੀਂ USSD ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
@@ -1723,11 +1728,11 @@
     <string name="unpin_target" msgid="3556545602439143442">"ਅਨਪਿੰਨ ਕਰੋ"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
+    <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨੀ ਹੈ?"</string>
     <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ਡੈਮੋ ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="demo_restarting_message" msgid="952118052531642451">"ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
+    <string name="demo_restarting_message" msgid="952118052531642451">"ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
+    <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"ਕੀ ਡੀਵਾਈਸ ਮੁੜ-ਸੈੱਟ ਕਰਨੀ ਹੈ?"</string>
     <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"ਤੁਸੀਂ ਕਿਸੇ ਵੀ ਤਬਦੀਲੀਆਂ ਨੂੰ ਗੁਆ ਬੈਠੋਂਗੇ ਅਤੇ ਡੈਮੋ <xliff:g id="TIMEOUT">%1$s</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਚਾਲੂ ਕੀਤਾ ਜਾਵੇਗਾ…"</string>
     <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"ਰੱਦ ਕਰੋ"</string>
     <string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ਹੁਣੇ ਮੁੜ-ਸੈੱਟ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 9a9ae8a..aa323ea 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Usługa nie jest świadczona."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia ID rozmówcy."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Brak usługi transmisji danych"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Brak możliwości wykonywania połączeń alarmowych"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Brak usługi połączeń alarmowych"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Brak usługi połączeń głosowych"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Brak usługi połączeń głosowych/alarmowych"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Usługa tymczasowo nieoferowana przez sieć komórkową w Twojej lokalizacji"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Twój operator tymczasowo zawiesił usługę transmisji danych w tej lokalizacji"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Twój operator tymczasowo zawiesił połączenia alarmowe w tej lokalizacji"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Twój operator tymczasowo zawiesił połączenia głosowe w tej lokalizacji"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Twój operator tymczasowo zawiesił połączenia głosowe i alarmowe w tej lokalizacji"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Brak zasięgu sieci"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Aby poprawić odbiór, zmień typ sieci – wybierz System &gt; Sieć i internet &gt; Sieci komórkowe &gt; Preferowany typ sieci."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerty"</string>
@@ -1229,6 +1232,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB w trybie MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Kliknij, by wyświetlić więcej opcji."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Nieobsługiwane akcesorium audio"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Kliknij, aby uzyskać więcej informacji"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Kliknij, by wyłączyć debugowanie USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Kliknij, by wybrać język i układ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Wyświetlanie nad innymi aplikacjami"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Wyświetlanie aplikacji <xliff:g id="NAME">%s</xliff:g> nad innymi"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Aplikacja <xliff:g id="NAME">%s</xliff:g> jest nad innymi"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jeśli nie chcesz, by aplikacja <xliff:g id="NAME">%s</xliff:g> korzystała z tej funkcji, otwórz ustawienia i ją wyłącz."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Kliknij, by zakończyć tryb samochodowy."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Wróć"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Dalej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Pomiń"</string>
@@ -1453,7 +1457,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łam..."</string>
+    <string name="sending" msgid="3245653681008218030">"Wysyłanie..."</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>
@@ -1647,7 +1651,7 @@
       <item quantity="one">Spróbuj ponownie za sekundę</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Spróbuj ponownie później"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"Włączony pełny ekran"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Widok na pełnym ekranie"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Aby wyjść, przesuń palcem z góry na dół."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"OK"</string>
     <string name="done_label" msgid="2093726099505892398">"Gotowe"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index dcaac52..5bf1f8d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"O serviço não foi habilitado."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Não é possível alterar a configuração de identificação de chamadas."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Sem serviço de dados"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Sem chamada de emergência"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sem serviço de emergência"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sem serviço de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Sua operadora suspendeu temporariamente o serviço de dados neste local"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Sua operadora suspendeu temporariamente as chamadas de emergência neste local"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Sua operadora suspendeu temporariamente as chamadas de voz neste local"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Sua operadora suspendeu temporariamente as chamadas de voz e de emergência neste local"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a recepção, tente alterar o tipo selecionado em Sistema &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -1013,7 +1016,7 @@
     <string name="whichSendToApplication" msgid="8272422260066642057">"Enviar usando"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"Enviar usando %1$s"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"Enviar"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de início"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de Página inicial"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Usar %1$s como Página inicial"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"Capturar imagem"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"Capturar imagem com"</string>
@@ -1185,8 +1188,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não compatível"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para mais informações"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração do USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Sobrepor a outros apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> exibido sobre outros apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> exibido sobre outros apps."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se você não deseja que o <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo carro."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
@@ -1623,7 +1627,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Excluído pelo seu administrador"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho do dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros apps que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros aplicativos que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode significar que as imagens não serão exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar Economia de dados?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a657720..e1afe56 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -63,7 +63,7 @@
     <string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
     <string name="enablePin" msgid="209412020907207950">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="one">Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item>
+      <item quantity="one">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
       <item quantity="other">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Serviço não fornecido."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Não pode alterar a definição da identificação de chamadas."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Sem serviço de dados"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Sem chamadas de emergência"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sem serviço de emergência"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sem serviço de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente não disponibilizado pela rede móvel na sua localização"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"O seu operador suspendeu temporariamente o serviço de dados nesta localização"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"O seu operador suspendeu temporariamente as chamadas de emergência nesta localização"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"O seu operador suspendeu temporariamente as chamadas de voz nesta localização"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"O seu operador suspendeu temporariamente as chamadas de voz e de emergência nesta localização"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não é possível ligar à rede"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a receção, experimente alterar o tipo selecionado em Sistema &gt; Rede e Internet &gt; Redes móveis &gt; Tipo de rede preferido."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -176,7 +179,7 @@
     <string name="low_memory" product="tv" msgid="516619861191025923">"O armazenamento da TV está cheio. Elimine alguns ficheiros para libertar espaço."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telemóvel está cheio. Elimine alguns ficheiros para libertar espaço."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
-      <item quantity="one">Autoridade de certificação instalada</item>
+      <item quantity="one">Certificate authorities installed</item>
       <item quantity="other">Autoridades de certificação instaladas</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por um terceiro desconhecido"</string>
@@ -232,7 +235,7 @@
     <string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string>
     <string name="bugreport_option_full_summary" msgid="7210859858969115745">"Utilize esta opção para uma interferência mínima do sistema quando o dispositivo não responder ou estiver demasiado lento, ou quando precisar de todas as secções de relatório. Não permite introduzir mais detalhes ou tirar capturas de ecrã adicionais."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
-      <item quantity="one">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_0">%d</xliff:g> segundo…</item>
+      <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
       <item quantity="other">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
     </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
@@ -868,7 +871,7 @@
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Há 1 mês"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Há mais de 1 mês"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
-      <item quantity="one">Último <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+      <item quantity="one">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
     </plurals>
     <string name="last_month" msgid="3959346739979055432">"Último mês"</string>
@@ -890,67 +893,67 @@
     <string name="years" msgid="6881577717993213522">"anos"</string>
     <string name="now_string_shortest" msgid="8912796667087856402">"agora"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> m</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> h</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> d</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> d</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
-      <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> a</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>a</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> min</item>
-      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> min</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
+      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>m</item>
     </plurals>
     <plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> h</item>
-      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
+      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>h</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> d</item>
-      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> d</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
+      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>d</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> a</item>
-      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
+      <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>a</item>
     </plurals>
     <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
-      <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
       <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
     </plurals>
     <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
-      <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
       <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
     </plurals>
     <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
-      <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
       <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
     </plurals>
     <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
-      <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
       <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
     </plurals>
     <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
       <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
     </plurals>
     <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
       <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
     </plurals>
     <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
     </plurals>
     <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
-      <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+      <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
       <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
     </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string>
@@ -1099,11 +1102,11 @@
     <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string>
     <string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="one">Rede Wi-Fi disponível</item>
+      <item quantity="one">Wi-Fi networks available</item>
       <item quantity="other">Redes Wi-Fi disponíveis</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="one">Rede Wi-Fi aberta disponível</item>
+      <item quantity="one">Open Wi-Fi networks available</item>
       <item quantity="other">Redes Wi-Fi abertas disponíveis</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Iniciar sessão na rede Wi-Fi"</string>
@@ -1155,7 +1158,7 @@
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Enviar"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Cancelar"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Memorizar a minha escolha"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Pode alterar mais tarde em Definições &gt; Aplicações"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Pode depois alterar isto em Definições &gt; Aplicações"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permitir Sempre"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nunca Permitir"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
@@ -1185,9 +1188,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ligado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para obter mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não suportado"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para obter mais informações"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccione para desativar depuração USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"A partilhar relatório de erro…"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o esquema"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Sobrepor a outras aplicações"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"A aplicação <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplicações"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"O <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplic."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se não pretende que a aplicação <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
@@ -1301,15 +1307,13 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo automóvel."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o administrador para obter detalhes."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Anterior"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
     <string name="no_matches" msgid="8129421908915840737">"Sem correspondências"</string>
     <string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
-      <item quantity="one">1 correspondência</item>
+      <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string>
@@ -1595,7 +1599,7 @@
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não correspondem. Tente novamente."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é demasiado pequeno. Deve ter, no mínimo, 4 dígitos."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
-      <item quantity="one">Tente novamente dentro de 1 segundo</item>
+      <item quantity="one">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
       <item quantity="other">Tente novamente dentro de <xliff:g id="COUNT">%d</xliff:g> segundos</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
@@ -1628,35 +1632,35 @@
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar a Poupança de dados?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
-      <item quantity="one">Durante um minuto (até à(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
-      <item quantity="other">Durante %1$d minutos (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597">
-      <item quantity="one">Durante 1 min (até à(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
-      <item quantity="other">Durante %1$d min (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">Durante %1$d min (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
-      <item quantity="one">Durante uma hora (até à(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
-      <item quantity="other">Durante %1$d horas (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">Durante %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371">
-      <item quantity="one">Durante 1 h (até à(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
-      <item quantity="other">Durante %1$d h (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="one">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">Durante %1$d h (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
-      <item quantity="one">Durante um minuto</item>
+      <item quantity="one">For %d minutes</item>
       <item quantity="other">Durante %d minutos</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128">
-      <item quantity="one">Durante 1 min</item>
+      <item quantity="one">For %d min</item>
       <item quantity="other">Durante %d min</item>
     </plurals>
     <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
-      <item quantity="one">Durante uma hora</item>
+      <item quantity="one">For %d hours</item>
       <item quantity="other">Durante %d horas</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217">
-      <item quantity="one">Durante 1 h</item>
+      <item quantity="one">For %d hr</item>
       <item quantity="other">Durante %d h</item>
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1692,7 +1696,7 @@
     <string name="close_button_text" msgid="3937902162644062866">"Fechar"</string>
     <string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string>
@@ -1756,7 +1760,7 @@
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher automaticamente o conteúdo"</string>
     <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Sem sugestões do preenchimento automático"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
-      <item quantity="one">Uma sugestão do preenchimento automático</item>
+      <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> sugestões do preenchimento automático</item>
     </plurals>
     <string name="autofill_save_title" msgid="3345527308992082601">"Pretende guardar no &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index dcaac52..5bf1f8d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"O serviço não foi habilitado."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Não é possível alterar a configuração de identificação de chamadas."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Sem serviço de dados"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Sem chamada de emergência"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Sem serviço de emergência"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sem serviço de voz"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Sem serviço de voz/emergência"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Serviço temporariamente bloqueado pela rede móvel no seu local"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Sua operadora suspendeu temporariamente o serviço de dados neste local"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Sua operadora suspendeu temporariamente as chamadas de emergência neste local"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Sua operadora suspendeu temporariamente as chamadas de voz neste local"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Sua operadora suspendeu temporariamente as chamadas de voz e de emergência neste local"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Não foi possível acessar a rede"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Para melhorar a recepção, tente alterar o tipo selecionado em Sistema &gt; Rede &amp; Internet &gt; Redes móveis &gt; Tipo de rede preferencial."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alertas"</string>
@@ -1013,7 +1016,7 @@
     <string name="whichSendToApplication" msgid="8272422260066642057">"Enviar usando"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"Enviar usando %1$s"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"Enviar"</string>
-    <string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de início"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de Página inicial"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Usar %1$s como Página inicial"</string>
     <string name="whichHomeApplicationLabel" msgid="809529747002918649">"Capturar imagem"</string>
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"Capturar imagem com"</string>
@@ -1185,8 +1188,10 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Acessório de áudio não compatível"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toque para mais informações"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração do USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Sobrepor a outros apps"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> exibido sobre outros apps"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> exibido sobre outros apps."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Se você não deseja que o <xliff:g id="NAME">%s</xliff:g> use este recurso, toque para abrir as configurações e desativá-lo."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Toque para sair do modo carro."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string>
@@ -1623,7 +1627,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu administrador"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu administrador"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Excluído pelo seu administrador"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho do dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros apps que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"A economia de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados em segundo plano para aumentar a duração da bateria. E-mails, mensagens e outros aplicativos que dependem de sincronização não serão atualizados, a não ser que você os abra.\n\nA economia de bateria é desligada automaticamente quando o dispositivo está sendo carregado."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode significar que as imagens não serão exibidas até que você toque nelas."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar Economia de dados?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ed0e996..9d17566 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -91,10 +91,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Nu se asigură accesul la acest serviciu."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nu puteți să modificați setarea pentru ID-ul apelantului."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Fără serviciu de date"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Fără apeluri de urgență"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Fără serviciu de urgență"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Fără servicii vocale"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Fără servicii vocale/de urgență"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentan nu este oferit de rețeaua mobilă în locația dvs."</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operatorul dvs. a suspendat temporar serviciul de date în această locație"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operatorul dvs. a suspendat temporar apelurile de urgență în această locație"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operatorul dvs. a suspendat temporar apelurile vocale în această locație"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operatorul dvs. a suspendat temporar apelurile vocale și de urgență în această locație"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nu se poate stabili conexiunea la rețea"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Pentru o recepție mai bună, încercați să schimbați tipul selectat în Sistem &gt; Rețea și internet &gt; Rețele mobile &gt; Tip preferat de rețea."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Alerte"</string>
@@ -285,7 +288,7 @@
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"trimită și să vadă mesajele SMS"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stocare"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"acceseze fotografiile, conținutul media și fișierele de pe dispozitiv"</string>
-    <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfon"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfonul"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistreze sunet"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera foto"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografieze și să înregistreze videoclipuri"</string>
@@ -1207,6 +1210,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"Conexiune USB pentru MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectat la un accesoriu USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Atingeți pentru mai multe opțiuni."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accesoriul audio nu este acceptat"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Atingeți pentru mai multe informații"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Atingeți ca să dezactivați remedierea erorilor prin USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva depanarea USB."</string>
@@ -1223,7 +1228,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Atingeți pentru a selecta limba și aspectul"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Afișare peste alte aplicații"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> se afișează peste alte aplicații"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> se afișează peste aplicații"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Dacă nu doriți ca <xliff:g id="NAME">%s</xliff:g> să utilizeze această funcție, atingeți pentru a deschide setările și dezactivați-o."</string>
@@ -1323,8 +1329,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Atingeți ca să ieșiți din modul Mașină."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Înapoi"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Înainte"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Omiteți"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 3e64fa6..b0c8ea2 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услуга не предоставляется."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Невозможно изменить параметр идентификатора вызывающего абонента."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Мобильный Интернет недоступен"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Экстренные вызовы заблокированы"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Экстренные вызовы недоступны"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Голосовые вызовы недоступны"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Голосовые и экстренные вызовы недоступны"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Местная мобильная сеть временно не поддерживает эту функцию."</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Ваш оператор временно заблокировал передачу данных по мобильной сети в этом месте."</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Ваш оператор временно заблокировал экстренные вызовы в этом месте."</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Ваш оператор временно заблокировал голосовые вызовы в этом месте."</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Ваш оператор временно заблокировал голосовые и экстренные вызовы в этом месте."</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Сеть недоступна"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Чтобы улучшить сигнал, попробуйте выбрать другой тип сети в настройках (раздел \"Мобильные сети\")."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Оповещения"</string>
@@ -210,7 +213,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Подготовка обновлений…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Обработка обновлений…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Перезагрузка…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сбросить к заводским настройкам"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сброс к заводским настройкам"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Перезагрузка…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
@@ -1229,9 +1232,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI через USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Нажмите, чтобы показать дополнительные параметры."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоустройство не поддерживается"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Нажмите, чтобы получить дополнительную информацию"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Нажмите, чтобы отключить отладку по USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Подготовка отчета об ошибке"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Разрешить доступ к информации об ошибке?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Отправка отчета об ошибке"</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Нажмите, чтобы выбрать язык и раскладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Поверх других приложений"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g>: поверх других приложений"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>: поверх других приложений"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Чтобы отключить эту функцию для приложения <xliff:g id="NAME">%s</xliff:g>, перейдите в настройки."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Нажмите, чтобы выйти из автомобильного режима."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далее"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропустить"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index bf62bf8..5aa8788 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"සේවාවන් සපයා නැත."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"අමතන්නාගේ ID සැකසීම ඔබට වෙනස්කල නොහැක."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"දත්ත සේවාව නැත"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"හදිසි ඇමතුම් නැත"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"හදිසි සේවාව නැත"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"හඬ සේවාව නැත"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"හඬ/හදිසි සේවාව නොමැත"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"ඔබේ ස්ථානයේ ජංගම ජාලය මගින් තාවකාලිකව පිරිනොනමයි"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ඔබගේ වාහකයා මෙම ස්ථානයේ දත්ත සේවාව තාවකාලිකව අත්හිටුවා ඇත"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ඔබගේ වාහකයා මෙම ස්ථානයේ හදිසි ඇමතුම් තාවකාලිකව අත්හිටුවා ඇත"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ඔබගේ වාහකයා මෙම ස්ථානයේ හඬ ඇමතුම් තාවකාලිකව අත්හිටුවා ඇත"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ඔබගේ වාහකයා මෙම ස්ථානයේ හඬ සහ හදිසි ඇමතුම් තාවකාලිකව අත්හිටුවා ඇත"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"ජාලය වෙත ළඟා විය නොහැකිය"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"ප්‍රතිග්‍රහණය වැඩි දියුණු කිරීමට, පද්ධතිය &gt; ජාලය සහ අන්තර්ජාලය &gt; ජංගම ජාල &gt; වඩා කැමති ජාල වර්ගය තුළ තෝරන ලද වර්ගය වෙනස් කිරීම උත්සාහ කරන්න."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"ඇඟවීම්"</string>
@@ -1187,6 +1190,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI සඳහා USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ශ්‍රව්‍ය ආයිත්තම සහාය නොදක්වයි"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB නිදොස්කරණය අබල කිරීමට තට්ටු කරන්න."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
@@ -1203,7 +1208,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"භාෂාව හා පිරිසැලසුම තේරීමට තට්ටු කරන්න"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"වෙනත් යෙදුම් උඩින් පෙන්වන්න"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"අනෙක් යෙදුම්වලට උඩින් <xliff:g id="NAME">%s</xliff:g> සංදර්ශනය කරමින්"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"අනෙක් යෙදුම්වලට උඩින් <xliff:g id="NAME">%s</xliff:g> දිස් වේ"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"ඔබට <xliff:g id="NAME">%s</xliff:g> මෙම විශේෂාංගය භාවිත කිරීමට අවශ්‍ය නැති නම්, සැකසීම් විවෘත කිරීමට තට්ටු කර එය ක්‍රියාවිරහිත කරන්න."</string>
@@ -1303,8 +1309,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"මෝටර් රථ ප්‍රකාරයෙන් ඉවත් වීමට තට්ටු කරන්න."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
     <string name="back_button_label" msgid="2300470004503343439">"ආපසු"</string>
     <string name="next_button_label" msgid="1080555104677992408">"මීලඟ"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"මඟ හරින්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 123bc85..d79caec 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Služba nie je poskytovaná."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nemôžete meniť nastavenia identifikácie volajúceho."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Žiadna dátová služba"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Žiadne tiesňové hovory"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Tiesňové volania nie sú k dispozícii"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Žiadne hlasové hovory"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hlasové ani tiesňové volania nie sú k dispozícii"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Momentálne nie sú v ponuke mobilnej siete na vašom mieste"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Váš operátor dočasne pozastavil dátovú službu na tomto mieste"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Váš operátor v tejto oblasti dočasne pozastavil tiesňové volania"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Váš operátor dočasne pozastavil hlasové hovory z tohto miesta"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Váš operátor v tejto oblasti dočasne blokuje hlasové a tiesňové hovory"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepodarilo sa pripojiť k sieti"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ak chcete vylepšiť príjem, skúste zmeniť vybratý typ siete v časti Systém &gt; Sieť a internet &gt; Mobilné siete &gt; Preferovaný typ siete."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Upozornenia"</string>
@@ -1229,9 +1232,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB na pripojenie zariadenia MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Pripojené k periférnemu zariadeniu USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte ďalšie možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvukové príslušenstvo nie je podporované"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ďalšie informácie zobrazíte klepnutím"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladenie cez USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Výberom zakážete ladenie USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Preberá sa hlásenie chyby…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chcete zdieľať hlásenie chyby?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Zdieľa sa hlásenie chyby…"</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozloženie"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Zobrazenie cez iné aplikácie"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Klepnutím ukončíte režim V aute."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Späť"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Ďalej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskočiť"</string>
@@ -1648,7 +1652,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Skúste to znova neskôr"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Zobrazenie na celú obrazovku"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Ukončíte prejdením prstom zhora nadol."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Ukončite prejdením prstom z hornej časti nadol."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Dobre"</string>
     <string name="done_label" msgid="2093726099505892398">"Hotovo"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Kruhový posúvač hodín"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0eac889..5257d6f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Storitev ni nastavljena in omogočena."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ne morete spremeniti nastavitve ID-ja klicatelja."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ni storitve za prenos podatkov"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Brez možnosti klicanja v sili"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ni storitve za klice v sili"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ni storitve za glasovne klice"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ni storitve za glasovne klice / klice v sili"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Ta storitev trenutno ni na voljo v mobilnem omrežju na vaši lokaciji"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Vaš operater je na tej lokaciji začasno onemogočil storitev za prenos podatkov"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Vaš operater je na tej lokaciji začasno onemogočil klice v sili"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Vaš operater je na tej lokaciji začasno onemogočil glasovne klice"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Vaš operater je na tej lokaciji začasno onemogočil glasovne klice in klice v sili"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Povezave z omrežjem ni mogoče vzpostaviti"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Če želite izboljšati sprejem, poskusite zamenjati vrsto omrežja v možnostih »Sistem« &gt; »Omrežje in internet« &gt; »Mobilna omrežja« &gt; »Prednostna vrsta omrežja«."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Opozorila"</string>
@@ -282,11 +285,11 @@
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostop do stikov"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"dostop do lokacije te naprave"</string>
-    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Koledar"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Google Koledar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"pošiljanje in ogled sporočil SMS"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Shramba"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"dostop do fotografij, predstavnosti in datotek v napravi"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string>
@@ -1229,6 +1232,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dotaknite se za več možnosti."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvočna oprema ni podprta"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dotaknite se za več informacij"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dotaknite se za izklop odpravljanja napak prek USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dotaknite se, če želite izbrati jezik in postavitev."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Prekrivanje drugih aplikacij"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> prekriva druge aplikacije"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> prekriva druge aplikacije"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Če ne želite, da aplikacija <xliff:g id="NAME">%s</xliff:g> uporablja to funkcijo, se dotaknite, da odprete nastavitve, in funkcijo izklopite."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dotaknite se, če želite zapreti avtomobilski način."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Nazaj"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Naprej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Preskoči"</string>
@@ -1647,8 +1651,8 @@
       <item quantity="other">Poskusite znova čez <xliff:g id="COUNT">%d</xliff:g> sekund</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Poskusite znova pozneje"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"Vklopljen je celozaslonski način"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Zaprete ga tako, da z vrha s prstom povlečete navzdol."</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Celozaslonski način"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Zaprete tako, da z vrha s prstom povlečete navzdol."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Razumem"</string>
     <string name="done_label" msgid="2093726099505892398">"Dokončano"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Okrogli drsnik za ure"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 097a427..b92732d 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Shërbimi nuk është përgatitur."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Nuk mund ta ndryshosh cilësimin e ID-së së telefonuesit."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Nuk ka shërbim për të dhënat"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Asnjë telefonatë urgjence"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Nuk ka shërbim urgjence"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Nuk ka shërbim zanor"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Nuk ka shërbim zanor/urgjence"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Përkohësisht nuk ofrohet nga rrjeti celular në vendndodhjen tënde"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operatori yt ka pezulluar përkohësisht shërbimin e të dhënave në këtë vendndodhje"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operatori yt ka pezulluar përkohësisht telefonatat e urgjencës në këtë vendndodhje"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operatori yt ka pezulluar përkohësisht telefonatat zanore në këtë vendndodhje"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operatori yt ka pezulluar përkohësisht telefonatat zanore dhe të urgjencës në këtë vendndodhje"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Rrjeti i paarritshëm"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Për të përmirësuar marrjen e sinjalit, provo të ndryshosh llojin e zgjedhur te Sistemi &gt; Rrjeti dhe interneti &gt; Lloji i preferuar i rrjetit."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Sinjalizimet"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB për MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"U lidh me një ndihmës USB-je"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trokit për më shumë opsione."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori i audios nuk mbështetet"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trokit për më shumë informacion"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trokit për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Po ndan raportin e defekteve në kod..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trokit për të zgjedhur gjuhën dhe strukturën"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Shfaq mbi aplikacionet e tjera"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> afishohet mbi aplikacionet e tjera"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> shfaqet mbi apl. e tjera"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Nëse nuk dëshiron që <xliff:g id="NAME">%s</xliff:g> ta përdorë këtë funksion, trokit për të hapur cilësimet dhe për ta çaktivizuar."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Trokit për të dalë nga modaliteti \"në makinë\"."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Prapa"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Përpara"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Kapërce"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a8fd720..b9e2b31 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -91,10 +91,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услуга није добављена."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Не можете да промените подешавање ИД-а корисника."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Нема услуге преноса података"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Хитни позиви нису могући"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Нема услуге за хитне позиве"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Нема гласовне услуге"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Нема гласовне услуге/услуге за хитне позиве"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Привремено је онемогућено на мобилној мрежи на вашој локацији"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Мобилни оператер је привремено суспендовао услугу преноса података на овој локацији"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Мобилни оператер је привремено суспендовао хитне позиве на овој локацији"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Мобилни оператер је привремено суспендовао гласовне позиве на овој локацији"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Мобилни оператер је привремено суспендовао гласовне и хитне позиве на овој локацији"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Повезивање са мрежом није успело"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Да бисте побољшали пријем, пробајте да промените изабрани тип у одељку Систем &gt; Мрежа и интернет &gt; Мобилне мреже &gt; Жељени тип мреже."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Обавештења"</string>
@@ -1207,7 +1210,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Повезано са USB додатком"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Додирните за још опција."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је омогућено"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Додатна опрема за аудио садржај није подржана"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Додирните за више информација"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Извештај о грешци се генерише…"</string>
@@ -1223,7 +1228,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Додирните да бисте изабрали језик и распоред"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Приказ преко других апликација"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Апликација <xliff:g id="NAME">%s</xliff:g> се приказује преко других апликација"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> се приказује преко других аплик."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ако не желите ову функцију за <xliff:g id="NAME">%s</xliff:g>, додирните да бисте отворили подешавања и искључили је."</string>
@@ -1323,8 +1329,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Додирните да бисте изашли из режима рада у аутомобилу."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Next"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Прескочи"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2ce5390..8062acb 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Tjänsten är inte etablerad."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Det går inte att ändra inställningen för nummerpresentatör."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Datatjänst har blockerats"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Det går inte att ringa nödsamtal"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Tjänsten för nödsamtal har blockerats"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Tjänsten för röstsamtal har blockerats"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Tjänster för röst- och nödsamtal har blockerats"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Detta erbjuds för tillfället inte på mobilnätverket där du befinner dig"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operatören har tillfälligt stängt av datatjänst på denna plats"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operatören har tillfälligt stängt av nödsamtal på denna plats"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operatören har tillfälligt stängt av röstsamtal på denna plats"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operatören har tillfälligt stängt av röst- och nödsamtal på denna plats"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Det går inte att nå nätverket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Testa om du får bättre mottagning genom att ändra till en annan typ under System &gt; Nätverk och internet &gt; Mobila nätverk &gt; Önskad nätverkstyp."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Aviseringar"</string>
@@ -1129,7 +1132,7 @@
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Appen %1$s vill ansluta till Wi-Fi-nätverket %2$s"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"En app"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi direkt"</string>
-    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Starta direkt Wi-Fi-användning. Detta inaktiverar Wi-Fi-användning med klient/surfzon."</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Starta direkt Wi-Fi-användning. Detta inaktiverar Wi-Fi-användning med klient/trådlös surfzon."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Det gick inte att starta Wi-Fi direkt."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct är aktiverat"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Tryck för inställningar"</string>
@@ -1185,9 +1188,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB för MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ansluten till ett USB-tillbehör"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryck för fler alternativ."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ljudtillbehöret stöds inte"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryck för mer information"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryck om du vill inaktivera USB-felsökning."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Felrapporten överförs …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vill du dela felrapporten?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Felrapporten delas …"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryck om du vill välja språk och layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Visa ovanpå andra appar"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> visas över andra appar"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> visas över andra appar"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Om du inte vill att den här funktionen används för <xliff:g id="NAME">%s</xliff:g> öppnar du inställningarna genom att trycka. Sedan inaktiverar du funktionen."</string>
@@ -1217,7 +1223,7 @@
     <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Enheten har inte stöd för <xliff:g id="NAME">%s</xliff:g>. Tryck här om du vill konfigurera i ett format som stöds."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Enheten stöder inte detta <xliff:g id="NAME">%s</xliff:g>. Välj för att konfigurera i ett format som stöds."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> togs bort oväntat"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Avmontera <xliff:g id="NAME">%s</xliff:g> före borttagningen för att undvika dataförlust"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Montera bort <xliff:g id="NAME">%s</xliff:g> före borttagningen för att undvika dataförlust"</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"Ditt <xliff:g id="NAME">%s</xliff:g> har tagits bort"</string>
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> togs bort. Mata in ett nytt"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Ditt <xliff:g id="NAME">%s</xliff:g> matas fortfarande ut …"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Tryck om du vill avsluta billäge."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfpunkt aktiverad"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Tillbaka"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Nästa"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Hoppa över"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a85d4cb..4d50e91 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Huduma haitathminiwi."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Hauwezi kubadilisha mpangilio wa kitambulisho cha anayepiga."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Hakuna huduma ya data"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Huwezi kupiga simu za dharura"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Hakuna huduma za dharura"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Hakuna huduma za simu za sauti"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hakuna huduma ya simu za dharura au za sauti"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Kwa sasa, huduma hii haipatikani katika mtandao wa simu mahali ulipo"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Mtoa huduma wako amesitisha kwa muda huduma ya data mahali hapa"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Mtoa huduma wako amesitisha kwa muda huduma ya kupiga simu za dharura mahali hapa"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Mtoa huduma wako amesitisha kwa muda mfupi huduma ya kupiga simu za sauti mahali hapa"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Mtoa huduma wako amesitisha kwa muda huduma ya kupiga simu za dharura na za sauti mahali hapa"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Haiwezi kufikia mtandao"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ili kupata mtandao thabiti, jaribu kubadilisha aina iliyochaguliwa katika Mfumo &gt; Mtandao na Intaneti &gt; Mitandao ya simu &gt; Aina ya mtandao unaopendelea."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Arifa"</string>
@@ -367,9 +370,9 @@
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Huruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye runinga yako, pamoja na marudio ya upigaji wako wa simu, utumaji wa barua pepe, au mawasiliano kwa njia nyingine na watu maalum unaowasiliana nao. Idhini hii huruhusu programu kuhifadhi data yako ya mawasiliano, na programu hasidi zinaweza kushiriki data ya mawasiliano bila wewe kujua."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"kurekebisha anwani zako"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Huruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye runinga yako, pamoja na marudio ya upigaji wako wa simu, utumaji wa barua pepe, au mawasiliano kwa njia nyingine na watu maalum unaowasiliana nao. Ruhusa hii huruhusu programu kufuta data ya anwani."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye simu yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"kusoma rekodi ya simu"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"Programu hii inaweza kusoma rekodi yako ya simu zilizopigwa."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"kuandika rekodi ya simu"</string>
@@ -1183,6 +1186,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB kwa ajili ya MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Imeunganishwa kwa kifuasi cha USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Gonga ili upate chaguo zaidi."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Kifuasi cha sauti hakiwezi kutumika"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Gonga ili upate maelezo zaidi"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Gonga ili uzime utatuaji wa USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
@@ -1199,7 +1204,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Gonga ili uchague lugha na muundo"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Onyesha juu ya programu zingine"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> inachomoza juu ya programu zingine"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> inachomoza juu ya programu zingine."</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Ikiwa hutaki <xliff:g id="NAME">%s</xliff:g> kutumia kipengele hiki, gonga ili ufungue mipangilio na ukizime."</string>
@@ -1299,8 +1305,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Gonga ili ufunge hali ya garini."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Gonga ili uweke mipangilio."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Nyuma"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Ifuatayo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Ruka"</string>
@@ -1383,7 +1387,7 @@
     <string name="data_usage_limit_body" msgid="291731708279614081">"Data imesitishwa kwa mzunguko uliosalia"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Kikomo cha data ya 2G-3G kimezidishwa"</string>
     <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Kikomo cha data cha 4G kimezidishwa"</string>
-    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Umepitisha kiwango cha data ulichoweka"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Kikomo cha data ya ya kifaa cha mkononi kimezidishwa"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Taarifa za Wi-fi zimevuka kiwanga"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> juu ya kikomo kilichobainishwa."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Data ya mandhari nyuma imezuiwa"</string>
@@ -1598,7 +1602,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Jaribu tena baadaye"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Unatazama skrini nzima"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Ili kuondoka, telezesha kidole kutoka juu hadi chini."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Ili kuondoka, telezesha kidole chini kutoka sehemu ya juu."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"Nimeelewa"</string>
     <string name="done_label" msgid="2093726099505892398">"Imekamilika"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Kitelezi cha mviringo wa saa"</string>
@@ -1621,7 +1625,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Imesakinishwa na msimamizi wako"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Imesasishwa na msimamizi wako"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Imefutwa na msimamizi wako"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Ili kuboresha muda wa matumizi ya betri, kiokoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali na data nyingi ya chini chini. Programu za barua pepe, za kutuma ujumbe na zinginezo, zinazotegemea usawazishaji huenda zisisasishwe usipozifungua.\n\nKiokoa betri hujizima kiotomatiki wakati kifaa chako kinachaji."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Ili kuboresha muda wa matumizi ya betri, kiokoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotegemea usawazishaji huenda zisisasishwe usipozifungua.\n\nKiokoa betri hujizima kiotomatiki wakati kifaa chako kinachaji."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Ili kusaidia kupunguza matumizi ya data, Kiokoa Data huzuia baadhi ya programu kupokea na kutuma data chini chini. Programu ambayo unatumia sasa inaweza kufikia data, lakini si kila wakati. Kwa mfano, haitaonyesha picha hadi utakapozifungua."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ungependa Kuwasha Kiokoa Data?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Washa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e59334b..91196b9 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"சேவை ஒதுக்கப்படவில்லை."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"அழைப்பாளர் ஐடி அமைப்பை மாற்ற முடியாது."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"தரவுச் சேவை இல்லை"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"அவசர அழைப்பு வசதி இல்லை"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"அவசரச் சேவை இல்லை"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"குரல் சேவை இல்லை"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"குரல்/அவசரச் சேவை இல்லை"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"தற்காலிகமாக உங்கள் இருப்பிடத்தில் மொபைல் நெட்வொர்க் வழங்கவில்லை"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"உங்கள் தொலைத்தொடர்பு நிறுவனம் தரவுச் சேவையை இந்த இடத்தில் தற்காலிகமாக நிறுத்தியுள்ளது"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"உங்கள் தொலைத்தொடர்பு நிறுவனம் அவசர அழைப்புகளை இந்த இடத்தில் தற்காலிகமாக நிறுத்தியுள்ளது"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"உங்கள் தொலைத்தொடர்பு நிறுவனம் குரல் அழைப்புகளை இந்த இடத்தில் தற்காலிகமாக நிறுத்தியுள்ளது"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"உங்கள் தொலைத்தொடர்பு நிறுவனம் குரல் மற்றும் அவசர அழைப்புகளை இந்த இடத்தில் தற்காலிகமாக நிறுத்தியுள்ளது"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"நெட்வொர்க்குடன் இணைக்க முடியவில்லை"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"பெறுதலை மேம்படுத்த, சாதனம் &gt; நெட்வொர்க் &amp; இணையம் &gt; மொபைல் நெட்வொர்க்குகள் &gt; விரும்பும் நெட்வொர்க் வகை என்பதற்குச் சென்று, தேர்ந்தெடுத்த வகையை மாற்றவும்."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"விழிப்பூட்டல்கள்"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB, MIDIக்கு மட்டும்"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB துணைக்கருவியுடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"மேலும் விருப்பங்களுக்கு, தட்டவும்."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ஆடியோ துணைக்கருவி ஆதரிக்கப்படவில்லை"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"மேலும் தகவலுக்கு, தட்டவும்"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB பிழை திருத்தத்தை முடக்க, தட்டவும்."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைத்திருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"பிழை அறிக்கையைப் பகிர்கிறது…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற பயன்பாடுகளின் மேலே காட்டு"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற பயன்பாடுகளின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"கார் பயன்முறையிலிருந்து வெளியேற, தட்டவும்."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
     <string name="back_button_label" msgid="2300470004503343439">"முந்தையது"</string>
     <string name="next_button_label" msgid="1080555104677992408">"அடுத்து"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"தவிர்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 9e28969..ddf6397 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -54,7 +54,7 @@
     <string name="serviceErased" msgid="1288584695297200972">"ఎరేజ్ చేయడం విజయవంతమైంది."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"చెల్లని పాస్‌వర్డ్."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI పూర్తయింది."</string>
-    <string name="badPin" msgid="9015277645546710014">"మీరు టైప్ చేసిన పాత పిన్ చెల్లదు."</string>
+    <string name="badPin" msgid="9015277645546710014">"మీరు టైప్ చేసిన పాత పిన్‌ చెల్లదు."</string>
     <string name="badPuk" msgid="5487257647081132201">"మీరు టైప్ చేసిన PUK చెల్లదు."</string>
     <string name="mismatchPin" msgid="609379054496863419">"మీరు టైప్ చేసిన పిన్‌లు సరిపోలలేదు."</string>
     <string name="invalidPin" msgid="3850018445187475377">"4 నుండి 8 సంఖ్యలు ఉండే పిన్‌ను టైప్ చేయండి."</string>
@@ -73,7 +73,7 @@
     <string name="ColpMmi" msgid="3065121483740183974">"కనెక్ట్ చేయబడిన పంక్తి ID"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"కనెక్ట్ చేయబడిన పంక్తి ID నియంత్రణ"</string>
     <string name="CfMmi" msgid="5123218989141573515">"కాల్ ఫార్వర్డింగ్"</string>
-    <string name="CwMmi" msgid="9129678056795016867">"కాల్ వెయిటింగ్"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"కాల్ నిరీక్షణ"</string>
     <string name="BaMmi" msgid="455193067926770581">"కాల్ బేరింగ్"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"పాస్‌వర్డ్ మార్పు"</string>
     <string name="PinMmi" msgid="3113117780361190304">"పిన్‌ మార్పు"</string>
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"సేవ కేటాయించబడలేదు."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"మీరు కాలర్ ID సెట్టింగ్‌ను మార్చలేరు."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"డేటా సేవ లేదు"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"అత్యవసర కాలింగ్ సదుపాయం లేదు"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"అత్యవసర సేవ లేదు"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"వాయిస్ సేవ లేదు"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"వాయిస్/అత్యవసర సేవ లేదు"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"మీ స్థానంలో మొబైల్ నెట్‌వర్క్ ద్వారా తాత్కాలికంగా అందించబడదు"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"మీ క్యారియర్ ఈ స్థానంలో డేటా సేవను తాత్కాలికంగా నిలిపివేసింది"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"మీ క్యారియర్ ఈ స్థానంలో అత్యవసర కాల్‌లను తాత్కాలికంగా నిలిపివేసింది"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"మీ క్యారియర్ ఈ స్థానంలో వాయిస్ కాల్‌లను తాత్కాలికంగా నిలిపివేసింది"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"మీ క్యారియర్ ఈ స్థానంలో వాయిస్ మరియు అత్యవసర కాల్‌లను తాత్కాలికంగా నిలిపివేసింది"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"నెట్‌వర్క్‌ను చేరుకోలేరు"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"స్వీకరణను మెరుగుపరచాలంటే, సిస్టమ్ &gt; నెట్‌వర్క్ &amp; ఇంటర్నెట్ &gt; మొబైల్ నెట్‌వర్క్‌లు &gt; ప్రాధాన్య నెట్‌వర్క్ రకంలో మీరు ఎంచుకున్న రకాన్ని మార్చి ప్రయత్నించండి."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"హెచ్చరికలు"</string>
@@ -124,8 +127,8 @@
     <string name="roamingText6" msgid="2059440825782871513">"రోమింగ్ - అందుబాటులో ఉన్న సిస్టమ్"</string>
     <string name="roamingText7" msgid="7112078724097233605">"రోమింగ్ - అనుబంధ భాగస్వామి"</string>
     <string name="roamingText8" msgid="5989569778604089291">"రోమింగ్ - ప్రీమియం భాగస్వామి"</string>
-    <string name="roamingText9" msgid="7969296811355152491">"రోమింగ్ - పూర్తి సేవ పనితనం"</string>
-    <string name="roamingText10" msgid="3992906999815316417">"రోమింగ్ - పాక్షిక సేవ పనితనం"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"రోమింగ్ - పూర్తి సేవ కార్యాచరణ"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"రోమింగ్ - పాక్షిక సేవ కార్యాచరణ"</string>
     <string name="roamingText11" msgid="4154476854426920970">"రోమింగ్ బ్యానర్ ఆన్‌లో ఉంది"</string>
     <string name="roamingText12" msgid="1189071119992726320">"రోమింగ్ బ్యానర్ ఆఫ్‌లో ఉంది"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"సేవ కోసం శోధిస్తోంది"</string>
@@ -183,13 +186,13 @@
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"మీ కార్యాలయ ప్రొఫైల్ నిర్వాహకుల ద్వారా"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> ద్వారా"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"కార్యాలయ ప్రొఫైల్ తొలగించబడింది"</string>
-    <string name="work_profile_deleted_description" msgid="1100529432509639864">"నిర్వాహక యాప్ లేనందున కార్యాలయ ప్రొఫైల్ తొలగించబడింది"</string>
-    <string name="work_profile_deleted_details" msgid="6307630639269092360">"కార్యాలయ ప్రొఫైల్ నిర్వాహక యాప్ లేదు లేదా పాడైంది. తత్ఫలితంగా, మీ కార్యాలయ ప్రొఫైల్ మరియు సంబంధిత డేటా తొలగించబడ్డాయి. సహాయం కోసం మీ నిర్వాహకులను సంప్రదించండి."</string>
+    <string name="work_profile_deleted_description" msgid="1100529432509639864">"నిర్వాహక అనువర్తనం లేనందున కార్యాలయ ప్రొఫైల్ తొలగించబడింది"</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"కార్యాలయ ప్రొఫైల్ నిర్వాహక అనువర్తనం లేదు లేదా పాడైంది. తత్ఫలితంగా, మీ కార్యాలయ ప్రొఫైల్ మరియు సంబంధిత డేటా తొలగించబడ్డాయి. సహాయం కోసం మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"ఈ పరికరంలో మీ కార్యాలయ ప్రొఫైల్ ఇప్పుడు అందుబాటులో లేదు"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"పరికరం నిర్వహించబడింది"</string>
     <string name="network_logging_notification_text" msgid="7930089249949354026">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string>
-    <string name="factory_reset_message" msgid="7972496262232832457">"నిర్వాహక యాప్‌ ఉపయోగించడం సాధ్యపడదు. మీ డివైజ్‌లోని డేటా ఇప్పుడు తొలగించబడుతుంది.\n\nమీకు సందేహాలుంటే, మీ సంస్థ యొక్క నిర్వాహకులను సంప్రదించండి."</string>
+    <string name="factory_reset_message" msgid="7972496262232832457">"నిర్వాహక అనువర్తనం ఉపయోగించడం సాధ్యపడదు. మీ పరికరంలోని డేటా ఇప్పుడు తొలగించబడుతుంది.\n\nమీకు సందేహాలుంటే, మీ సంస్థ యొక్క నిర్వాహకులను సంప్రదించండి."</string>
     <string name="me" msgid="6545696007631404292">"నేను"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"టాబ్లెట్ ఎంపికలు"</string>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"టీవీ ఎంపికలు"</string>
@@ -202,9 +205,9 @@
     <string name="silent_mode_silent" msgid="319298163018473078">"రింగర్ ఆఫ్‌లో ఉంది"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"రింగర్ వైబ్రేట్‌లో ఉంది"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"రింగర్ ఆన్‌లో ఉంది"</string>
-    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android సిస్టమ్ అప్‌డేట్"</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Android సిస్టమ్ నవీకరణ"</string>
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"నవీకరించడానికి సిద్ధం చేస్తోంది…"</string>
-    <string name="reboot_to_update_package" msgid="3871302324500927291">"అప్‌డేట్ ప్యాకేజీని ప్రాసెస్ చేస్తోంది…"</string>
+    <string name="reboot_to_update_package" msgid="3871302324500927291">"నవీకరణ ప్యాకేజీని ప్రాసెస్ చేస్తోంది…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"పునఃప్రారంభించబడుతోంది…"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"ఫ్యాక్టరీ డేటా రీసెట్ చేయండి"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"పునఃప్రారంభించబడుతోంది…"</string>
@@ -243,7 +246,7 @@
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"ఎయిర్‌ప్లేన్ మోడ్ ఆఫ్‌లో ఉంది"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"సెట్టింగ్‌లు"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"సహాయం"</string>
-    <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ అసిస్టెంట్"</string>
+    <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ సహాయకం"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"కంటెంట్‌లు దాచబడ్డాయి"</string>
@@ -317,9 +320,9 @@
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"ఫోన్ కాల్‌లకు సమాధానమివ్వు"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ఇన్‌కమింగ్ ఫోన్ కాల్‌లకు సమాధానమివ్వడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"వచన సందేశాలను (SMS) స్వీకరించడం"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. యాప్ మీ డివైజ్‌కు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మీ పరికరానికి పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"వచన సందేశాలను (MMS) స్వీకరించడం"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. యాప్ మీ డివైజ్‌కు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మీ పరికరానికి పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"సెల్ ప్రసార సందేశాలను చదవడం"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సెల్ ప్రసార హెచ్చరికలు అత్యవసర పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని స్థానాల్లో అందించబడతాయి. అత్యవసర సెల్ ప్రసారం స్వీకరించినప్పుడు హానికరమైన అనువర్తనాలు మీ పరికరం యొక్క పనితీరు లేదా నిర్వహణకు అంతరాయం కలిగించవచ్చు."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"చందా చేయబడిన ఫీడ్‌లను చదవడం"</string>
@@ -327,9 +330,9 @@
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS సందేశాలను పంపడం మరియు వీక్షించడం"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS సందేశాలు పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన ఊహించని ఛార్జీలు విధించబడవచ్చు. హానికరమైన అనువర్తనాలు మీ నిర్ధారణ లేకుండానే సందేశాలను పంపడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"మీ వచన సందేశాలు (SMS లేదా MMS) చదవడం"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"ఈ యాప్‌ మీ టాబ్లెట్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"ఈ యాప్‌ మీ టీవీలో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
-    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"ఈ యాప్‌ మీ ఫోన్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"ఈ అనువర్తనం మీ టాబ్లెట్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"ఈ అనువర్తనం మీ టీవీలో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
+    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"ఈ అనువర్తనం మీ ఫోన్‌లో నిల్వ చేసిన అన్ని SMS (వచన) సందేశాలను చదవగలదు."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"వచన సందేశాలను (WAP) స్వీకరించడం"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీకు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగల లేదా తొలగించగల సామర్థ్యాన్ని కలిగి ఉంటుంది."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"అమలవుతున్న అనువర్తనాలను పునరుద్ధరించడం"</string>
@@ -337,28 +340,28 @@
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"ప్రొఫైల్ మరియు పరికర యజమానులను నిర్వహించడం"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ప్రొఫైల్ యజమానులను మరియు పరికరం యజమానిని సెట్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"అమలవుతున్న అనువర్తనాలను మళ్లీ క్రమం చేయడం"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"విధులను ముందుకు మరియు నేపథ్యానికి తరలించడానికి యాప్‌ను అనుమతిస్తుంది. యాప్ మీ ప్రమేయం లేకుండానే దీన్ని చేయవచ్చు."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"విధులను ముందుకు మరియు నేపథ్యానికి తరలించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మీ ప్రమేయం లేకుండానే దీన్ని చేయవచ్చు."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"కారు మోడ్‌ను ప్రారంభించడం"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"కారు మోడ్‌ను ప్రారంభించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"ఇతర అనువర్తనాలను మూసివేయడం"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"ఇతర అనువర్తనాల నేపథ్య ప్రాసెస్‌లను ముగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన ఇతర అనువర్తనాలు అమలు కాకుండా ఆపివేయబడవచ్చు."</string>
-    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"ఈ యాప్ ఇతర యాప్‌ల పైభాగాన కనిపించగలదు"</string>
-    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"ఈ యాప్ ఇతర యాప్‌ల పైభాగాన లేదా స్క్రీన్ యొక్క ఇతర భాగాలపైన కనిపించగలదు. ఇది సాధారణ యాప్ వినియోగానికి అంతరాయం కలిగించవచ్చు మరియు ఆ ఇతర యాప్‌లు కనిపించే విధానాన్ని మార్చవచ్చు."</string>
+    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"ఈ అనువర్తనం ఇతర అనువర్తనాల పైభాగాన కనిపించగలదు"</string>
+    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"ఈ అనువర్తనం ఇతర అనువర్తనాల పైభాగాన లేదా స్క్రీన్ యొక్క ఇతర భాగాలపైన కనిపించగలదు. ఇది సాధారణ అనువర్తన వినియోగానికి అంతరాయం కలిగించవచ్చు మరియు ఆ ఇతర అనువర్తనాలు కనిపించే విధానాన్ని మార్చవచ్చు."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"నేపథ్యంలో అమలు చేయండి"</string>
-    <string name="permdesc_runInBackground" msgid="7370142232209999824">"ఈ యాప్ నేపథ్యంలో అమలు కావచ్చు. దీని వలన ఎక్కువ బ్యాటరీ శక్తి వినియోగం కావచ్చు."</string>
+    <string name="permdesc_runInBackground" msgid="7370142232209999824">"ఈ అనువర్తనం నేపథ్యంలో అమలు కావచ్చు. దీని వలన ఎక్కువ బ్యాటరీ శక్తి వినియోగం కావచ్చు."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"నేపథ్యంలో డేటాను ఉపయోగించండి"</string>
-    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ఈ యాప్ నేపథ్యంలో డేటాను ఉపయోగించవచ్చు. దీని వలన డేటా వినియోగం అధికం కావచ్చు."</string>
+    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"ఈ అనువర్తనం నేపథ్యంలో డేటాను ఉపయోగించవచ్చు. దీని వలన డేటా వినియోగం అధికం కావచ్చు."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"అనువర్తనాన్ని ఎల్లప్పుడూ అమలు చేయడం"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"యాప్‌, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర యాప్‌లకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, టాబ్లెట్ నెమ్మదిగా పని చేస్తుంది."</string>
-    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"యాప్‌ దానిలోని కొన్ని భాగాలను మెమరీలో ఉంచడానికి దాన్ని అనుమతిస్తుంది. ఇది టీవీ నెమ్మదిగా పని చేసేలా చేస్తూ ఇతర అనువర్తనాలకు అందుబాటులో ఉన్న మెమరీని పరిమితం చేయవచ్చు."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"యాప్‌, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర యాప్‌లకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, ఫోన్ నెమ్మదిగా పని చేస్తుంది."</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"అనువర్తనం, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర అనువర్తనాలకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, టాబ్లెట్ నెమ్మదిగా పని చేస్తుంది."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"అనువర్తనం దానిలోని కొన్ని భాగాలను మెమరీలో ఉంచడానికి దాన్ని అనుమతిస్తుంది. ఇది టీవీ నెమ్మదిగా పని చేసేలా చేస్తూ ఇతర అనువర్తనాలకు అందుబాటులో ఉన్న మెమరీని పరిమితం చేయవచ్చు."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"అనువర్తనం, దాని భాగాలు మెమరీలో ఉండేలా చేయడానికి దానిని అనుమతిస్తుంది. ఇది ఇతర అనువర్తనాలకు అందుబాటులో ఉన్న మెమరీని ఆక్రమిస్తుంది, ఫోన్ నెమ్మదిగా పని చేస్తుంది."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"అనువర్తన నిల్వ స్థలాన్ని అంచనా వేయడం"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"యాప్‌ కోడ్, డేటా మరియు కాష్ పరిమాణాలను తిరిగి పొందడానికి దాన్ని అనుమతిస్తుంది"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"అనువర్తనం కోడ్, డేటా మరియు కాష్ పరిమాణాలను తిరిగి పొందడానికి దాన్ని అనుమతిస్తుంది"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"సిస్టమ్ సెట్టింగ్‌లను సవరించడం"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"సిస్టమ్ యొక్క సెట్టింగ్‌ల డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సిస్టమ్ యొక్క కాన్ఫిగరేషన్‌ను నాశనం చేయవచ్చు."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ప్రారంభంలో అమలు చేయడం"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది టాబ్లెట్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం టాబ్లెట్‌ను నెమ్మదిగా పని చేయడానికి అనువర్తనాన్ని అనుమతించేలా చేయవచ్చు."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే యాప్ దానికదే ప్రారంభం కావడానికి అనుమతిస్తుంది. ఇది టీవీ ప్రారంభం కావడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు కావడం ద్వారా మొత్తం టాబ్లెట్ పనితీరును నెమ్మది చేయడానికి యాప్‌ను అనుమతించవచ్చు."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే అనువర్తనం దానికదే ప్రారంభం కావడానికి అనుమతిస్తుంది. ఇది టీవీ ప్రారంభం కావడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు కావడం ద్వారా మొత్తం టాబ్లెట్ పనితీరును నెమ్మది చేయడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"సిస్టమ్ బూటింగ్‌ను పూర్తి చేసిన వెంటనే దానికదే ప్రారంభించబడటానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది ఫోన్‌ను ప్రారంభించడానికి ఎక్కువ సమయం పట్టేలా చేయవచ్చు మరియు ఎల్లప్పుడూ అమలు చేయడం ద్వారా మొత్తం ఫోన్‌ను నెమ్మదిగా పని చేయడానికి అనువర్తనాన్ని అనుమతించేలా చేయవచ్చు."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"స్టిక్కీ ప్రసారాన్ని పంపడం"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అత్యధిక వినియోగం వలన టాబ్లెట్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
@@ -373,7 +376,7 @@
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టీవీలో నిల్వ చేసిన మీ పరిచయాలకు సంబంధించిన డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్‌లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"కాల్ లాగ్‌ను చదవడం"</string>
-    <string name="permdesc_readCallLog" msgid="3204122446463552146">"ఈ యాప్‌ మీ కాల్ చరిత్రను చదవగలదు."</string>
+    <string name="permdesc_readCallLog" msgid="3204122446463552146">"ఈ అనువర్తనం మీ కాల్ చరిత్రను చదవగలదు."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"కాల్ లాగ్‌ను వ్రాయడం"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌ల గురించిన డేటాతో సహా మీ టాబ్లెట్ యొక్క కాల్ లాగ్‌ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్‌ను ఎరేజ్ చేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ కాల్‌లకు సంబంధించిన డేటాతో సహా మీ టీవీ కాల్ లాగ్‌ను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ కాల్ లాగ్‌ను తీసివేయడానికి లేదా సవరించడానికి దీన్ని ఉపయోగించవచ్చు."</string>
@@ -381,32 +384,32 @@
     <string name="permlab_bodySensors" msgid="4683341291818520277">"శరీర సెన్సార్‌లను (గుండె స్పందన రేటు మానిటర్‌ల వంటివి) ప్రాప్యత చేయడం"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"మీ శారీరక పరిస్థితిని అనగా మీ గుండె స్పందన రేటు వంటి వాటిని పర్యవేక్షించే సెన్సార్‌ల నుండి డేటాను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"క్యాలెండర్ ఈవెంట్‌లు మరియు వివరాలను చదవడం"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"ఈ యాప్ మీ టాబ్లెట్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"ఈ యాప్‌ మీ టీవీలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"ఈ యాప్ మీ ఫోన్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"ఈ అనువర్తనం మీ టాబ్లెట్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను భాగస్వామ్యం చేయగలదు లేదా సేవ్ చేయగలదు."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"ఈ అనువర్తనం మీ టీవీలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను భాగస్వామ్యం చేయగలదు లేదా సేవ్ చేయగలదు."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"ఈ అనువర్తనం మీ ఫోన్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను భాగస్వామ్యం చేయగలదు లేదా సేవ్ చేయగలదు."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"యజమానికి తెలియకుండానే క్యాలెండర్ ఈవెంట్‌లను జోడించి లేదా సవరించి, అతిథులకు ఇమెయిల్ పంపడం"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"ఈ యాప్ మీ టాబ్లెట్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"ఈ యాప్ మీ టీవీలో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"ఈ యాప్ మీ ఫోన్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ యాప్ క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"ఈ అనువర్తనం మీ టాబ్లెట్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ అనువర్తనం క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"ఈ అనువర్తనం మీ టీవీలో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ అనువర్తనం క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"ఈ అనువర్తనం మీ ఫోన్‌లో క్యాలెండర్ ఈవెంట్‌లను జోడించగలదు, తీసివేయగలదు లేదా మార్చగలదు. ఈ అనువర్తనం క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా సందేశాలను పంపగలదు లేదా ఈవెంట్‌లను వాటి యజమానులకు తెలియకుండానే మార్చగలదు."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"అదనపు స్థాన ప్రదాత ఆదేశాలను ప్రాప్యత చేయడం"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో యాప్‌ ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"అదనపు స్థాన ప్రదాత ఆదేశాలను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో అనువర్తనం ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"ఖచ్చితమైన స్థానాన్ని (GPS మరియు నెట్‌వర్క్-ఆధారితం) ప్రాప్యత చేయడం"</string>
-    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"ఈ యాప్‌ GPS ఆధారంగా లేదా సెల్ టవర్‌లు, Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ స్థాన మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి. ఇది బ్యాటరీ వినియోగాన్ని పెంచవచ్చు."</string>
+    <string name="permdesc_accessFineLocation" msgid="5821994817969957884">"ఈ అనువర్తనం GPS ఆధారంగా లేదా సెల్ టవర్‌లు, Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ స్థాన మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. అనువర్తనం ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి. ఇది బ్యాటరీ వినియోగాన్ని పెంచవచ్చు."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ఇంచుమించు స్థానాన్ని (నెట్‌వర్క్-ఆధారితం) ప్రాప్యత చేయడం"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ టాబ్లెట్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ టీవీలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ఈ యాప్‌ సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్‌ ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ఈ అనువర్తనం సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. అనువర్తనం ఉపయోగించడానికి మీ టాబ్లెట్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ఈ అనువర్తనం సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. అనువర్తనం ఉపయోగించడానికి మీ టీవీలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ఈ అనువర్తనం సెల్ టవర్‌లు మరియు Wi-Fi నెట్‌వర్క్‌ల వంటి నెట్‌వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. అనువర్తనం ఉపయోగించడానికి మీ ఫోన్‌లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"మీ ఆడియో సెట్టింగ్‌లను మార్చడం"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"వాల్యూమ్ మరియు అవుట్‌పుట్ కోసం ఉపయోగించాల్సిన స్పీకర్ వంటి సార్వజనీన ఆడియో సెట్టింగ్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ఆడియోను రికార్డ్ చేయడం"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"ఈ యాప్ మైక్రోఫోన్‌ని ఉపయోగించి ఎప్పుడైనా ఆడియోను రికార్డ్ చేయగలదు."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"ఈ అనువర్తనం మైక్రోఫోన్‌ని ఉపయోగించి ఎప్పుడైనా ఆడియోను రికార్డ్ చేయగలదు."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"SIMకి ఆదేశాలను పంపడం"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"సిమ్‌కు ఆదేశాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది చాలా ప్రమాదకరం."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"చిత్రాలు మరియు వీడియోలు తీయడం"</string>
-    <string name="permdesc_camera" msgid="5392231870049240670">"ఈ యాప్‌ కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు."</string>
+    <string name="permdesc_camera" msgid="5392231870049240670">"ఈ అనువర్తనం కెమెరాను ఉపయోగించి ఎప్పుడైనా చిత్రాలను తీయగలదు మరియు వీడియోలను రికార్డ్ చేయగలదు."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"వైబ్రేషన్‌ను నియంత్రించడం"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"వైబ్రేటర్‌ను నియంత్రించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
-    <string name="permlab_callPhone" msgid="3925836347681847954">"నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ఫోన్ నంబర్‌లకు నేరుగా కాల్ చేయడం"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"మీ ప్రమేయం లేకుండా ఫోన్ నంబర్‌లకు కాల్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. దీని వలన అనుకోని ఛార్జీలు విధించబడవచ్చు లేదా కాల్‌లు రావచ్చు. ఇది అత్యవసర నంబర్‌లకు కాల్ చేయడానికి అనువర్తనాన్ని అనుమతించదని గుర్తుంచుకోండి. హానికరమైన అనువర్తనాలు మీ నిర్ధారణ లేకుండానే కాల్‌లు చేయడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS కాల్ సేవ ప్రాప్యత అనుమతి"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"మీ ప్రమేయం లేకుండా కాల్‌లు చేయడం కోసం IMS సేవను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
@@ -486,7 +489,7 @@
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"వేలిముద్ర హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"వేలిముద్రను నిల్వ చేయడం సాధ్యపడదు. దయచేసి ఇప్పటికే ఉన్న వేలిముద్రను తీసివేయండి."</string>
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
-    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"వేలిముద్ర కార్యకలాపం రద్దయింది."</string>
+    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"వేలిముద్ర కార్యాచరణ రద్దయింది."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"అనేకసార్లు ప్రయత్నించారు. వేలిముద్ర సెన్సార్ నిలిపివేయబడింది."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"మళ్లీ ప్రయత్నించండి."</string>
@@ -495,9 +498,9 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"వేలిముద్ర చిహ్నం"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"సమకాలీకరణ సెట్టింగ్‌లను చదవడం"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది. ఉదాహరణకు, వ్యక్తుల యాప్‌ ఖాతాతో సమకాలీకరించబడాలా లేదా అనే విషయాన్ని ఇది నిశ్చయించవచ్చు."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, వ్యక్తుల అనువర్తనం ఖాతాతో సమకాలీకరించబడాలా లేదా అనే విషయాన్ని ఇది నిశ్చయించవచ్చు."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"సమకాలీకరణను ఆన్ మరియు ఆఫ్‌కు టోగుల్ చేయడం"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను సవరించడానికి యాప్‌ను అనుమతిస్తుంది. ఉదాహరణకు, ఇది ఒక ఖాతాతో వ్యక్తుల యాప్ యొక్క సమకాలీకరణను ప్రారంభించడానికి ఉపయోగించబడవచ్చు."</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, ఇది ఒక ఖాతాతో వ్యక్తుల అనువర్తనం యొక్క సమకాలీకరణను ప్రారంభించడానికి ఉపయోగించబడవచ్చు."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"సమకాలీకరణ గణాంకాలను చదవడం"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ఖాతా యొక్క సమకాలీకరణ గణాంకాలను అలాగే సమకాలీకరణ ఈవెంట్‌ల చరిత్రను మరియు ఎంత డేటా సమకాలీకరించబడింది అనేవాటిని చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"మీ USB నిల్వ యొక్క కంటెంట్‌లను చదవడం"</string>
@@ -698,7 +701,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"ఇల్లు"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"కార్యాలయం"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ఇతరం"</string>
-    <string name="quick_contacts_not_available" msgid="746098007828579688">"ఈ కాంటాక్ట్‌ను చూసే యాప్ కనుగొనబడలేదు."</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"ఈ పరిచయాన్ని వీక్షించడానికి అనువర్తనం కనుగొనబడలేదు."</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"పిన్‌ కోడ్‌ను టైప్ చేయండి"</string>
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK మరియు కొత్త పిన్‌ కోడ్‌ను టైప్ చేయండి"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK కోడ్"</string>
@@ -757,7 +760,7 @@
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"నమూనాను మర్చిపోయారా?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ఖాతా అన్‌లాక్"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"చాలా ఎక్కువ ఆకృతి ప్రయత్నాలు చేసారు"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"చాలా ఎక్కువ నమూనా ప్రయత్నాలు చేసారు"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"అన్‌లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"వినియోగదారు పేరు (ఇమెయిల్)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"పాస్‌వర్డ్"</string>
@@ -768,12 +771,12 @@
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"అన్‌లాక్ చేయండి"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ధ్వని ఆన్‌లో ఉంది"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ధ్వని ఆఫ్‌లో ఉంది"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ఆకృతి ప్రారంభించబడింది"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ఆకృతి క్లియర్ చేయబడింది"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"నమూనా ప్రారంభించబడింది"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"నమూనా క్లియర్ చేయబడింది"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"గడి జోడించబడింది"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>వ సెల్‌ను జోడించారు"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ఆకృతి పూర్తయింది"</string>
-    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ఆకృతి ప్రాంతం."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"నమూనా పూర్తయింది"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"నమూనా ప్రాంతం."</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$dలో విడ్జెట్ %2$d."</string>
     <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"విడ్జెట్‌ను జోడించండి."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ఖాళీ"</string>
@@ -789,11 +792,11 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"విడ్జెట్ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> తొలగించబడింది."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"అన్‌లాక్ ప్రాంతాన్ని విస్తరింపజేయండి."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"స్లయిడ్ అన్‌లాక్."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ఆకృతి అన్‌లాక్."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"నమూనా అన్‌లాక్."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ముఖంతో అన్‌లాక్."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"పిన్ అన్‌లాక్."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"పాస్‌వర్డ్ అన్‌లాక్."</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ఆకృతి ప్రాంతం."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"నమూనా ప్రాంతం."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"స్లయిడ్ ప్రాంతం."</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
@@ -1044,7 +1047,7 @@
     <string name="report" msgid="4060218260984795706">"నివేదించు"</string>
     <string name="wait" msgid="7147118217226317732">"వేచి ఉండు"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"పేజీ ప్రతిస్పందించడం లేదు.\n\nమీరు దీన్ని మూసివేయాలనుకుంటున్నారా?"</string>
-    <string name="launch_warning_title" msgid="1547997780506713581">"యాప్ దారి మళ్లించబడింది"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"అనువర్తనం దారి మళ్లించబడింది"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> ఇప్పుడు అమలవుతోంది."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> వాస్తవంగా ప్రారంభించబడింది."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"ప్రమాణం"</string>
@@ -1052,7 +1055,7 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"సిస్టమ్ సెట్టింగ్‌లు &gt; అనువర్తనాలు &gt; డౌన్‌లోడ్ చేసినవిలో దీన్ని పునఃప్రారంభించండి."</string>
     <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రస్తుత ప్రదర్శన పరిమాణ సెట్టింగ్‌కు మద్దతు ఇవ్వదు, దీని వలన ఊహించని సమస్యలు తలెత్తవచ్చు."</string>
     <string name="unsupported_display_size_show" msgid="7969129195360353041">"ఎల్లప్పుడూ చూపు"</string>
-    <string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> యాప్ (<xliff:g id="PROCESS">%2$s</xliff:g> ప్రాసెస్) అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
+    <string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> అనువర్తనం (<xliff:g id="PROCESS">%2$s</xliff:g> ప్రాసెస్) అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
     <string name="smv_process" msgid="5120397012047462446">"ప్రక్రియ <xliff:g id="PROCESS">%1$s</xliff:g> అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android అప్‌గ్రేడ్ అవుతోంది…"</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android ప్రారంభమవుతోంది…"</string>
@@ -1067,15 +1070,15 @@
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> అమలవుతోంది"</string>
     <string name="heavy_weight_notification_detail" msgid="867643381388543170">"అనువర్తనానికి మారడానికి నొక్కండి"</string>
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"అనువర్తనాలను మార్చాలా?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"మరో యాప్ ఇప్పటికే అమలవుతోంది, మీరు మరోదాన్ని ప్రారంభించడానికి ముందు అది తప్పనిసరిగా ఆపివేయబడాలి."</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"మరో అనువర్తనం ఇప్పటికే అమలవుతోంది, మీరు మరోదాన్ని ప్రారంభించడానికి ముందు అది తప్పనిసరిగా ఆపివేయబడాలి."</string>
     <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>కు తిరిగి వెళ్లండి"</string>
     <string name="old_app_description" msgid="2082094275580358049">"కొత్త అనువర్తనాన్ని ప్రారంభించవద్దు."</string>
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>ని ప్రారంభించండి"</string>
     <string name="new_app_description" msgid="1932143598371537340">"పాత అనువర్తనాన్ని సేవ్ చేయకుండానే ఆపివేయండి."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> మెమరీ పరిమితిని మించిపోయింది"</string>
-    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"కుప్పలు తెప్పలుగా సేకరించబడింది; షేర్ చేయడానికి నొక్కండి"</string>
+    <string name="dump_heap_notification_detail" msgid="6901391084243999274">"కుప్పలు తెప్పలుగా సేకరించబడింది; భాగస్వామ్యం చేయడానికి నొక్కండి"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"హీప్ డంప్‌ను భాగస్వామ్యం చేయాలా?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ప్రాసెస్ దాని <xliff:g id="SIZE">%2$s</xliff:g> ప్రాసెస్ మెమరీ పరిమితిని మించిపోయింది. మీకు దాని డెవలపర్‌తో షేర్ చేయడానికి హీప్ డంప్ అందుబాటులో ఉంది. జాగ్రత్తగా ఉండండి: ఈ హీప్ డంప్‌లో యాప్‌ యాక్సెస్ కలిగి ఉన్న మీ వ్యక్తిగత సమాచారం ఏదైనా ఉండవచ్చు."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ప్రాసెస్ దాని <xliff:g id="SIZE">%2$s</xliff:g> ప్రాసెస్ మెమరీ పరిమితిని మించిపోయింది. మీకు దాని డెవలపర్‌తో భాగస్వామ్యం చేయడానికి హీప్ డంప్ అందుబాటులో ఉంది. జాగ్రత్తగా ఉండండి: ఈ హీప్ డంప్‌లో అనువర్తనం ప్రాప్యత కలిగి ఉన్న మీ వ్యక్తిగత సమాచారం ఏదైనా ఉండవచ్చు."</string>
     <string name="sendText" msgid="5209874571959469142">"వచనం కోసం చర్యను ఎంచుకోండి"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"రింగర్ వాల్యూమ్"</string>
     <string name="volume_music" msgid="5421651157138628171">"మీడియా వాల్యూమ్"</string>
@@ -1126,8 +1129,8 @@
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiకి కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" బలహీన ఇంటర్నెట్ కనెక్షన్‌ను కలిగి ఉంది."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"కనెక్షన్‌ని అనుమతించాలా?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s యాప్ %2$s Wifi నెట్‌వర్క్‌కు కనెక్ట్ చేయాలనుకుంటోంది"</string>
-    <string name="wifi_connect_default_application" msgid="7143109390475484319">"ఒక యాప్"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s అనువర్తనం %2$s Wifi నెట్‌వర్క్‌కు కనెక్ట్ చేయాలనుకుంటోంది"</string>
+    <string name="wifi_connect_default_application" msgid="7143109390475484319">"ఒక అనువర్తనం"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Directను ప్రారంభించండి. దీని వలన Wi-Fi క్లయింట్/హాట్‌స్పాట్ ఆపివేయబడుతుంది."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Directను ప్రారంభించడం సాధ్యపడలేదు."</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI కోసం USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ఉపకరణానికి కనెక్ట్ చేయబడింది"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ఆడియో ఉపకరణానికి మద్దతు లేదు"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"మరింత సమాచారం కోసం నొక్కండి"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి నొక్కండి."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్‌ని నిలిపివేయడానికి ఎంచుకోండి."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"బగ్ నివేదికను భాగస్వామ్యం చేస్తోంది..."</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"భాష మరియు లేఅవుట్‌ను ఎంచుకోవడానికి నొక్కండి"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"ఇతర యాప్‌ల ఎగువన ప్రదర్శన"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ఇతర అనువర్తనాలలో చూపబడుతోంది"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ఇతర అనువర్తనాలలో చూపబడుతోంది"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్‌లను తెరవడానికి నొక్కి, దీన్ని ఆఫ్ చేయండి."</string>
@@ -1254,7 +1261,7 @@
     <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"ప్యాకేజీలను తొలగించడానికి అభ్యర్థించు"</string>
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"ప్యాకేజీల తొలగింపును అభ్యర్థించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"బ్యాటరీ అనుకూలీకరణలను విస్మరించడానికి అడగాలి"</string>
-    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"ఆ యాప్ కోసం బ్యాటరీ అనుకూలీకరణలు విస్మరించేలా అనుమతి కోరడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"ఆ అనువర్తనం కోసం బ్యాటరీ అనుకూలీకరణలు విస్మరించేలా అనుమతి కోరడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"వెళ్లు"</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"కారు మోడ్ నుండి నిష్క్రమించడానికి నొక్కండి."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్‌స్పాట్ సక్రియంగా ఉండేది"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"టీథెరింగ్ నిలిపివేయబడింది"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string>
     <string name="back_button_label" msgid="2300470004503343439">"వెనుకకు"</string>
     <string name="next_button_label" msgid="1080555104677992408">"తదుపరి"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"దాటవేయి"</string>
@@ -1439,7 +1444,7 @@
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", సురక్షితం"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"నమూనాను మర్చిపోయాను"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"ఆకృతి తప్పు"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"నమూనా తప్పు"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"పాస్‌వర్డ్ తప్పు"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"పిన్‌ తప్పు"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
@@ -1456,7 +1461,7 @@
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK కోడ్ 8 సంఖ్యలు ఉండాలి."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"సరైన PUK కోడ్‌ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"పిన్‌ కోడ్‌లు సరిపోలలేదు"</string>
-    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"చాలా ఎక్కువ ఆకృతి ప్రయత్నాలు చేసారు"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"చాలా ఎక్కువ నమూనా ప్రయత్నాలు చేసారు"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"అన్‌లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"వినియోగదారు పేరు (ఇమెయిల్)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"పాస్‌వర్డ్"</string>
@@ -1494,7 +1499,7 @@
     <string name="owner_name" msgid="2716755460376028154">"యజమాని"</string>
     <string name="error_message_title" msgid="4510373083082500195">"లోపం"</string>
     <string name="error_message_change_not_allowed" msgid="1238035947357923497">"ఈ మార్పును మీ నిర్వాహకులు అనుమతించలేదు"</string>
-    <string name="app_not_found" msgid="3429141853498927379">"ఈ చర్యను నిర్వహించడానికి యాప్ ఏదీ కనుగొనబడలేదు"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ఈ చర్యను నిర్వహించడానికి అనువర్తనం ఏదీ కనుగొనబడలేదు"</string>
     <string name="revoke" msgid="5404479185228271586">"ఉపసంహరించండి"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
@@ -1585,7 +1590,7 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"ముద్రణ సేవ ప్రారంభించబడలేదు"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> సేవ ఇన్‌స్టాల్ చేయబడింది"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"ప్రారంభించడానికి నొక్కండి"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"నిర్వాహకుల పిన్‌ను నమోదు చేయండి"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"నిర్వాహకుల PINని నమోదు చేయండి"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"పిన్‌ను నమోదు చేయండి"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"తప్పు"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ప్రస్తుత పిన్‌"</string>
@@ -1618,13 +1623,13 @@
     <string name="lock_to_app_start" msgid="6643342070839862795">"స్క్రీన్ పిన్ చేయబడింది"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"స్క్రీన్ అన్‌పిన్ చేయబడింది"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"అన్‌పిన్ చేయడానికి ముందు పిన్‌ కోసం అడుగు"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"అన్‌పిన్ చేయడానికి ముందు అన్‌లాక్ ఆకృతి కోసం అడుగు"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"అన్‌పిన్ చేయడానికి ముందు అన్‌లాక్ నమూనా కోసం అడుగు"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్‌పిన్ చేయడానికి ముందు పాస్‌వర్డ్ కోసం అడుగు"</string>
     <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="data_saver_description" msgid="6015391409098303235">"డేటా వినియోగాన్ని తగ్గించడంలో సహాయకరంగా ఉండటానికి, డేటా సేవర్ కొన్ని యాప్‌లను నేపథ్యంలో డేటాను పంపకుండా లేదా స్వీకరించకుండా నిరోధిస్తుంది. మీరు ప్రస్తుతం ఉపయోగిస్తున్న యాప్‌ డేటాను యాక్సెస్ చేయగలదు కానీ అలా అరుదుగా చేయవచ్చు. అంటే, ఉదాహరణకు, మీరు ఆ చిత్రాలను నొక్కే వరకు అవి ప్రదర్శించబడవు."</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>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1712,7 +1717,7 @@
     <string name="work_mode_turn_on" msgid="2062544985670564875">"ఆన్ చేయి"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"మీకు కొత్త సందేశాలు ఉన్నాయి"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"వీక్షించడానికి SMS అనువర్తనాన్ని తెరవండి"</string>
-    <string name="user_encrypted_title" msgid="9054897468831672082">"కొంత పనితనం పరిమితం కావచ్చు"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"కొంత కార్యాచరణ పరిమితం కావచ్చు"</string>
     <string name="user_encrypted_message" msgid="4923292604515744267">"అన్‌లాక్ చేయడానికి నొక్కండి"</string>
     <string name="user_encrypted_detail" msgid="5708447464349420392">"వినియోగదారు డేటా లాక్ అయ్యింది"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"కార్యాలయ ప్రొఫైల్ లాక్ అయింది"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index d62b93e..cf67abf 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -39,4 +39,7 @@
 
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">false</bool>
+
+    <!-- Allow SystemUI to show the shutdown dialog -->
+    <bool name="config_showSysuiShutdown">false</bool>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 55559d3..86f1be3 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"ไม่มีการนำเสนอบริการ"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"คุณไม่สามารถเปลี่ยนการตั้งค่าหมายเลขผู้โทร"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ไม่มีบริการอินเทอร์เน็ต"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"ไม่มีหมายเลขฉุกเฉิน"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"ไม่มีบริการฉุกเฉิน"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"ไม่มีบริการเสียง"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"ไม่มีบริการเสียง/บริการฉุกเฉิน"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"งดให้บริการชั่วคราวโดยเครือข่ายมือถือในตำแหน่งของคุณ"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"ผู้ให้บริการของคุณระงับบริการอินเทอร์เน็ตที่นี่ชั่วคราว"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"ผู้ให้บริการของคุณระงับหมายเลขฉุกเฉินที่นี่ชั่วคราว"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"ผู้ให้บริการของคุณระงับการโทรด้วยเสียงที่นี่ชั่วคราว"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"ผู้ให้บริการของคุณระงับการโทรด้วยเสียงและหมายเลขฉุกเฉินที่นี่ชั่วคราว"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"เข้าถึงเครือข่ายไม่ได้"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"เพื่อให้การรับสัญญาณดีขึ้น ลองเปลี่ยนประเภทที่เลือกใน \"การตั้งค่า\" &gt; \"เครือข่ายและอินเทอร์เน็ต\" &gt; \"เครือข่ายมือถือ\" &gt; \"ประเภทเครือข่ายที่ต้องการ\""</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"การแจ้งเตือน"</string>
@@ -288,7 +291,7 @@
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"ถ่ายภาพและบันทึกวิดีโอ"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"โทรศัพท์"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"โทรและจัดการการโทร"</string>
-    <string name="permgrouplab_sensors" msgid="416037179223226722">"เซ็นเซอร์ร่างกาย"</string>
+    <string name="permgrouplab_sensors" msgid="416037179223226722">"เซ็นเซอร์สำหรับร่างกาย"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"เข้าถึงข้อมูลเซ็นเซอร์เกี่ยวกับสัญญาณชีพของคุณ"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
@@ -1110,7 +1113,7 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi เชื่อมต่ออินเทอร์เน็ตไม่ได้"</string>
+    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi ไม่สามารถเข้าถึงอินเทอร์เน็ต"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"แตะเพื่อดูตัวเลือก"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"เปลี่ยนเป็น <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
     <string name="network_switch_metered_detail" msgid="5325661434777870353">"อุปกรณ์จะใช้ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> เมื่อ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ไม่สามารถเข้าถึงอินเทอร์เน็ต อาจมีค่าบริการ"</string>
@@ -1185,7 +1188,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB สำหรับ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน USB แล้ว"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ไม่รองรับอุปกรณ์เสริมสำหรับเสียง"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"แตะเพื่อปิดใช้การแก้ไขข้อบกพร่องของ USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"แตะเพื่อเลือกภาษาและรูปแบบ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"แสดงทับแอปอื่นๆ"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> แสดงทับแอปอื่นๆ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> กำลังแสดงทับแอปอื่นๆ"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"แตะเพื่อออกจากโหมดรถยนต์"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
     <string name="back_button_label" msgid="2300470004503343439">"กลับ"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ถัดไป"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"ข้าม"</string>
@@ -1623,7 +1627,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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 201890d8..5405d03 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Hindi naprobisyon ang serbisyo."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Hindi mo mababago ang setting ng caller ID."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Walang serbisyo sa data"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Walang emergency na tawag"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Walang serbisyo para sa emergency"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Walang serbisyo para sa boses"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Walang serbisyo para sa voice/emergency"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Pansamantalang hindi inaalok ng mobile network sa iyong lokasyon"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Pansamantalang sinuspinde ng iyong carrier ang serbisyo sa data sa lokasyong ito"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Pansamantalang sinuspinde ng iyong carrier ang mga emergency na tawag sa lokasyong ito"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Pansamantalang sinuspinde ng iyong carrier ang mga voice call sa lokasyong ito"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Pansamantalang sinuspinde ng iyong carrier ang mga voice call at emergency na tawag sa lokasyong ito"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Hindi maabot ang network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Upang lumakas ang reception, subukang baguhin ang uring napili sa System &gt; Network at Internet &gt; Mga mobile network &gt; Gustong uri ng network."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Mga Alerto"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para sa MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang accessory ng USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"I-tap para sa higit pang mga opsyon."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Hindi sinusuportahan ang audio accessory"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"I-tap para sa higit pang impormasyon"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"I-tap upang i-disable ang pag-debug ng USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"I-tap upang pumili ng wika at layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Ipakita sa ibabaw ng ibang app"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Ipinapakita sa itaas ng iba pang app ang <xliff:g id="NAME">%s</xliff:g>."</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"Nasa ibabaw ng ibang app ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Kung ayaw mong gamitin ng <xliff:g id="NAME">%s</xliff:g> ang feature na ito, i-tap upang buksan ang mga setting at i-off ito."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"I-tap upang lumabas sa car mode."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Bumalik"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Susunod"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Laktawan"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 812ac76..936f827 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Hizmet sağlanamadı."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Arayanın kimliği ayarını değiştiremezsiniz."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Veri hizmeti yok"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Acil durum çağrısı yok"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Acil durum hizmeti yok"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Sesli çağrı hizmeti yok"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ses/acil durum hizmeti yok"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Bulunduğunuz yerdeki mobil ağ tarafından geçici olarak sunulmuyor"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Operatörünüz bu konumdaki veri hizmetini geçici olarak askıya aldı"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Operatörünüz bu konumdaki acil durum çağrılarını geçici olarak askıya aldı"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Operatörünüz bu konumdaki sesli çağrıları geçici olarak askıya aldı"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Operatörünüz bu konumdaki sesli ve acil durum çağrılarını geçici olarak askıya aldı"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ağa erişilemiyor"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Sinyal gücünü iyileştirmek için Sistem &gt; Ağ ve İnternet &gt; Mobil ağlar &gt; Tercih edilen ağ türü\'nden seçili türü değiştirmeyi deneyin."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Uyarılar"</string>
@@ -1185,9 +1188,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI için USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Diğer seçenekler için dokunun."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ses aksesuarı desteklenmiyor"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Daha fazla bilgi için dokunun"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hata raporu alınıyor…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Hata raporu paylaşılsın mı?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Hata raporu paylaşılıyor..."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dili ve düzeni seçmek için dokunun"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Diğer uygulamaların üzerinde göster"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g>, diğer uygulamaların üzerinde görüntüleniyor"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>, diğer uygulamaların üzerinde gösteriliyor"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> uygulamasının bu özelliği kullanmasını istemiyorsanız dokunarak ayarları açın ve özelliği kapatın."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Araba modundan çıkmak için dokunun."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Geri"</string>
     <string name="next_button_label" msgid="1080555104677992408">"İleri"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Atla"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7767202..0b5677e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -21,10 +21,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="8340973892742019101">"б"</string>
-    <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
-    <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
-    <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
-    <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
+    <string name="kilobyteShort" msgid="7542884022844556968">"Кб"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> дн."</string>
@@ -92,10 +92,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Службу не ініціалізовано."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ви не можете змінювати налаштування ідентифікатора абонента."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Немає мобільного Інтернету"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Екстрені виклики заблоковано"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Немає екстреної служби"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Немає голосової служби"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Немає голосової/екстреної служби"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Тимчасово не пропонується мобільною мережею у вашому місцезнаходженні"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Оператор тимчасово заблокував передавання даних у цьому місці"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Оператор тимчасово заблокував екстрені виклики в цьому місці"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Оператор тимчасово заблокував голосові виклики в цьому місці"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Оператор тимчасово заблокував голосові й екстрені виклики в цьому місці"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Не вдається під’єднатися до мережі"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Щоб покращити якість сигналу, змініть тип у меню \"Система\" &gt; \"Мережа й Інтернет\" &gt; \"Мобільні мережі\" &gt; \"Тип мережі\"."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Сповіщення"</string>
@@ -1027,7 +1030,7 @@
     <string name="browse" msgid="6993590095938149861">"Веб-переглядач"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 МБ вільного місця, і повторіть спробу."</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 Мб вільного місця, і повторіть спробу."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string>
     <string name="app_running_notification_text" msgid="1197581823314971177">"Торкніться, щоб дізнатися більше або зупинити додаток."</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
@@ -1064,7 +1067,7 @@
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Очистити налаштування за умовчанням у меню Налаштування системи &gt; Програми &gt; Завантажені."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Виберіть дію"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Вибрати програму для пристрою USB"</string>
-    <string name="noApplications" msgid="2991814273936504689">"Жодний додаток не може виконати цю дію."</string>
+    <string name="noApplications" msgid="2991814273936504689">"Жодна програма не може виконати цю дію."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g>: збій у роботі"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g>: збій у роботі"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"Додаток <xliff:g id="APPLICATION">%1$s</xliff:g> періодично перестає працювати"</string>
@@ -1229,9 +1232,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для режиму MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Під’єднано до аксесуара USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Торкніться, щоб переглянути більше опцій."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аксесуар для аудіо не підтримується"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Торкніться, щоб дізнатися більше"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Торкніться, щоб вимкнути налагодження USB."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Вибер., щоб вимкн. налагодж. USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Створюється повідомлення про помилку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Надіслати звіт про помилку?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Надсилається звіт про помилку…"</string>
@@ -1245,7 +1250,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Торкніться, щоб вибрати мову та розкладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Показувати поверх додатків"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"Додаток <xliff:g id="NAME">%s</xliff:g> відображається поверх інших додатків"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> відображається поверх інших додатків"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Щоб у додатку <xliff:g id="NAME">%s</xliff:g> не працювала ця функція, вимкніть її в налаштуваннях."</string>
@@ -1345,8 +1351,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Торкніться, щоб вийти з режиму автомобіля."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далі"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Пропустити"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 0342b8a..038baaf 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"سروس فراہم نہیں کی گئی۔"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"‏آپ کالر ID کی ترتیبات تبدیل نہیں کر سکتے ہیں۔"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"کوئی ڈیٹا سروس نہیں"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"کوئی ایمرجنسی کالنگ نہیں ہے"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"کوئی ہنگامی سروس نہیں"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"کوئی صوتی سروس نہیں"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"کوئی صوتی/ہنگامی سروس نہیں"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"عارضی طور پر آپ کے مقام پر موبائل نیٹ ورک کی طرف سے پیش نہیں ہے"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"آپ کے کیریئر نے عارضی طور پر اس مقام پر ڈیٹا سروس کو معطل کر دیا ہے"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"آپ کے کیریئر نے عارضی طور پر اس مقام پر ہنگامی کالز کو معطل کر دیا ہے"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"آپ کے کیریئر نے عارضی طور پر اس مقام پر صوتی کالز کو معطل کر دیا ہے"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"آپ کے کیریئر نے عارضی طور پر اس مقام پر صوتی اور ہنگامی کالز کو معطل کر دیا ہے"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"نیٹ ورک تک نہیں پہنچا جا سکتا"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"‏ریسپشن کو بہتر بنانے کیلئے، سسٹم ‎&gt; نیٹ ورک اور انٹرنیٹ ‎&gt; موبائل نیٹ ورکس ‎&gt; ترجیحی نیٹ ورک کی قسم تبدیل کرنے کی کوشش کریں۔"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"الرٹس"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏MIDI کیلئے USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏ایک USB لوازم سے مربوط ہے"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"آڈیو لوازم تعاون یافتہ نہیں ہے"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"مزید معلومات کے لیے تھپتھپائيں"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"بگ رپورٹ کا اشتراک ہو رہا ہے…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"زبان اور لے آؤٹ منتخب کرنے کیلئے تھپتھپائیں"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"دیگر ایپس پر ڈسپلے کریں"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> کو دیگر ایپس پر دکھایا کیا جا رہا ہے"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> دیگر ایپس پر ڈسپلے ہو رہی ہے"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"اگر آپ نہیں چاہتے ہیں کہ <xliff:g id="NAME">%s</xliff:g> اس خصوصیت کا استعمال کرے تو ترتیبات کھولنے کیلئے تھپتھپائیں اور اسے بند کریں۔"</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"کار موڈ سے خارج ہونے کیلئے تھپتھپائیں۔"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیتھرنگ یا ہاٹ اسپاٹ فعال"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ربط بنانا غیر فعال ہے"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
     <string name="back_button_label" msgid="2300470004503343439">"واپس جائیں"</string>
     <string name="next_button_label" msgid="1080555104677992408">"اگلا"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"نظر انداز کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 9724c6c..3974ab3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Xizmat ishalamaydi."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Qo‘ng‘iroq qiluvchining ID raqami sozlamasini o‘zgartirib bo‘lmaydi."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Mobil internet ishlamaydi"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Favqulodda chaqiruvlar ishlamaydi"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Favqulodda chaqiruvlar ishlamaydi"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ovozli chaqiruvlar ishlamaydi"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ovozli va favqulodda chaqiruvlar ishlamaydi"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Hududingizda mobil tarmoq tomonidan vaqtinchalik taklif etilmayapti"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Aloqa operatoringiz bu joyda mobil internetni bloklagan"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Aloqa operatoringiz bu joyda favqulodda chaqiruvlarni bloklagan"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Aloqa operatoringiz bu joyda ovozli chaqiruvlarni bloklagan"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Aloqa operatoringiz bu joyda ovozli va favqulodda chaqiruvlarni bloklagan"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Tarmoq bilan bog‘lanib bo‘lmadi"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Qabul qilish sifatini yaxshilash uchun Tizim &gt; Tarmoq va Internet &gt; Mobil tarmoqlar > Asosiy tarmoq turi orqali o‘zgartirib ko‘ring."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Ogohlantirishlar"</string>
@@ -1185,9 +1188,12 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB orqali MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB jihozga ulangan"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Boshqa parametrlarini ko‘rish uchun bosing."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio aksessuar ishlamaydi"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tafsilotlar uchun bosing"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Faolsizlantirish uchun bu yerga bosing."</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Xatoliklar hisoboti yuborilmoqda…"</string>
@@ -1201,7 +1207,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Til va sxemani belgilash uchun bosing"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Boshqa ilovalar ustidan ochilish"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> boshqa ilovalar ustidan ochilgan"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> boshqa ilovalar ustidan ochilgan"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> ilovasi uchun bu funksiyani sozlamalar orqali o‘chirib qo‘yish mumkin."</string>
@@ -1301,8 +1308,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Avtomobil rejimidan chiqish uchun bosing."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Orqaga"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Keyingisi"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Tashlab o‘tish"</string>
@@ -1439,7 +1444,7 @@
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit noto‘g‘ri"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN-kod noto‘g‘ri"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
@@ -1599,7 +1604,7 @@
       <item quantity="one">1 soniyadan so‘ng qayta urinib ko‘ring</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Keyinroq urinib ko‘ring"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"To‘liq ekranli rejim"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"To‘liq ekran ko‘rsatilmoqda"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Chiqish uchun tepadan pastga torting."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"OK"</string>
     <string name="done_label" msgid="2093726099505892398">"Tayyor"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 87db26f..4d39e34 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Dịch vụ không được cấp phép."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Bạn không thể thay đổi cài đặt ID người gọi."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Không có dịch vụ dữ liệu"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Không gọi điện khẩn cấp được"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Không có dịch vụ khẩn cấp"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Không có dịch vụ thoại"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Không có dịch vụ thoại/khẩn cấp"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Tạm thời không được cung cấp bởi mạng di động tại vị trí của bạn"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Nhà cung cấp dịch vụ của bạn đã tạm ngưng dịch vụ dữ liệu ở vị trí này"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Nhà cung cấp dịch vụ của bạn đã tạm ngưng các cuộc gọi khẩn cấp ở vị trí này"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Nhà cung cấp dịch vụ của bạn đã tạm ngưng các cuộc gọi thoại ở vị trí này"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Nhà cung cấp dịch vụ của bạn đã tạm ngưng các cuộc gọi thoại và cuộc gọi khẩn cấp ở vị trí này"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Không thể kết nối mạng"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Để cải thiện khả năng thu tín hiệu, hãy thử thay đổi loại mạng được chọn trong Hệ thống &gt; Mạng và Internet &gt; Mạng di động &gt; Loại mạng ưa thích."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Thông báo"</string>
@@ -1185,7 +1188,9 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB cho MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Nhấn để biết thêm tùy chọn."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối gỡ lỗi USB"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Phụ kiện âm thanh không được hỗ trợ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Nhấn để biết thêm thông tin"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Nhấn để vô hiệu hóa gỡ lỗi USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Đang thu thập báo cáo lỗi…"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Nhấn để chọn ngôn ngữ và bố cục"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Hiển thị trên các ứng dụng khác"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên các ứng dụng khác"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên ứng dụng khác"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Nếu bạn không muốn <xliff:g id="NAME">%s</xliff:g> sử dụng tính năng này, hãy nhấn để mở cài đặt và tắt tính năng này."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Nhấn để thoát khỏi chế độ trên ô tô."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Quay lại"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Tiếp theo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Bỏ qua"</string>
@@ -1600,7 +1604,7 @@
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Hãy thử lại sau"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Xem toàn màn hình"</string>
-    <string name="immersive_cling_description" msgid="3482371193207536040">"Để thoát, hãy vuốt từ trên cùng xuống dưới."</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Để thoát, hãy vuốt xuống từ trên cùng."</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"OK"</string>
     <string name="done_label" msgid="2093726099505892398">"Xong"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Thanh trượt giờ hình tròn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f3a5738..1d2aa50 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供服务。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"您无法更改来电显示设置。"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"无法使用数据服务"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"无法进行紧急呼救"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"无法使用紧急呼救服务"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"无法使用语音通话服务"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"无法使用语音通话/紧急呼救服务"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的移动网络暂时不提供这项服务"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"您的运营商在此位置暂时不提供数据服务"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"您的运营商在此位置暂时不提供紧急呼救服务"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"您的运营商在此位置暂时不提供语音通话服务"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"您的运营商在此位置暂时不提供语音通话和紧急呼救服务"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"无法连接网络"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"要改善信号情况,请尝试更改在“系统”&gt;“网络和互联网”&gt;“移动网络”&gt;“首选网络类型”中选择的类型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"提醒"</string>
@@ -1011,7 +1014,7 @@
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"使用%1$s分享"</string>
     <string name="whichSendApplicationLabel" msgid="4579076294675975354">"分享"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"通过以下应用发送"</string>
-    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"通过%1$s发送"</string>
+    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"通过1$s发送"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"发送"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"选择主屏幕应用"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"将“%1$s”设为主屏幕应用"</string>
@@ -1185,9 +1188,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"正在通过 USB 连接到 MIDI 接口"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到USB配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"点按即可查看更多选项。"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到 USB 调试"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"音频配件不受支持"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"点按即可了解详情"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"点按即可停用 USB 调试功能。"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择停用USB调试。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在生成错误报告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享错误报告吗?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享错误报告…"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"点按即可选择语言和布局"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"显示在其他应用的上层"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g>正在其他应用的上层显示内容"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g>正在其他应用的上层显示内容"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"如果您不想让<xliff:g id="NAME">%s</xliff:g>使用此功能,请点按以打开设置,然后关闭此功能。"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"点按即可退出车载模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string>
     <string name="back_button_label" msgid="2300470004503343439">"上一步"</string>
     <string name="next_button_label" msgid="1080555104677992408">"下一步"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"跳过"</string>
@@ -1599,7 +1603,7 @@
       <item quantity="one">1 秒后重试</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"稍后重试"</string>
-    <string name="immersive_cling_title" msgid="8394201622932303336">"目前处于全屏模式"</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"正在全屏模式下查看"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"要退出,请从顶部向下滑动。"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"知道了"</string>
     <string name="done_label" msgid="2093726099505892398">"完成"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 8ea8ee3..09c7c35 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供此服務。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"您無法更改來電顯示設定。"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"沒有數據服務"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"無法撥打緊急電話"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"沒有緊急服務"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"沒有語音服務"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"沒有語音/緊急服務"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"您所在位置的流動網絡暫不提供這項服務"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"您的流動網絡供應商已在此地點暫時停權數據服務"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"您的流動網絡供應商已在此地點暫時停權緊急通話"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"您的流動網絡供應商已在此地點暫時停權語音通話"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"您的流動網絡供應商已在此地點暫時停權語音和緊急通話"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連接網絡"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"如要改善接收品質,請前往 [系統] &gt; [網絡與互聯網] &gt; [流動網絡] &gt; [偏好的網絡類型],然後變更所選的網絡類型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"通知"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕按即可查看更多選項。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕按即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"輕按即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕按即可選取語言和鍵盤配置"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"顯示在其他應用程式上層"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"「<xliff:g id="NAME">%s</xliff:g>」目前可顯示在其他應用程式上面"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"輕按即可結束車用模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string>
     <string name="back_button_label" msgid="2300470004503343439">"返回"</string>
     <string name="next_button_label" msgid="1080555104677992408">"繼續"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"略過"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 43599e9..3379ea5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"無法提供此服務。"</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"你無法變更來電顯示設定。"</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"無法使用數據連線服務"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"無法撥打緊急電話"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"無法使用緊急通話服務"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"無法使用語音通話服務"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"無法使用語音/緊急通話服務"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"你所在位置的行動網路暫時不提供這項服務"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"你的電信業者在這個地點暫時不提供數據連線服務"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"你的電信業者在這個地點暫時不提供緊急通話服務"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"你的電信業者在這個地點暫時不提供語音通話服務"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"你的電信業者在這個地點暫時不提供語音和緊急通話服務"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"無法連上網路"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"如要改善收訊狀況,請依序開啟 [系統] &gt; [網路與網際網路] &gt; [行動網路] &gt; [偏好的網路類型],然後選取其他網路類型。"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"快訊"</string>
@@ -288,7 +291,7 @@
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照及錄製影片"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
-    <string name="permgrouplab_sensors" msgid="416037179223226722">"人體感應器"</string>
+    <string name="permgrouplab_sensors" msgid="416037179223226722">"身體感應器"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取與你生命徵象相關的感應器資料"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查你存取的視窗內容。"</string>
@@ -378,7 +381,7 @@
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允許應用程式修改平板電腦的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改你的通話紀錄。"</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"允許應用程式修改電視的通話紀錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此清除或修改你的通話紀錄。"</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允許應用程式修改手機的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改你的通話紀錄。"</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"存取人體感應器 (例如心跳速率監測器)"</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"存取身體感應器 (例如心跳速率監測器)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允許應用程式存取感測器所收集的資料 (這類感測器可監測你的體能狀態,例如你的心跳速率)。"</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"讀取日曆活動和詳細資訊"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"這個應用程式可讀取所有儲存在平板電腦上的日曆活動資訊,以及共用或儲存日曆資料。"</string>
@@ -1185,9 +1188,11 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕觸即可查看更多選項。"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
-    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯功能。"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string>
+    <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕觸即可選取語言和版面配置"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"顯示在其他應用程式上層"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"「<xliff:g id="NAME">%s</xliff:g>」在其他應用程式上顯示內容"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"如果你不想讓「<xliff:g id="NAME">%s</xliff:g>」使用這項功能,請輕觸開啟設定頁面,然後停用此功能。"</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"輕觸即可結束車用模式。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string>
     <string name="back_button_label" msgid="2300470004503343439">"返回"</string>
     <string name="next_button_label" msgid="1080555104677992408">"繼續"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"略過"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 961f1fa..34d191b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -90,10 +90,13 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Isevisi ayilungiselelwe."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Ngeke ukwazi ukuguqul izilungiselelo zemininingwane yoshayayo."</string>
     <string name="RestrictedOnDataTitle" msgid="1322504692764166532">"Ayikho isevisi yedatha"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="3646729271176394091">"Akukho ukushaya kwesimo esiphuthumayo"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"Ayikho isevisi yesimo esiphuthumayo"</string>
     <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Ayikho isevisi yezwi"</string>
     <string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Ayikho isevisi yezwi/yesimo esiphuthumayo"</string>
-    <string name="RestrictedStateContent" msgid="4278821484643362350">"Okwesikhashana akunikezwa inethiwekhi yeselula endaweni yakho"</string>
+    <string name="RestrictedOnDataContent" msgid="8997474569390996587">"Inkampani yakho yenethiwekhi imise okwesikhashana isevisi yedatha kule ndawo"</string>
+    <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Inkampani yakho yenethiwekhi imise okwesikhashana amakholi esimo esiphuthumayo kule ndawo"</string>
+    <string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Inkampani yakho yenethiwekhi imise okwesikhashana amakholi ezwi kule ndawo"</string>
+    <string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Inkampani yakho yenethiwekhi imise okwesikhashana amakholi ezwi nawezimo eziphuthumayo kule ndawo"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Ayikwazi ukufinyelela inethiwekhi"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"Ukuze kuthuthukiswe ukwamukelwa, zama ukushintsha uhlobo olukhethiwe kusistimu &gt; Inethiwekhi ne-inthanethi &gt; amanethiwekhi eselula &gt; uhlobo oluncanyelwayo lwenethiwekhi."</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Izexwayiso"</string>
@@ -1185,6 +1188,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"I-USB ye-MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ixhunywe ku-accessory ye-USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Thepha ngezinketho eziningi."</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Insiza yomsindo ayisekelwa"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Thepha ngolwazi olungeziwe"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Thepha ukuze ukhubaze ukususa isiphazamisi se-USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
@@ -1201,7 +1206,8 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Thepha ukuze ukhethe ulimi nesakhiwo"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Bonisa ngaphezulu kwezinye izinhlelo zokusebenza"</string>
+    <!-- no translation found for alert_windows_notification_channel_group_name (1463953341148606396) -->
+    <skip />
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ukubonisa ngaphezu kwezinye izinhlelo zokusebenza"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ibonisa ngaphezu kwezinye izinhlelo zokusebenza"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"Uma ungafuni ukuthi i-<xliff:g id="NAME">%s</xliff:g> isebenzise lesi sici, thepha ukuze uvule izilungiselelo bese usivale."</string>
@@ -1301,8 +1307,6 @@
     <string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Thepha ukuze uphume kumodi yemoto."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Emuva"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Okulandelayo"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Yeqa"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index e190bd1..5baf985 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -66,8 +66,10 @@
         <item>@drawable/ic_find_previous_material</item>
         <item>@drawable/ic_go</item>
         <item>@drawable/ic_go_search_api_material</item>
-        <item>@drawable/ic_media_route_connecting_material</item>
-        <item>@drawable/ic_media_route_material</item>
+        <item>@drawable/ic_media_route_connecting_material_dark</item>
+        <item>@drawable/ic_media_route_connecting_material_light</item>
+        <item>@drawable/ic_media_route_material_dark</item>
+        <item>@drawable/ic_media_route_material_light</item>
         <item>@drawable/ic_menu_close_clear_cancel</item>
         <item>@drawable/ic_menu_copy_material</item>
         <item>@drawable/ic_menu_cut_material</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7849245..40fb6e8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -463,9 +463,6 @@
     <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
     <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
 
-    <!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled -->
-    <bool translatable="false" name="config_wifi_hotspot2_enabled">false</bool>
-
     <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
     <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
 
@@ -510,6 +507,12 @@
     <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
     <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
     <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
+    <!-- Integers specifying the max packet Tx/Rx rates for full scan -->
+    <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
+    <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
+    <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
+    <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
+    <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
     <!-- Integer parameters of the wifi to cellular handover feature
          wifi should not stick to bad networks -->
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
@@ -584,6 +587,10 @@
     <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
     <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
 
+    <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements
+         during voice calls -->
+    <bool translatable="false" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit">false</bool>
+
     <!-- Wifi driver supports batched scan -->
     <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
 
@@ -971,15 +978,7 @@
         <item>30</item>
     </integer-array>
 
-    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
-    <integer-array name="config_safeModeDisabledVibePattern">
-        <item>0</item>
-        <item>1</item>
-        <item>20</item>
-        <item>21</item>
-    </integer-array>
-
-    <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
+    <!-- Vibrator pattern for feedback about booting with safe mode enabled -->
     <integer-array name="config_safeModeEnabledVibePattern">
         <item>0</item>
         <item>1</item>
@@ -997,14 +996,6 @@
         <item>10</item>
     </integer-array>
 
-    <!-- Vibrator pattern for feedback about a context click -->
-    <integer-array name="config_contextClickVibePattern">
-        <item>0</item>
-        <item>1</item>
-        <item>20</item>
-        <item>21</item>
-    </integer-array>
-
     <bool name="config_use_strict_phone_number_comparation">false</bool>
 
     <!-- Display low battery warning when battery level dips to this value.
@@ -1874,6 +1865,21 @@
     <!-- Type of the double tap sensor. Empty if double tap is not supported. -->
     <string name="config_dozeDoubleTapSensorType" translatable="false"></string>
 
+    <!-- Type of the long press sensor. Empty if long press is not supported. -->
+    <string name="config_dozeLongPressSensorType" translatable="false"></string>
+
+    <!-- Control whether the always on display mode is available. This should only be enabled on
+         devices where the display has be tuned to be power efficient in DOZE and/or DOZE_SUSPEND
+         states. -->
+    <bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>
+
+    <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
+    <bool name="config_displayBlanksAfterDoze">false</bool>
+
+    <!-- True if the display hardware only has brightness buckets rather than a full range of
+         backlight values -->
+    <bool name="config_displayBrightnessBucketsInDoze">false</bool>
+
     <!-- Power Management: Specifies whether to decouple the auto-suspend state of the
          device from the display on/off state.
 
@@ -2421,9 +2427,13 @@
     <string-array translatable="false" name="config_gpsParameters">
         <item>SUPL_HOST=supl.google.com</item>
         <item>SUPL_PORT=7275</item>
-        <item>NTP_SERVER=north-america.pool.ntp.org</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
+        <item>SUPL_ES=0</item>
+        <item>LPP_PROFILE=0</item>
+        <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
+        <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
+        <item>GPS_LOCK=0</item>
     </string-array>
 
     <!-- Sprint need a 70 ms delay for 3way call -->
@@ -2772,18 +2782,6 @@
     <!-- True if camera app should be pinned via Pinner Service -->
     <bool name="config_pinnerCameraApp">false</bool>
 
-    <!-- Component that is the default launcher when demo mode is enabled. -->
-    <string name="config_demoModeLauncherComponent">com.android.retaildemo/.DemoPlayer</string>
-
-    <!-- Hashed password (SHA-256) used to restrict carrier demo mode operation. -->
-    <string name="config_carrierDemoModePassword" translatable="false"></string>
-
-    <!-- Secure setting used to activate carrier demo mode. -->
-    <string name="config_carrierDemoModeSetting" translatable="false"></string>
-
-    <!-- List of packages to enable in carrier demo mode (comma separated). -->
-    <string name="config_carrierDemoModePackages" translatable="false"></string>
-
     <!-- Number of days preloaded file cache should be preserved on a device before it can be
          deleted -->
     <integer name="config_keepPreloadsMinDays">7</integer>
@@ -2890,6 +2888,11 @@
     <!-- TODO(b/35230407) complete the link field -->
     <bool name="config_allowEscrowTokenForTrustAgent">false</bool>
 
+    <!-- A flattened ComponentName which corresponds to the only trust agent that should be enabled
+         by default. If the default value is used, or set to an empty string, the restriction will
+         not be applied. -->
+    <string name="config_defaultTrustAgent" translatable="false"></string>
+
     <!-- Colon separated list of package names that should be granted Notification Listener access -->
     <string name="config_defaultListenerAccessPackages" translatable="false"></string>
 
@@ -2911,6 +2914,11 @@
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
 
+    <!-- Flag indicating that the entire notification header can be clicked to expand the
+         notification. If false, then the expand icon has to be clicked in order for the expand
+         to occur. The expand button will have increased touch boundaries to accomodate this. -->
+    <bool name="config_notificationHeaderClickableForExpand">false</bool>
+
     <!-- Configuration for automotive -->
     <bool name="enable_pbap_pce_profile">false</bool>
 
@@ -2962,6 +2970,22 @@
          relative to the overall voice call stream volume [0..100] -->
     <integer name="config_inCallNotificationVolumeRelative">67</integer>
 
+    <!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
+    <integer name="config_cameraLiftTriggerSensorType">-1</integer>
+    <!-- The OEM specified sensor string type for the gesture to launch camera app, this value
+        must match the value of config_cameraLiftTriggerSensorType in OEM's HAL -->
+    <string translatable="false" name="config_cameraLiftTriggerSensorStringType"></string>
+
+    <!-- Default number of days to retain for the automatic storage manager. -->
+    <integer translatable="false" name="config_storageManagerDaystoRetainDefault">90</integer>
+
+    <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
+    <string name="config_headlineFontFamily" translatable="false"></string>
+    <!-- Name of a font family to use for headlines. Defaults to sans-serif-light -->
+    <string name="config_headlineFontFamilyLight" translatable="false">sans-serif-light</string>
+    <!-- Allows setting custom fontFeatureSettings on specific text. -->
+    <string name="config_headlineFontFeatureSettings" translatable="false"></string>
+
     <!-- An array of packages that need to be treated as type system in battery settings -->
     <string-array translatable="false" name="config_batteryPackageTypeSystem">
         <item>com.android.providers.calendar</item>
@@ -2972,6 +2996,15 @@
     <!-- An array of packages that need to be treated as type service in battery settings -->
     <string-array translatable="false" name="config_batteryPackageTypeService"/>
 
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">false</bool>
+
+    <!-- Enable the RingtonePickerActivity in 'com.android.providers.media'. -->
+    <bool name="config_defaultRingtonePickerEnabled">true</bool>
+
+    <!-- Allow SystemUI to show the shutdown dialog -->
+    <bool name="config_showSysuiShutdown">true</bool>
+
     <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only'
          when SIM is unready. -->
     <bool name="config_display_no_service_when_sim_unready">false</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ece0e82..b4636a6 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -30,7 +30,7 @@
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
 
-    <dimen name="toast_y_offset">64dip</dimen>
+    <dimen name="toast_y_offset">24dp</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">24dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
@@ -67,6 +67,9 @@
     <!-- The amount to leave on-screen when the PIP is minimized. -->
     <dimen name="pip_minimized_visible_size">48dp</dimen>
 
+    <!-- The the PIP decelerates at while moving from a fling. -->
+    <dimen name="pip_fling_deceleration">-3000dp</dimen>
+
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
@@ -177,6 +180,12 @@
     <!-- height of the content margin on the bottom -->
     <dimen name="notification_content_margin_bottom">16dp</dimen>
 
+    <!-- The height of the progress bar. -->
+    <dimen name="notification_progress_bar_height">15dp</dimen>
+
+    <!-- The top margin before the notification progress bar. -->
+    <dimen name="notification_progress_margin_top">8dp</dimen>
+
     <!-- height of the notification header (for icon and package name) -->
     <dimen name="notification_header_height">48dp</dimen>
 
@@ -185,20 +194,40 @@
 
     <!-- The top padding for the notification header -->
     <dimen name="notification_header_padding_top">10dp</dimen>
+
     <!-- The bottom padding for the notification header -->
     <dimen name="notification_header_padding_bottom">11dp</dimen>
 
+    <!-- The margin at the bottom of the notification header. -->
+    <dimen name="notification_header_margin_bottom">5dp</dimen>
+
+    <!-- The end margin after the application icon in the notification header -->
+    <dimen name="notification_header_icon_margin_end">3dp</dimen>
+
     <!-- size (width and height) of the icon in the notification header -->
     <dimen name="notification_header_icon_size">18dp</dimen>
 
     <!-- size (width and height) of the icon in the notification header -->
     <dimen name="notification_header_icon_size_ambient">20dp</dimen>
 
+    <!-- The margin before the start of the app name in the header. -->
+    <dimen name="notification_header_app_name_margin_start">3dp</dimen>
+
+    <!-- The margin before and after each of the items in the notification header. -->
+    <dimen name="notification_header_separating_margin">2dp</dimen>
+
+    <!-- The absolute size of the notification expand icon. -2 for wrap_content. -->
+    <dimen name="notification_header_expand_icon_size">-2px</dimen>
+
+    <!-- The top padding for the notification expand button. -->
+    <dimen name="notification_expand_button_padding_top">1dp</dimen>
+
     <!-- Height of a small notification in the status bar -->
     <dimen name="notification_min_height">92dp</dimen>
 
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_width">64dp</dimen>
+
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_height">64dp</dimen>
 
@@ -208,12 +237,21 @@
     <!-- The minimum height of the content if there are at least two lines or a picture-->
     <dimen name="notification_min_content_height">41dp</dimen>
 
-    <!-- The small size of the image if the height drawing doesn't work anymore -->
-    <dimen name="media_notification_expanded_image_small_size">72dp</dimen>
+    <!-- The size of the media actions in the media notification. -->
+    <dimen name="media_notification_action_button_size">48dp</dimen>
+
+    <!-- The bottom padding for the media actions container. -->
+    <dimen name="media_notification_actions_padding_bottom">12dp</dimen>
+
+    <!-- The maximum size of the image in the expanded media notification -->
+    <dimen name="media_notification_expanded_image_max_size">94dp</dimen>
 
     <!-- The maximum size of the image in the expanded media notification -->
     <dimen name="media_notification_expanded_image_margin_bottom">20dp</dimen>
 
+    <!-- The absolute height for the header in a media notification. -->
+    <dimen name="media_notification_header_height">53dp</dimen>
+
     <!-- The margin of the content to an image-->
     <dimen name="notification_content_image_margin_end">8dp</dimen>
 
@@ -492,6 +530,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>
@@ -537,6 +577,21 @@
     <dimen name="item_touch_helper_swipe_escape_velocity">120dp</dimen>
     <dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</dimen>
 
+    <!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined by the maximum notification height -->
+    <dimen name="notification_custom_view_max_image_height">284dp</dimen>
+    <!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined a maximum notification width -->
+    <dimen name="notification_custom_view_max_image_width">450dp</dimen>
+    <!-- The maximum height of a big picture in a notification. The images will be reduced to that height in case they are bigger. This value is determined by the maximum notification height -->
+    <dimen name="notification_big_picture_max_height">284dp</dimen>
+    <!-- The maximum width of a big picture in a notification. The images will be reduced to that width in case they are bigger. This value is determined by the standard panel size -->
+    <dimen name="notification_big_picture_max_width">416dp</dimen>
+    <!-- The maximum height of a image in a media notification. The images will be reduced to that height in case they are bigger. This value is determined by the expanded media template-->
+    <dimen name="notification_media_image_max_height">140dp</dimen>
+    <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
+    <dimen name="notification_media_image_max_width">280dp</dimen>
+    <!-- The size of the right icon -->
+    <dimen name="notification_right_icon_size">40dp</dimen>
+
     <!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
     <dimen name="autofill_dataset_picker_max_size">90%</dimen>
 
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index ba14843..04ea077 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -380,7 +380,6 @@
         <item>nl-NL</item> <!-- Dutch (Netherlands) -->
         <item>nl-SR</item> <!-- Dutch (Suriname) -->
         <item>nl-SX</item> <!-- Dutch (Sint Maarten) -->
-        <item>nmg-CM</item> <!-- Kwasio (Cameroon) -->
         <item>nn-NO</item> <!-- Norwegian Nynorsk (Norway) -->
         <item>nnh-CM</item> <!-- Ngiemboon (Cameroon) -->
         <item>nus-SS</item> <!-- Nuer (South Sudan) -->
@@ -463,8 +462,6 @@
         <item>teo-KE</item> <!-- Teso (Kenya) -->
         <item>teo-UG</item> <!-- Teso (Uganda) -->
         <item>th-TH</item> <!-- Thai (Thailand) -->
-        <item>ti-ER</item> <!-- Tigrinya (Eritrea) -->
-        <item>ti-ET</item> <!-- Tigrinya (Ethiopia) -->
         <item>to-TO</item> <!-- Tongan (Tonga) -->
         <item>tr-CY</item> <!-- Turkish (Cyprus) -->
         <item>tr-TR</item> <!-- Turkish (Turkey) -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 07dbc5d..2329056 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -266,11 +266,11 @@
     <string name="wfcRegErrorTitle">Wi-Fi Calling</string>
     <!-- WFC Operator Error Messages showed as alerts -->
     <string-array name="wfcOperatorErrorAlertMessages">
-        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings. (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
     </string-array>
     <!-- WFC Operator Error Messages showed as notifications -->
     <string-array name="wfcOperatorErrorNotificationMessages">
-        <item>Register with your carrier</item>
+        <item>Register with your carrier (Error code: <xliff:g id="code" example="REG09 - No 911 Address">%1$s</xliff:g>)</item>
     </string-array>
     <!-- Template for showing mobile network operator name while WFC is active -->
     <string-array name="wfcSpnFormats">
@@ -591,10 +591,7 @@
     <string name="notification_header_divider_symbol_with_spaces" translatable="false">" • "</string>
 
     <!-- Text shown in place of notification contents when the notification is hidden on a secure lockscreen -->
-    <string name="notification_hidden_text">Contents hidden</string>
-
-    <!-- Text shown in place of notification contents when the notification is hidden by policy on a secure lockscreen -->
-    <string name="notification_hidden_by_policy_text">Contents hidden by policy</string>
+    <string name="notification_hidden_text">New notification</string>
 
     <!-- Text shown when viewing channel settings for notifications related to the virtual keyboard -->
     <string name="notification_channel_virtual_keyboard">Virtual keyboard</string>
@@ -644,17 +641,18 @@
     <!-- This is the label for the notification channel settings that controls the behavior
         of the notification about applications that are running in the background (that is,
         perhaps confusingly, running foreground services but not the foreground UI on the screen).
-        [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_foreground_service">Apps running in background</string>
+        [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6665375982962336520] -->
+    <string name="notification_channel_foreground_service">Apps consuming battery</string>
 
-    <!-- Label for foreground service notification when one app is running. [CHAR LIMIT=NONE] -->
+    <!-- Label for foreground service notification when one app is running.
+    [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=6826789589341671842] -->
     <string name="foreground_service_app_in_background"><xliff:g id="app_name">%1$s</xliff:g> is
-        running in the background</string>
+        using battery</string>
 
     <!-- Label for foreground service notification when multiple apps are running.
-        [CHAR LIMIT=NONE] -->
+        [CHAR LIMIT=NONE BACKUP_MESSAGE_ID=7150914856893450380] -->
     <string name="foreground_service_apps_in_background"><xliff:g id="number">%1$d</xliff:g> apps
-        are running in the background</string>
+        are using battery</string>
 
     <!-- Content for foreground service notification when one app is running.
         [CHAR LIMIT=NONE] -->
@@ -3003,6 +3001,21 @@
         <item quantity="other">Open Wi-Fi networks available</item>
     </plurals>
 
+    <!-- Notification title for a nearby open wireless network.-->
+    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system is connecting to the specified open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connecting">Connecting to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system has connected to the open network. The network name is specified in the notification content. -->
+    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
+    <!-- Notification title when the system failed to connect to the specified open network. -->
+    <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
+    <!-- Notification content when the system failed to connect to the specified open network. This informs the user that tapping on this notification will open the wifi picker. -->
+    <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
+    <!-- Notification action name for connecting to the network specified in the notification body. -->
+    <string name="wifi_available_action_connect">Connect</string>
+    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
+    <string name="wifi_available_action_all_networks">All Networks</string>
+
     <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
     <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
 
@@ -3170,6 +3183,11 @@
     <string name="usb_accessory_notification_title">Connected to a USB accessory</string>
     <!-- See USB_PREFERENCES. This is the message. -->
     <string name="usb_notification_message">Tap for more options.</string>
+    <!-- USB_PREFERENCES: Notification for when a type-c USB audio accessory is attached but not supported.  This is the title -->
+    <string name="usb_unsupported_audio_accessory_title">Analog audio accessory detected</string>
+    <!-- Message of notification shown when a type-c USB audio accessory is attached but not supported. -->
+    <string name="usb_unsupported_audio_accessory_message">The attached device is not compatible with this phone. Tap to learn more.</string>
+
 
     <!-- Title of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_title">USB debugging connected</string>
@@ -3481,13 +3499,6 @@
     <string name="tethered_notification_title">Tethering or hotspot active</string>
     <string name="tethered_notification_message">Tap to set up.</string>
 
-    <!-- Strings for tether disabling notification -->
-    <!-- This notification is shown when tethering has been disabled on a user's device.
-    The device is managed by the user's employer. Tethering can't be turned on unless the
-    IT administrator allows it. The noun "admin" is another reference for "IT administrator." -->
-    <string name="disable_tether_notification_title">Tethering is disabled</string>
-    <string name="disable_tether_notification_message">Contact your admin for details</string>
-
     <!--  Strings for possible PreferenceActivity Back/Next buttons -->
     <string name="back_button_label">Back</string>
     <string name="next_button_label">Next</string>
@@ -4582,22 +4593,10 @@
     <!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.-->
     <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
 
-    <!-- Title of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
-    <string name="reset_retail_demo_mode_title">Reset device?</string>
-    <!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
-    <string name="reset_retail_demo_mode_text">Tap to reset device</string>
     <!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] -->
     <string name="demo_starting_message">Starting demo\u2026</string>
     <!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] -->
     <string name="demo_restarting_message">Resetting device\u2026</string>
-    <!-- Title of the dialog shown when user inactivity times out in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_title">Reset device?</string>
-    <!-- Warning message shown when user inactivity times out in retail demo mode [CHAR LIMIT=none] -->
-    <string name="demo_user_inactivity_timeout_countdown">You\u2019ll lose any changes and the demo will start again in <xliff:g id="timeout" example="9">%1$s</xliff:g> seconds\u2026</string>
-    <!-- Text of button to allow user to abort countdown and continue current session in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_left_button">Cancel</string>
-    <!-- Text of button to allow user to abort countdown and immediately start another session in retail demo mode [CHAR LIMIT=40] -->
-    <string name="demo_user_inactivity_timeout_right_button">Reset now</string>
 
     <!-- Accessibilty string added to a widget that has been suspended [CHAR LIMIT=20] -->
     <string name="suspended_widget_accessibility">Disabled <xliff:g id="label" example="Calendar">%1$s</xliff:g></string>
@@ -4705,6 +4704,9 @@
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test -->
     <string name="etws_primary_default_message_test">Emergency messages test</string>
 
+    <!-- Content description for the reply button in the notification area [CHAR LIMIT=NONE]-->
+    <string name="notification_reply_button_accessibility">Reply</string>
+
     <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others -->
     <string name="etws_primary_default_message_others"></string>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 690b051..4b0fe3f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -931,7 +931,7 @@
          <item name="textStyle">normal</item>
          <item name="textColor">?textColorPrimaryInverse</item>
          <item name="textColorHint">?textColorHintInverse</item>
-     </style>	
+     </style>
 
      <!-- @hide -->
      <style name="TextAppearance.SearchResult.Title">
@@ -956,7 +956,8 @@
     </style>
 
     <style name="TextAppearance.Toast">
-        <item name="fontFamily">sans-serif-condensed</item>
+        <item name="fontFamily">sans-serif</item>
+        <item name="textSize">14sp</item>
     </style>
 
     <style name="TextAppearance.Tooltip">
@@ -1492,4 +1493,15 @@
         <item name="background">@drawable/autofill_dataset_picker_background</item>
     </style>
 
+    <!-- The style for the container of media actions in a notification. -->
+    <!-- @hide -->
+    <style name="NotificationMediaActionContainer">
+        <item name="layout_width">wrap_content</item>
+        <item name="layout_height">wrap_content</item>
+        <item name="layout_marginTop">-21dp</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingBottom">@dimen/media_notification_actions_padding_bottom</item>
+        <item name="gravity">top</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index ec16611..f39904d 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1054,7 +1054,7 @@
     </style>
 
     <style name="Widget.Material.MediaRouteButton" parent ="Widget.Material.ActionButton">
-        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material_dark</item>
         <item name="contentDescription">@string/media_route_button_content_description</item>
     </style>
 
@@ -1203,7 +1203,10 @@
     <style name="Widget.Material.Light.ActionBar" parent="Widget.Material.ActionBar" />
     <style name="Widget.Material.Light.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid" />
     <style name="Widget.Material.Light.FastScroll" parent="Widget.Material.FastScroll"/>
-    <style name="Widget.Material.Light.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
+
+    <style name="Widget.Material.Light.MediaRouteButton" parent ="Widget.Material.MediaRouteButton">
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_material_light</item>
+    </style>
 
     <!-- Animation Styles -->
 
@@ -1290,7 +1293,7 @@
     <style name="Notification.Header" parent="">
         <item name="paddingTop">@dimen/notification_header_padding_top</item>
         <item name="paddingBottom">@dimen/notification_header_padding_bottom</item>
-        <item name="layout_marginBottom">5dp</item>
+        <item name="layout_marginBottom">@dimen/notification_header_margin_bottom</item>
         <item name="paddingStart">@dimen/notification_content_margin_start</item>
         <item name="paddingEnd">16dp</item>
     </style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4724399..d562498 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -312,6 +312,7 @@
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
   <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
+  <java-symbol type="bool" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit" />
   <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
   <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
   <java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
@@ -372,6 +373,10 @@
   <java-symbol type="integer"  name="config_wifi_tx_cur_ma" />
   <java-symbol type="integer"  name="config_wifi_operating_voltage_mv" />
   <java-symbol type="string"  name="config_wifi_framework_sap_2G_channel_list" />
+  <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
+  <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
+  <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
+  <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
 
   <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
   <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
@@ -1162,10 +1167,6 @@
   <java-symbol type="string" name="lockscreen_transport_pause_description" />
   <java-symbol type="string" name="config_ethernet_tcp_buffers" />
   <java-symbol type="string" name="config_wifi_tcp_buffers" />
-  <java-symbol type="string" name="config_demoModeLauncherComponent" />
-  <java-symbol type="string" name="config_carrierDemoModePassword" />
-  <java-symbol type="string" name="config_carrierDemoModeSetting" />
-  <java-symbol type="string" name="config_carrierDemoModePackages" />
   <java-symbol type="string" name="demo_starting_message" />
   <java-symbol type="string" name="demo_restarting_message" />
   <java-symbol type="string" name="conference_call" />
@@ -1314,10 +1315,8 @@
   <java-symbol type="drawable" name="unlock_wave" />
   <java-symbol type="drawable" name="notification_template_icon_bg" />
   <java-symbol type="drawable" name="notification_template_icon_low_bg" />
-  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
   <java-symbol type="drawable" name="ic_media_route_off_holo_dark" />
-  <java-symbol type="drawable" name="ic_media_route_connecting_holo_dark" />
-  <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
+  <java-symbol type="drawable" name="ic_media_route_off_holo_light" />
   <java-symbol type="drawable" name="cling_button" />
   <java-symbol type="drawable" name="cling_arrow_up" />
   <java-symbol type="drawable" name="cling_bg" />
@@ -1479,6 +1478,7 @@
   <java-symbol type="xml" name="global_keys" />
   <java-symbol type="xml" name="default_zen_mode_config" />
   <java-symbol type="xml" name="sms_7bit_translation_table" />
+  <java-symbol type="xml" name="color_extraction" />
 
   <java-symbol type="raw" name="color_fade_vert" />
   <java-symbol type="raw" name="color_fade_frag" />
@@ -1549,9 +1549,7 @@
   <java-symbol type="array" name="config_autoRotationTiltTolerance" />
   <java-symbol type="array" name="config_keyboardTapVibePattern" />
   <java-symbol type="array" name="config_longPressVibePattern" />
-  <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
   <java-symbol type="array" name="config_safeModeEnabledVibePattern" />
-  <java-symbol type="array" name="config_contextClickVibePattern" />
   <java-symbol type="array" name="config_virtualKeyVibePattern" />
   <java-symbol type="attr" name="actionModePopupWindowStyle" />
   <java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
@@ -1580,6 +1578,7 @@
   <java-symbol type="dimen" name="docked_stack_divider_insets" />
   <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="dimen" name="pip_minimized_visible_size" />
+  <java-symbol type="dimen" name="pip_fling_deceleration" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
   <java-symbol type="integer" name="config_pictureInPictureSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
@@ -1745,6 +1744,7 @@
   <java-symbol type="bool" name="config_animateScreenLights" />
   <java-symbol type="bool" name="config_automatic_brightness_available" />
   <java-symbol type="bool" name="config_autoBrightnessResetAmbientLuxAfterWarmUp" />
+  <java-symbol type="bool" name="config_notificationHeaderClickableForExpand" />
   <java-symbol type="bool" name="config_dozeAfterScreenOff" />
   <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
   <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
@@ -1771,7 +1771,6 @@
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
   <java-symbol type="bool" name="config_wifi_background_scan_support" />
   <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="bool" name="config_wifi_hotspot2_enabled" />
   <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
@@ -1869,6 +1868,13 @@
   <java-symbol type="layout" name="app_error_dialog" />
   <java-symbol type="plurals" name="wifi_available" />
   <java-symbol type="plurals" name="wifi_available_detailed" />
+  <java-symbol type="string" name="wifi_available_title" />
+  <java-symbol type="string" name="wifi_available_title_connecting" />
+  <java-symbol type="string" name="wifi_available_title_connected" />
+  <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
+  <java-symbol type="string" name="wifi_available_action_connect" />
+  <java-symbol type="string" name="wifi_available_action_all_networks" />
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
@@ -1958,8 +1964,6 @@
   <java-symbol type="string" name="smv_process" />
   <java-symbol type="string" name="tethered_notification_message" />
   <java-symbol type="string" name="tethered_notification_title" />
-  <java-symbol type="string" name="disable_tether_notification_message" />
-  <java-symbol type="string" name="disable_tether_notification_title" />
   <java-symbol type="string" name="adb_debugging_notification_channel_tv" />
   <java-symbol type="string" name="usb_accessory_notification_title" />
   <java-symbol type="string" name="usb_mtp_notification_title" />
@@ -1968,6 +1972,8 @@
   <java-symbol type="string" name="usb_ptp_notification_title" />
   <java-symbol type="string" name="usb_midi_notification_title" />
   <java-symbol type="string" name="usb_supplying_notification_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_message" />
   <java-symbol type="string" name="config_UsbDeviceConnectionHandling_component" />
   <java-symbol type="string" name="vpn_text" />
   <java-symbol type="string" name="vpn_text_long" />
@@ -2006,12 +2012,6 @@
   <java-symbol type="string" name="config_customVpnAlwaysOnDisconnectedDialogComponent" />
   <java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
   <java-symbol type="string" name="config_persistentDataPackageName" />
-  <java-symbol type="string" name="reset_retail_demo_mode_title" />
-  <java-symbol type="string" name="reset_retail_demo_mode_text" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_title" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_countdown" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_left_button" />
-  <java-symbol type="string" name="demo_user_inactivity_timeout_right_button" />
 
   <java-symbol type="layout" name="resolver_list" />
   <java-symbol type="id" name="resolver_list" />
@@ -2524,6 +2524,8 @@
   <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
   <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
   <java-symbol type="bool" name="config_cameraDoubleTapPowerGestureEnabled" />
+  <java-symbol type="integer" name="config_cameraLiftTriggerSensorType" />
+  <java-symbol type="string" name="config_cameraLiftTriggerSensorStringType" />
 
   <java-symbol type="drawable" name="platlogo_m" />
 
@@ -2546,7 +2548,6 @@
   <java-symbol type="id" name="notification_material_reply_text_3" />
 
   <java-symbol type="string" name="notification_hidden_text" />
-  <java-symbol type="string" name="notification_hidden_by_policy_text" />
   <java-symbol type="id" name="app_name_text" />
   <java-symbol type="id" name="header_text" />
   <java-symbol type="id" name="expand_button" />
@@ -2566,6 +2567,13 @@
   <java-symbol type="dimen" name="notification_content_margin_top" />
   <java-symbol type="dimen" name="notification_content_margin_bottom" />
   <java-symbol type="dimen" name="notification_header_background_height" />
+  <java-symbol type="dimen" name="notification_header_height" />
+  <java-symbol type="dimen" name="notification_header_expand_icon_size" />
+  <java-symbol type="dimen" name="notification_expand_button_padding_top" />
+  <java-symbol type="dimen" name="notification_header_icon_margin_end" />
+  <java-symbol type="dimen" name="notification_header_icon_size" />
+  <java-symbol type="dimen" name="notification_header_app_name_margin_start" />
+  <java-symbol type="dimen" name="notification_header_separating_margin" />
   <java-symbol type="string" name="default_notification_channel_label" />
   <java-symbol type="string" name="importance_from_user" />
   <java-symbol type="string" name="importance_from_person" />
@@ -2630,7 +2638,6 @@
   <java-symbol type="string" name="new_sms_notification_title" />
   <java-symbol type="string" name="new_sms_notification_content" />
 
-  <java-symbol type="dimen" name="media_notification_expanded_image_small_size" />
   <java-symbol type="dimen" name="media_notification_expanded_image_margin_bottom" />
   <java-symbol type="dimen" name="notification_content_image_margin_end" />
 
@@ -2925,14 +2932,25 @@
   <java-symbol type="style" name="AutofillDatasetPicker" />
   <java-symbol type="dimen" name="autofill_dataset_picker_max_size"/>
 
+  <java-symbol type="dimen" name="notification_big_picture_max_height"/>
+  <java-symbol type="dimen" name="notification_big_picture_max_width"/>
+  <java-symbol type="dimen" name="notification_media_image_max_width"/>
+  <java-symbol type="dimen" name="notification_media_image_max_height"/>
+  <java-symbol type="dimen" name="notification_right_icon_size"/>
+  <java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
+  <java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
+
   <!-- Accessibility fingerprint gestures -->
   <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
   <java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
 
   <!-- android.service.trust -->
   <java-symbol type="bool" name="config_allowEscrowTokenForTrustAgent"/>
+  <java-symbol type="string" name="config_defaultTrustAgent" />
 
   <!-- Time picker -->
+  <java-symbol type="id" name="right_icon_container"/>
+  <java-symbol type="id" name="reply_icon_action"/>
   <java-symbol type="id" name="toggle_mode"/>
   <java-symbol type="id" name="input_mode"/>
   <java-symbol type="id" name="input_header"/>
@@ -2999,13 +3017,9 @@
 
   <!-- ETWS primary messages -->
   <java-symbol type="string" name="etws_primary_default_message_earthquake" />
-
   <java-symbol type="string" name="etws_primary_default_message_tsunami" />
-
   <java-symbol type="string" name="etws_primary_default_message_earthquake_and_tsunami" />
-
   <java-symbol type="string" name="etws_primary_default_message_test" />
-
   <java-symbol type="string" name="etws_primary_default_message_others" />
 
   <java-symbol type="bool" name="config_quickSettingsSupported" />
@@ -3026,17 +3040,31 @@
 
   <java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
 
+  <java-symbol type="string" name="config_dozeLongPressSensorType" />
+
   <java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
 
   <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
-
   <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
+  <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
+  <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
+  <java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
+  <java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
+  <java-symbol type="string" name="config_headlineFontFamily" />
+  <java-symbol type="string" name="config_headlineFontFamilyLight" />
+
   <java-symbol type="drawable" name="stat_sys_vitals" />
 
+  <java-symbol type="color" name="text_color_primary" />
+
   <java-symbol type="array" name="config_batteryPackageTypeSystem" />
   <java-symbol type="array" name="config_batteryPackageTypeService" />
+  <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
+  <java-symbol type="layout" name="shutdown_dialog" />
+  <java-symbol type="dimen" name="chooser_service_spacing" />
+  <java-symbol type="bool" name="config_showSysuiShutdown" />
 
   <java-symbol type="bool" name="config_display_no_service_when_sim_unready" />
 </resources>
diff --git a/core/res/res/xml/color_extraction.xml b/core/res/res/xml/color_extraction.xml
new file mode 100644
index 0000000..7d52b20
--- /dev/null
+++ b/core/res/res/xml/color_extraction.xml
@@ -0,0 +1,348 @@
+<?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
+  -->
+
+<colorextraction>
+    <!-- List of material color palettes in HSL -->
+    <palettes>
+        <!-- Grey scale -->
+        <palette h="0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f"
+                 s="0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f"
+                 l="0.08f, 0.11f, 0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+                0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+                0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f"/>
+        <!-- All colors -->
+        <palette h="1,1,0.991,0.991,0.9833333333333333,0,0,0,
+                0.01134380453752181,0.015625000000000003,0.024193548387096798,
+                0.027397260273972573,0.017543859649122865"
+                 s="1,1,1,1,1,1,1,0.8434782608695652,1,1,1,1,1"
+                 l="0.04,0.09,0.14,0.2,0.27450980392156865,
+                0.34901960784313724,0.4235294117647059,0.5490196078431373,
+                0.6254901960784314,0.6862745098039216,0.7568627450980392,
+                0.8568627450980393,0.9254901960784314"/>
+        <palette h="0.638,0.638,0.6385767790262171,0.6301169590643275,
+                0.6223958333333334,0.6151079136690647,0.6065400843881856,
+                0.5986964618249534,0.5910746812386157,0.5833333333333334,
+                0.5748031496062993,0.5582010582010583"
+                 s="1,1,1,1,0.9014084507042253,0.8128654970760234,
+                0.7979797979797981,0.7816593886462883,0.778723404255319,1,1,1"
+                 l="0.05,0.12,0.17450980392156862,0.2235294117647059,
+                0.2784313725490196,0.3352941176470588,0.388235294117647,
+                0.44901960784313727,0.5392156862745098,0.6509803921568628,
+                0.7509803921568627,0.8764705882352941"/>
+        <palette h="0.563,0.569,0.5666,0.5669934640522876,0.5748031496062993,
+                0.5595238095238095,0.5473118279569893,0.5393258426966292,
+                0.5315955766192734,0.524031007751938,0.5154711673699016,
+                0.508080808080808,0.5"
+                 s="1,1,1,1,1,1,1,1,1,0.8847736625514403,1,1,1"
+                 l="0.07,0.12,0.16,0.2,0.24901960784313726,
+                0.27450980392156865,0.30392156862745096,0.34901960784313724,
+                0.4137254901960784,0.47647058823529415,0.5352941176470588,
+                0.6764705882352942,0.8"/>
+        <palette h="0.508,0.511,0.508,0.508,0.5082304526748972,
+                0.5069444444444444,0.5,0.5,0.5,0.48724954462659376,
+                0.4800347222222222,0.4755134281200632,0.4724409448818897,
+                0.4671052631578947"
+                 s="1,1,1,1,1,0.8888888888888887,0.9242424242424242,1,
+                1,0.8133333333333332,0.7868852459016393,1,1,1"
+                 l="0.04,0.06,0.08,0.12,0.1588235294117647,
+                0.21176470588235297,0.25882352941176473,0.3,0.34901960784313724,
+                0.44117647058823534,0.5215686274509804,0.5862745098039216,
+                0.7509803921568627,0.8509803921568627"/>
+        <palette h="0.333,0.333,0.333,0.3333333333333333,0.3333333333333333,
+                0.34006734006734,0.34006734006734,0.34006734006734,
+                0.34259259259259256,0.3475783475783476,0.34767025089605735,
+                0.3467741935483871,0.3703703703703704"
+                 s="0.70,0.72,0.69,0.6703296703296703,0.728813559322034,
+                0.5657142857142856,0.5076923076923077,0.3944223107569721,
+                0.6206896551724138,0.8931297709923666,1,1,1"
+                 l="0.05,0.08,0.14,0.1784313725490196,0.23137254901960785,
+                0.3431372549019608,0.38235294117647056,0.49215686274509807,
+                0.6588235294117647,0.7431372549019608,0.8176470588235294,
+                0.8784313725490196,0.9294117647058824"/>
+        <palette h="0.161,0.163,0.163,0.162280701754386,0.15032679738562088,
+                0.15879265091863518,0.16236559139784948,0.17443868739205526,
+                0.17824074074074076,0.18674698795180725,0.18692449355432778,
+                0.1946778711484594,0.18604651162790695"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.05,0.08,0.11,0.14901960784313725,0.2,
+                0.24901960784313726,0.30392156862745096,0.3784313725490196,
+                0.4235294117647059,0.48823529411764705,0.6450980392156863,
+                0.7666666666666666,0.8313725490196078"/>
+        <palette h="0.108,0.105,0.105,0.105,0.10619469026548674,
+                0.11924686192468618,0.13046448087431692,0.14248366013071895,
+                0.1506024096385542,0.16220238095238093,0.16666666666666666,
+                0.16666666666666666,0.162280701754386,0.15686274509803924"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.17,0.22,0.28,0.35,0.44313725490196076,
+                0.46862745098039216,0.47843137254901963,0.5,0.5117647058823529,
+                0.5607843137254902,0.6509803921568628,0.7509803921568627,
+                0.8509803921568627,0.9"/>
+        <palette h="0.036,0.036,0.036,0.036,0.03561253561253561,
+                0.05098039215686275,0.07516339869281045,0.09477124183006536,
+                0.1150326797385621,0.134640522875817,0.14640522875816991,
+                0.1582397003745319,0.15773809523809523,0.15359477124183002"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.19,0.26,0.34,0.39,0.4588235294117647,0.5,0.5,0.5,
+                0.5,0.5,0.5,0.6509803921568628,0.7803921568627451,0.9"/>
+        <palette h="0.955,0.961,0.958,0.9596491228070175,0.9593837535014005,
+                0.9514767932489452,0.943859649122807,0.9396825396825397,
+                0.9395424836601307,0.9393939393939394,0.9362745098039216,
+                0.9754098360655739,0.9824561403508771"
+                 s="0.87,0.85,0.85,0.84070796460177,0.8206896551724138,
+                0.7979797979797981,0.7661290322580644,0.9051724137931036,
+                1,1,1,1,1"
+                 l="0.06,0.11,0.16,0.22156862745098038,0.2843137254901961,
+                0.388235294117647,0.48627450980392156,0.5450980392156863,
+                0.6,0.6764705882352942,0.8,0.8803921568627451,
+                0.9254901960784314"/>
+        <palette h="0.866,0.855,0.841025641025641,0.8333333333333334,
+                0.8285256410256411,0.821522309711286,0.8083333333333333,
+                0.8046594982078853,0.8005822416302766,0.7842377260981912,
+                0.7771084337349398,0.7747747747747749"
+                 s="1,1,1,1,1,1,1,1,1,
+                0.737142857142857,0.6434108527131781,0.46835443037974644"
+                 l="0.05,0.08,0.12745098039215685,0.15490196078431373,
+                0.20392156862745098,0.24901960784313726,0.3137254901960784,
+                0.36470588235294116,0.44901960784313727,0.6568627450980392,
+                0.7470588235294118,0.8450980392156863"/>
+        <palette h="0.925,0.93,0.938,0.947,0.955952380952381,
+                0.9681069958847737,0.9760479041916167,0.9873563218390804,0,0,
+                0.009057971014492771,0.026748971193415648,
+                0.041666666666666616,0.05303030303030304"
+                 s="1,1,1,1,1,0.8350515463917526,0.6929460580912863,
+                0.6387665198237885,0.6914893617021276,0.7583892617449666,
+                0.8070175438596495,0.9310344827586209,1,1"
+                 l="0.10,0.13,0.17,0.2,0.27450980392156865,
+                0.3803921568627451,0.4725490196078432,0.5549019607843138,
+                0.6313725490196078,0.707843137254902,0.7764705882352941,
+                0.8294117647058823,0.9058823529411765,0.9568627450980391"/>
+        <palette h="0.733,0.736,0.744,0.7514619883040936,0.7679738562091503,
+                0.7802083333333333,0.7844311377245509,0.796875,
+                0.8165618448637316,0.8487179487179487,0.8582375478927203,
+                0.8562091503267975,0.8666666666666667"
+                 s="1,1,1,1,1,0.8163265306122449,0.6653386454183268,
+                0.7547169811320753,0.929824561403509,0.9558823529411766,
+                0.9560439560439562,1,1"
+                 l="0.07,0.12,0.17,0.2235294117647059,0.3,
+                0.38431372549019605,0.492156862745098,0.5843137254901961,
+                0.6647058823529411,0.7333333333333334,0.8215686274509804,0.9,
+                0.9411764705882353"/>
+        <palette h="0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666,0.6666666666666666,
+                0.6666666666666666,0.6666666666666666"
+                 s="0.25,0.24590163934426232,0.17880794701986752,
+                0.14606741573033713,0.13761467889908252,0.14893617021276592,
+                0.16756756756756758,0.20312500000000017,0.26086956521739135,
+                0.29999999999999966,0.5000000000000004"
+                 l="0.18,0.2392156862745098,0.296078431372549,
+                0.34901960784313724,0.4274509803921569,0.5392156862745098,
+                0.6372549019607843,0.7490196078431373,0.8196078431372549,
+                0.8823529411764706,0.9372549019607843"/>
+        <palette h="0.938,0.944,0.952,0.961,0.9678571428571429,
+                0.9944812362030905,0,0,
+                0.0047348484848484815,0.00316455696202532,0,
+                0.9980392156862745,0.9814814814814816,0.9722222222222221"
+                 s="1,1,1,1,1,0.7023255813953488,0.6638655462184874,
+                0.6521739130434782,0.7719298245614035,0.8315789473684211,
+                0.6867469879518071,0.7264957264957265,0.8181818181818182,
+                0.8181818181818189"
+                 l="0.08,0.13,0.18,0.23,0.27450980392156865,
+                0.4215686274509804,
+                0.4666666666666667,0.503921568627451,0.5529411764705883,
+                0.6274509803921569,0.6745098039215687,0.7705882352941176,
+                0.892156862745098,0.9568627450980391"/>
+        <palette h="0.88,0.888,0.897,0.9052287581699346,0.9112021857923498,
+                0.9270152505446624,0.9343137254901961,0.9391534391534391,
+                0.9437984496124031,0.943661971830986,0.9438943894389439,
+                0.9426229508196722,0.9444444444444444"
+                 s="1,1,1,1,0.8133333333333332,0.7927461139896375,
+                0.7798165137614679,0.7777777777777779,0.8190476190476191,
+                0.8255813953488372,0.8211382113821142,0.8133333333333336,
+                0.8000000000000006"
+                 l="0.08,0.12,0.16,0.2,0.29411764705882354,
+                0.3784313725490196,0.42745098039215684,0.4764705882352941,
+                0.5882352941176471,0.6627450980392157,0.7588235294117647,
+                0.8529411764705882,0.9411764705882353"/>
+        <palette h="0.669,0.680,0.6884057971014492,0.6974789915966387,
+                0.7079889807162534,0.7154471544715447,0.7217741935483872,
+                0.7274143302180687,0.7272727272727273,0.7258064516129031,
+                0.7252252252252251,0.7333333333333333"
+                 s="0.81,0.81,0.8214285714285715,0.6878612716763006,
+                0.6080402010050251,0.5774647887323943,0.5391304347826086,
+                0.46724890829694316,0.4680851063829788,0.462686567164179,
+                0.45679012345678977,0.4545454545454551"
+                 l="0.12,0.16,0.2196078431372549,0.33921568627450976,
+                0.39019607843137255,0.4176470588235294,0.45098039215686275,
+                0.5509803921568628,0.6313725490196078,0.7372549019607844,
+                0.8411764705882353,0.9352941176470588"/>
+        <palette h="0.6470588235294118,0.6516666666666667,0.6464174454828661,
+                0.6441441441441442,0.6432748538011696,0.6416666666666667,
+                0.6402439024390243,0.6412429378531074,0.6435185185185186,
+                0.6428571428571429"
+                 s="0.8095238095238095,0.6578947368421053,0.5721925133689839,
+                0.5362318840579711,0.5,0.4424778761061947,0.44086021505376327,
+                0.44360902255639095,0.4499999999999997,0.4375000000000006"
+                 l="0.16470588235294117,0.2980392156862745,0.36666666666666664,
+                0.40588235294117647,0.44705882352941173,
+                0.5568627450980392,0.6352941176470588,0.7392156862745098,
+                0.8431372549019608,0.9372549019607843"/>
+        <palette h="0.469,0.46732026143790845,0.4718614718614719,
+                0.4793650793650794,0.48071625344352614,0.4829683698296837,
+                0.484375,0.4841269841269842,0.48444444444444457,
+                0.48518518518518516,0.4907407407407408"
+                 s="1,1,1,1,1,1,0.6274509803921569,0.41832669322709176,
+                0.41899441340782106,0.4128440366972478,0.4090909090909088"
+                 l="0.07,0.1,0.15098039215686274,0.20588235294117646,
+                0.2372549019607843,0.26862745098039215,0.4,0.5078431372549019,
+                0.6490196078431372,0.7862745098039216,0.9137254901960784"/>
+        <palette h="0.542,0.5444444444444444,0.5555555555555556,
+                0.5555555555555556,0.553763440860215,0.5526315789473684,
+                0.5555555555555556,0.5555555555555555,0.5555555555555556,
+                0.5512820512820514,0.5666666666666667"
+                 s="0.25,0.24590163934426232,0.19148936170212766,
+                0.1791044776119403,0.18343195266272191,0.18446601941747576,
+                0.1538461538461539,0.15625000000000003,0.15328467153284678,
+                0.15662650602409653,0.151515151515151"
+                 l="0.05,0.1196078431372549,0.1843137254901961,
+                0.2627450980392157,
+                0.33137254901960783,0.403921568627451,0.5411764705882354,
+                0.6235294117647059,0.7313725490196079,0.8372549019607843,
+                0.9352941176470588"/>
+        <palette h="0.022222222222222223,0.02469135802469136,0.031249999999999997,
+                0.03947368421052631,0.04166666666666668,
+                0.043650793650793655,0.04411764705882352,0.04166666666666652,
+                0.04444444444444459,0.05555555555555529"
+                 s="0.33333333333333337,0.2783505154639175,0.2580645161290323,
+                0.25675675675675674,0.2528735632183908,0.17500000000000002,
+                0.15315315315315312,0.15189873417721522,
+                0.15789473684210534,0.15789473684210542"
+                 l="0.08823529411764705,0.19019607843137254,0.2431372549019608,
+                0.2901960784313725,0.3411764705882353,0.47058823529411764,
+                0.5647058823529412,0.6901960784313725,0.8137254901960784,
+                0.9254901960784314"/>
+        <palette h="0.027,0.03,0.038,0.044,0.050884955752212385,
+                0.07254901960784313,0.0934640522875817,
+                0.10457516339869281,0.11699346405228758,
+                0.1255813953488372,0.1268939393939394,0.12533333333333332,
+                0.12500000000000003,0.12777777777777777"
+                 s="1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+                 l="0.25,0.3,0.35,0.4,0.44313725490196076,0.5,0.5,0.5,
+                0.5,0.5784313725490196,
+                0.6549019607843137,0.7549019607843137,0.8509803921568627,
+                0.9411764705882353"/>
+    </palettes>
+    <blacklist>
+        <!-- Red -->
+        <range h="0, 20"
+               s="0.7, 1"
+               l="0.21, 0.79"/>
+        <range h="0, 20"
+               s="0.3, 0.7"
+               l="0.355, 0.653"/>
+        <!-- Red Orange -->
+        <range h="20, 40"
+               s="0.7, 1"
+               l="0.28, 0.643"/>
+        <range h="20, 40"
+               s="0.3, 0.7"
+               l="0.414, 0.561"/>
+        <range h="20, 40"
+               s="0, 3"
+               l="0.343, 0.584"/>
+        <!-- Orange -->
+        <range h="40, 60"
+               s="0.7, 1"
+               l="0.173, 0.349"/>
+        <range h="40, 60"
+               s="0.3, 0.7"
+               l="0.233, 0.427"/>
+        <range h="40, 60"
+               s="0, 0.3"
+               l="0.231, 0.484"/>
+        <!-- Yellow 60 -->
+        <range h="60, 80"
+               s="0.7, 1"
+               l="0.488, 0.737"/>
+        <range h="60, 80"
+               s="0.3, 0.7"
+               l="0.673, 0.837"/>
+        <!-- Yellow Green 80 -->
+        <range h="80, 100"
+               s="0.7, 1"
+               l="0.469, 0.61"/>
+        <!-- Yellow green 100 -->
+        <range h="100, 120"
+               s="0.7, 1"
+               l="0.388, 0.612"/>
+        <range h="100, 120"
+               s="0.3, 0.7"
+               l="0.424, 0.541"/>
+        <!-- Green -->
+        <range h="120, 140"
+               s="0.7, 1"
+               l="0.375, 0.52"/>
+        <range h="120, 140"
+               s="0.3, 0.7"
+               l="0.435, 0.524"/>
+        <!-- Green Blue 140 -->
+        <range h="140, 160"
+               s="0.7, 1"
+               l="0.496, 0.641"/>
+        <!-- Seaoam -->
+        <range h="160, 180"
+               s="0.7, 1"
+               l="0.496, 0.567"/>
+        <!-- Cyan -->
+        <range h="180, 200"
+               s="0.7, 1"
+               l="0.52, 0.729"/>
+        <!-- Blue -->
+        <range h="220, 240"
+               s="0.7, 1"
+               l="0.396, 0.571"/>
+        <range h="220, 240"
+               s="0.3, 0.7"
+               l="0.425, 0.551"/>
+        <!-- Blue Purple 240 -->
+        <range h="240, 260"
+               s="0.7, 1"
+               l="0.418, 0.639"/>
+        <range h="220, 240"
+               s="0.3, 0.7"
+               l="0.441, 0.576"/>
+        <!-- Blue Purple 260 -->
+        <range h="260, 280"
+               s="0.3, 1"
+               l="0.461, 0.553"/>
+        <!-- Fuchsia -->
+        <range h="300, 320"
+               s="0.7, 1"
+               l="0.484, 0.588"/>
+        <range h="300, 320"
+               s="0.3, 0.7"
+               l="0.48, 0.592"/>
+        <!-- Pink -->
+        <range h="320, 340"
+               s="0.7, 1"
+               l="0.466, 0.629"/>
+        <!-- Soft red -->
+        <range h="340, 360"
+               s="0.7, 1"
+               l="0.437, 0.596"/>
+    </blacklist>
+</colorextraction>
\ No newline at end of file
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 94a515b..e127896 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1172,6 +1172,7 @@
         </activity>
         <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
         <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
+        <activity android:name="com.android.internal.app.IntentForwarderActivityTest$IntentForwarderWrapperActivity"/>
 
         <receiver android:name="android.app.activity.AbortReceiver">
             <intent-filter android:priority="1">
@@ -1309,14 +1310,16 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.animation.BasicAnimatorActivity">
+        <activity android:name="android.animation.BasicAnimatorActivity"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
 
-        <activity android:name="android.animation.AnimatorSetActivity">
+        <activity android:name="android.animation.AnimatorSetActivity"
+                  android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index ed96bc1..23d70b8 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksCoreTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.coretests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
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/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
index e9e3a18..2470e87 100644
--- a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
+++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
@@ -16,16 +16,14 @@
 
 package android.app.admin;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /** Unit tests for {@link PasswordMetrics}. */
 @RunWith(AndroidJUnit4.class)
@@ -43,20 +41,6 @@
         assertEquals(0, metrics.numeric);
         assertEquals(0, metrics.symbols);
         assertEquals(0, metrics.nonLetter);
-        assertTrue("default constructor does not produce default metrics", metrics.isDefault());
-    }
-
-    @Test
-    public void testIsNotDefault() {
-        final PasswordMetrics metrics = new PasswordMetrics(
-                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, 12);
-        assertFalse("non-default metrics are repoted as default", metrics.isDefault());
-    }
-
-    @Test
-    public void testComputeForEmptyPassword() {
-        final PasswordMetrics metrics = PasswordMetrics.computeForPassword("");
-        assertTrue("empty password has default metrics", metrics.isDefault());
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1ffc1b3..423d45ea 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -36,6 +36,7 @@
 import android.content.res.Resources.NotFoundException;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -64,9 +65,14 @@
 import com.android.frameworks.coretests.R;
 import com.android.internal.content.PackageHelper;
 
+import dalvik.system.VMRuntime;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -78,9 +84,9 @@
 
     public static final String TAG = "PackageManagerTests";
 
-    public final long MAX_WAIT_TIME = 25 * 1000;
+    public static final long MAX_WAIT_TIME = 25 * 1000;
 
-    public final long WAIT_TIME_INCR = 5 * 1000;
+    public static final long WAIT_TIME_INCR = 5 * 1000;
 
     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
 
@@ -3844,6 +3850,117 @@
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
 
+    private static class TestDexModuleRegisterCallback
+            extends PackageManager.DexModuleRegisterCallback {
+        private String mDexModulePath = null;
+        private boolean mSuccess = false;
+        private String mMessage = null;
+        CountDownLatch doneSignal = new CountDownLatch(1);
+
+        @Override
+        public void onDexModuleRegistered(String dexModulePath, boolean success, String message) {
+            mDexModulePath = dexModulePath;
+            mSuccess = success;
+            mMessage = message;
+            doneSignal.countDown();
+        }
+
+        boolean waitTillDone() {
+            long startTime = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startTime < MAX_WAIT_TIME) {
+                try {
+                    return doneSignal.await(MAX_WAIT_TIME, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    Log.i(TAG, "Interrupted during sleep", e);
+                }
+            }
+            return false;
+        }
+
+    }
+
+    // Verify that the base code path cannot be registered.
+    public void testRegisterDexModuleBaseCode() throws Exception {
+        PackageManager pm = getPm();
+        ApplicationInfo info = getContext().getApplicationInfo();
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        pm.registerDexModule(info.getBaseCodePath(), callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(info.getBaseCodePath(), callback.mDexModulePath);
+        assertFalse("BaseCodePath should not be registered", callback.mSuccess);
+    }
+
+    // Verify thatmodules which are not own by the calling package are not registered.
+    public void testRegisterDexModuleNotOwningModule() throws Exception {
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
+        getPm().registerDexModule(moduleBelongingToOtherPackage, callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(moduleBelongingToOtherPackage, callback.mDexModulePath);
+        assertTrue(callback.waitTillDone());
+        assertFalse("Only modules belonging to the calling package can be registered",
+                callback.mSuccess);
+    }
+
+    // Verify that modules owned by the package are successfully registered.
+    public void testRegisterDexModuleSuccessfully() throws Exception {
+        ApplicationInfo info = getContext().getApplicationInfo();
+        // Copy the main apk into the data folder and use it as a "module".
+        File dexModuleDir = new File(info.dataDir, "module-dir");
+        File dexModule = new File(dexModuleDir, "module.apk");
+        try {
+            assertNotNull(FileUtils.createDir(
+                    dexModuleDir.getParentFile(), dexModuleDir.getName()));
+            Files.copy(Paths.get(info.getBaseCodePath()), dexModule.toPath(),
+                    StandardCopyOption.REPLACE_EXISTING);
+            TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+            getPm().registerDexModule(dexModule.toString(), callback);
+            assertTrue(callback.waitTillDone());
+            assertEquals(dexModule.toString(), callback.mDexModulePath);
+            assertTrue(callback.waitTillDone());
+            assertTrue(callback.mMessage, callback.mSuccess);
+
+            // NOTE:
+            // This actually verifies internal behaviour which might change. It's not
+            // ideal but it's the best we can do since there's no other place we can currently
+            // write a better test.
+            for(String isa : getAppDexInstructionSets(info)) {
+                Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.odex"));
+                Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.vdex"));
+            }
+        } finally {
+            FileUtils.deleteContentsAndDir(dexModuleDir);
+        }
+    }
+
+    // If the module does not exist on disk we should get a failure.
+    public void testRegisterDexModuleNotExists() throws Exception {
+        ApplicationInfo info = getContext().getApplicationInfo();
+        String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
+        TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
+        getPm().registerDexModule(nonExistentApk, callback);
+        assertTrue(callback.waitTillDone());
+        assertEquals(nonExistentApk, callback.mDexModulePath);
+        assertTrue(callback.waitTillDone());
+        assertFalse("DexModule registration should fail", callback.mSuccess);
+    }
+
+    // Copied from com.android.server.pm.InstructionSets because we don't have access to it here.
+    private static String[] getAppDexInstructionSets(ApplicationInfo info) {
+        if (info.primaryCpuAbi != null) {
+            if (info.secondaryCpuAbi != null) {
+                return new String[] {
+                        VMRuntime.getInstructionSet(info.primaryCpuAbi),
+                        VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
+            } else {
+                return new String[] {
+                        VMRuntime.getInstructionSet(info.primaryCpuAbi) };
+            }
+        }
+
+        return new String[] { VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]) };
+    }
+
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
index 31cf515..c9db034 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
@@ -23,68 +23,29 @@
         TestSuite suite =
           new TestSuite(NewDatabasePerformanceTestSuite.class.getName());
 
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Insert1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertIndexed1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Select100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringComparison100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoin100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoinOneSide100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InnerJoinNoIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectSubQIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndexStringComparison100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectInteger100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectString100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIntegerIndex100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIndexString100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringStartsWith100.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteIndexed1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           Delete1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           DeleteIndexWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           UpdateIndexWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           UpdateWhere1000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertInteger10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertIntegerIndex10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertString10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           InsertStringIndexed10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringStartsWith10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringIndexedStartsWith10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectInteger10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectIntegerIndexed10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringContains10000.class);
-        suite.addTestSuite(NewDatabasePerformanceTests.
-                           SelectStringIndexedContains10000.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Insert100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InsertIndexed100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Select100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringComparison100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoin100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoinOneSide100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.InnerJoinNoIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectSubQIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndexStringComparison100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectInteger100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectString100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIntegerIndex100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectIndexString100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringStartsWith100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteIndexed100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.Delete100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.DeleteIndexWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.UpdateIndexWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.UpdateWhere100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringContains100.class);
+        suite.addTestSuite(NewDatabasePerformanceTests.SelectStringIndexedContains100.class);
 
         return suite;
     }
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index adf88d2..f8d8e5e 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -19,6 +19,7 @@
 import android.content.ContentValues;
 import android.database.sqlite.SQLiteDatabase;
 import android.test.PerformanceTestCase;
+import android.util.Log;
 
 import junit.framework.TestCase;
 
@@ -31,17 +32,20 @@
  */
 
 public class NewDatabasePerformanceTests {
+    private static final String TAG = "NewDatabasePerformanceTests";
 
     // Edit this to change the test run times.  The original is 100.
-    final static int kMultiplier = 1;
+    private static final int SIZE_MULTIPLIER = 100;
 
     public static class PerformanceBase extends TestCase
     implements PerformanceTestCase {
         protected static final int CURRENT_DATABASE_VERSION = 42;
         protected SQLiteDatabase mDatabase;
         protected File mDatabaseFile;
+        private long mSetupFinishedTime;
 
         public void setUp() {
+            long setupStarted = System.currentTimeMillis();
             mDatabaseFile = new File("/sdcard", "perf_database_test.db");
             if (mDatabaseFile.exists()) {
                 mDatabaseFile.delete();
@@ -51,9 +55,14 @@
                             null);
             assertTrue(mDatabase != null);
             mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+            mSetupFinishedTime = System.currentTimeMillis();
+            Log.i(TAG, "Setup for " + getClass().getSimpleName() + " took "
+                    + (mSetupFinishedTime - setupStarted) + " ms");
         }
 
         public void tearDown() {
+            long duration = System.currentTimeMillis() - mSetupFinishedTime;
+            Log.i(TAG, "Test " + getClass().getSimpleName() + " took " + duration + " ms");
             mDatabase.close();
             mDatabaseFile.delete();
         }
@@ -100,11 +109,11 @@
     }
 
     /**
-     * Test 1000 inserts.
+     * Test 100 inserts.
      */
 
-    public static class Insert1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class Insert100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         private String[] statements = new String[SIZE];
 
@@ -132,11 +141,11 @@
     }
 
     /**
-     * Test 1000 inserts into an indexed table.
+     * Test 100 inserts into an indexed table.
      */
 
-    public static class InsertIndexed1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class InsertIndexed100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         private String[] statements = new String[SIZE];
 
@@ -169,7 +178,8 @@
      */
 
     public static class Select100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -196,9 +206,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -206,9 +218,9 @@
     /**
      * 100 SELECTs on a string comparison
      */
-
     public static class SelectStringComparison100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -233,9 +245,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -243,9 +257,9 @@
     /**
      * 100 SELECTs with an index
      */
-
     public static class SelectIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -273,9 +287,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -283,9 +299,9 @@
     /**
      *  INNER JOIN without an index
      */
-
     public static class InnerJoin100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -312,8 +328,10 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
@@ -322,7 +340,8 @@
      */
 
     public static class InnerJoinOneSide100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -351,17 +370,19 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
     /**
      *  INNER JOIN without an index on one side
      */
-
     public static class InnerJoinNoIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
@@ -390,17 +411,19 @@
         }
 
         public void testRun() {
-            mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
-                    null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
+                        null, null, null, null);
+            }
         }
     }
 
     /**
      *  100 SELECTs with subqueries. Subquery is using an index
      */
-
     public static class SelectSubQIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         private String[] where = new String[SIZE];
@@ -449,9 +472,9 @@
     /**
      *  100 SELECTs on string comparison with Index
      */
-
     public static class SelectIndexStringComparison100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
         private String[] where = new String[SIZE];
@@ -477,9 +500,11 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
@@ -487,9 +512,9 @@
     /**
      *  100 SELECTs on integer
      */
-
     public static class SelectInteger100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
@@ -509,8 +534,10 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -518,9 +545,9 @@
     /**
      *  100 SELECTs on String
      */
-
     public static class SelectString100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
@@ -536,12 +563,13 @@
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
-
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -549,9 +577,9 @@
     /**
      *  100 SELECTs on integer with index
      */
-
     public static class SelectIntegerIndex100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
@@ -572,8 +600,10 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
     }
@@ -581,9 +611,9 @@
     /**
      *  100 SELECTs on String with index
      */
-
     public static class SelectIndexString100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
@@ -600,22 +630,24 @@
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
-
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+                }
             }
         }
+
     }
 
     /**
      *  100 SELECTs on String with starts with
      */
-
     public static class SelectStringStartsWith100 extends PerformanceBase {
-        private static final int SIZE = 1 * kMultiplier;
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
         private String[] where = new String[SIZE];
 
@@ -643,19 +675,20 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase
+                            .query("t1", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
     /**
-     *  1000 Deletes on an indexed table
+     *  100 Deletes on an indexed table
      */
-
-    public static class DeleteIndexed1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteIndexed100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         @Override
         public void setUp() {
@@ -682,11 +715,10 @@
     }
 
     /**
-     *  1000 Deletes
+     *  100 Deletes
      */
-
-    public static class Delete1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class Delete100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
 
         @Override
         public void setUp() {
@@ -712,11 +744,10 @@
     }
 
     /**
-     *  1000 DELETE's without an index with where clause
+     *  100 DELETE's without an index with where clause
      */
-
-    public static class DeleteWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
 
         @Override
@@ -748,11 +779,10 @@
     }
 
     /**
-     *  1000 DELETE's with an index with where clause
+     * 100 DELETE's with an index with where clause
      */
-
-    public static class DeleteIndexWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class DeleteIndexWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
 
         @Override
@@ -785,11 +815,10 @@
     }
 
     /**
-     *  1000 update's with an index with where clause
+     * 100 update's with an index with where clause
      */
-
-    public static class UpdateIndexWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class UpdateIndexWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
         ContentValues[] mValues = new ContentValues[SIZE];
 
@@ -828,11 +857,10 @@
     }
 
     /**
-     *  1000 update's without an index with where clause
+     * 100 update's without an index with where clause
      */
-
-    public static class UpdateWhere1000 extends PerformanceBase {
-        private static final int SIZE = 10 * kMultiplier;
+    public static class UpdateWhere100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
         private String[] where = new String[SIZE];
         ContentValues[] mValues = new ContentValues[SIZE];
 
@@ -869,284 +897,11 @@
     }
 
     /**
-     *  10000 inserts for an integer
+     * 100 selects for a String - contains 'e'
      */
-
-    public static class InsertInteger10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for an integer -indexed table
-     */
-
-    public static class InsertIntegerIndex10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER)");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", r);
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for a String
-     */
-
-    public static class InsertString10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-    /**
-     *  10000 inserts for a String - indexed table
-     */
-
-    public static class InsertStringIndexed10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        ContentValues[] mValues = new ContentValues[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                ContentValues b = new ContentValues(1);
-                b.put("a", numberName(r));
-                mValues[i] = b;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.insert("t1", null, mValues[i]);
-            }
-        }
-    }
-
-
-    /**
-     *  10000 selects for a String -starts with
-     */
-
-    public static class SelectStringStartsWith10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for a String - indexed table -starts with
-     */
-
-    public static class SelectStringIndexedStartsWith10000 extends
-    PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t3 VALUES('"
-                        + numberName(r) + "')");
-            }
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for an integer -
-     */
-
-    public static class SelectInteger10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t4(a INTEGER)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-    /**
-     *  10000 selects for an integer -indexed table
-     */
-
-    public static class SelectIntegerIndexed10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
-        private static final String[] COLUMNS = {"t4.a"};
-        private String[] where = new String[SIZE];
-
-        @Override
-        public void setUp() {
-            super.setUp();
-            Random random = new Random(42);
-
-            mDatabase
-            .execSQL("CREATE TABLE t4(a INTEGER)");
-            mDatabase.execSQL("CREATE INDEX i4a ON t4(a)");
-
-            for (int i = 0; i < SIZE; i++) {
-                int r = random.nextInt(100000);
-                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-
-                int lower = i * 100;
-                int upper = (i + 10) * 100;
-                where[i] = "a >= " + lower + " AND a < " + upper;
-            }
-
-        }
-
-        public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-            }
-        }
-    }
-
-
-    /**
-     *  10000 selects for a String - contains 'e'
-     */
-
-    public static class SelectStringContains10000 extends PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
+    public static class SelectStringContains100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
         private String[] where = new String[SIZE];
 
@@ -1171,19 +926,20 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
     /**
-     *  10000 selects for a String - contains 'e'-indexed table
+     * 100 selects for a String - contains 'e'-indexed table
      */
-
-    public static class SelectStringIndexedContains10000 extends
-    PerformanceBase {
-        private static final int SIZE = 100 * kMultiplier;
+    public static class SelectStringIndexedContains100 extends PerformanceBase {
+        private static final int SIZE = SIZE_MULTIPLIER;
+        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
         private String[] where = new String[SIZE];
 
@@ -1209,19 +965,21 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
+                for (int i = 0; i < SIZE; i++) {
+                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+                }
             }
         }
     }
 
-    public static final String[] ONES =
+    static final String[] ONES =
         {"zero", "one", "two", "three", "four", "five", "six", "seven",
         "eight", "nine", "ten", "eleven", "twelve", "thirteen",
         "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
         "nineteen"};
 
-    public static final String[] TENS =
+    static final String[] TENS =
         {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
         "seventy", "eighty", "ninety"};
 }
diff --git a/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
new file mode 100644
index 0000000..1faeceb
--- /dev/null
+++ b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+# 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.
+
+import re
+import sys
+
+def main():
+    args = sys.argv
+    if len(args) <= 1:
+        exit("Usage %s <log_file>" % args[0])
+    with open(args[1], 'r') as f:
+        all_lines = f.readlines()
+    timings = {}
+    running_sum = 0
+    for line in all_lines:
+        regex = r"NewDatabasePerformanceTests: Test (\w+) took (\d+) ms"
+        matches = re.search(regex, line)
+        if matches:
+            test_name = matches.group(1)
+            duration = int(matches.group(2))
+            if not test_name in timings:
+                timings[test_name] = []
+            timings[test_name].append(duration)
+            running_sum += duration
+        if ("TestRunner: run finished:" in line) and (running_sum > 0):
+            test_name = '*** TOTAL ALL TESTS (ms) ***'
+            if not test_name in timings:
+                timings[test_name] = []
+            timings[test_name].append(running_sum)
+            running_sum=0
+
+    for k in sorted(timings):
+        timings_ar = timings[k]
+        print "%s: %s avg: %s" % (k, timings_ar, sum(timings_ar) / float(len(timings_ar)) )
+
+if __name__ == '__main__':
+    main()
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d875ed4..a979ac8 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -17,24 +17,25 @@
 package android.provider;
 
 import static com.google.android.collect.Sets.newHashSet;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
+
 import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.lang.reflect.Field;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 /** Tests that ensure appropriate settings are backed up. */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -102,6 +103,7 @@
                     Settings.Global.APP_IDLE_CONSTANTS,
                     Settings.Global.ASSISTED_GPS_ENABLED,
                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
+                    Settings.Global.BACKUP_REFACTORED_SERVICE_DISABLED,
                     Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
                     Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
                     Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
@@ -193,6 +195,8 @@
                     Settings.Global.ENHANCED_4G_MODE_ENABLED,
                     Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
                     Settings.Global.ERROR_LOGCAT_PREFIX,
+                    Settings.Global.EUICC_PROVISIONED,
+                    Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
                     Settings.Global.FANCY_IME_ANIMATIONS,
                     Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                     Settings.Global.FSTRIM_MANDATORY_INTERVAL,
@@ -294,7 +298,6 @@
                     Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
                     Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                     Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT,
-                    Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
                     Settings.Global.SAFE_BOOT_DISALLOWED,
                     Settings.Global.SAMPLING_PROFILER_MS,
                     Settings.Global.SELINUX_STATUS,
@@ -408,10 +411,12 @@
                  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,
                  Settings.Secure.BACKUP_TRANSPORT,
+                 Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
                  Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
                  Settings.Secure.COMPLETED_CATEGORY_PREFIX,
@@ -424,6 +429,7 @@
                  Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS,
                  Settings.Secure.DISPLAY_DENSITY_FORCED,
                  Settings.Secure.DOZE_ALWAYS_ON,
+                 Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
                  Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION,
                  Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT,
                  Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
@@ -444,17 +450,15 @@
                  Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
                  Settings.Secure.MULTI_PRESS_TIMEOUT,
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
+                 Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
+                 Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                  Settings.Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
                  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/BidiFormatterTest.java b/core/tests/coretests/src/android/text/BidiFormatterTest.java
new file mode 100644
index 0000000..14705ad
--- /dev/null
+++ b/core/tests/coretests/src/android/text/BidiFormatterTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BidiFormatterTest {
+    private static final BidiFormatter LTR_FMT = BidiFormatter.getInstance(false /* LTR context */);
+    private static final BidiFormatter RTL_FMT = BidiFormatter.getInstance(true /* RTL context */);
+
+    private static final String EN = "abba";
+    private static final String HE = "\u05E0\u05E1";
+
+    private static final String LRM = "\u200E";
+    private static final String RLM = "\u200F";
+
+    @Test
+    public void testMarkAfter() {
+        assertEquals("uniform dir matches LTR context",
+                "", LTR_FMT.markAfter(EN, TextDirectionHeuristics.LTR));
+        assertEquals("uniform dir matches RTL context",
+                "", RTL_FMT.markAfter(HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("exit dir opposite to LTR context",
+                LRM, LTR_FMT.markAfter(EN + HE, TextDirectionHeuristics.LTR));
+        assertEquals("exit dir opposite to RTL context",
+                RLM, RTL_FMT.markAfter(HE + EN, TextDirectionHeuristics.RTL));
+
+        assertEquals("overall dir (but not exit dir) opposite to LTR context",
+                LRM, LTR_FMT.markAfter(HE + EN, TextDirectionHeuristics.RTL));
+        assertEquals("overall dir (but not exit dir) opposite to RTL context",
+                RLM, RTL_FMT.markAfter(EN + HE, TextDirectionHeuristics.LTR));
+
+        assertEquals("exit dir neutral, overall dir matches LTR context",
+                "", LTR_FMT.markAfter(".", TextDirectionHeuristics.LTR));
+        assertEquals("exit dir neutral, overall dir matches RTL context",
+                "", RTL_FMT.markAfter(".", TextDirectionHeuristics.RTL));
+    }
+
+    @Test
+    public void testMarkBefore() {
+        assertEquals("uniform dir matches LTR context",
+                "", LTR_FMT.markBefore(EN, TextDirectionHeuristics.LTR));
+        assertEquals("uniform dir matches RTL context",
+                "", RTL_FMT.markBefore(HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("entry dir opposite to LTR context",
+                LRM, LTR_FMT.markBefore(HE + EN, TextDirectionHeuristics.LTR));
+        assertEquals("entry dir opposite to RTL context",
+                RLM, RTL_FMT.markBefore(EN + HE, TextDirectionHeuristics.RTL));
+
+        assertEquals("overall dir (but not entry dir) opposite to LTR context",
+                LRM, LTR_FMT.markBefore(EN + HE, TextDirectionHeuristics.RTL));
+        assertEquals("overall dir (but not entry dir) opposite to RTL context",
+                RLM, RTL_FMT.markBefore(HE + EN, TextDirectionHeuristics.LTR));
+
+        assertEquals("exit dir neutral, overall dir matches LTR context",
+                "", LTR_FMT.markBefore(".", TextDirectionHeuristics.LTR));
+        assertEquals("exit dir neutral, overall dir matches RTL context",
+                "", RTL_FMT.markBefore(".", TextDirectionHeuristics.RTL));
+    }
+}
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
index bc9f44d..08e1b5b 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
@@ -67,7 +67,10 @@
     }
 
     private void update(int startLine, int endLine, int newLineCount) {
-        dl.setBlocksDataForTest(initialBlockEnds, initialBlockIndices, initialBlockEnds.length);
+        final int totalLines = initialBlockEnds[initialBlockEnds.length - 1]
+                + newLineCount - endLine + startLine;
+        dl.setBlocksDataForTest(
+                initialBlockEnds, initialBlockIndices, initialBlockEnds.length, totalLines);
         checkInvariants();
         dl.updateBlocks(startLine, endLine, newLineCount);
     }
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutTest.java b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
index da6dc7e..811bf2c 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
@@ -17,15 +17,14 @@
 package android.text;
 
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.style.ReplacementSpan;
@@ -54,6 +53,16 @@
         assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
     }
 
+    private class MockReplacementSpan extends ReplacementSpan {
+        public int getSize(Paint paint, CharSequence text, int start, int end,
+                Paint.FontMetricsInt fm) {
+            return 10;
+        }
+
+        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
+                int y, int bottom, Paint paint) { }
+    }
+
     @Test
     public void testGetBlocksAlwaysNeedToBeRedrawn_replacementSpan() {
         final SpannableStringBuilder builder = new SpannableStringBuilder();
@@ -66,17 +75,11 @@
         builder.append("hijk lmn\n");
         assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
 
-        ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
-        when(mockReplacementSpan.getSize(any(), any(), any(), any(), any()))
-            .thenReturn(10);
-        doNothing().when(mockReplacementSpan)
-            .draw(any(), any(), any(), any(), any(), any(), any(), any(), any());
-
-        builder.setSpan(mockReplacementSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(new MockReplacementSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         assertNotNull(layout.getBlocksAlwaysNeedToBeRedrawn());
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
 
-        builder.setSpan(mockReplacementSpan, 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(new MockReplacementSpan(), 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
         assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(1));
 
diff --git a/core/tests/coretests/src/android/text/LayoutTest.java b/core/tests/coretests/src/android/text/LayoutTest.java
new file mode 100644
index 0000000..6d610bb
--- /dev/null
+++ b/core/tests/coretests/src/android/text/LayoutTest.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2008 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.text;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.Layout.Alignment;
+import android.text.style.StrikethroughSpan;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LayoutTest {
+    private static final int LINE_COUNT = 5;
+    private static final int LINE_HEIGHT = 12;
+    private static final int LINE_DESCENT = 4;
+    private static final CharSequence LAYOUT_TEXT = "alwei\t;sdfs\ndf @";
+
+    private SpannableString mSpannedText;
+
+    private int mWidth;
+    private Layout.Alignment mAlign;
+    private float mSpacingMult;
+    private float mSpacingAdd;
+    private TextPaint mTextPaint;
+
+    @Before
+    public void setup() {
+        mTextPaint = new TextPaint();
+        mSpannedText = new SpannableString(LAYOUT_TEXT);
+        mSpannedText.setSpan(new StrikethroughSpan(), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+        mWidth = 11;
+        mAlign = Alignment.ALIGN_CENTER;
+        mSpacingMult = 1;
+        mSpacingAdd = 2;
+    }
+
+    @Test
+    public void testConstructor() {
+        new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testConstructorNull() {
+        new MockLayout(null, null, -1, null, 0, 0);
+    }
+
+    @Test
+    public void testGetText() {
+        CharSequence text = "test case 1";
+        Layout layout = new MockLayout(text, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(text, layout.getText());
+
+        layout = new MockLayout(null, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getText());
+    }
+
+    @Test
+    public void testGetPaint() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+
+        assertSame(mTextPaint, layout.getPaint());
+
+        layout = new MockLayout(LAYOUT_TEXT, null, mWidth, mAlign, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getPaint());
+    }
+
+    @Test
+    public void testGetWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 10,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(10,  layout.getWidth());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0,  layout.getWidth());
+    }
+
+    @Test
+    public void testGetEllipsizedWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 15,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(15, layout.getEllipsizedWidth());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0,  layout.getEllipsizedWidth());
+    }
+
+    @Test
+    public void testIncreaseWidthTo() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        int oldWidth = layout.getWidth();
+
+        layout.increaseWidthTo(oldWidth);
+        assertEquals(oldWidth, layout.getWidth());
+
+        try {
+            layout.increaseWidthTo(oldWidth - 1);
+            fail("should throw runtime exception attempted to reduce Layout width");
+        } catch (RuntimeException e) {
+        }
+
+        layout.increaseWidthTo(oldWidth + 1);
+        assertEquals(oldWidth + 1, layout.getWidth());
+    }
+
+    @Test
+    public void testGetHeight() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(60, layout.getHeight());
+    }
+
+    @Test
+    public void testGetAlignment() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getAlignment());
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, null, mSpacingMult, mSpacingAdd);
+        assertNull(layout.getAlignment());
+    }
+
+    @Test
+    public void testGetSpacingMultiplier() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, -1, mSpacingAdd);
+        assertEquals(-1.0f, layout.getSpacingMultiplier(), 0.0f);
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, 5, mSpacingAdd);
+        assertEquals(5.0f, layout.getSpacingMultiplier(), 0.0f);
+    }
+
+    @Test
+    public void testGetSpacingAdd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, -1);
+        assertEquals(-1.0f, layout.getSpacingAdd(), 0.0f);
+
+        layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, 20);
+        assertEquals(20.0f, layout.getSpacingAdd(), 0.0f);
+    }
+
+    @Test
+    public void testGetLineBounds() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        Rect bounds = new Rect();
+
+        assertEquals(32, layout.getLineBounds(2, bounds));
+        assertEquals(0, bounds.left);
+        assertEquals(mWidth, bounds.right);
+        assertEquals(24, bounds.top);
+        assertEquals(36, bounds.bottom);
+    }
+
+    @Test
+    public void testGetLineForVertical() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getLineForVertical(-1));
+        assertEquals(0, layout.getLineForVertical(0));
+        assertEquals(0, layout.getLineForVertical(LINE_COUNT));
+        assertEquals(LINE_COUNT - 1, layout.getLineForVertical(1000));
+    }
+
+    @Test
+    public void testGetLineForOffset() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getLineForOffset(-1));
+        assertEquals(1, layout.getLineForOffset(1));
+        assertEquals(LINE_COUNT - 1, layout.getLineForOffset(LINE_COUNT - 1));
+        assertEquals(LINE_COUNT - 1, layout.getLineForOffset(1000));
+    }
+
+    @Test
+    public void testGetLineEnd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(2, layout.getLineEnd(1));
+    }
+
+    @Test
+    public void testGetLineVisibleEnd() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+
+        assertEquals(2, layout.getLineVisibleEnd(1));
+        assertEquals(LINE_COUNT, layout.getLineVisibleEnd(LINE_COUNT - 1));
+        assertEquals(LAYOUT_TEXT.length(), layout.getLineVisibleEnd(LAYOUT_TEXT.length() - 1));
+        try {
+            layout.getLineVisibleEnd(LAYOUT_TEXT.length());
+            fail("should throw .StringIndexOutOfBoundsException here");
+        } catch (StringIndexOutOfBoundsException e) {
+        }
+    }
+
+    @Test
+    public void testGetLineBottom() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(LINE_HEIGHT, layout.getLineBottom(0));
+    }
+
+    @Test
+    public void testGetLineBaseline() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(8, layout.getLineBaseline(0));
+    }
+
+    @Test
+    public void testGetLineAscent() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(-8, layout.getLineAscent(0));
+    }
+
+    @Test
+    public void testGetParagraphAlignment() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getParagraphAlignment(0));
+
+        layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertSame(mAlign, layout.getParagraphAlignment(0));
+        assertSame(mAlign, layout.getParagraphAlignment(1));
+    }
+
+    @Test
+    public void testGetParagraphLeft() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(0, layout.getParagraphLeft(0));
+    }
+
+    @Test
+    public void testGetParagraphRight() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertEquals(mWidth, layout.getParagraphRight(0));
+    }
+
+    @Test
+    public void testIsSpanned() {
+        MockLayout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        // default is not spanned text
+        assertFalse(layout.mockIsSpanned());
+
+        // try to create a spanned text
+        layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        assertTrue(layout.mockIsSpanned());
+    }
+
+    private static final class MockLayout extends Layout {
+        MockLayout(CharSequence text, TextPaint paint, int width,
+                Alignment align, float spacingmult, float spacingadd) {
+            super(text, paint, width, align, spacingmult, spacingadd);
+        }
+
+        protected boolean mockIsSpanned() {
+            return super.isSpanned();
+        }
+
+        @Override
+        public int getBottomPadding() {
+            return 0;
+        }
+
+        @Override
+        public int getEllipsisCount(int line) {
+            return 0;
+        }
+
+        @Override
+        public int getEllipsisStart(int line) {
+            return 0;
+        }
+
+        @Override
+        public boolean getLineContainsTab(int line) {
+            return false;
+        }
+
+        @Override
+        public int getLineCount() {
+            return LINE_COUNT;
+        }
+
+        @Override
+        public int getLineDescent(int line) {
+            return LINE_DESCENT;
+        }
+
+        @Override
+        public Directions getLineDirections(int line) {
+            return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+        }
+
+        @Override
+        public int getLineStart(int line) {
+            if (line < 0) {
+                return 0;
+            }
+            return line;
+        }
+
+        @Override
+        public int getLineTop(int line) {
+            if (line < 0) {
+                return 0;
+            }
+            return LINE_HEIGHT * (line);
+        }
+
+        @Override
+        public int getParagraphDirection(int line) {
+            return 0;
+        }
+
+        @Override
+        public int getTopPadding() {
+            return 0;
+        }
+    }
+
+    @Test
+    public void testGetLineWidth() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        for (int i = 0; i < LINE_COUNT; i++) {
+            int start = layout.getLineStart(i);
+            int end = layout.getLineEnd(i);
+            String text = LAYOUT_TEXT.toString().substring(start, end);
+            assertEquals(mTextPaint.measureText(text), layout.getLineWidth(i), 1.0f);
+        }
+    }
+
+    @Test
+    public void testGetCursorPath() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        Path path = new Path();
+        final float epsilon = 1.0f;
+        for (int i = 0; i < LINE_COUNT; i++) {
+            layout.getCursorPath(i, path, LAYOUT_TEXT);
+            RectF bounds = new RectF();
+            path.computeBounds(bounds, false);
+            assertTrue(bounds.top >= layout.getLineTop(i) - epsilon);
+            assertTrue(bounds.bottom <= layout.getLineBottom(i) + epsilon);
+        }
+    }
+
+    @Test
+    public void testDraw() {
+        Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
+                mAlign, mSpacingMult, mSpacingAdd);
+        final int width = 256;
+        final int height = 256;
+        MockCanvas c = new MockCanvas(width, height);
+        layout.draw(c);
+        List<MockCanvas.DrawCommand> drawCommands = c.getDrawCommands();
+        assertEquals(LINE_COUNT, drawCommands.size());
+        for (int i = 0; i < LINE_COUNT; i++) {
+            MockCanvas.DrawCommand drawCommand = drawCommands.get(i);
+            int start = layout.getLineStart(i);
+            int end = layout.getLineEnd(i);
+            assertEquals(LAYOUT_TEXT.toString().substring(start, end), drawCommand.text);
+            float expected_y = (i + 1) * LINE_HEIGHT - LINE_DESCENT;
+            assertEquals(expected_y, drawCommand.y, 0.0f);
+        }
+    }
+
+    private final class MockCanvas extends Canvas {
+
+        class DrawCommand {
+            public final String text;
+            public final float x;
+            public final float y;
+
+            DrawCommand(String text, float x, float y) {
+                this.text = text;
+                this.x = x;
+                this.y = y;
+            }
+        }
+
+        List<DrawCommand> mDrawCommands;
+
+        MockCanvas(int width, int height) {
+            super();
+            mDrawCommands = new ArrayList<>();
+            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            setBitmap(bitmap);
+        }
+
+        // Drawing text with either drawText or drawTextRun is valid; we don't care which.
+        // We also don't care which of the string representations is used.
+
+        @Override
+        public void drawText(String text, int start, int end, float x, float y, Paint p) {
+            mDrawCommands.add(new DrawCommand(text.substring(start, end), x, y));
+        }
+
+        @Override
+        public void drawText(CharSequence text, int start, int end, float x, float y, Paint p) {
+            drawText(text.toString(), start, end, x, y, p);
+        }
+
+        @Override
+        public void drawText(char[] text, int index, int count, float x, float y, Paint p) {
+            mDrawCommands.add(new DrawCommand(new String(text, index, count), x, y));
+        }
+
+        @Override
+        public void drawTextRun(CharSequence text, int start, int end, int contextStart,
+                int contextEnd, float x, float y, boolean isRtl, Paint paint) {
+            drawText(text, start, end, x, y, paint);
+        }
+
+        @Override
+        public void drawTextRun(char[] text, int index, int count, int contextIndex,
+                int contextCount, float x, float y, boolean isRtl, Paint paint) {
+            drawText(text, index, count, x, y, paint);
+        }
+
+        List<DrawCommand> getDrawCommands() {
+            return mDrawCommands;
+        }
+    }
+}
+
diff --git a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
index 1f1a689..04a486e 100644
--- a/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
+++ b/core/tests/coretests/src/android/text/SpannableStringBuilderTest.java
@@ -16,9 +16,46 @@
 
 package android.text;
 
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.text.style.BulletSpan;
+import android.text.style.QuoteSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.UnderlineSpan;
+
+import org.junit.Test;
+
 public class SpannableStringBuilderTest extends SpannableTest {
 
     protected Spannable newSpannableWithText(String text) {
         return new SpannableStringBuilder(text);
     }
+
+    @Test
+    public void testGetSpans_sortsByPriorityEvenWhenSortParamIsFalse() {
+        String text = "p_in_s";
+        SpannableStringBuilder builder = new SpannableStringBuilder(text);
+        Object first = new SubscriptSpan();
+        Object second = new UnderlineSpan();
+        Object third = new BulletSpan();
+        Object fourth = new QuoteSpan();
+
+        builder.setSpan(first, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(second, 1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        builder.setSpan(third, 2, text.length(), 1 << Spanned.SPAN_PRIORITY_SHIFT);
+        builder.setSpan(fourth, 0, text.length(), 2 << Spanned.SPAN_PRIORITY_SHIFT);
+
+        Object[] spans = builder.getSpans(0, text.length(), Object.class, false);
+
+        assertNotNull(spans);
+        assertEquals(4, spans.length);
+        // priority spans are first
+        assertEquals(fourth, spans[0]);
+        assertEquals(third, spans[1]);
+        // other spans should be there
+        assertEquals(second, spans[2]);
+        assertEquals(first, spans[3]);
+    }
 }
diff --git a/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java b/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
new file mode 100644
index 0000000..2ee855e
--- /dev/null
+++ b/core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2012 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.text;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.Layout.Alignment;
+import android.text.style.MetricAffectingSpan;
+import android.util.Log;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutLineBreakingTest {
+    // Span test are currently not supported because text measurement uses the MeasuredText
+    // internal mWorkPaint instead of the provided MockTestPaint.
+    private static final boolean SPAN_TESTS_SUPPORTED = false;
+    private static final boolean DEBUG = false;
+
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
+    private static final int WIDTH = 100;
+    private static final Alignment ALIGN = Alignment.ALIGN_LEFT;
+
+    private static final char SURR_FIRST = '\uD800';
+    private static final char SURR_SECOND = '\uDF31';
+
+    private static final int[] NO_BREAK = new int[] {};
+
+    private static final TextPaint sTextPaint = new MockTextPaint();
+
+    private static class MockTextPaint extends TextPaint {
+
+        @Override
+        public float getTextRunAdvances(char[] chars, int index, int count,
+                int contextIndex, int contextCount, boolean isRtl, float[] advances,
+                int advancesIndex) {
+
+            // Conditions copy pasted from Paint
+            if (chars == null) {
+                throw new IllegalArgumentException("text cannot be null");
+            }
+
+            if ((index | count | contextIndex | contextCount | advancesIndex
+                    | (index - contextIndex) | (contextCount - count)
+                    | ((contextIndex + contextCount) - (index + count))
+                    | (chars.length - (contextIndex + contextCount))
+                    | (advances == null ? 0 :
+                        (advances.length - (advancesIndex + count)))) < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            float res = 0.0f;
+
+            if (advances != null) {
+                for (int i = 0; i < count; i++) {
+                    float width = getCharWidth(chars[index + i]);
+                    advances[advancesIndex + i] = width;
+                    res += width;
+                }
+            }
+
+            return res;
+        }
+    }
+
+    private static float getCharWidth(char c) {
+        switch (Character.toUpperCase(c)) {
+            // Roman figures
+            case 'I': return 1.0f;
+            case 'V': return 5.0f;
+            case 'X': return 10.0f;
+            case 'L': return 50.0f;
+            case 'C': return 100.0f; // equals to WIDTH
+            case ' ': return 10.0f;
+            case '_': return 0.0f; // 0-width character
+            case SURR_FIRST: return 7.0f;
+            case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10
+            default: return 10.0f;
+        }
+    }
+
+    private static StaticLayout getStaticLayout(CharSequence source, int width) {
+        return new StaticLayout(source, sTextPaint, width, ALIGN, SPACE_MULTI, SPACE_ADD, false);
+    }
+
+    private static int[] getBreaks(CharSequence source) {
+        return getBreaks(source, WIDTH);
+    }
+
+    private static int[] getBreaks(CharSequence source, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
+        int[] breaks = new int[staticLayout.getLineCount() - 1];
+        for (int line = 0; line < breaks.length; line++) {
+            breaks[line] = staticLayout.getLineEnd(line);
+        }
+        return breaks;
+    }
+
+    private static void debugLayout(CharSequence source, StaticLayout staticLayout) {
+        if (DEBUG) {
+            int count = staticLayout.getLineCount();
+            Log.i("SLLBTest", "\"" + source.toString() + "\": "
+                    + count + " lines");
+            for (int line = 0; line < count; line++) {
+                int lineStart = staticLayout.getLineStart(line);
+                int lineEnd = staticLayout.getLineEnd(line);
+                Log.i("SLLBTest", "Line " + line + " [" + lineStart + ".."
+                        + lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
+            }
+        }
+    }
+
+    private static void layout(CharSequence source, int[] breaks) {
+        layout(source, breaks, WIDTH);
+    }
+
+    private static void layout(CharSequence source, int[] breaks, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
+        debugLayout(source, staticLayout);
+
+        int lineCount = breaks.length + 1;
+        assertEquals("Number of lines", lineCount, staticLayout.getLineCount());
+
+        for (int line = 0; line < lineCount; line++) {
+            int lineStart = staticLayout.getLineStart(line);
+            int lineEnd = staticLayout.getLineEnd(line);
+
+            if (line == 0) {
+                assertEquals("Line start for first line", 0, lineStart);
+            } else {
+                assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+            }
+
+            if (line == lineCount - 1) {
+                assertEquals("Line end for last line", source.length(), lineEnd);
+            } else {
+                assertEquals("Line end for line " + line, breaks[line], lineEnd);
+            }
+        }
+    }
+
+    private static void layoutMaxLines(CharSequence source, int[] breaks, int maxLines) {
+        StaticLayout staticLayout = new StaticLayout(source, 0, source.length(), sTextPaint, WIDTH,
+                ALIGN, TextDirectionHeuristics.LTR, SPACE_MULTI, SPACE_ADD, false /* includePad */,
+                null, WIDTH, maxLines);
+
+        debugLayout(source, staticLayout);
+
+        final int lineCount = staticLayout.getLineCount();
+
+        for (int line = 0; line < lineCount; line++) {
+            int lineStart = staticLayout.getLineStart(line);
+            int lineEnd = staticLayout.getLineEnd(line);
+
+            if (line == 0) {
+                assertEquals("Line start for first line", 0, lineStart);
+            } else {
+                assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+            }
+
+            if (line == lineCount - 1 && line != breaks.length - 1) {
+                assertEquals("Line end for last line", source.length(), lineEnd);
+            } else {
+                assertEquals("Line end for line " + line, breaks[line], lineEnd);
+            }
+        }
+    }
+
+    private static final int MAX_SPAN_COUNT = 10;
+    private static final int[] sSpanStarts = new int[MAX_SPAN_COUNT];
+    private static final int[] sSpanEnds = new int[MAX_SPAN_COUNT];
+
+    private static MetricAffectingSpan getMetricAffectingSpan() {
+        return new MetricAffectingSpan() {
+            @Override
+            public void updateDrawState(TextPaint tp) { /* empty */ }
+
+            @Override
+            public void updateMeasureState(TextPaint p) { /* empty */ }
+        };
+    }
+
+    /**
+     * Replaces the "<...>" blocks by spans, assuming non overlapping, correctly defined spans
+     * @param text
+     * @return A CharSequence with '<' '>' replaced by MetricAffectingSpan
+     */
+    private static CharSequence spanify(String text) {
+        int startIndex = text.indexOf('<');
+        if (startIndex < 0) return text;
+
+        int spanCount = 0;
+        do {
+            int endIndex = text.indexOf('>');
+            if (endIndex < 0) throw new IllegalArgumentException("Unbalanced span markers");
+
+            text = text.substring(0, startIndex) + text.substring(startIndex + 1, endIndex)
+                    + text.substring(endIndex + 1);
+
+            sSpanStarts[spanCount] = startIndex;
+            sSpanEnds[spanCount] = endIndex - 2;
+            spanCount++;
+
+            startIndex = text.indexOf('<');
+        } while (startIndex >= 0);
+
+        SpannableStringBuilder result = new SpannableStringBuilder(text);
+        for (int i = 0; i < spanCount; i++) {
+            result.setSpan(getMetricAffectingSpan(), sSpanStarts[i], sSpanEnds[i],
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        }
+        return result;
+    }
+
+    @Test
+    public void testNoLineBreak() {
+        // Width lower than WIDTH
+        layout("", NO_BREAK);
+        layout("I", NO_BREAK);
+        layout("V", NO_BREAK);
+        layout("X", NO_BREAK);
+        layout("L", NO_BREAK);
+        layout("I VILI", NO_BREAK);
+        layout("XXXX", NO_BREAK);
+        layout("LXXXX", NO_BREAK);
+
+        // Width equal to WIDTH
+        layout("C", NO_BREAK);
+        layout("LL", NO_BREAK);
+        layout("L XXXX", NO_BREAK);
+        layout("XXXXXXXXXX", NO_BREAK);
+        layout("XXX XXXXXX", NO_BREAK);
+        layout("XXX XXXX X", NO_BREAK);
+        layout("XXX XXXXX ", NO_BREAK);
+        layout(" XXXXXXXX ", NO_BREAK);
+        layout("  XX  XXX ", NO_BREAK);
+        //      0123456789
+
+        // Width greater than WIDTH, but no break
+        layout("  XX  XXX  ", NO_BREAK);
+        layout("XX XXX XXX ", NO_BREAK);
+        layout("XX XXX XXX     ", NO_BREAK);
+        layout("XXXXXXXXXX     ", NO_BREAK);
+        //      01234567890
+    }
+
+    @Test
+    public void testOneLineBreak() {
+        //      01234567890
+        layout("XX XXX XXXX", new int[] {7});
+        layout("XX XXXX XXX", new int[] {8});
+        layout("XX XXXXX XX", new int[] {9});
+        layout("XX XXXXXX X", new int[] {10});
+        //      01234567890
+        layout("XXXXXXXXXXX", new int[] {10});
+        layout("XXXXXXXXX X", new int[] {10});
+        layout("XXXXXXXX XX", new int[] {9});
+        layout("XXXXXXX XXX", new int[] {8});
+        layout("XXXXXX XXXX", new int[] {7});
+        //      01234567890
+        layout("LL LL", new int[] {3});
+        layout("LLLL", new int[] {2});
+        layout("C C", new int[] {2});
+        layout("CC", new int[] {1});
+    }
+
+    @Test
+    public void testSpaceAtBreak() {
+        //      0123456789012
+        layout("XXXX XXXXX X", new int[] {11});
+        layout("XXXXXXXXXX X", new int[] {11});
+        layout("XXXXXXXXXV X", new int[] {11});
+        layout("C X", new int[] {2});
+    }
+
+    @Test
+    public void testMultipleSpacesAtBreak() {
+        //      0123456789012
+        layout("LXX XXXX", new int[] {4});
+        layout("LXX  XXXX", new int[] {5});
+        layout("LXX   XXXX", new int[] {6});
+        layout("LXX    XXXX", new int[] {7});
+        layout("LXX     XXXX", new int[] {8});
+    }
+
+    @Test
+    public void testZeroWidthCharacters() {
+        //      0123456789012345678901234
+        layout("X_X_X_X_X_X_X_X_X_X", NO_BREAK);
+        layout("___X_X_X_X_X_X_X_X_X_X___", NO_BREAK);
+        layout("C_X", new int[] {2});
+        layout("C__X", new int[] {3});
+    }
+
+    /**
+     * Note that when the text has spans, StaticLayout does not use the provided TextPaint to
+     * measure text runs anymore. This is probably a bug.
+     * To be able to use the fake sTextPaint and make this test pass, use mPaint instead of
+     * mWorkPaint in MeasuredText#addStyleRun
+     */
+    @Test
+    public void testWithSpans() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        layout(spanify("<012 456 89>"), NO_BREAK);
+        layout(spanify("012 <456> 89"), NO_BREAK);
+        layout(spanify("<012> <456>< 89>"), NO_BREAK);
+        layout(spanify("<012> <456> <89>"), NO_BREAK);
+
+        layout(spanify("<012> <456> <89>012"), new int[] {8});
+        layout(spanify("<012> <456> 89<012>"), new int[] {8});
+        layout(spanify("<012> <456> <89><012>"), new int[] {8});
+        layout(spanify("<012> <456> 89 <123>"), new int[] {11});
+        layout(spanify("<012> <456> 89< 123>"), new int[] {11});
+        layout(spanify("<012> <456> <89> <123>"), new int[] {11});
+        layout(spanify("012 456 89 <LXX> XX XX"), new int[] {11, 18});
+    }
+
+    /*
+     * Adding a span to the string should not change the layout, since the metrics are unchanged.
+     */
+    @Test
+    public void testWithOneSpan() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
+                "012 456 89012 456 89012", "0123456789012" };
+
+        MetricAffectingSpan metricAffectingSpan = getMetricAffectingSpan();
+
+        for (String text : texts) {
+            // Get the line breaks without any span
+            int[] breaks = getBreaks(text);
+
+            // Add spans on all possible offsets
+            for (int spanStart = 0; spanStart < text.length(); spanStart++) {
+                for (int spanEnd = spanStart; spanEnd < text.length(); spanEnd++) {
+                    SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+                    ssb.setSpan(metricAffectingSpan, spanStart, spanEnd,
+                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+                    layout(ssb, breaks);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testWithTwoSpans() {
+        if (!SPAN_TESTS_SUPPORTED) return;
+
+        String[] texts = new String[] { "0123", "012 456", "012 456 89 123", "012 45678 012",
+                "012 456 89012 456 89012", "0123456789012" };
+
+        MetricAffectingSpan metricAffectingSpan1 = getMetricAffectingSpan();
+        MetricAffectingSpan metricAffectingSpan2 = getMetricAffectingSpan();
+
+        for (String text : texts) {
+            // Get the line breaks without any span
+            int[] breaks = getBreaks(text);
+
+            // Add spans on all possible offsets
+            for (int spanStart1 = 0; spanStart1 < text.length(); spanStart1++) {
+                for (int spanEnd1 = spanStart1; spanEnd1 < text.length(); spanEnd1++) {
+                    SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+                    ssb.setSpan(metricAffectingSpan1, spanStart1, spanEnd1,
+                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+                    for (int spanStart2 = 0; spanStart2 < text.length(); spanStart2++) {
+                        for (int spanEnd2 = spanStart2; spanEnd2 < text.length(); spanEnd2++) {
+                            ssb.setSpan(metricAffectingSpan2, spanStart2, spanEnd2,
+                                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+                            layout(ssb, breaks);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static String replace(String string, char c, char r) {
+        return string.replaceAll(String.valueOf(c), String.valueOf(r));
+    }
+
+    @Test
+    public void testWithSurrogate() {
+        layout("LX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
+        layout("LXXXX" + SURR_FIRST + SURR_SECOND, NO_BREAK);
+        // LXXXXI (91) + SURR_FIRST (7) fits. But we should not break the surrogate pair
+        // Bug: surrogate pair is broken, should be 6 (breaking after the 'V')
+        // Maybe not: may be ok if the second character of a pair always has a 0-width
+        layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {7});
+
+        // LXXXXI (95) + SURR_SECOND (3) fits, but this is not a valid surrogate pair, breaking it
+        layout("LXXXXV" + SURR_SECOND + SURR_FIRST, new int[] {7});
+
+        layout("C" + SURR_FIRST + SURR_SECOND, new int[] {1});
+    }
+
+    @Test
+    public void testNarrowWidth() {
+        int[] widths = new int[] { 0, 4, 10 };
+        String[] texts = new String[] { "", "X", " ", "XX", " X", "XXX" };
+
+        for (String text: texts) {
+            // 15 is such that only one character will fit
+            int[] breaks = getBreaks(text, 15);
+
+            // Width under 15 should all lead to the same line break
+            for (int width: widths) {
+                layout(text, breaks, width);
+            }
+        }
+    }
+
+    @Test
+    public void testNarrowWidthZeroWidth() {
+        int[] widths = new int[] { 1, 4 };
+        for (int width: widths) {
+            layout("X.", new int[] {1}, width);
+            layout("X__", NO_BREAK, width);
+            layout("X__X", new int[] {3}, width);
+            layout("X__X_", new int[] {3}, width);
+
+            layout("_", NO_BREAK, width);
+            layout("__", NO_BREAK, width);
+            layout("_X", new int[] {1}, width);
+            layout("_X_", new int[] {1}, width);
+            layout("__X__", new int[] {2}, width);
+        }
+    }
+
+    @Test
+    public void testMaxLines() {
+        layoutMaxLines("C", NO_BREAK, 1);
+        layoutMaxLines("C C", new int[] {2}, 1);
+        layoutMaxLines("C C", new int[] {2}, 2);
+        layoutMaxLines("CC", new int[] {1}, 1);
+        layoutMaxLines("CC", new int[] {1}, 2);
+    }
+}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index b7ca219..74a6cc6 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -17,7 +17,9 @@
 package android.text;
 
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Paint.FontMetricsInt;
 import android.support.test.filters.SmallTest;
@@ -26,15 +28,68 @@
 import android.text.method.EditorState;
 import android.util.Log;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.text.Normalizer;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Tests StaticLayout vertical metrics behavior.
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class StaticLayoutTest {
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
+    private static final int DEFAULT_OUTER_WIDTH = 150;
+
+    private static final CharSequence LAYOUT_TEXT = "CharSe\tq\nChar"
+            + "Sequence\nCharSequence\nHelllo\n, world\nLongLongLong";
+    private static final CharSequence LAYOUT_TEXT_SINGLE_LINE = "CharSequence";
+
+    private static final Alignment DEFAULT_ALIGN = Alignment.ALIGN_CENTER;
+    private static final int ELLIPSIZE_WIDTH = 8;
+
+    private StaticLayout mDefaultLayout;
+    private TextPaint mDefaultPaint;
+
+    @Before
+    public void setup() {
+        mDefaultPaint = new TextPaint();
+        mDefaultLayout = createDefaultStaticLayout();
+    }
+
+    private StaticLayout createDefaultStaticLayout() {
+        return new StaticLayout(LAYOUT_TEXT, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+    }
+
+    @Test
+    public void testBuilder() {
+        {
+            // Obtain.
+            final StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            final StaticLayout layout = builder.build();
+            // Check default value.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+        }
+        {
+            // setTextDirection.
+            final StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setTextDirection(TextDirectionHeuristics.RTL);
+            final StaticLayout layout = builder.build();
+            // Always returns TextDirectionHeuristics.FIRSTSTRONG_LTR.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+        }
+    }
+
     /**
      * Basic test showing expected behavior and relationship between font
      * metrics and line metrics.
@@ -410,4 +465,210 @@
         state.setByString("| U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB");
         moveCursorToLeftCursorableOffset(state, paint);
     }
+
+    private StaticLayout createEllipsizeStaticLayout(CharSequence text,
+            TextUtils.TruncateAt ellipsize, int maxLines) {
+        return new StaticLayout(text, 0, text.length(),
+                mDefaultPaint, DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
+                TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                SPACE_MULTI, SPACE_ADD, true /* include pad */,
+                ellipsize,
+                ELLIPSIZE_WIDTH,
+                maxLines);
+    }
+
+    @Test
+    public void testEllipsis_singleLine() {
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MIDDLE so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MIDDLE, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MARQUEE so that we have NO ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MARQUEE, 1);
+            assertTrue(layout.getEllipsisCount(0) == 0);
+        }
+        {
+            final String text = "\u3042" // HIRAGANA LETTER A
+                    + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+            final float textWidth = mDefaultPaint.measureText(text);
+            final int halfWidth = (int) (textWidth / 2.0f);
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.END, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.START, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertEquals(0, mDefaultLayout.getEllipsisStart(0));
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MIDDLE, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MARQUEE, halfWidth, 1);
+                assertEquals(0, layout.getEllipsisCount(0));
+            }
+        }
+
+        {
+            // The white spaces in this text will be trailing if maxLines is larger than 1, but
+            // width of the trailing white spaces must not be ignored if ellipsis is applied.
+            final String text = "abc                                             def";
+            final float textWidth = mDefaultPaint.measureText(text);
+            final int halfWidth = (int) (textWidth / 2.0f);
+            {
+                StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                        halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                        SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.END, halfWidth, 1);
+                assertTrue(layout.getEllipsisCount(0) > 0);
+                assertTrue(layout.getEllipsisStart(0) > 0);
+            }
+        }
+
+        {
+            // 2 family emojis (11 code units + 11 code units).
+            final String text = "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66"
+                    + "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66";
+            final float textWidth = mDefaultPaint.measureText(text);
+
+            final TextUtils.TruncateAt[] kinds = {TextUtils.TruncateAt.START,
+                    TextUtils.TruncateAt.MIDDLE, TextUtils.TruncateAt.END};
+            for (final TextUtils.TruncateAt kind : kinds) {
+                for (int i = 0; i <= 8; i++) {
+                    int avail = (int) (textWidth * i / 7.0f);
+                    StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                            avail, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                            SPACE_MULTI, SPACE_ADD, false, kind, avail, 1);
+
+                    assertTrue(layout.getEllipsisCount(0) == text.length()
+                                    || layout.getEllipsisCount(0) == text.length() / 2
+                                    || layout.getEllipsisCount(0) == 0);
+                }
+            }
+        }
+    }
+
+    // String wrapper for testing not well known implementation of CharSequence.
+    private class FakeCharSequence implements CharSequence {
+        private String mStr;
+
+        FakeCharSequence(String str) {
+            mStr = str;
+        }
+
+        @Override
+        public char charAt(int index) {
+            return mStr.charAt(index);
+        }
+
+        @Override
+        public int length() {
+            return mStr.length();
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return mStr.subSequence(start, end);
+        }
+
+        @Override
+        public String toString() {
+            return mStr;
+        }
+    };
+
+    private List<CharSequence> buildTestCharSequences(String testString, Normalizer.Form[] forms) {
+        List<CharSequence> result = new ArrayList<>();
+
+        List<String> normalizedStrings = new ArrayList<>();
+        for (Normalizer.Form form: forms) {
+            normalizedStrings.add(Normalizer.normalize(testString, form));
+        }
+
+        for (String str: normalizedStrings) {
+            result.add(str);
+            result.add(new SpannedString(str));
+            result.add(new SpannableString(str));
+            result.add(new SpannableStringBuilder(str));  // as a GraphicsOperations implementation.
+            result.add(new FakeCharSequence(str));  // as a not well known implementation.
+        }
+        return result;
+    }
+
+    private String buildTestMessage(CharSequence seq) {
+        String normalized;
+        if (Normalizer.isNormalized(seq, Normalizer.Form.NFC)) {
+            normalized = "NFC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFD)) {
+            normalized = "NFD";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKC)) {
+            normalized = "NFKC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKD)) {
+            normalized = "NFKD";
+        } else {
+            throw new IllegalStateException("Normalized form is not NFC/NFD/NFKC/NFKD");
+        }
+
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < seq.length(); ++i) {
+            builder.append(String.format("0x%04X ", Integer.valueOf(seq.charAt(i))));
+        }
+
+        return "testString: \"" + seq.toString() + "\"[" + builder.toString() + "]"
+                + ", class: " + seq.getClass().getName()
+                + ", Normalization: " + normalized;
+    }
+
+    @Test
+    public void testGetOffset_UNICODE_Hebrew() {
+        String testString = "\u05DE\u05E1\u05E2\u05D3\u05D4"; // Hebrew Characters
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
+                    TextDirectionHeuristics.RTL, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(5));
+
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index 9271cb4..6063e1a 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -24,12 +24,16 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DateUtilsTest {
@@ -103,6 +107,42 @@
         assertEquals("48h", DateUtils.formatDuration(172800000, DateUtils.LENGTH_SHORTEST));
     }
 
+    @Test
+    public void testFormatSameDayTime() {
+        // This test assumes a default DateFormat.is24Hour setting.
+        DateFormat.is24Hour = null;
+        Date date = new Date(109, 0, 19, 3, 30, 15);
+        long fixedTime = date.getTime();
+
+        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+        Date dateWithCurrentYear = new Date(currentYear - 1900, 0, 19, 3, 30, 15);
+
+        final long dayDuration = 5 * 24 * 60 * 60 * 1000;
+        assertEquals("Saturday, January 24, 2009", DateUtils.formatSameDayTime(
+                fixedTime + dayDuration, fixedTime, java.text.DateFormat.FULL,
+                java.text.DateFormat.FULL));
+        assertEquals("Jan 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.DEFAULT, java.text.DateFormat.FULL));
+        assertEquals("January 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.LONG, java.text.DateFormat.FULL));
+        assertEquals("Jan 24, 2009", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.MEDIUM, java.text.DateFormat.FULL));
+        assertEquals("1/24/09", DateUtils.formatSameDayTime(fixedTime + dayDuration,
+                fixedTime, java.text.DateFormat.SHORT, java.text.DateFormat.FULL));
+
+        final long hourDuration = 2 * 60 * 60 * 1000;
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.FULL));
+        assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.DEFAULT));
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.LONG));
+        assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.MEDIUM));
+        assertEquals("5:30 AM", DateUtils.formatSameDayTime(fixedTime + hourDuration,
+                fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.SHORT));
+    }
+
     private void setLocales(LocaleList locales) {
         final Resources systemResources = Resources.getSystem();
         final Configuration config = new Configuration(systemResources.getConfiguration());
diff --git a/core/tests/coretests/src/android/text/method/WordIteratorTest.java b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
index 3499a74..d1f4f7e 100644
--- a/core/tests/coretests/src/android/text/method/WordIteratorTest.java
+++ b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
@@ -21,19 +21,131 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.support.test.runner.AndroidJUnit4;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.text.BreakIterator;
 import java.util.Locale;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 
 // TODO(Bug: 24062099): Add more tests for non-ascii text.
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class WordIteratorTest {
 
+    private WordIterator mWordIterator = new WordIterator();
+
+    private void verifyIsWordWithSurrogate(int beginning, int end, int surrogateIndex) {
+        for (int i = beginning; i <= end; i++) {
+            if (i == surrogateIndex) continue;
+            assertEquals(beginning, mWordIterator.getBeginning(i));
+            assertEquals(end, mWordIterator.getEnd(i));
+        }
+    }
+
+    private void setCharSequence(String string) {
+        mWordIterator.setCharSequence(string, 0, string.length());
+    }
+
+    private void verifyIsWord(int beginning, int end) {
+        verifyIsWordWithSurrogate(beginning, end, -1);
+    }
+
+    private void verifyIsNotWord(int beginning, int end) {
+        for (int i = beginning; i <= end; i++) {
+            assertEquals(BreakIterator.DONE, mWordIterator.getBeginning(i));
+            assertEquals(BreakIterator.DONE, mWordIterator.getEnd(i));
+        }
+    }
+
+    @Test
+    public void testEmptyString() {
+        setCharSequence("");
+        assertEquals(BreakIterator.DONE, mWordIterator.following(0));
+        assertEquals(BreakIterator.DONE, mWordIterator.preceding(0));
+
+        assertEquals(BreakIterator.DONE, mWordIterator.getBeginning(0));
+        assertEquals(BreakIterator.DONE, mWordIterator.getEnd(0));
+    }
+
+    @Test
+    public void testOneWord() {
+        setCharSequence("I");
+        verifyIsWord(0, 1);
+
+        setCharSequence("am");
+        verifyIsWord(0, 2);
+
+        setCharSequence("zen");
+        verifyIsWord(0, 3);
+    }
+
+    @Test
+    public void testSpacesOnly() {
+        setCharSequence(" ");
+        verifyIsNotWord(0, 1);
+
+        setCharSequence(", ");
+        verifyIsNotWord(0, 2);
+
+        setCharSequence(":-)");
+        verifyIsNotWord(0, 3);
+    }
+
+    @Test
+    public void testBeginningEnd() {
+        setCharSequence("Well hello,   there! ");
+        //                  0123456789012345678901
+        verifyIsWord(0, 4);
+        verifyIsWord(5, 10);
+        verifyIsNotWord(11, 13);
+        verifyIsWord(14, 19);
+        verifyIsNotWord(20, 21);
+
+        setCharSequence("  Another - sentence");
+        //                  012345678901234567890
+        verifyIsNotWord(0, 1);
+        verifyIsWord(2, 9);
+        verifyIsNotWord(10, 11);
+        verifyIsWord(12, 20);
+
+        setCharSequence("This is \u0644\u0627 tested"); // Lama-aleph
+        //                  012345678     9     01234567
+        verifyIsWord(0, 4);
+        verifyIsWord(5, 7);
+        verifyIsWord(8, 10);
+        verifyIsWord(11, 17);
+    }
+
+    @Test
+    public void testSurrogate() {
+        final String gothicBairkan = "\uD800\uDF31";
+
+        setCharSequence("one we" + gothicBairkan + "ird word");
+        //                  012345    67         890123456
+
+        verifyIsWord(0, 3);
+        // Skip index 7 (there is no point in starting between the two surrogate characters)
+        verifyIsWordWithSurrogate(4, 11, 7);
+        verifyIsWord(12, 16);
+
+        setCharSequence("one " + gothicBairkan + "xxx word");
+        //                  0123    45         678901234
+
+        verifyIsWord(0, 3);
+        verifyIsWordWithSurrogate(4, 9, 5);
+        verifyIsWord(10, 14);
+
+        setCharSequence("one xxx" + gothicBairkan + " word");
+        //                  0123456    78         901234
+
+        verifyIsWord(0, 3);
+        verifyIsWordWithSurrogate(4, 9, 8);
+        verifyIsWord(10, 14);
+    }
+
     @Test
     public void testSetCharSequence() {
         final String text = "text";
diff --git a/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java b/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java
new file mode 100644
index 0000000..e5c4b82
--- /dev/null
+++ b/core/tests/coretests/src/android/text/style/UnderlineSpanTest.java
@@ -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.
+ */
+
+package android.text.style;
+
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UnderlineSpanTest {
+    private class RedUnderlineSpan extends UnderlineSpan {
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            ds.setUnderlineText(android.graphics.Color.RED, 1.0f);
+        }
+    }
+
+    // Identical to the normal UnderlineSpan test, except that a subclass of UnderlineSpan is used
+    // that draws a red underline. This shouldn't affect width either.
+    @Test
+    public void testDoesntAffectWidth_colorUnderlineSubclass() {
+        // Roboto kerns between "P" and "."
+        final SpannableString text = new SpannableString("P.");
+        final float origLineWidth = textWidth(text);
+        // Underline just the "P".
+        text.setSpan(new RedUnderlineSpan(), 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        final float underlinedLineWidth = textWidth(text);
+        assertEquals(origLineWidth, underlinedLineWidth, 0.0f);
+    }
+
+    // Measures the width of some potentially-spanned text, assuming it's not too wide.
+    private float textWidth(CharSequence text) {
+        final TextPaint tp = new TextPaint();
+        tp.setTextSize(100.0f); // Large enough so that the difference in kerning is visible.
+        final int largeWidth = 10000; // Enough width so the whole text fits in one line.
+        final StaticLayout layout = StaticLayout.Builder.obtain(
+                text, 0, text.length(), tp, largeWidth).build();
+        return layout.getLineWidth(0);
+    }
+}
diff --git a/core/tests/coretests/src/android/text/util/LinkifyTest.java b/core/tests/coretests/src/android/text/util/LinkifyTest.java
index 23c34085..73ff046 100644
--- a/core/tests/coretests/src/android/text/util/LinkifyTest.java
+++ b/core/tests/coretests/src/android/text/util/LinkifyTest.java
@@ -16,6 +16,7 @@
 
 package android.text.util;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -25,15 +26,20 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.method.LinkMovementMethod;
+import android.text.style.URLSpan;
+import android.util.Patterns;
 import android.widget.TextView;
 
-import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Locale;
+
 /**
  * LinkifyTest tests {@link Linkify}.
  */
@@ -98,4 +104,49 @@
         overrideConfig.setLocales(LOCALE_LIST_US);
         return mContext.createConfigurationContext(overrideConfig);
     }
+
+    @Test
+    public void testAddLinks_addsLinksWhenDefaultSchemeIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, null, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+        assertEquals("android.com", spans[1].getURL());
+    }
+
+    @Test
+    public void testAddLinks_addsLinksWhenSchemesArrayIsNull() {
+        Spannable spannable = new SpannableString("any https://android.com any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://", null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
+        // expected behavior, passing null schemes array means: prepend defaultScheme to all links.
+        assertEquals("http://https://android.com", spans[0].getURL());
+        assertEquals("http://android.com", spans[1].getURL());
+    }
+
+    @Test
+    public void testAddLinks_prependsDefaultSchemeToBeginingOfLink() {
+        Spannable spannable = new SpannableString("any android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("http://android.com", spans[0].getURL());
+    }
+
+    @Test
+    public void testAddLinks_doesNotPrependSchemeIfSchemeExists() {
+        Spannable spannable = new SpannableString("any https://android.com any");
+        Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
+                new String[] { "http://", "https://"}, null, null);
+
+        URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+        assertEquals("android.com should be linkified", 1, spans.length);
+        assertEquals("https://android.com", spans[0].getURL());
+    }
 }
diff --git a/core/tests/coretests/src/android/transition/FadeTransitionTest.java b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
index 0140a04..674b363 100644
--- a/core/tests/coretests/src/android/transition/FadeTransitionTest.java
+++ b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
@@ -48,23 +48,23 @@
         View square1 = mActivity.findViewById(R.id.square1);
         Fade fadeOut = new Fade(Fade.MODE_OUT);
         TransitionLatch latch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(latch.startLatch.await(400, TimeUnit.MILLISECONDS));
         assertEquals(View.VISIBLE, square1.getVisibility());
         waitForAnimation();
         assertFalse(square1.getTransitionAlpha() == 0 || square1.getTransitionAlpha() == 1);
-        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(latch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.INVISIBLE, square1.getVisibility());
 
         Fade fadeIn = new Fade(Fade.MODE_IN);
         latch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(latch.startLatch.await(400, TimeUnit.MILLISECONDS));
         assertEquals(View.VISIBLE, square1.getVisibility());
         waitForAnimation();
         final float transitionAlpha = square1.getTransitionAlpha();
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " + transitionAlpha,
                 transitionAlpha > 0 && transitionAlpha < 1);
-        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(latch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.VISIBLE, square1.getVisibility());
     }
@@ -76,14 +76,14 @@
         FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
         fadeOut.addListener(fadeOutValueCheck);
         TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
         waitForAnimation();
 
         Fade fadeIn = new Fade(Fade.MODE_IN);
         FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
         fadeIn.addListener(fadeInValueCheck);
         TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
 
         assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
@@ -91,7 +91,7 @@
                 fadeOutValueCheck.pauseTransitionAlpha > 0 &&
                         fadeOutValueCheck.pauseTransitionAlpha < 1);
 
-        assertTrue(inLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.VISIBLE, square1.getVisibility());
     }
@@ -109,22 +109,22 @@
         FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
         fadeIn.addListener(fadeInValueCheck);
         TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
-        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(inLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
         waitForAnimation();
 
         Fade fadeOut = new Fade(Fade.MODE_OUT);
         FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
         fadeOut.addListener(fadeOutValueCheck);
         TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
-        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.startLatch.await(400, TimeUnit.MILLISECONDS));
 
-        assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
+        assertEquals(fadeInValueCheck.pauseTransitionAlpha, fadeOutValueCheck.startTransitionAlpha);
         assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
                         fadeInValueCheck.pauseTransitionAlpha,
                 fadeInValueCheck.pauseTransitionAlpha > 0 &&
                         fadeInValueCheck.pauseTransitionAlpha < 1);
 
-        assertTrue(outLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
+        assertTrue(outLatch.endLatch.await(800, TimeUnit.MILLISECONDS));
         assertEquals(1.0f, square1.getTransitionAlpha());
         assertEquals(View.INVISIBLE, square1.getVisibility());
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
new file mode 100644
index 0000000..b18fa74
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -0,0 +1,296 @@
+/*
+ * 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.internal.app;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(AndroidJUnit4.class)
+public class IntentForwarderActivityTest {
+    private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME =
+            new ComponentName(
+                    "android",
+                    IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE
+            );
+    private static final String TYPE_PLAIN_TEXT = "text/plain";
+
+    private static UserInfo MANAGED_PROFILE_INFO = new UserInfo();
+    static {
+        MANAGED_PROFILE_INFO.id = 10;
+        MANAGED_PROFILE_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE;
+    }
+
+    private static UserInfo CURRENT_USER_INFO = new UserInfo();
+    static {
+        CURRENT_USER_INFO.id = UserHandle.myUserId();
+        CURRENT_USER_INFO.flags = 0;
+    }
+
+    private static IntentForwarderActivity.Injector sInjector;
+    private static ComponentName sComponentName;
+
+    @Mock private IPackageManager mIPm;
+    @Mock private PackageManager mPm;
+    @Mock private UserManager mUserManager;
+
+    @Rule
+    public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule =
+            new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false);
+
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getTargetContext();
+        sInjector = new TestInjector();
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        intent.setType(TYPE_PLAIN_TEXT);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_SEND, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_cannotForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent cannot be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(false);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_noManagedProfile_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), anyString(), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile does not exist.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_chooserIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create chooser Intent
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_CHOOSER);
+        Intent sendIntent = new Intent(Intent.ACTION_SEND);
+        sendIntent.setComponent(new ComponentName("xx", "yyy"));
+        sendIntent.setType(TYPE_PLAIN_TEXT);
+        intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+
+        Intent innerIntent = activity.mStartActivityIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+        assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_selectorIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create selector intent.
+        Intent intent = Intent.makeMainSelectorActivity(
+                Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(
+                intentCaptor.capture(), nullable(String.class), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        Intent innerIntent = activity.mStartActivityIntent.getSelector();
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_VIEW, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+
+    public static class IntentForwarderWrapperActivity extends IntentForwarderActivity {
+        private Intent mStartActivityIntent;
+        private int mUserIdActivityLaunchedIn;
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            getIntent().setComponent(sComponentName);
+            super.onCreate(savedInstanceState);
+        }
+
+        @Override
+        protected Injector createInjector() {
+            return sInjector;
+        }
+
+        @Override
+        public void startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean
+                ignoreTargetSecurity, int userId) {
+            mStartActivityIntent = intent;
+            mUserIdActivityLaunchedIn = userId;
+        }
+    }
+
+    class TestInjector implements IntentForwarderActivity.Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPm;
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return mUserManager;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPm;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index c539f78..c21c3be 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -217,10 +217,6 @@
         curr = 1000 * (clocks.realtime = clocks.uptime = 305);
         bi.updateTimeBasesLocked(false, false, curr, curr); // off battery
 
-        // Stop timer
-        curr = 1000 * (clocks.realtime = clocks.uptime = 409);
-        bi.noteBluetoothScanStoppedFromSourceLocked(ws);
-
         // Start timer (unoptimized)
         curr = 1000 * (clocks.realtime = clocks.uptime = 1000);
         bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
@@ -233,9 +229,13 @@
         curr = 1000 * (clocks.realtime = clocks.uptime = 3004);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
 
-        // Stop timer
+        // Stop timer (optimized)
+        curr = 1000 * (clocks.realtime = clocks.uptime = 3409);
+        bi.noteBluetoothScanStoppedFromSourceLocked(ws, false);
+
+        // Stop timer (unoptimized)
         curr = 1000 * (clocks.realtime = clocks.uptime = 4008);
-        bi.noteBluetoothScanStoppedFromSourceLocked(ws);
+        bi.noteBluetoothScanStoppedFromSourceLocked(ws, true);
 
         // Test
         curr = 1000 * (clocks.realtime = clocks.uptime = 5000);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
index f01c33f..e81f678 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
@@ -18,9 +18,12 @@
 package com.android.internal.os;
 
 
+import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -54,11 +57,16 @@
 @SmallTest
 public class BatteryStatsHelperTest extends TestCase {
     private static final long TIME_FOREGROUND_ACTIVITY_ZERO = 0;
-    private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS * 1000;
+    private static final long TIME_STATE_FOREGROUND_MS = 10 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long TIME_STATE_FOREGROUND_US = TIME_STATE_FOREGROUND_MS * 1000;
 
     private static final int UID = 123456;
     private static final double BATTERY_SCREEN_USAGE = 300;
     private static final double BATTERY_SYSTEM_USAGE = 600;
+    private static final double BATTERY_WIFI_USAGE = 200;
+    private static final double BATTERY_IDLE_USAGE = 600;
+    private static final double BATTERY_BLUETOOTH_USAGE = 300;
     private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
     private static final double BATTERY_UNACCOUNTED_USAGE = 700;
     private static final double BATTERY_APP_USAGE = 100;
@@ -68,6 +76,12 @@
     @Mock
     private BatteryStats.Uid mUid;
     @Mock
+    private BatterySipper mWifiBatterySipper;
+    @Mock
+    private BatterySipper mBluetoothBatterySipper;
+    @Mock
+    private BatterySipper mIdleBatterySipper;
+    @Mock
     private BatterySipper mNormalBatterySipper;
     @Mock
     private BatterySipper mScreenBatterySipper;
@@ -109,6 +123,15 @@
         mUnaccountedBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
         mUnaccountedBatterySipper.totalPowerMah = BATTERY_UNACCOUNTED_USAGE;
 
+        mWifiBatterySipper.drainType = BatterySipper.DrainType.WIFI;
+        mWifiBatterySipper.totalPowerMah = BATTERY_WIFI_USAGE;
+
+        mBluetoothBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
+        mBluetoothBatterySipper.totalPowerMah = BATTERY_BLUETOOTH_USAGE;
+
+        mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE;
+        mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE;
+
         mContext = InstrumentationRegistry.getContext();
         mBatteryStatsHelper = spy(new BatteryStatsHelper(mContext));
         mBatteryStatsHelper.setPackageManager(mPackageManager);
@@ -165,6 +188,9 @@
         sippers.add(mSystemBatterySipper);
         sippers.add(mOvercountedBatterySipper);
         sippers.add(mUnaccountedBatterySipper);
+        sippers.add(mWifiBatterySipper);
+        sippers.add(mBluetoothBatterySipper);
+        sippers.add(mIdleBatterySipper);
         doReturn(true).when(mBatteryStatsHelper).isTypeSystem(mSystemBatterySipper);
         doNothing().when(mBatteryStatsHelper).smearScreenBatterySipper(any(), any());
 
@@ -219,6 +245,19 @@
         assertThat(mBatteryStatsHelper.isTypeService(mNormalBatterySipper)).isTrue();
     }
 
+    @Test
+    public void testGetProcessForegroundTimeMs_largerActivityTime_returnMinTime() {
+        doReturn(TIME_STATE_FOREGROUND_US + 500).when(mBatteryStatsHelper)
+                .getForegroundActivityTotalTimeUs(eq(mUid), anyLong());
+        doReturn(TIME_STATE_FOREGROUND_US).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP),
+                anyLong(), anyInt());
+
+        final long time = mBatteryStatsHelper.getProcessForegroundTimeMs(mUid,
+                BatteryStats.STATS_SINCE_CHARGED);
+
+        assertThat(time).isEqualTo(TIME_STATE_FOREGROUND_MS);
+    }
+
     private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
             int uidCode, boolean isUidNull) {
         final BatterySipper sipper = mock(BatterySipper.class);
@@ -227,8 +266,8 @@
         doReturn(uidCode).when(sipper).getUid();
         if (!isUidNull) {
             final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
-            doReturn(activityTime).when(mBatteryStatsHelper).getForegroundActivityTotalTimeMs(
-                    eq(uid), anyLong());
+            doReturn(activityTime).when(mBatteryStatsHelper).getProcessForegroundTimeMs(eq(uid),
+                    anyInt());
             doReturn(uidCode).when(uid).getUid();
             sipper.uidObj = uid;
         }
@@ -236,5 +275,4 @@
         return sipper;
     }
 
-
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 4e8ab31..ed54f53 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -44,8 +44,6 @@
         assertEquals(101,
                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
                         .getCountLocked(STATS_SINCE_CHARGED));
-        // TODO: remove next line when Counter misreporting values when plugged-in bug is fixed.
-        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
         BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter();
         if (bgCntr != null) {
             assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED));
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index af4a6d9..8fd4e31 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -400,7 +400,7 @@
         assertNotNull(sensor.getSensorBackgroundTime());
 
         // Reset the stats. Since the sensor is still running, we should still see the timer
-        bi.getUidStatsLocked(UID).reset();
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
 
         sensor = uid.getSensorStats().get(SENSOR_ID);
         assertNotNull(sensor);
@@ -410,9 +410,111 @@
         bi.noteStopSensorLocked(UID, SENSOR_ID);
 
         // Now the sensor timer has stopped so this reset should also take out the sensor.
-        bi.getUidStatsLocked(UID).reset();
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
 
         sensor = uid.getSensorStats().get(SENSOR_ID);
         assertNull(sensor);
     }
+
+    @SmallTest
+    public void testSensorResetTimes() throws Exception {
+        final MockClocks clocks = new MockClocks();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        final int which = BatteryStats.STATS_SINCE_CHARGED;
+        bi.mForceOnBattery = true;
+        clocks.realtime = 100; // in ms
+        clocks.uptime = 100; // in ms
+
+        // TimeBases are on for some time.
+        BatteryStatsImpl.TimeBase timeBase = bi.getOnBatteryTimeBase();
+        BatteryStatsImpl.TimeBase bgTimeBase = bi.getOnBatteryBackgroundTimeBase(UID);
+        timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // TimeBases are turned off
+        timeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timer is turned on
+        bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timebase was off so times are all 0.
+        BatteryStats.Uid.Sensor sensor = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID);
+        BatteryStats.Timer timer = sensor.getSensorTime();
+        BatteryStats.Timer bgTimer = sensor.getSensorBackgroundTime();
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Reset the stats. Since the sensor is still running, we should still see the timer
+        // but still with 0 times.
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Now stop the timer. The times should still be 0.
+        bi.noteStopSensorLocked(UID, SENSOR_ID);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        // Now repeat with the TimeBases turned on the entire time.
+        timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Timer is turned on
+        bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+        clocks.realtime += 111;
+        clocks.uptime += 1111;
+
+        // Timebase and timer was on so times have increased.
+        assertEquals(111_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(111, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(111_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(111, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 100;
+        clocks.uptime += 100;
+
+        // Reset the stats. Since the sensor is still running, we should still see the timer
+        // but with 0 times.
+        bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+        assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+        clocks.realtime += 112;
+        clocks.uptime += 112;
+
+        // Now stop the timer. The times should have increased since the timebase was on.
+        bi.noteStopSensorLocked(UID, SENSOR_ID);
+        assertEquals(112_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(112, timer.getTotalDurationMsLocked(clocks.realtime));
+        assertEquals(112_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+        assertEquals(112, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
index 1471796..912b7ec 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
@@ -60,11 +60,9 @@
         TestViewGroup viewGroup = new TestViewGroup(mContext);
         viewGroup.addView(mActionBarContainer);
 
-        ActionMode mode = mActionBarContainer.startActionModeForChild(
-                null, null, ActionMode.TYPE_FLOATING);
+        mActionBarContainer.startActionModeForChild(null, null, ActionMode.TYPE_FLOATING);
 
         // Should bubble up.
-        assertNotNull(mode);
         assertTrue(viewGroup.isStartActionModeForChildTypedCalled);
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
index a249925..1806b22 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
@@ -21,9 +21,11 @@
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
+import android.text.Layout;
 import android.view.View.MeasureSpec;
 import android.widget.TextView;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -102,6 +104,16 @@
                 + "Yada yada, yada yada. Lorem ipsum dolor sit amet.");
     }
 
+    @Test
+    public void usesTransformationMethod() {
+        mView.setSingleLine();
+        String text = "Test \n Test";
+        parametrizedTest(text);
+        Layout layout = mView.getLayout();
+        Assert.assertFalse("The transformation method wasn't used, string is still the same",
+                text.equals(layout.getText()));
+    }
+
     private void parametrizedTest(CharSequence text) {
         int heightMeasureSpec = MeasureSpec.makeMeasureSpec(500, MeasureSpec.AT_MOST);
         int widthMeasureSpec = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
new file mode 100644
index 0000000..f73950a
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
@@ -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.
+ */
+
+package com.android.internal.widget;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LockPatternUtilsTest {
+
+    @Test
+    public void testUserFrp_isNotRegularUser() throws Exception {
+        assertTrue(LockPatternUtils.USER_FRP < 0);
+    }
+
+    @Test
+    public void testUserFrp_isNotAReservedSpecialUser() throws Exception {
+        assertNotEquals(UserHandle.USER_NULL, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_ALL, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_CURRENT, LockPatternUtils.USER_FRP);
+        assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_FRP);
+    }
+}
diff --git a/core/tests/utiltests/AndroidManifest.xml b/core/tests/utiltests/AndroidManifest.xml
index da09894..d6384e7 100644
--- a/core/tests/utiltests/AndroidManifest.xml
+++ b/core/tests/utiltests/AndroidManifest.xml
@@ -40,6 +40,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/core/tests/utiltests/AndroidTest.xml b/core/tests/utiltests/AndroidTest.xml
index 9ebf568..65bb8de 100644
--- a/core/tests/utiltests/AndroidTest.xml
+++ b/core/tests/utiltests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksUtilTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.utiltests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
new file mode 100644
index 0000000..b18ee17
--- /dev/null
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.internal.util;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.test.mock.MockContentResolver;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LockPatternUtilsTest {
+
+    private static final int DEMO_USER_ID = 5;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    private void configureTest(boolean isSecure, boolean isDemoUser, int deviceDemoMode)
+            throws Exception {
+        final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+        final MockContentResolver cr = new MockContentResolver(context);
+        cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(context.getContentResolver()).thenReturn(cr);
+        Settings.Global.putInt(cr, Settings.Global.DEVICE_DEMO_MODE, deviceDemoMode);
+
+        final ILockSettings ils = Mockito.mock(ILockSettings.class);
+        when(ils.havePassword(DEMO_USER_ID)).thenReturn(isSecure);
+        when(ils.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, DEMO_USER_ID))
+                .thenReturn((long) PASSWORD_QUALITY_MANAGED);
+        // TODO(b/63758238): stop spying the class under test
+        mLockPatternUtils = spy(new LockPatternUtils(context));
+        when(mLockPatternUtils.getLockSettings()).thenReturn(ils);
+
+        final UserInfo userInfo = Mockito.mock(UserInfo.class);
+        when(userInfo.isDemo()).thenReturn(isDemoUser);
+        final UserManager um = Mockito.mock(UserManager.class);
+        when(um.getUserInfo(DEMO_USER_ID)).thenReturn(userInfo);
+        when(context.getSystemService(Context.USER_SERVICE)).thenReturn(um);
+    }
+
+    @Test
+    public void isLockScreenDisabled_isDemoUser_true() throws Exception {
+        configureTest(false, true, 2);
+        assertTrue(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isSecureAndDemoUser_false() throws Exception {
+        configureTest(true, true, 2);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isNotDemoUser_false() throws Exception {
+        configureTest(false, false, 2);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+
+    @Test
+    public void isLockScreenDisabled_isNotInDemoMode_false() throws Exception {
+        configureTest(false, true, 0);
+        assertFalse(mLockPatternUtils.isLockScreenDisabled(DEMO_USER_ID));
+    }
+}
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index 7fafef7..3a81c13 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -28,4 +28,6 @@
     <backup-transport-whitelisted-service
         service="android/com.android.internal.backup.LocalTransportService" />
 
+    <!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
+    <app-link package="com.android.carrierdefaultapp" />
 </config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index efed165..92b6aa3 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -163,6 +163,7 @@
         <permission name="android.permission.UPDATE_LOCK"/>
         <permission name="android.permission.WRITE_APN_SETTINGS"/>
         <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>
@@ -229,6 +230,7 @@
         <permission name="android.permission.MANAGE_FINGERPRINT"/>
         <permission name="android.permission.MANAGE_USB"/>
         <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MANAGE_USER_OEM_UNLOCK_STATE" />
         <permission name="android.permission.MASTER_CLEAR"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
@@ -313,6 +315,7 @@
         <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
         <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
         <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/>
+        <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.CONTROL_VPN"/>
         <permission name="android.permission.DUMP"/>
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 5baa75b..7b2fa76 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -81,6 +81,33 @@
 build-one-font-module :=
 font_src_files :=
 
+################################
+# Copies the font configuration file into system/etc for the product as fonts.xml.
+# In the case where $(ADDITIONAL_FONTS_FILE) is defined, the content of $(ADDITIONAL_FONTS_FILE)
+# is added to the $(AOSP_FONTS_FILE).
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fonts.xml
+LOCAL_MODULE_CLASS := ETC
+
+AOSP_FONTS_FILE := frameworks/base/data/fonts/fonts.xml
+
+ifdef ADDITIONAL_FONTS_FILE
+ADDITIONAL_FONTS_SCRIPT := frameworks/base/tools/fonts/add_additional_fonts.py
+ADD_ADDITIONAL_FONTS := $(local-generated-sources-dir)/fonts.xml
+
+$(ADD_ADDITIONAL_FONTS): PRIVATE_SCRIPT := $(ADDITIONAL_FONTS_SCRIPT)
+$(ADD_ADDITIONAL_FONTS): PRIVATE_ADDITIONAL_FONTS_FILE := $(ADDITIONAL_FONTS_FILE)
+$(ADD_ADDITIONAL_FONTS): $(ADDITIONAL_FONTS_SCRIPT) $(AOSP_FONTS_FILE) $(ADDITIONAL_FONTS_FILE)
+	rm -f $@
+	python $(PRIVATE_SCRIPT) $@ $(PRIVATE_ADDITIONAL_FONTS_FILE)
+else
+ADD_ADDITIONAL_FONTS := $(AOSP_FONTS_FILE)
+endif
+
+LOCAL_PREBUILT_MODULE_FILE := $(ADD_ADDITIONAL_FONTS)
+
+include $(BUILD_PREBUILT)
 
 # Run sanity tests on fonts on checkbuild
 checkbuild: fontchain_lint
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 23c54ae..e884f2f 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -14,9 +14,7 @@
 
 # Warning: this is actually a product definition, to be inherited from
 
-PRODUCT_COPY_FILES := \
-    frameworks/base/data/fonts/fonts.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/fonts.xml
-
 PRODUCT_PACKAGES := \
     DroidSansMono.ttf \
-    AndroidClock.ttf
+    AndroidClock.ttf \
+    fonts.xml
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 318353f..ae93608 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -51,10 +51,13 @@
         <font weight="300" style="italic">RobotoCondensed-LightItalic.ttf</font>
         <font weight="400" style="normal">RobotoCondensed-Regular.ttf</font>
         <font weight="400" style="italic">RobotoCondensed-Italic.ttf</font>
+        <font weight="500" style="normal">RobotoCondensed-Medium.ttf</font>
+        <font weight="500" style="italic">RobotoCondensed-MediumItalic.ttf</font>
         <font weight="700" style="normal">RobotoCondensed-Bold.ttf</font>
         <font weight="700" style="italic">RobotoCondensed-BoldItalic.ttf</font>
     </family>
     <alias name="sans-serif-condensed-light" to="sans-serif-condensed" weight="300" />
+    <alias name="sans-serif-condensed-medium" to="sans-serif-condensed" weight="500" />
 
     <family name="serif">
         <font weight="400" style="normal">NotoSerif-Regular.ttf</font>
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
deleted file mode 100644
index ee37cb9..0000000
--- a/data/sounds/AudioTv.mk
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright 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 := frameworks/base/data/sounds
-
-PRODUCT_COPY_FILES += \
-    $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
-    $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
-    $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
-    $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
-    $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
-    $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
-    $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
-    $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \
-    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
-    $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
-    $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
-    $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
-    $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
-    $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
-    $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \
-    $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \
-    $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \
-    $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-    $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
-    $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
-    $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \
-    $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
-    $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
-    $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \
-    $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \
-    $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \
-    $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
-    $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-    $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \
-    $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
-    $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \
-    $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
-    $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
-    $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
-    $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \
-    $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \
-    $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
-    $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
-    $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-    $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-    $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
-    $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 5973d3e..76eab4a 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -262,7 +262,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/drm/java/android/drm/DrmUtils.java b/drm/java/android/drm/DrmUtils.java
index 2a86996..60ee6d9 100644
--- a/drm/java/android/drm/DrmUtils.java
+++ b/drm/java/android/drm/DrmUtils.java
@@ -17,6 +17,7 @@
 package android.drm;
 
 import java.io.BufferedInputStream;
+import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -79,26 +80,16 @@
         file.delete();
     }
 
-    private static void quietlyDispose(InputStream stream) {
+    private static void quietlyDispose(Closeable closable) {
         try {
-            if (null != stream) {
-                stream.close();
+            if (null != closable) {
+                closable.close();
             }
         } catch (IOException e) {
             // no need to care, at least as of now
         }
     }
 
-    private static void quietlyDispose(OutputStream stream) {
-        try {
-            if (null != stream) {
-                stream.close();
-            }
-        } catch (IOException e) {
-            // no need to care
-        }
-    }
-
     /**
      * Gets an instance of {@link DrmUtils.ExtendedMetadataParser}, which can be used to parse
      * extended metadata embedded in DRM constraint information.
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index 0ca3729..b24b988 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -14,19 +14,22 @@
  * limitations under the License.
  */
 
-// This file was generated from the C++ include file: SkColorFilter.h
-// Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
-
 package android.graphics;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * A color filter can be used with a {@link Paint} to modify the color of
  * each pixel drawn with that paint. This is an abstract class that should
  * never be used directly.
  */
 public class ColorFilter {
+
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                ColorFilter.class.getClassLoader(), nativeGetFinalizer(), 50);
+    }
+
     /**
      * @deprecated Use subclass constructors directly instead.
      */
@@ -34,9 +37,11 @@
     public ColorFilter() {}
 
     /**
-     * Holds the pointer to the native SkColorFilter instance.
+     * Current native SkColorFilter instance.
      */
     private long mNativeInstance;
+    // Runnable to do immediate destruction
+    private Runnable mCleaner;
 
     long createNativeInstance() {
         return 0;
@@ -44,35 +49,28 @@
 
     void discardNativeInstance() {
         if (mNativeInstance != 0) {
-            nSafeUnref(mNativeInstance);
+            mCleaner.run();
+            mCleaner = null;
             mNativeInstance = 0;
         }
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativeInstance != 0) {
-                nSafeUnref(mNativeInstance);
-            }
-            mNativeInstance = -1;
-        } finally {
-            super.finalize();
-        }
-    }
-
     /** @hide */
     public long getNativeInstance() {
-        if (mNativeInstance == -1) {
-            throw new IllegalStateException("attempting to use a finalized ColorFilter");
-        }
-
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance();
+
+            if (mNativeInstance != 0) {
+                // Note: we must check for null here, since it's possible for createNativeInstance()
+                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
+                // See native implementations of subclass create methods for more info.
+                mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+                        this, mNativeInstance);
+            }
         }
         return mNativeInstance;
 
     }
 
-    static native void nSafeUnref(long native_instance);
+    private static native long nativeGetFinalizer();
 }
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index a226e85..e3527e3 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -662,6 +662,15 @@
     public static final int DEPTH_POINT_CLOUD = 0x101;
 
     /**
+     * Unprocessed implementation-dependent raw
+     * depth measurements, opaque with 16 bit
+     * samples.
+     *
+     * @hide
+     */
+    public static final int RAW_DEPTH = 0x1002;
+
+    /**
      * Android private opaque image format.
      * <p>
      * The choices of the actual format and pixel data layout are entirely up to
@@ -723,6 +732,7 @@
                 return 24;
             case FLEX_RGBA_8888:
                 return 32;
+            case RAW_DEPTH:
             case RAW_SENSOR:
                 return 16;
             case RAW10:
@@ -765,6 +775,7 @@
             case DEPTH16:
             case DEPTH_POINT_CLOUD:
             case PRIVATE:
+            case RAW_DEPTH:
                 return true;
         }
 
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f931d21..e1eb69a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -80,6 +80,11 @@
     private String      mFontFeatureSettings;
     private String      mFontVariationSettings;
 
+    private float mShadowLayerRadius;
+    private float mShadowLayerDx;
+    private float mShadowLayerDy;
+    private int mShadowLayerColor;
+
     private static final Object sCacheLock = new Object();
 
     /**
@@ -530,6 +535,11 @@
         setElegantTextHeight(false);
         mFontFeatureSettings = null;
         mFontVariationSettings = null;
+
+        mShadowLayerRadius = 0.0f;
+        mShadowLayerDx = 0.0f;
+        mShadowLayerDy = 0.0f;
+        mShadowLayerColor = 0;
     }
 
     /**
@@ -567,6 +577,54 @@
         mLocales = paint.mLocales;
         mFontFeatureSettings = paint.mFontFeatureSettings;
         mFontVariationSettings = paint.mFontVariationSettings;
+
+        mShadowLayerRadius = paint.mShadowLayerRadius;
+        mShadowLayerDx = paint.mShadowLayerDx;
+        mShadowLayerDy = paint.mShadowLayerDy;
+        mShadowLayerColor = paint.mShadowLayerColor;
+    }
+
+    /**
+     * Returns true if all attributes are equal.
+     *
+     * The caller is expected to have checked the trivial cases, like the pointers being equal,
+     * the objects having different classes, or the parameter being null.
+     * @hide
+     */
+    public boolean hasEqualAttributes(@NonNull Paint other) {
+        return mColorFilter == other.mColorFilter
+                && mMaskFilter == other.mMaskFilter
+                && mPathEffect == other.mPathEffect
+                && mShader == other.mShader
+                && mTypeface == other.mTypeface
+                && mXfermode == other.mXfermode
+                && mHasCompatScaling == other.mHasCompatScaling
+                && mCompatScaling == other.mCompatScaling
+                && mInvCompatScaling == other.mInvCompatScaling
+                && mBidiFlags == other.mBidiFlags
+                && mLocales.equals(other.mLocales)
+                && TextUtils.equals(mFontFeatureSettings, other.mFontFeatureSettings)
+                && TextUtils.equals(mFontVariationSettings, other.mFontVariationSettings)
+                && mShadowLayerRadius == other.mShadowLayerRadius
+                && mShadowLayerDx == other.mShadowLayerDx
+                && mShadowLayerDy == other.mShadowLayerDy
+                && mShadowLayerColor == other.mShadowLayerColor
+                && getFlags() == other.getFlags()
+                && getHinting() == other.getHinting()
+                && getStyle() == other.getStyle()
+                && getColor() == other.getColor()
+                && getStrokeWidth() == other.getStrokeWidth()
+                && getStrokeMiter() == other.getStrokeMiter()
+                && getStrokeCap() == other.getStrokeCap()
+                && getStrokeJoin() == other.getStrokeJoin()
+                && getTextAlign() == other.getTextAlign()
+                && isElegantTextHeight() == other.isElegantTextHeight()
+                && getTextSize() == other.getTextSize()
+                && getTextScaleX() == other.getTextScaleX()
+                && getTextSkewX() == other.getTextSkewX()
+                && getLetterSpacing() == other.getLetterSpacing()
+                && getWordSpacing() == other.getWordSpacing()
+                && getHyphenEdit() == other.getHyphenEdit();
     }
 
     /** @hide */
@@ -758,6 +816,27 @@
     }
 
     /**
+     * Distance from top of the underline to the baseline. Positive values mean below the baseline.
+     * This method returns where the underline should be drawn independent of if the underlineText
+     * bit is set at the moment.
+     * @hide
+     */
+    public float getUnderlinePosition() {
+        // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
+        // TODO: replace with position from post and MVAR tables (b/62353930).
+        return (1.0f / 9.0f) * getTextSize();
+    }
+
+    /**
+     * @hide
+     */
+    public float getUnderlineThickness() {
+        // kStdUnderline_Thickness = 1/18, defined in SkTextFormatParams.h
+        // TODO: replace with thickness from post and MVAR tables (b/62353930).
+        return (1.0f / 18.0f) * getTextSize();
+    }
+
+    /**
      * Helper for setFlags(), setting or clearing the UNDERLINE_TEXT_FLAG bit
      *
      * @param underlineText true to set the underlineText bit in the paint's
@@ -1238,6 +1317,10 @@
      * opaque, or the alpha from the shadow color if not.
      */
     public void setShadowLayer(float radius, float dx, float dy, int shadowColor) {
+      mShadowLayerRadius = radius;
+      mShadowLayerDx = dx;
+      mShadowLayerDy = dy;
+      mShadowLayerColor = shadowColor;
       nSetShadowLayer(mNativePaint, radius, dx, dy, shadowColor);
     }
 
@@ -2798,7 +2881,7 @@
     private static native int nGetFontMetricsInt(long paintPtr,
             long typefacePtr, FontMetricsInt fmi);
 
-    
+
     // ---------------- @CriticalNative ------------------------
 
     @CriticalNative
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 8616d58..1d0cfa5 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -289,6 +289,9 @@
     }
 
     private void updateLayerBounds(Rect bounds) {
+        if (bounds.isEmpty()) {
+            return;
+        }
         try {
             suspendChildInvalidation();
             updateLayerBoundsInternal(bounds);
@@ -1109,4 +1112,4 @@
             mCheckedStateful = false;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 8ce7ed0..c329918 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -44,6 +44,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -493,7 +494,7 @@
             case TYPE_DATA:
                 return getDataLength() == otherIcon.getDataLength()
                         && getDataOffset() == otherIcon.getDataOffset()
-                        && getDataBytes() == otherIcon.getDataBytes();
+                        && Arrays.equals(getDataBytes(), otherIcon.getDataBytes());
             case TYPE_RESOURCE:
                 return getResId() == otherIcon.getResId()
                         && Objects.equals(getResPackage(), otherIcon.getResPackage());
@@ -804,6 +805,43 @@
     };
 
     /**
+     * Scale down a bitmap to a given max width and max height. The scaling will be done in a uniform way
+     * @param bitmap the bitmap to scale down
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @return the scaled bitmap if necessary or the original bitmap if no scaling was needed
+     * @hide
+     */
+    public static Bitmap scaleDownIfNecessary(Bitmap bitmap, int maxWidth, int maxHeight) {
+        int bitmapWidth = bitmap.getWidth();
+        int bitmapHeight = bitmap.getHeight();
+        if (bitmapWidth > maxWidth || bitmapHeight > maxHeight) {
+            float scale = Math.min((float) maxWidth / bitmapWidth,
+                    (float) maxHeight / bitmapHeight);
+            bitmap = Bitmap.createScaledBitmap(bitmap, (int) (scale * bitmapWidth),
+                    (int) (scale * bitmapHeight), true /* filter */);
+        }
+        return bitmap;
+    }
+
+    /**
+     * Scale down this icon to a given max width and max height.
+     * The scaling will be done in a uniform way and currently only bitmaps are supported.
+     * @param maxWidth the maximum width allowed
+     * @param maxHeight the maximum height allowed
+     *
+     * @hide
+     */
+    public void scaleDownIfNecessary(int maxWidth, int maxHeight) {
+        if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
+            return;
+        }
+        Bitmap bitmap = getBitmap();
+        setBitmap(scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
+    }
+
+    /**
      * Implement this interface to receive a callback when
      * {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
      * is finished and your Drawable is ready.
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 0122338..3dfd680 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -118,6 +118,18 @@
     }
 
     /**
+     * Show the second layer on top of the first layer immediately
+     *
+     * @hide
+     */
+    public void showSecondLayer() {
+        mAlpha = 255;
+        mReverse = false;
+        mTransitionState = TRANSITION_NONE;
+        invalidateSelf();
+    }
+
+    /**
      * Show only the first layer.
      */
     public void resetTransition() {
diff --git a/graphics/java/android/graphics/pdf/PdfDocument.java b/graphics/java/android/graphics/pdf/PdfDocument.java
index d603436..1b8336f 100644
--- a/graphics/java/android/graphics/pdf/PdfDocument.java
+++ b/graphics/java/android/graphics/pdf/PdfDocument.java
@@ -202,7 +202,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             dispose();
         } finally {
             super.finalize();
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index cd1f8de..245d769 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -270,7 +270,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             if (mInput != null) {
                 doClose();
             }
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 7b7a290..b7b81ae 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -230,7 +230,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             if (mInput != null) {
                 doClose();
             }
@@ -444,7 +447,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 if (mNativePage != 0) {
                     doClose();
                 }
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index d023866..d5b34c4 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -260,13 +260,13 @@
      * Example:
      *
      * <pre class="prettyprint">
-     * Calendar start = new Calendar();
-     * Calendar end = new Calendar();
-     * end.add(1, Calendar.YEAR);
+     * Calendar start = Calendar.getInstance();
+     * Calendar end = Calendar.getInstance();
+     * end.add(Calendar.YEAR, 1);
      *
      * KeyPairGeneratorSpec spec =
      *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
-     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
+     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerialNumber(BigInteger.valueOf(1337))
      *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
      * </pre>
      *
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index bfd1422..ccf9de0 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -341,12 +341,14 @@
         }
     }
 
-    public boolean grant(String key, int uid) {
+    public String grant(String key, int uid) {
         try {
-            return mBinder.grant(key, uid) == NO_ERROR;
+            String grantAlias =  mBinder.grant(key, uid);
+            if (grantAlias == "") return null;
+            return grantAlias;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
+            return null;
         }
     }
 
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ae4eabf..303d05f 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -5,11 +5,6 @@
 
         //"hwui_bugreport_font_cache_usage",
         //"hwui_compile_for_perf",
-
-        // Enables fine-grained GLES error checking
-        // If enabled, every GLES call is wrapped & error checked
-        // Has moderate overhead
-        //"hwui_enable_opengl-validation",
     ],
 
     cflags: [
@@ -62,7 +57,7 @@
         "libskia",
         "libui",
         "libgui",
-        "libprotobuf-cpp-full",
+        "libprotobuf-cpp-lite",
         "libharfbuzz_ng",
         "libft2",
         "libminikin",
@@ -108,7 +103,6 @@
     name: "hwui_enable_opengl_validation",
     defaults: ["hwui_debug"],
     cflags: ["-DDEBUG_OPENGL=3"],
-    srcs: ["debug/wrap_gles.cpp"],
     include_dirs: ["frameworks/native/opengl/libs/GLES2"],
 }
 
@@ -147,6 +141,7 @@
         "renderstate/Scissor.cpp",
         "renderstate/Stencil.cpp",
         "renderstate/TextureState.cpp",
+        "renderthread/CacheManager.cpp",
         "renderthread/CanvasContext.cpp",
         "renderthread/OpenGLPipeline.cpp",
         "renderthread/DrawFrameTask.cpp",
@@ -242,7 +237,14 @@
 
 cc_library {
     name: "libhwui",
-    defaults: ["libhwui_defaults"],
+    defaults: [
+        "libhwui_defaults",
+
+        // Enables fine-grained GLES error checking
+        // If enabled, every GLES call is wrapped & error checked
+        // Has moderate overhead
+        "hwui_enable_opengl_validation",
+],
 }
 
 // ------------------------
@@ -264,6 +266,7 @@
 cc_defaults {
     name: "hwui_test_defaults",
     defaults: ["hwui_defaults"],
+    test_suites: ["device-tests"],
     srcs: [
         "tests/common/scenes/*.cpp",
         "tests/common/LeakChecker.cpp",
@@ -298,6 +301,7 @@
         "tests/unit/BakedOpRendererTests.cpp",
         "tests/unit/BakedOpStateTests.cpp",
         "tests/unit/BitmapTests.cpp",
+        "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
         "tests/unit/CanvasStateTests.cpp",
         "tests/unit/ClipAreaTests.cpp",
diff --git a/libs/hwui/AndroidTest.xml b/libs/hwui/AndroidTest.xml
new file mode 100644
index 0000000..eab32c5
--- /dev/null
+++ b/libs/hwui/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<configuration description="Config for hwuimicro">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="hwui_unit_tests->/data/nativetest/hwui_unit_tests" />
+        <option name="push" value="hwuimicro->/data/benchmarktest/hwuimicro" />
+        <option name="push" value="hwuimacro->/data/benchmarktest/hwuimacro" />
+    </target_preparer>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/nativetest" />
+        <option name="module-name" value="hwui_unit_tests" />
+    </test>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/benchmarktest" />
+        <option name="benchmark-module-name" value="hwuimicro" />
+    </test>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/benchmarktest" />
+        <option name="benchmark-module-name" value="hwuimacro" />
+    </test>
+</configuration>
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index d154730..df2b35b 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -32,7 +32,8 @@
 OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) {
     LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
 
-    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+    OffscreenBuffer* buffer = mRenderState.layerPool().get(
+            mRenderState, width, height, mWideColorGamut);
     startRepaintLayer(buffer, Rect(width, height));
     return buffer;
 }
@@ -103,7 +104,8 @@
 OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
     const uint32_t width = area.getWidth();
     const uint32_t height = area.getHeight();
-    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+    OffscreenBuffer* buffer = mRenderState.layerPool().get(
+            mRenderState, width, height, mWideColorGamut);
     if (!area.isEmpty() && width != 0 && height != 0) {
         mCaches.textureState().activateTexture(0);
         mCaches.textureState().bindTexture(buffer->texture.id());
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index 4d76a3d..01ca367 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -54,12 +54,13 @@
         uint8_t spotShadowAlpha;
     };
 
-    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque,
+    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
             const LightInfo& lightInfo)
             : mGlopReceiver(DefaultGlopReceiver)
             , mRenderState(renderState)
             , mCaches(caches)
             , mOpaque(opaque)
+            , mWideColorGamut(wideColorGamut)
             , mLightInfo(lightInfo) {
     }
 
@@ -118,6 +119,7 @@
     RenderState& mRenderState;
     Caches& mCaches;
     bool mOpaque;
+    bool mWideColorGamut;
     bool mHasDrawn = false;
 
     // render target state - setup by start/end layer/frame
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 2e9a6e8..c19c1a1 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -457,11 +457,13 @@
     return *this;
 }
 
-GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) {
+GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+        bool requiresFilter) {
     TRIGGER_STAGE(kFillStage);
     REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
 
-    mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform };
+    GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
+    mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform };
 
     setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap,
             nullptr, nullptr);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 87b1568..6d11da1 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -75,7 +75,8 @@
     GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
     // TODO: setFillLayer normally forces its own wrap & filter mode,
     // which isn't always correct.
-    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
+    GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+            bool requiresFilter);
 
     GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
 
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index c460c0d..19d5d9d 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -27,6 +27,7 @@
 #include <GLES2/gl2.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <gui/Surface.h>
 
 namespace android {
 namespace uirenderer {
@@ -132,8 +133,7 @@
         return CopyResult::DestinationInvalid;
     }
 
-    // TODO: Add support for RGBA_F16 destinations
-    if (bitmap->colorType() == kRGBA_F16_SkColorType) {
+    if (bitmap->colorType() == kRGBA_F16_SkColorType && !caches.extensions().hasFloatTextures()) {
         ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
         return CopyResult::DestinationInvalid;
     }
@@ -144,29 +144,37 @@
         return CopyResult::UnknownError;
     }
 
-    SkAutoLockPixels alp(*bitmap);
-
     GLuint texture;
 
     GLenum format;
+    GLenum internalFormat;
     GLenum type;
 
     switch (bitmap->colorType()) {
         case kAlpha_8_SkColorType:
             format = GL_ALPHA;
+            internalFormat = GL_ALPHA;
             type = GL_UNSIGNED_BYTE;
             break;
         case kRGB_565_SkColorType:
             format = GL_RGB;
+            internalFormat = GL_RGB;
             type = GL_UNSIGNED_SHORT_5_6_5;
             break;
         case kARGB_4444_SkColorType:
             format = GL_RGBA;
+            internalFormat = GL_RGBA;
             type = GL_UNSIGNED_SHORT_4_4_4_4;
             break;
+        case kRGBA_F16_SkColorType:
+            format = GL_RGBA;
+            internalFormat = GL_RGBA16F;
+            type = GL_HALF_FLOAT;
+            break;
         case kN32_SkColorType:
         default:
             format = GL_RGBA;
+            internalFormat = GL_RGBA;
             type = GL_UNSIGNED_BYTE;
             break;
     }
@@ -185,12 +193,13 @@
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexImage2D(GL_TEXTURE_2D, 0, format, destWidth, destHeight,
+    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, destWidth, destHeight,
             0, format, type, nullptr);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
             GL_TEXTURE_2D, texture, 0);
 
     {
+        bool requiresFilter;
         // Draw & readback
         renderState.setViewport(destWidth, destHeight);
         renderState.scissor().setEnabled(false);
@@ -208,12 +217,17 @@
             croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(),
                     srcRect.getHeight() / sourceTexture.height(), 1);
             croppedTexTransform.multiply(sFlipV);
+            requiresFilter = srcRect.getWidth() != (float) destWidth
+                    || srcRect.getHeight() != (float) destHeight;
+        } else {
+            requiresFilter = sourceTexture.width() != (uint32_t) destWidth
+                    || sourceTexture.height() != (uint32_t) destHeight;
         }
         Glop glop;
         GlopBuilder(renderState, caches, &glop)
                 .setRoundRectClipState(nullptr)
                 .setMeshTexturedUnitQuad(nullptr)
-                .setFillExternalTexture(sourceTexture, croppedTexTransform)
+                .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter)
                 .setTransform(Matrix4::identity(), TransformFlags::None)
                 .setModelViewMapUnitToRect(Rect(destWidth, destHeight))
                 .build();
@@ -221,6 +235,7 @@
         ortho.loadOrtho(destWidth, destHeight);
         renderState.render(glop, ortho);
 
+        // TODO: We should convert to linear space when the target is RGBA16F
         glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
                 type, bitmap->getPixels());
     }
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index c9222cf..403f2e3 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -18,6 +18,9 @@
 
 #include "Readback.h"
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index b763953..7cf4262 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -20,10 +20,10 @@
 #include "Rect.h"
 
 #include <SkBitmap.h>
-#include <gui/Surface.h>
 
 namespace android {
 class GraphicBuffer;
+class Surface;
 namespace uirenderer {
 
 // Keep in sync with PixelCopy.java codes
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 374c1b1..d966372 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -540,12 +540,13 @@
 }
 
 // Text
-void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
-            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
-            float boundsRight, float boundsBottom, float totalAdvance) {
-    if (!glyphs || !positions || glyphCount <= 0 || paint.nothingToDraw()) return;
-    glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
-    positions = refBuffer<float>(positions, glyphCount * 2);
+void RecordingCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int glyphCount, const SkPaint& paint,
+        float x, float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+        float totalAdvance) {
+    if (glyphCount <= 0 || paint.nothingToDraw()) return;
+    uint16_t* glyphs = (glyph_t*)alloc().alloc<glyph_t>(glyphCount * sizeof(glyph_t));
+    float* positions = (float*)alloc().alloc<float>(2 * glyphCount * sizeof(float));
+    glyphFunc(glyphs, positions);
 
     // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
     addOp(alloc().create_trivial<TextOp>(
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 44181bd..ccdb4b0 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -168,9 +168,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-            const float* verts, const float* tex, const int* colors,
-            const uint16_t* indices, int indexCount, const SkPaint& paint) override
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) override
         { /* RecordingCanvas does not support drawVertices(); ignore */ }
 
     virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
@@ -191,9 +189,8 @@
     virtual bool drawTextAbsolutePos() const override { return false; }
 
 protected:
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) override;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 3e5e3bf..623b496 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -482,7 +482,7 @@
 void SkiaCanvas::drawRect(float left, float top, float right, float bottom,
         const SkPaint& paint) {
     if (CC_UNLIKELY(paint.nothingToDraw())) return;
-    mCanvas->drawRectCoords(left, top, right, bottom, paint);
+    mCanvas->drawRect({left, top, right, bottom}, paint);
 
 }
 
@@ -521,17 +521,8 @@
     mCanvas->drawPath(path, paint);
 }
 
-void SkiaCanvas::drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-                              const float* verts, const float* texs, const int* colors,
-                              const uint16_t* indices, int indexCount, const SkPaint& paint) {
-#ifndef SK_SCALAR_IS_FLOAT
-    SkDEBUGFAIL("SkScalar must be a float for these conversions to be valid");
-#endif
-    const int ptCount = vertexCount >> 1;
-    mCanvas->drawVertices(SkVertices::MakeCopy(vertexMode, ptCount, (SkPoint*)verts,
-                                               (SkPoint*)texs, (SkColor*)colors,
-                                               indexCount, indices),
-                          SkBlendMode::kModulate, paint);
+void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
+    mCanvas->drawVertices(vertices, mode, paint);
 }
 
 // ----------------------------------------------------------------------------
@@ -572,7 +563,7 @@
     if (colors) {
         flags |= SkVertices::kHasColors_BuilderFlag;
     }
-    SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, ptCount, indexCount, flags);
+    SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, ptCount, indexCount, flags);
     memcpy(builder.positions(), vertices, ptCount * sizeof(SkPoint));
     if (colors) {
         memcpy(builder.colors(), colors, ptCount * sizeof(SkColor));
@@ -685,11 +676,10 @@
 // Canvas draw operations: Text
 // ----------------------------------------------------------------------------
 
-void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int count,
-        const SkPaint& paint, float x, float y,
-        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+        float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
         float totalAdvance) {
-     if (!text || !positions || count <= 0 || paint.nothingToDraw()) return;
+    if (count <= 0 || paint.nothingToDraw()) return;
     // Set align to left for drawing, as we don't want individual
     // glyphs centered or right-aligned; the offset above takes
     // care of all alignment.
@@ -701,10 +691,7 @@
 
     SkTextBlobBuilder builder;
     const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(paintCopy, count, &bounds);
-    // TODO: we could reduce the number of memcpy's if the this were exposed further up
-    //       in the architecture.
-    memcpy(buffer.glyphs, text, count * sizeof(uint16_t));
-    memcpy(buffer.pos, positions, (count << 1) * sizeof(float));
+    glyphFunc(buffer.glyphs, buffer.pos);
 
     sk_sp<SkTextBlob> textBlob(builder.make());
     mCanvas->drawTextBlob(textBlob, 0, 0, paintCopy);
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index aeecafa..af2c23e 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -123,9 +123,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-            const float* verts, const float* tex, const int* colors,
-            const uint16_t* indices, int indexCount, const SkPaint& paint) override;
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) override;
 
     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
@@ -159,9 +157,8 @@
     void reset(SkCanvas* skiaCanvas);
     void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
 
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) override;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) override;
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index f6e92dc..34dddd1 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -183,18 +183,10 @@
 
 void SkiaCanvasProxy::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
         const SkPaint& paint) {
-    // TODO: should we pass through blendmode
     if (mFilterHwuiCalls) {
         return;
     }
-    // convert the SkPoints into floats
-    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    const int floatCount = vertices->vertexCount() << 1;
-    const float* vArray = (const float*)vertices->positions();
-    const float* tArray = (const float*)vertices->texCoords();
-    const int* cArray = (const int*)vertices->colors();
-    mCanvas->drawVertices(vertices->mode(), floatCount, vArray, tArray, cArray,
-            vertices->indices(), vertices->indexCount(), paint);
+    mCanvas->drawVertices(vertices, bmode, paint);
 }
 
 sk_sp<SkSurface> SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
@@ -286,7 +278,6 @@
     GlyphIDConverter glyphs(text, byteLength, origPaint);
 
     // compute the glyph positions
-    std::unique_ptr<SkPoint[]> pointStorage(new SkPoint[glyphs.count]);
     std::unique_ptr<SkScalar[]> glyphWidths(new SkScalar[glyphs.count]);
     glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get());
 
@@ -320,22 +311,33 @@
         xBaseline = x;
         yBaseline = y;
     }
-    pointStorage[0].set(xBaseline, yBaseline);
-
-    // setup the remaining glyph positions
-    if (glyphs.paint.isVerticalText()) {
-        for (int i = 1; i < glyphs.count; i++) {
-            pointStorage[i].set(xBaseline, glyphWidths[i-1] + pointStorage[i-1].fY);
-        }
-    } else {
-        for (int i = 1; i < glyphs.count; i++) {
-            pointStorage[i].set(glyphWidths[i-1] + pointStorage[i-1].fX, yBaseline);
-        }
-    }
 
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawGlyphs(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
-                      x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+    auto glyphFunc = [&] (uint16_t* text, float* positions) {
+        memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t));
+        size_t posIndex = 0;
+        // setup the first glyph position
+        positions[posIndex++] = xBaseline;
+        positions[posIndex++] = yBaseline;
+        // setup the remaining glyph positions
+        if (glyphs.paint.isVerticalText()) {
+            float yPosition = yBaseline;
+            for (int i = 1; i < glyphs.count; i++) {
+                positions[posIndex++] = xBaseline;
+                yPosition += glyphWidths[i-1];
+                positions[posIndex++] = yPosition;
+            }
+        } else {
+            float xPosition = xBaseline;
+            for (int i = 1; i < glyphs.count; i++) {
+                xPosition += glyphWidths[i-1];
+                positions[posIndex++] = xPosition;
+                positions[posIndex++] = yBaseline;
+            }
+        }
+    };
+    mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop,
+            bounds.fRight, bounds.fBottom, 0);
 }
 
 void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
@@ -345,21 +347,12 @@
 
     // convert to relative positions if necessary
     int x, y;
-    const SkPoint* posArray;
-    std::unique_ptr<SkPoint[]> pointStorage;
     if (mCanvas->drawTextAbsolutePos()) {
         x = 0;
         y = 0;
-        posArray = pos;
     } else {
         x = pos[0].fX;
         y = pos[0].fY;
-        pointStorage.reset(new SkPoint[glyphs.count]);
-        for (int i = 0; i < glyphs.count; i++) {
-            pointStorage[i].fX = pos[i].fX - x;
-            pointStorage[i].fY = pos[i].fY - y;
-        }
-        posArray = pointStorage.get();
     }
 
     // Compute conservative bounds.  If the content has already been processed
@@ -375,8 +368,19 @@
     }
 
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
-                      bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
+    auto glyphFunc = [&] (uint16_t* text, float* positions) {
+        memcpy(text, glyphs.glyphIDs, glyphs.count*sizeof(uint16_t));
+        if (mCanvas->drawTextAbsolutePos()) {
+            memcpy(positions, pos, 2*glyphs.count*sizeof(float));
+        } else {
+            for (int i = 0, posIndex = 0; i < glyphs.count; i++) {
+                positions[posIndex++] = pos[i].fX - x;
+                positions[posIndex++] = pos[i].fY - y;
+            }
+        }
+    };
+    mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop,
+            bounds.fRight, bounds.fBottom, 0);
 }
 
 void SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
@@ -456,19 +460,13 @@
     if (mFilterHwuiCalls) {
         return;
     }
-    SkPatchUtils::VertexData data;
-
     SkMatrix matrix;
     mCanvas->getMatrix(&matrix);
     SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix);
 
-    // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
-    // If it fails to generate the vertices, then we do not draw.
-    if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
-        this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
-                           data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
-                           paint);
-    }
+    mCanvas->drawVertices(SkPatchUtils::MakeVertices(cubics, colors, texCoords,
+                                                     lod.width(), lod.height()).get(),
+                          bmode, paint);
 }
 
 void SkiaCanvasProxy::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle) {
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 959059f..4ef31d5 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -120,6 +120,10 @@
 void Texture::upload(GLint internalFormat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
     GL_CHECKPOINT(MODERATE);
+
+    // We don't have color space information, we assume the data is gamma encoded
+    mIsLinear = false;
+
     bool needsAlloc = updateLayout(width, height, internalFormat, format, GL_TEXTURE_2D);
     if (!mId) {
         glGenTextures(1, &mId);
@@ -309,11 +313,16 @@
     bool rgba16fNeedsConversion = bitmap.colorType() == kRGBA_F16_SkColorType
             && internalFormat != GL_RGBA16F;
 
+    // RGBA16F is always linear extended sRGB
+    if (internalFormat == GL_RGBA16F) {
+        mIsLinear = true;
+    }
+
     mConnector.reset();
 
-    // RGBA16F is always extended sRGB, alpha masks don't have color profiles
+    // Alpha masks don't have color profiles
     // If an RGBA16F bitmap needs conversion, we know the target will be sRGB
-    if (internalFormat != GL_RGBA16F && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
+    if (!mIsLinear && internalFormat != GL_ALPHA && !rgba16fNeedsConversion) {
         SkColorSpace* colorSpace = bitmap.info().colorSpace();
         // If the bitmap is sRGB we don't need conversion
         if (colorSpace != nullptr && !colorSpace->isSRGB()) {
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 55b74ed..7f742e6 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -88,7 +88,8 @@
      * The image data is undefined after calling this.
      */
     void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
-        upload(internalFormat, width, height, format, GL_UNSIGNED_BYTE, nullptr);
+        upload(internalFormat, width, height, format,
+                internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr);
     }
 
     /**
@@ -155,7 +156,7 @@
      * Returns true if this texture uses a linear encoding format.
      */
     constexpr bool isLinear() const {
-        return mInternalFormat == GL_RGBA16F;
+        return mIsLinear;
     }
 
     /**
@@ -219,6 +220,9 @@
     GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
     GLenum mMagFilter = GL_LINEAR;
 
+    // Indicates whether the content of the texture is in linear space
+    bool mIsLinear = false;
+
     Caches& mCaches;
 
     std::unique_ptr<ColorSpaceConnector> mConnector;
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 8823a92..f6b2912 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -491,6 +491,36 @@
     return *mCache.bitmap;
 }
 
+void Tree::updateCache(sk_sp<SkSurface> surface) {
+    if (surface.get()) {
+        mCache.surface = surface;
+    }
+    if (surface.get() || mCache.dirty) {
+        SkSurface* vdSurface = mCache.surface.get();
+        SkCanvas* canvas = vdSurface->getCanvas();
+        float scaleX = vdSurface->width() / mProperties.getViewportWidth();
+        float scaleY = vdSurface->height() / mProperties.getViewportHeight();
+        SkAutoCanvasRestore acr(canvas, true);
+        canvas->clear(SK_ColorTRANSPARENT);
+        canvas->scale(scaleX, scaleY);
+        mRootNode->draw(canvas, false);
+        mCache.dirty = false;
+        canvas->flush();
+    }
+}
+
+void Tree::draw(SkCanvas* canvas) {
+   /*
+    * TODO address the following...
+    *
+    * 1) figure out how to set path's as volatile during animation
+    * 2) if mRoot->getPaint() != null either promote to layer (during
+    *    animation) or cache in SkSurface (for static content)
+    */
+    canvas->drawImageRect(mCache.surface->makeImageSnapshot().get(),
+        mutateProperties()->getBounds(), getPaint());
+}
+
 void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
     SkBitmap outCache;
     bitmap.getSkBitmap(&outCache);
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 729a4dd..22cfe29 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,6 +31,7 @@
 #include <SkPathMeasure.h>
 #include <SkRect.h>
 #include <SkShader.h>
+#include <SkSurface.h>
 
 #include <cutils/compiler.h>
 #include <stddef.h>
@@ -677,15 +678,37 @@
     // This should only be called from animations on RT
     TreeProperties* mutateProperties() { return &mProperties; }
 
+    // called from RT only
+    const TreeProperties& properties() const { return mProperties; }
+
     // This should always be called from RT.
     void markDirty() { mCache.dirty = true; }
     bool isDirty() const { return mCache.dirty; }
     bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; }
     void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }
 
+    // Returns true if VD cache surface is big enough. This should always be called from RT and it
+    // works with Skia pipelines only.
+    bool canReuseSurface() {
+        SkSurface* surface = mCache.surface.get();
+        return surface && surface->width() >= mProperties.getScaledWidth()
+              && surface->height() >= mProperties.getScaledHeight();
+    }
+
+    // Draws VD cache into a canvas. This should always be called from RT and it works with Skia
+    // pipelines only.
+    void draw(SkCanvas* canvas);
+
+    // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must
+    // contain a new surface. This should always be called from RT and it works with Skia pipelines
+    // only.
+    void updateCache(sk_sp<SkSurface> surface);
+
 private:
     struct Cache {
-        sk_sp<Bitmap> bitmap;
+        sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software
+        //TODO: use surface instead of bitmap when drawing in software canvas
+        sk_sp<SkSurface> surface; //used only by Skia pipelines
         bool dirty = true;
     };
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index bb1e674..6dde005 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -26,16 +26,12 @@
 #include <log/log.h>
 #include <cutils/ashmem.h>
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
 #include <private/gui/ComposerService.h>
 #include <binder/IServiceManager.h>
 #include <ui/PixelFormat.h>
 
 #include <SkCanvas.h>
+#include <SkImagePriv.h>
 
 namespace android {
 
@@ -51,9 +47,9 @@
 }
 
 typedef sk_sp<Bitmap> (*AllocPixeRef)(size_t allocSize, const SkImageInfo& info, size_t rowBytes,
-        SkColorTable* ctable);
+        sk_sp<SkColorTable> ctable);
 
-static sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, SkColorTable* ctable, AllocPixeRef alloc) {
+static sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable, AllocPixeRef alloc) {
     const SkImageInfo& info = bitmap->info();
     if (info.colorType() == kUnknown_SkColorType) {
         LOG_ALWAYS_FATAL("unknown bitmap configuration");
@@ -69,201 +65,32 @@
         return nullptr;
     }
 
-    auto wrapper = alloc(size, info, rowBytes, ctable);
+    auto wrapper = alloc(size, info, rowBytes, std::move(ctable));
     if (wrapper) {
         wrapper->getSkBitmap(bitmap);
-        // since we're already allocated, we lockPixels right away
-        // HeapAllocator behaves this way too
-        bitmap->lockPixels();
     }
     return wrapper;
 }
 
-sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
-   return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
+sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable) {
+   return allocateBitmap(bitmap, std::move(ctable), &Bitmap::allocateAshmemBitmap);
 }
 
 static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
-        SkColorTable* ctable) {
+        sk_sp<SkColorTable> ctable) {
     void* addr = calloc(size, 1);
     if (!addr) {
         return nullptr;
     }
-    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
-}
-
-#define FENCE_TIMEOUT 2000000000
-
-// TODO: handle SRGB sanely
-static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
-    switch (internalFormat) {
-    case GL_LUMINANCE:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_SRGB8_ALPHA8:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_RGBA:
-        return PIXEL_FORMAT_RGBA_8888;
-    case GL_RGB:
-        return PIXEL_FORMAT_RGB_565;
-    case GL_RGBA16F:
-        return PIXEL_FORMAT_RGBA_FP16;
-    default:
-        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
-        return PIXEL_FORMAT_UNKNOWN;
-    }
-}
-
-class AutoEglFence {
-public:
-    AutoEglFence(EGLDisplay display)
-            : mDisplay(display) {
-        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
-    }
-
-    ~AutoEglFence() {
-        if (fence != EGL_NO_SYNC_KHR) {
-            eglDestroySyncKHR(mDisplay, fence);
-        }
-    }
-
-    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoEglImage {
-public:
-    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
-            : mDisplay(display) {
-        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
-                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
-    }
-
-    ~AutoEglImage() {
-        if (image != EGL_NO_IMAGE_KHR) {
-            eglDestroyImageKHR(mDisplay, image);
-        }
-    }
-
-    EGLImageKHR image = EGL_NO_IMAGE_KHR;
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoGlTexture {
-public:
-    AutoGlTexture(uirenderer::Caches& caches)
-            : mCaches(caches) {
-        glGenTextures(1, &mTexture);
-        caches.textureState().bindTexture(mTexture);
-    }
-
-    ~AutoGlTexture() {
-        mCaches.textureState().deleteTexture(mTexture);
-    }
-
-private:
-    uirenderer::Caches& mCaches;
-    GLuint mTexture = 0;
-};
-
-static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
-        GraphicBuffer& buffer, GLint format, GLint type) {
-    SkAutoLockPixels alp(bitmap);
-    EGLDisplay display = eglGetCurrentDisplay();
-    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
-                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
-                uirenderer::renderthread::EglManager::eglErrorString());
-    // We use an EGLImage to access the content of the GraphicBuffer
-    // The EGL image is later bound to a 2D texture
-    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
-    AutoEglImage autoImage(display, clientBuffer);
-    if (autoImage.image == EGL_NO_IMAGE_KHR) {
-        ALOGW("Could not create EGL image, err =%s",
-                uirenderer::renderthread::EglManager::eglErrorString());
-        return false;
-    }
-    AutoGlTexture glTexture(caches);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
-
-    GL_CHECKPOINT(MODERATE);
-
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
-            format, type, bitmap.getPixels());
-
-    GL_CHECKPOINT(MODERATE);
-
-    // The fence is used to wait for the texture upload to finish
-    // properly. We cannot rely on glFlush() and glFinish() as
-    // some drivers completely ignore these API calls
-    AutoEglFence autoFence(display);
-    if (autoFence.fence == EGL_NO_SYNC_KHR) {
-        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
-        return false;
-    }
-    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
-    // pipeline flush (similar to what a glFlush() would do.)
-    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
-            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
-    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
-        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
-        return false;
-    }
-    return true;
-}
-
-sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
-        SkBitmap& skBitmap) {
-    renderThread.eglManager().initialize();
-    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
-
-    const SkImageInfo& info = skBitmap.info();
-    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
-        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
-        return nullptr;
-    }
-
-    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
-    bool hasLinearBlending = caches.extensions().hasLinearBlending();
-    GLint format, type, internalFormat;
-    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
-            needSRGB && hasLinearBlending, &internalFormat, &format, &type);
-
-    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
-    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
-            GraphicBuffer::USAGE_HW_TEXTURE |
-            GraphicBuffer::USAGE_SW_WRITE_NEVER |
-            GraphicBuffer::USAGE_SW_READ_NEVER,
-            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
-
-    status_t error = buffer->initCheck();
-    if (error < 0) {
-        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
-        return nullptr;
-    }
-
-    SkBitmap bitmap;
-    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
-            hasLinearBlending))) {
-        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
-        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
-    } else {
-        bitmap = skBitmap;
-    }
-
-    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
-        return nullptr;
-    }
-    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, std::move(ctable)));
 }
 
 sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
     return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
 }
 
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
-   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable) {
+   return allocateBitmap(bitmap, std::move(ctable), &android::allocateHeapBitmap);
 }
 
 sk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
@@ -276,7 +103,7 @@
 }
 
 sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
-        size_t rowBytes, SkColorTable* ctable) {
+        size_t rowBytes, sk_sp<SkColorTable> ctable) {
     // Create new ashmem region with read/write priv
     int fd = ashmem_create_region("bitmap", size);
     if (fd < 0) {
@@ -294,20 +121,18 @@
         close(fd);
         return nullptr;
     }
-    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
+    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, std::move(ctable)));
 }
 
 void FreePixelRef(void* addr, void* context) {
     auto pixelRef = (SkPixelRef*) context;
-    pixelRef->unlockPixels();
     pixelRef->unref();
 }
 
 sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
     pixelRef.ref();
-    pixelRef.lockPixels();
     return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
-            info, pixelRef.rowBytes(), pixelRef.colorTable()));
+            info, pixelRef.rowBytes(), sk_ref_sp(pixelRef.colorTable())));
 }
 
 sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
@@ -323,76 +148,87 @@
 }
 
 void Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
-    // TODO: See todo in reconfigure() below
-    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
-    *myInfo = info().makeColorSpace(std::move(colorSpace));
+    mInfo = mInfo.makeColorSpace(std::move(colorSpace));
 }
 
-void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
-    if (kIndex_8_SkColorType != newInfo.colorType()) {
-        ctable = nullptr;
-    }
-    mRowBytes = rowBytes;
-    if (mColorTable.get() != ctable) {
-        mColorTable.reset(SkSafeRef(ctable));
-    }
-
+static SkImageInfo validateAlpha(const SkImageInfo& info) {
     // Need to validate the alpha type to filter against the color type
     // to prevent things like a non-opaque RGB565 bitmap
     SkAlphaType alphaType;
     LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
-            newInfo.colorType(), newInfo.alphaType(), &alphaType),
+            info.colorType(), info.alphaType(), &alphaType),
             "Failed to validate alpha type!");
+    return info.makeAlphaType(alphaType);
+}
+
+void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, sk_sp<SkColorTable> ctable) {
+    if (kIndex_8_SkColorType != newInfo.colorType()) {
+        ctable = nullptr;
+    }
+
+    mInfo = validateAlpha(newInfo);
 
     // Dirty hack is dirty
     // TODO: Figure something out here, Skia's current design makes this
     // really hard to work with. Skia really, really wants immutable objects,
     // but with the nested-ref-count hackery going on that's just not
     // feasible without going insane trying to figure it out
-    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
-    *myInfo = newInfo;
-    changeAlphaType(alphaType);
-
-    // Docs say to only call this in the ctor, but we're going to call
-    // it anyway even if this isn't always the ctor.
-    // TODO: Fix this too as part of the above TODO
-    setPreLocked(getStorage(), mRowBytes, mColorTable.get());
+    this->android_only_reset(mInfo.width(), mInfo.height(), rowBytes, std::move(ctable));
 }
 
-Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+static sk_sp<SkColorTable> sanitize(const SkImageInfo& info, sk_sp<SkColorTable> ctable) {
+    if (info.colorType() == kIndex_8_SkColorType) {
+        SkASSERT(ctable);
+        return ctable;
+    }
+    return nullptr; // drop the ctable if we're not indexed
+}
+Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes,
+        sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::Heap) {
     mPixelStorage.heap.address = address;
     mPixelStorage.heap.size = size;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(void* address, void* context, FreeFunc freeFunc,
-                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+                const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::External) {
     mPixelStorage.external.address = address;
     mPixelStorage.external.context = context;
     mPixelStorage.external.freeFunc = freeFunc;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(void* address, int fd, size_t mappedSize,
-                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
-            : SkPixelRef(info)
+                const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable)
+            : SkPixelRef(info.width(), info.height(), address, rowBytes,
+                    sanitize(info, std::move(ctable)))
+            , mInfo(validateAlpha(info))
             , mPixelStorageType(PixelStorageType::Ashmem) {
     mPixelStorage.ashmem.address = address;
     mPixelStorage.ashmem.fd = fd;
     mPixelStorage.ashmem.size = mappedSize;
-    reconfigure(info, rowBytes, ctable);
 }
 
 Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info)
-        : SkPixelRef(info)
+        : SkPixelRef(info.width(), info.height(), nullptr,
+                     bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride(),
+                     nullptr)
+        , mInfo(validateAlpha(info))
         , mPixelStorageType(PixelStorageType::Hardware) {
     mPixelStorage.hardware.buffer = buffer;
     buffer->incStrong(buffer);
-    mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride();
+    setImmutable(); // HW bitmaps are always immutable
+    if (uirenderer::Properties::isSkiaEnabled()) {
+        // TODO: add color correctness for Skia pipeline - pass null color space for now
+        mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer),
+                mInfo.alphaType(), nullptr);
+    }
 }
 
 Bitmap::~Bitmap() {
@@ -440,17 +276,6 @@
     }
 }
 
-bool Bitmap::onNewLockPixels(LockRec* rec) {
-    rec->fPixels = getStorage();
-    rec->fRowBytes = mRowBytes;
-    rec->fColorTable = mColorTable.get();
-    return true;
-}
-
-size_t Bitmap::getAllocatedSizeInBytes() const {
-    return info().getSafeSize(mRowBytes);
-}
-
 int Bitmap::getAshmemFd() const {
     switch (mPixelStorageType) {
     case PixelStorageType::Ashmem:
@@ -478,7 +303,7 @@
         return;
     }
 
-    changeAlphaType(alphaType);
+    mInfo = mInfo.makeAlphaType(alphaType);
 }
 
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
@@ -494,23 +319,13 @@
         uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
         return;
     }
-    outBitmap->setInfo(info(), rowBytes());
-    outBitmap->setPixelRef(this);
-}
-
-void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
-    if (isHardware() && uirenderer::Properties::isSkiaEnabled()) {
-        getSkBitmap(outBitmap);
-    } else {
-        outBitmap->setInfo(info(), rowBytes());
-        outBitmap->setPixelRef(this);
-        outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
-    }
+    outBitmap->setInfo(mInfo, rowBytes());
+    outBitmap->setPixelRef(sk_ref_sp(this), 0, 0);
 }
 
 void Bitmap::getBounds(SkRect* bounds) const {
     SkASSERT(bounds);
-    bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
+    bounds->set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
 }
 
 GraphicBuffer* Bitmap::graphicBuffer() {
@@ -520,4 +335,20 @@
     return nullptr;
 }
 
+sk_sp<SkImage> Bitmap::makeImage() {
+    sk_sp<SkImage> image = mImage;
+    if (!image) {
+        SkASSERT(!(isHardware() && uirenderer::Properties::isSkiaEnabled()));
+        SkBitmap skiaBitmap;
+        skiaBitmap.setInfo(info(), rowBytes());
+        skiaBitmap.setPixelRef(sk_ref_sp(this), 0, 0);
+        skiaBitmap.setHasHardwareMipMap(mHasHardwareMipMap);
+        // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap
+        // internally and ~Bitmap won't be invoked.
+        // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here.
+        image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
+    }
+    return image;
+}
+
 } // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index da45f76..364240670 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -18,10 +18,12 @@
 #include <SkBitmap.h>
 #include <SkColorSpace.h>
 #include <SkColorTable.h>
+#include <SkImage.h>
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
 #include <cutils/compiler.h>
 #include <ui/GraphicBuffer.h>
+#include <SkImage.h>
 
 namespace android {
 
@@ -44,66 +46,54 @@
 
 class ANDROID_API Bitmap : public SkPixelRef {
 public:
-    static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
+    static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable);
     static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
 
     static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
 
-    static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
+    static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, sk_sp<SkColorTable> ctable);
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
-        size_t rowBytes, SkColorTable* ctable);
+        size_t rowBytes, sk_sp<SkColorTable> ctable);
 
     static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer);
 
     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
 
-    static sk_sp<Bitmap> allocateHardwareBitmap(uirenderer::renderthread::RenderThread&,
-            SkBitmap& bitmap);
-
     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
-            SkColorTable* ctable);
+            sk_sp<SkColorTable> ctable);
     Bitmap(void* address, void* context, FreeFunc freeFunc,
-            const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
+            const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable);
     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
-            size_t rowBytes, SkColorTable* ctable);
-
-    int width() const { return info().width(); }
-    int height() const { return info().height(); }
-
-    // Can't mark as override since SkPixelRef::rowBytes isn't virtual
-    // but that's OK since we just want Bitmap to be able to rely
-    // on calling rowBytes() on an unlocked pixelref, which it will be
-    // doing on a Bitmap type, not a SkPixelRef, so static
-    // dispatching will do what we want.
-    size_t rowBytes() const { return mRowBytes; }
+            size_t rowBytes, sk_sp<SkColorTable> ctable);
+    Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
 
     int rowBytesAsPixels() const {
-        return mRowBytes >> info().shiftPerPixel();
+        return rowBytes() >> SkColorTypeShiftPerPixel(mInfo.colorType());
     }
 
-    void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
+    void reconfigure(const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable);
     void reconfigure(const SkImageInfo& info);
     void setColorSpace(sk_sp<SkColorSpace> colorSpace);
     void setAlphaType(SkAlphaType alphaType);
 
     void getSkBitmap(SkBitmap* outBitmap);
 
-    // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
-    // so it would crash if anyone tries to render this bitmap.
-    void getSkBitmapForShaders(SkBitmap* outBitmap);
-
     int getAshmemFd() const;
     size_t getAllocationByteCount() const;
 
     void setHasHardwareMipMap(bool hasMipMap);
     bool hasHardwareMipMap() const;
 
-    bool isOpaque() const {return info().isOpaque(); }
-    SkColorType colorType() const { return info().colorType(); }
+    bool isOpaque() const { return mInfo.isOpaque(); }
+    SkColorType colorType() const { return mInfo.colorType(); }
+    const SkImageInfo& info() const {
+        return mInfo;
+    }
+
     void getBounds(SkRect* bounds) const;
 
     bool readyToDraw() const {
-        return this->colorType() != kIndex_8_SkColorType || mColorTable;
+        return this->colorType() != kIndex_8_SkColorType || this->colorTable();
     }
 
     bool isHardware() const {
@@ -111,19 +101,18 @@
     }
 
     GraphicBuffer* graphicBuffer();
-protected:
-    virtual bool onNewLockPixels(LockRec* rec) override;
-    virtual void onUnlockPixels() override { };
-    virtual size_t getAllocatedSizeInBytes() const override;
+
+    // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread.
+    // Caching is supported only for HW Bitmaps with skia pipeline.
+    sk_sp<SkImage> makeImage();
 private:
-    Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
     virtual ~Bitmap();
     void* getStorage() const;
 
-    PixelStorageType mPixelStorageType;
+    SkImageInfo mInfo;
 
-    size_t mRowBytes = 0;
-    sk_sp<SkColorTable> mColorTable;
+    const PixelStorageType mPixelStorageType;
+
     bool mHasHardwareMipMap = false;
 
     union {
@@ -145,6 +134,8 @@
             GraphicBuffer* buffer;
         } hardware;
     } mPixelStorage;
+
+    sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline.
 };
 
-} //namespace android
\ No newline at end of file
+} //namespace android
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index c64a89d..679cb50 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -80,13 +80,11 @@
 
 class DrawTextFunctor {
 public:
-    DrawTextFunctor(const minikin::Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos,
+    DrawTextFunctor(const minikin::Layout& layout, Canvas* canvas,
             const SkPaint& paint, float x, float y, minikin::MinikinRect& bounds,
             float totalAdvance)
         : layout(layout)
         , canvas(canvas)
-        , glyphs(glyphs)
-        , pos(pos)
         , paint(paint)
         , x(x)
         , y(y)
@@ -95,19 +93,21 @@
     }
 
     void operator()(size_t start, size_t end) {
-        if (canvas->drawTextAbsolutePos()) {
-            for (size_t i = start; i < end; i++) {
-                glyphs[i] = layout.getGlyphId(i);
-                pos[2 * i] = x + layout.getX(i);
-                pos[2 * i + 1] = y + layout.getY(i);
+        auto glyphFunc = [&] (uint16_t* text, float* positions) {
+            if (canvas->drawTextAbsolutePos()) {
+                for (size_t i = start, textIndex = 0, posIndex = 0; i < end; i++) {
+                    text[textIndex++] = layout.getGlyphId(i);
+                    positions[posIndex++] = x + layout.getX(i);
+                    positions[posIndex++] = y + layout.getY(i);
+                }
+            } else {
+                for (size_t i = start, textIndex = 0, posIndex = 0; i < end; i++) {
+                    text[textIndex++] = layout.getGlyphId(i);
+                    positions[posIndex++] = layout.getX(i);
+                    positions[posIndex++] = layout.getY(i);
+                }
             }
-        } else {
-            for (size_t i = start; i < end; i++) {
-                glyphs[i] = layout.getGlyphId(i);
-                pos[2 * i] = layout.getX(i);
-                pos[2 * i + 1] = layout.getY(i);
-            }
-        }
+        };
 
         size_t glyphCount = end - start;
 
@@ -121,26 +121,24 @@
             SkPaint outlinePaint(paint);
             simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
             outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, outlinePaint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
 
             // inner
             SkPaint innerPaint(paint);
             simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint);
             innerPaint.setStyle(SkPaint::kFill_Style);
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, innerPaint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
         } else {
             // standard draw path
-            canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, paint, x, y,
-                    bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
+            canvas->drawGlyphs(glyphFunc, glyphCount, paint, x, y, bounds.mLeft, bounds.mTop,
+                    bounds.mRight, bounds.mBottom, totalAdvance);
         }
     }
 private:
     const minikin::Layout& layout;
     Canvas* canvas;
-    uint16_t* glyphs;
-    float* pos;
     const SkPaint& paint;
     float x;
     float y;
@@ -156,10 +154,6 @@
     minikin::Layout layout = MinikinUtils::doLayout(
             &paint, bidiFlags, typeface, text, start, count, contextCount);
 
-    size_t nGlyphs = layout.nGlyphs();
-    std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]);
-    std::unique_ptr<float[]> pos(new float[nGlyphs * 2]);
-
     x += MinikinUtils::xOffsetForTextAlign(&paint, layout);
 
     minikin::MinikinRect bounds;
@@ -173,8 +167,7 @@
     // care of all alignment.
     paint.setTextAlign(Paint::kLeft_Align);
 
-    DrawTextFunctor f(layout, this, glyphs.get(), pos.get(),
-            paint, x, y, bounds, layout.getAdvance());
+    DrawTextFunctor f(layout, this, paint, x, y, bounds, layout.getAdvance());
     MinikinUtils::forFontRun(layout, &paint, f);
 }
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 86af678..ac8a081 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -28,6 +28,7 @@
 #include <SkMatrix.h>
 
 class SkCanvasState;
+class SkVertices;
 
 namespace minikin {
     class Layout;
@@ -67,6 +68,8 @@
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
+typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
+
 class Bitmap;
 class Paint;
 struct Typeface;
@@ -228,9 +231,7 @@
     virtual void drawArc(float left, float top, float right, float bottom,
             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) = 0;
     virtual void drawPath(const SkPath& path, const SkPaint& paint) = 0;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-                              const float* verts, const float* tex, const int* colors,
-                              const uint16_t* indices, int indexCount, const SkPaint& paint) = 0;
+    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) = 0;
 
     // Bitmap-based
     virtual void drawBitmap(Bitmap& bitmap, float left, float top,
@@ -274,12 +275,12 @@
     void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
 
     /**
+     * glyphFunc: valid only for the duration of the call and should not be cached.
      * drawText: count is of glyphs
      * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
      */
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
+            float y, float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
             float totalAdvance) = 0;
     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
             const SkPaint& paint, const SkPath& path, size_t start, size_t end) = 0;
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 68a0869..975f849 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -21,7 +21,6 @@
 
 #include <SkBlurMask.h>
 #include <SkBlurMaskFilter.h>
-#include <SkGaussianEdgeShader.h>
 #include <SkPathOps.h>
 #include <SkRRectsGaussianEdgeMaskFilter.h>
 #include <SkShadowUtils.h>
@@ -137,7 +136,6 @@
 
     float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha;
     float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha;
-    const float casterZValue = casterProperties.getZ();
 
     const RevealClip& revealClip = casterProperties.getRevealClip();
     const SkPath* revealClipPath = revealClip.getPath();
@@ -178,6 +176,7 @@
     // intersect the shadow-casting path with the reveal, if present
     if (revealClipPath) {
         Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
 
@@ -186,36 +185,23 @@
         SkPath clipBoundsPath;
         clipBoundsPath.addRect(casterClipRect);
         Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
     const Vector3 lightPos = SkiaPipeline::getLightCenter();
     SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
-    if (shadowMatrix.hasPerspective() || revealClipPath || clippedToBounds) {
-        std::function<SkScalar(SkScalar, SkScalar)> casterHeightFunc;
-        if (shadowMatrix.hasPerspective()) {
-            // get the matrix with the full 3D transform
-            mat4 zMatrix;
-            caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
-            SkScalar A = zMatrix[2];
-            SkScalar B = zMatrix[6];
-            SkScalar C = zMatrix[mat4::kTranslateZ];
-            casterHeightFunc = [A, B, C](SkScalar x, SkScalar y) {
-                return A*x + B*y + C;  // casterZValue already baked into C
-            };
-        } else {
-            casterHeightFunc = [casterZValue] (SkScalar, SkScalar) {
-                return casterZValue;
-            };
-        }
-
-        SkShadowUtils::DrawUncachedShadow(canvas, *casterPath, casterHeightFunc, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+    SkPoint3 zParams;
+    if (shadowMatrix.hasPerspective()) {
+        // get the matrix with the full 3D transform
+        mat4 zMatrix;
+        caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
+        zParams = SkPoint3::Make(zMatrix[2], zMatrix[6], zMatrix[mat4::kTranslateZ]);
     } else {
-        SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+        zParams = SkPoint3::Make(0, 0, casterProperties.getZ());
     }
+    SkShadowUtils::DrawShadow(canvas, *casterPath, zParams, skiaLightPos,
+        SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
+        casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 496f7ba..3ddc09f 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -19,6 +19,7 @@
 #include "renderthread/CanvasContext.h"
 #include "VectorDrawable.h"
 #include "DumpOpsCanvas.h"
+#include "SkiaPipeline.h"
 
 #include <SkImagePriv.h>
 
@@ -92,6 +93,8 @@
         // If any vector drawable in the display list needs update, damage the node.
         if (vectorDrawable->isDirty()) {
             isDirty = true;
+            static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
+                ->getVectorDrawables()->push_back(vectorDrawable);
         }
         vectorDrawable->setPropertyChangeWillBeConsumed(true);
     }
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 6ee5922..66375d1 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -60,7 +60,7 @@
      * Use the linear allocator to create any SkDrawables needed by the display
      * list. This could be dangerous as these objects are ref-counted, so we
      * need to monitor that they don't extend beyond the lifetime of the class
-     * that creates them.
+     * that creates them. Allocator dtor invokes all SkDrawable dtors.
      */
     template<class T, typename... Params>
     SkDrawable* allocateDrawable(Params&&... params) {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index ae13131..6d5ef1d 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -16,6 +16,7 @@
 
 #include "SkiaOpenGLPipeline.h"
 
+#include "hwui/Bitmap.h"
 #include "DeferredLayerUpdater.h"
 #include "GlLayer.h"
 #include "LayerDrawable.h"
@@ -60,7 +61,7 @@
         const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector<sp<RenderNode>>& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -84,7 +85,8 @@
             mRenderThread.getGrContext(), renderTargetDesc, &props));
 
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
+            contentDrawBounds, surface);
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
@@ -155,7 +157,8 @@
     }
 }
 
-bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+        ColorMode colorMode) {
 
     if (mEglSurface != EGL_NO_SURFACE) {
         mEglManager.destroySurface(mEglSurface);
@@ -163,7 +166,8 @@
     }
 
     if (surface) {
-        mEglSurface = mEglManager.createSurface(surface);
+        const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+        mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
 
     if (mEglSurface != EGL_NO_SURFACE) {
@@ -197,6 +201,186 @@
     }
 }
 
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+    AutoEglFence(EGLDisplay display)
+            : mDisplay(display) {
+        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+    }
+
+    ~AutoEglFence() {
+        if (fence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, fence);
+        }
+    }
+
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+            : mDisplay(display) {
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+    }
+
+    ~AutoEglImage() {
+        if (image != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mDisplay, image);
+        }
+    }
+
+    EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoSkiaGlTexture {
+public:
+    AutoSkiaGlTexture() {
+        glGenTextures(1, &mTexture);
+        glBindTexture(GL_TEXTURE_2D, mTexture);
+    }
+
+    ~AutoSkiaGlTexture() {
+        glDeleteTextures(1, &mTexture);
+    }
+
+private:
+    GLuint mTexture = 0;
+};
+
+sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    renderThread.eglManager().initialize();
+
+    sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
+    const SkImageInfo& info = skBitmap.info();
+    PixelFormat pixelFormat;
+    GLint format, type;
+    bool isSupported = false;
+
+    //TODO: add support for linear blending (when ANDROID_ENABLE_LINEAR_BLENDING is defined)
+    switch (info.colorType()) {
+    case kRGBA_8888_SkColorType:
+        isSupported = true;
+    // ARGB_4444 and Index_8 are both upconverted to RGBA_8888
+    case kIndex_8_SkColorType:
+    case kARGB_4444_SkColorType:
+        pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        format = GL_RGBA;
+        type = GL_UNSIGNED_BYTE;
+        break;
+    case kRGBA_F16_SkColorType:
+        isSupported = grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig);
+        if (isSupported) {
+            type = GL_HALF_FLOAT;
+            pixelFormat = PIXEL_FORMAT_RGBA_FP16;
+        } else {
+            type = GL_UNSIGNED_BYTE;
+            pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        }
+        format = GL_RGBA;
+        break;
+    case kRGB_565_SkColorType:
+        isSupported = true;
+        pixelFormat = PIXEL_FORMAT_RGB_565;
+        format = GL_RGB;
+        type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case kGray_8_SkColorType:
+        isSupported = true;
+        pixelFormat = PIXEL_FORMAT_RGBA_8888;
+        format = GL_LUMINANCE;
+        type = GL_UNSIGNED_BYTE;
+        break;
+    default:
+        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+        return nullptr;
+    }
+
+    SkBitmap bitmap;
+    if (isSupported) {
+        bitmap = skBitmap;
+    } else {
+        bitmap.allocPixels(SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(),
+                nullptr));
+        bitmap.eraseColor(0);
+        if (info.colorType() == kRGBA_F16_SkColorType) {
+            // Drawing RGBA_F16 onto ARGB_8888 is not supported
+            skBitmap.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
+                    bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
+        } else {
+            SkCanvas canvas(bitmap);
+            canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
+        }
+    }
+
+    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("Bitmap::allocateSkiaHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    //upload the bitmap into a texture
+    EGLDisplay display = eglGetCurrentDisplay();
+    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+    // We use an EGLImage to access the content of the GraphicBuffer
+    // The EGL image is later bound to a 2D texture
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer();
+    AutoEglImage autoImage(display, clientBuffer);
+    if (autoImage.image == EGL_NO_IMAGE_KHR) {
+        ALOGW("Could not create EGL image, err =%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+        return nullptr;
+    }
+    AutoSkiaGlTexture glTexture;
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+    GL_CHECKPOINT(MODERATE);
+
+    // glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we provide.
+    // But asynchronous in sense that driver may upload texture onto hardware buffer when we first
+    // use it in drawing
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info.width(), info.height(), format, type,
+            bitmap.getPixels());
+    GL_CHECKPOINT(MODERATE);
+
+    // The fence is used to wait for the texture upload to finish
+    // properly. We cannot rely on glFlush() and glFinish() as
+    // some drivers completely ignore these API calls
+    AutoEglFence autoFence(display);
+    if (autoFence.fence == EGL_NO_SYNC_KHR) {
+        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+        return nullptr;
+    }
+    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+    // pipeline flush (similar to what a glFlush() would do.)
+    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+        return nullptr;
+    }
+
+    grContext->resetContext(kTextureBinding_GrGLBackendState);
+
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
 } /* namespace skiapipeline */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 36685dd..aa29c8e 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -19,6 +19,9 @@
 #include "SkiaPipeline.h"
 
 namespace android {
+
+class Bitmap;
+
 namespace uirenderer {
 namespace skiapipeline {
 
@@ -32,7 +35,7 @@
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -40,12 +43,15 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+            renderthread::ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     renderthread::EglManager& mEglManager;
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index a18d264..89697d7 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -63,8 +63,6 @@
     CopyResult copyResult = CopyResult::UnknownError;
     sk_sp<SkImage> image(SkImage::MakeFromAdoptedTexture(grContext.get(), textureDescription));
     if (image) {
-        SkAutoLockPixels alp(*bitmap);
-
         // convert to Skia data structures
         const SkRect bufferRect = SkRect::MakeIWH(imgWidth, imgHeight);
         SkRect skiaSrcRect = srcRect.toSkRect();
@@ -88,23 +86,17 @@
         textureMatrix.mapRect(&skiaSrcRect);
 
         if (skiaSrcRect.intersect(bufferRect)) {
-            SkPoint srcOrigin = SkPoint::Make(skiaSrcRect.fLeft, skiaSrcRect.fTop);
+            // we render in an offscreen buffer to scale and to avoid an issue b/62262733
+            // with reading incorrect data from EGLImage backed SkImage (likely a driver bug)
+            sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
+                    grContext.get(), SkBudgeted::kYes, bitmap->info());
+            SkPaint paint;
+            paint.setBlendMode(SkBlendMode::kSrc);
+            scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
+                    SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
+            image = scaledSurface->makeImageSnapshot();
 
-            // if we need to scale the result we must render to an offscreen buffer
-            if (bitmap->width() != skiaSrcRect.width()
-                    || bitmap->height() != skiaSrcRect.height()) {
-                sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
-                        grContext.get(), SkBudgeted::kYes, bitmap->info());
-                SkPaint paint;
-                paint.setBlendMode(SkBlendMode::kSrc);
-                scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
-                        SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
-                image = scaledSurface->makeImageSnapshot();
-                srcOrigin.set(0,0);
-            }
-
-            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
-                                  srcOrigin.fX, srcOrigin.fY)) {
+            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) {
                 copyResult = CopyResult::Success;
             }
         }
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 10c1865..0bab793 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -25,6 +25,7 @@
 #include <SkPictureRecorder.h>
 #include <SkPixelSerializer.h>
 #include <SkStream.h>
+#include "VectorDrawable.h"
 
 #include <unistd.h>
 
@@ -40,15 +41,16 @@
 
 Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
 
-SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) { }
+SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) {
+    mVectorDrawables.reserve(30);
+}
 
 TaskManager* SkiaPipeline::getTaskManager() {
     return &mTaskManager;
 }
 
 void SkiaPipeline::onDestroyHardwareResources() {
-    // No need to flush the caches here. There is a timer
-    // which will flush temporary resources over time.
+    mRenderThread.cacheManager().trimStaleResources();
 }
 
 bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
@@ -70,15 +72,18 @@
 }
 
 void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-        LayerUpdateQueue* layerUpdateQueue, bool opaque,
+        LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo) {
     updateLighting(lightGeometry, lightInfo);
     ATRACE_NAME("draw layers");
-    renderLayersImpl(*layerUpdateQueue, opaque);
+    renderVectorDrawableCache();
+    renderLayersImpl(*layerUpdateQueue, opaque, wideColorGamut);
     layerUpdateQueue->clear();
 }
 
-void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
+void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers,
+        bool opaque, bool wideColorGamut) {
+    // TODO: Handle wide color gamut
     // Render all layers that need to be updated, in order.
     for (size_t i = 0; i < layers.entries().size(); i++) {
         RenderNode* layerNode = layers.entries()[i].renderNode.get();
@@ -126,12 +131,13 @@
 }
 
 bool SkiaPipeline::createOrUpdateLayer(RenderNode* node,
-        const DamageAccumulator& damageAccumulator) {
+        const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
     SkSurface* layer = node->getLayerSurface();
     if (!layer || layer->width() != node->getWidth() || layer->height() != node->getHeight()) {
         SkImageInfo info = SkImageInfo::MakeN32Premul(node->getWidth(), node->getHeight());
         SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
         SkASSERT(mRenderThread.getGrContext() != nullptr);
+        // TODO: Handle wide color gamut requests
         node->setLayerSurface(
                 SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
                         info, 0, &props));
@@ -155,11 +161,11 @@
     GrContext* context = thread.getGrContext();
     if (context) {
         ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
-        SkBitmap skiaBitmap;
-        bitmap->getSkBitmap(&skiaBitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
-        SkImage_pinAsTexture(image.get(), context);
-        SkImage_unpinAsTexture(image.get(), context);
+        auto image = bitmap->makeImage();
+        if (image.get() && !bitmap->isHardware()) {
+            SkImage_pinAsTexture(image.get(), context);
+            SkImage_unpinAsTexture(image.get(), context);
+        }
     }
 }
 
@@ -176,12 +182,37 @@
     }
 };
 
+void SkiaPipeline::renderVectorDrawableCache() {
+    //render VectorDrawables into offscreen buffers
+    for (auto vd : mVectorDrawables) {
+        sk_sp<SkSurface> surface;
+        if (!vd->canReuseSurface()) {
+#ifndef ANDROID_ENABLE_LINEAR_BLENDING
+            sk_sp<SkColorSpace> colorSpace = nullptr;
+#else
+            sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
+#endif
+            int scaledWidth = SkScalarCeilToInt(vd->properties().getScaledWidth());
+            int scaledHeight = SkScalarCeilToInt(vd->properties().getScaledHeight());
+            SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight,
+                    kPremul_SkAlphaType, colorSpace);
+            SkASSERT(mRenderThread.getGrContext() != nullptr);
+            surface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+                    info);
+        }
+        vd->updateCache(surface);
+    }
+    mVectorDrawables.clear();
+}
+
 void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
-        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
-        sk_sp<SkSurface> surface) {
+        const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
+        const Rect &contentDrawBounds, sk_sp<SkSurface> surface) {
+
+    renderVectorDrawableCache();
 
     // draw all layers up front
-    renderLayersImpl(layers, opaque);
+    renderLayersImpl(layers, opaque, wideColorGamut);
 
     // initialize the canvas for the current frame
     SkCanvas* canvas = surface->getCanvas();
@@ -199,7 +230,7 @@
         }
     }
 
-    renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas);
+    renderFrameImpl(layers, clip, nodes, opaque, wideColorGamut, contentDrawBounds, canvas);
 
     if (skpCaptureEnabled() && recordingPicture) {
         sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture();
@@ -232,8 +263,8 @@
 }
 
 void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
-        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
-        SkCanvas* canvas) {
+        const std::vector<sp<RenderNode>>& nodes, bool opaque, bool wideColorGamut,
+        const Rect &contentDrawBounds, SkCanvas* canvas) {
     SkAutoCanvasRestore saver(canvas, true);
     canvas->androidFramework_setDeviceClipRestriction(clip.roundOut());
 
@@ -360,7 +391,7 @@
     // each time a pixel would have been drawn.
     // Pass true for opaque so we skip the clear - the overdrawCanvas is already zero
     // initialized.
-    renderFrameImpl(layers, clip, nodes, true, contentDrawBounds, &overdrawCanvas);
+    renderFrameImpl(layers, clip, nodes, true, false, contentDrawBounds, &overdrawCanvas);
     sk_sp<SkImage> counts = offscreen->makeImageSnapshot();
 
     // Draw overdraw colors to the canvas.  The color filter will convert counts to colors.
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index c58fedf..19ffc46 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -39,21 +39,23 @@
     void unpinImages() override;
 
     void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) override;
 
     bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) override;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
 
     void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
-            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
-            sk_sp<SkSurface> surface);
+            const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
+            const Rect &contentDrawBounds, sk_sp<SkSurface> surface);
+
+    std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }
 
     static void destroyLayer(RenderNode* node);
 
     static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
 
-    static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
+    static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque, bool wideColorGamut);
 
     static bool skpCaptureEnabled() { return false; }
 
@@ -108,8 +110,8 @@
 
 private:
     void renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
-            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
-            SkCanvas* canvas);
+            const std::vector< sp<RenderNode> >& nodes, bool opaque, bool wideColorGamut,
+            const Rect &contentDrawBounds, SkCanvas* canvas);
 
     /**
      *  Debugging feature.  Draws a semi-transparent overlay on each pixel, indicating
@@ -119,8 +121,18 @@
             const std::vector< sp<RenderNode> >& nodes, const Rect &contentDrawBounds,
             sk_sp<SkSurface>);
 
+    /**
+     *  Render mVectorDrawables into offscreen buffers.
+     */
+    void renderVectorDrawableCache();
+
     TaskManager mTaskManager;
     std::vector<sk_sp<SkImage>> mPinnedImages;
+
+    /**
+     *  populated by prepareTree with dirty VDs
+     */
+    std::vector<VectorDrawableRoot*> mVectorDrawables;
     static float mLightRadius;
     static uint8_t mAmbientShadowAlpha;
     static uint8_t mSpotShadowAlpha;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 559d268..a0cce98 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -62,6 +62,7 @@
         uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
         uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
         uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+    // Destructor of drawables created with allocateDrawable, will be invoked by ~LinearAllocator.
     drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom,
             rx, ry, paint));
 }
@@ -92,13 +93,14 @@
 void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
     if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) {
         uirenderer::Layer* layer = layerUpdater->backingLayer();
+        // Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL.
         sk_sp<SkDrawable> drawable(new LayerDrawable(layer));
         drawDrawable(drawable.get());
     }
 }
 
 void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
-    // record the child node
+    // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
     mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
     auto& renderNodeDrawable = mDisplayList->mChildNodes.back();
     drawDrawable(&renderNodeDrawable);
@@ -113,6 +115,7 @@
 
 void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
         uirenderer::GlFunctorLifecycleListener* listener) {
+    // Drawable dtor will be invoked when mChildFunctors deque is cleared.
     mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas());
     drawDrawable(&mDisplayList->mChildFunctors.back());
 }
@@ -126,22 +129,7 @@
          return SkRect::MakeLargest();
      }
      virtual void onDraw(SkCanvas* canvas) override {
-         Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty();
-         SkBitmap bitmap;
-         hwuiBitmap.getSkBitmap(&bitmap);
-         SkPaint* paint = mRoot->getPaint();
-         canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint);
-         /*
-          * TODO we can draw this directly but need to address the following...
-          *
-          * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot
-          * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path
-          *    so that we don't break caching
-          * 3) figure out how to set path's as volatile during animation
-          * 4) if mRoot->getPaint() != null either promote to layer (during
-          *    animation) or cache in SkSurface (for static content)
-          *
-          */
+         mRoot->draw(canvas);
      }
 
  private:
@@ -168,53 +156,47 @@
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
-    SkBitmap skBitmap;
-    bitmap.getSkBitmap(&skBitmap);
-
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
-    if (!skBitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = bitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
+    // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
+    // it is not safe to store a raw SkImage pointer, because the image object will be destroyed
+    // when this function ends.
+    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
         const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
     SkAutoCanvasRestore acr(&mRecorder, true);
     concat(matrix);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
         float dstBottom, const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
     SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
     SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
     SkPaint tmpPaint;
     mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty()
+            && !dstRect.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
-    SkBitmap bitmap;
-    hwuiBitmap.getSkBitmap(&bitmap);
-
     SkCanvas::Lattice lattice;
-    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height());
 
     lattice.fFlags = nullptr;
     int numFlags = 0;
@@ -231,13 +213,13 @@
 
     lattice.fBounds = nullptr;
     SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = hwuiBitmap.makeImage();
 
     SkPaint tmpPaint;
     mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
+    if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index d28e605..e1ef71f7 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -66,7 +66,7 @@
         const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector<sp<RenderNode>>& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -76,7 +76,8 @@
         return false;
     }
     SkiaPipeline::updateLighting(lightGeometry, lightInfo);
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, wideColorGamut,
+            contentDrawBounds, backBuffer);
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
@@ -131,13 +132,15 @@
 void SkiaVulkanPipeline::onStop() {
 }
 
-bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+        ColorMode colorMode) {
     if (mVkSurface) {
         mVkManager.destroySurface(mVkSurface);
         mVkSurface = nullptr;
     }
 
     if (surface) {
+        // TODO: handle color mode
         mVkSurface = mVkManager.createSurface(surface);
     }
 
@@ -158,6 +161,25 @@
     (*functor)(mode, nullptr);
 }
 
+sk_sp<Bitmap> SkiaVulkanPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    //TODO: implement this function for Vulkan pipeline
+    //code below is a hack to avoid crashing because of missing HW Bitmap support
+    sp<GraphicBuffer> buffer = new GraphicBuffer(skBitmap.info().width(), skBitmap.info().height(),
+            PIXEL_FORMAT_RGBA_8888,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("SkiaVulkanPipeline::allocateHardwareBitmap pid [")
+            + std::to_string(getpid()) + "]");
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("SkiaVulkanPipeline::allocateHardwareBitmap() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), skBitmap.info()));
+}
+
 } /* namespace skiapipeline */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index aab1d7a..263206d 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -33,7 +33,7 @@
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -41,12 +41,15 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+            renderthread::ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     renderthread::VulkanManager& mVkManager;
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index a9bbb27..90b27c8 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -35,17 +35,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
-        uint32_t viewportWidth, uint32_t viewportHeight)
+        uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut)
         : GpuMemoryTracker(GpuObjectType::OffscreenBuffer)
         , renderState(renderState)
         , viewportWidth(viewportWidth)
         , viewportHeight(viewportHeight)
-        , texture(caches) {
+        , texture(caches)
+        , wideColorGamut(wideColorGamut) {
     uint32_t width = computeIdealDimension(viewportWidth);
     uint32_t height = computeIdealDimension(viewportHeight);
     ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height);
     caches.textureState().activateTexture(0);
-    texture.resize(width, height, caches.rgbaInternalFormat(), GL_RGBA);
+    texture.resize(width, height,
+            wideColorGamut ? GL_RGBA16F : caches.rgbaInternalFormat(), GL_RGBA);
     texture.blend = true;
     texture.setWrap(GL_CLAMP_TO_EDGE);
     // not setting filter on texture, since it's set when drawing, based on transform
@@ -127,7 +129,10 @@
     int deltaInt = int(lhs.width) - int(rhs.width);
     if (deltaInt != 0) return deltaInt;
 
-    return int(lhs.height) - int(rhs.height);
+    deltaInt = int(lhs.height) - int(rhs.height);
+    if (deltaInt != 0) return deltaInt;
+
+    return int(lhs.wideColorGamut) - int(rhs.wideColorGamut);
 }
 
 void OffscreenBufferPool::clear() {
@@ -139,10 +144,10 @@
 }
 
 OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState,
-        const uint32_t width, const uint32_t height) {
+        const uint32_t width, const uint32_t height, bool wideColorGamut) {
     OffscreenBuffer* layer = nullptr;
 
-    Entry entry(width, height);
+    Entry entry(width, height, wideColorGamut);
     auto iter = mPool.find(entry);
 
     if (iter != mPool.end()) {
@@ -154,7 +159,8 @@
         layer->viewportHeight = height;
         mSize -= layer->getSizeInBytes();
     } else {
-        layer = new OffscreenBuffer(renderState, Caches::getInstance(), width, height);
+        layer = new OffscreenBuffer(renderState, Caches::getInstance(),
+                width, height, wideColorGamut);
     }
 
     return layer;
@@ -174,7 +180,7 @@
         return layer;
     }
     putOrDelete(layer);
-    return get(renderState, width, height);
+    return get(renderState, width, height, layer->wideColorGamut);
 }
 
 void OffscreenBufferPool::dump() {
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h
index 26d4e36..d9422c9 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.h
+++ b/libs/hwui/renderstate/OffscreenBufferPool.h
@@ -43,7 +43,7 @@
 class OffscreenBuffer : GpuMemoryTracker {
 public:
     OffscreenBuffer(RenderState& renderState, Caches& caches,
-            uint32_t viewportWidth, uint32_t viewportHeight);
+            uint32_t viewportWidth, uint32_t viewportHeight, bool wideColorGamut = false);
     ~OffscreenBuffer();
 
     Rect getTextureCoordinates();
@@ -68,6 +68,8 @@
     uint32_t viewportHeight;
     Texture texture;
 
+    bool wideColorGamut = false;
+
     // Portion of layer that has been drawn to. Used to minimize drawing area when
     // drawing back to screen / parent FBO.
     Region region;
@@ -90,7 +92,7 @@
     ~OffscreenBufferPool();
 
     WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
-            const uint32_t width, const uint32_t height);
+            const uint32_t width, const uint32_t height, bool wideColorGamut = false);
 
     WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
             const uint32_t width, const uint32_t height);
@@ -122,14 +124,16 @@
     struct Entry {
         Entry() {}
 
-        Entry(const uint32_t layerWidth, const uint32_t layerHeight)
+        Entry(const uint32_t layerWidth, const uint32_t layerHeight, bool wideColorGamut)
                 : width(OffscreenBuffer::computeIdealDimension(layerWidth))
-                , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}
+                , height(OffscreenBuffer::computeIdealDimension(layerHeight))
+                , wideColorGamut(wideColorGamut) {}
 
         explicit Entry(OffscreenBuffer* layer)
                 : layer(layer)
                 , width(layer->texture.width())
-                , height(layer->texture.height()) {
+                , height(layer->texture.height())
+                , wideColorGamut(layer->wideColorGamut) {
         }
 
         static int compare(const Entry& lhs, const Entry& rhs);
@@ -149,6 +153,7 @@
         OffscreenBuffer* layer = nullptr;
         uint32_t width = 0;
         uint32_t height = 0;
+        bool wideColorGamut = false;
     }; // struct Entry
 
     std::multiset<Entry> mPool;
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 787946f..4b7a865 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -45,6 +45,7 @@
 class DeferredLayerUpdater;
 
 namespace renderthread {
+class CacheManager;
 class CanvasContext;
 class RenderThread;
 }
@@ -55,6 +56,7 @@
     PREVENT_COPY_AND_ASSIGN(RenderState);
     friend class renderthread::RenderThread;
     friend class Caches;
+    friend class renderthread::CacheManager;
 public:
     void onGLContextCreated();
     void onGLContextDestroyed();
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
new file mode 100644
index 0000000..f0d6b38
--- /dev/null
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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 "CacheManager.h"
+
+#include "Layer.h"
+#include "RenderThread.h"
+#include "renderstate/RenderState.h"
+
+#include <gui/Surface.h>
+#include <GrContextOptions.h>
+#include <math.h>
+#include <set>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+// This multiplier was selected based on historical review of cache sizes relative
+// to the screen resolution. This is meant to be a conservative default based on
+// that analysis. The 4.0f is used because the default pixel format is assumed to
+// be ARGB_8888.
+#define SURFACE_SIZE_MULTIPLIER (12.0f * 4.0f)
+#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
+
+// for super large fonts we will draw them as paths so no need to keep linearly
+// increasing the font cache size.
+#define FONT_CACHE_MIN_MB (0.5f)
+#define FONT_CACHE_MAX_MB (4.0f)
+
+CacheManager::CacheManager(const DisplayInfo& display)
+        : mMaxSurfaceArea(display.w * display.h) {
+    mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+}
+
+void CacheManager::reset(GrContext* context) {
+    if (context != mGrContext.get()) {
+        destroy();
+    }
+
+    if (context) {
+        mGrContext = sk_ref_sp(context);
+        mGrContext->getResourceCacheLimits(&mMaxResources, nullptr);
+        updateContextCacheSizes();
+    }
+}
+
+void CacheManager::destroy() {
+    // cleanup any caches here as the GrContext is about to go away...
+    mGrContext.reset(nullptr);
+    mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+}
+
+void CacheManager::updateContextCacheSizes() {
+    mMaxResourceBytes = mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER;
+    mBackgroundResourceBytes = mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE;
+
+    mGrContext->setResourceCacheLimits(mMaxResources, mMaxResourceBytes);
+}
+
+void CacheManager::configureContext(GrContextOptions* contextOptions) {
+    contextOptions->fAllowPathMaskCaching = true;
+
+    float screenMP = mMaxSurfaceArea / 1024.0f / 1024.0f;
+    float fontCacheMB = 0;
+    float decimalVal = std::modf(screenMP, &fontCacheMB);
+
+    // This is a basic heuristic to size the cache to a multiple of 512 KB
+    if (decimalVal > 0.8f) {
+        fontCacheMB += 1.0f;
+    } else if (decimalVal > 0.5f) {
+        fontCacheMB += 0.5f;
+    }
+
+    // set limits on min/max size of the cache
+    fontCacheMB = std::max(FONT_CACHE_MIN_MB, std::min(FONT_CACHE_MAX_MB, fontCacheMB));
+
+    // We must currently set the size of the text cache based on the size of the
+    // display even though we like to  be dynamicallysizing it to the size of the window.
+    // Skia's implementation doesn't provide a mechanism to resize the font cache due to
+    // the potential cost of recreating the glyphs.
+    contextOptions->fGlyphCacheTextureMaximumBytes = fontCacheMB * 1024 * 1024;
+}
+
+void CacheManager::trimMemory(TrimMemoryMode mode) {
+    if (!mGrContext) {
+        return;
+    }
+
+    mGrContext->flush();
+
+    switch (mode) {
+        case TrimMemoryMode::Complete:
+            mVectorDrawableAtlas.reset(new VectorDrawableAtlas);
+            mGrContext->freeGpuResources();
+            break;
+        case TrimMemoryMode::UiHidden:
+            mGrContext->purgeUnlockedResources(mMaxResourceBytes - mBackgroundResourceBytes, true);
+            break;
+    }
+}
+
+void CacheManager::trimStaleResources() {
+    if (!mGrContext) {
+        return;
+    }
+    mGrContext->flush();
+    mGrContext->purgeResourcesNotUsedInMs(std::chrono::seconds(30));
+}
+
+VectorDrawableAtlas* CacheManager::acquireVectorDrawableAtlas() {
+    LOG_ALWAYS_FATAL_IF(mVectorDrawableAtlas.get() == nullptr);
+    LOG_ALWAYS_FATAL_IF(mGrContext == nullptr);
+
+    /**
+     * TODO LIST:
+     *    1) compute the atlas based on the surfaceArea surface
+     *    2) identify a way to reuse cache entries
+     *    3) add ability to repack the cache?
+     *    4) define memory conditions where we clear the cache (e.g. surface->reset())
+     */
+
+    return mVectorDrawableAtlas.release();
+}
+void CacheManager::releaseVectorDrawableAtlas(VectorDrawableAtlas* atlas) {
+    LOG_ALWAYS_FATAL_IF(mVectorDrawableAtlas.get() != nullptr);
+    mVectorDrawableAtlas.reset(atlas);
+    mVectorDrawableAtlas->isNewAtlas = false;
+}
+
+void CacheManager::dumpMemoryUsage(String8& log, const RenderState* renderState) {
+    if (!mGrContext) {
+        log.appendFormat("No valid cache instance.\n");
+        return;
+    }
+
+    size_t bytesCached;
+    mGrContext->getResourceCacheUsage(nullptr, &bytesCached);
+
+    log.appendFormat("Caches:\n");
+    log.appendFormat("                         Current / Maximum\n");
+    log.appendFormat("  VectorDrawableAtlas  %6.2f kB / %6.2f kB (entries = %zu)\n",
+            0.0f, 0.0f, (size_t)0);
+
+    if (renderState) {
+        if (renderState->mActiveLayers.size() > 0) {
+            log.appendFormat("  Layer Info:\n");
+        }
+
+        size_t layerMemoryTotal = 0;
+        for (std::set<Layer*>::iterator it = renderState->mActiveLayers.begin();
+                it != renderState->mActiveLayers.end(); it++) {
+            const Layer* layer = *it;
+            const char* layerType = layer->getApi() == Layer::Api::OpenGL ? "GlLayer" : "VkLayer";
+            log.appendFormat("    %s size %dx%d\n", layerType,
+                    layer->getWidth(), layer->getHeight());
+            layerMemoryTotal += layer->getWidth() * layer->getHeight() * 4;
+        }
+        log.appendFormat("  Layers Total         %6.2f kB (numLayers = %zu)\n",
+                         layerMemoryTotal / 1024.0f, renderState->mActiveLayers.size());
+    }
+
+
+    log.appendFormat("Total memory usage:\n");
+    log.appendFormat("  %zu bytes, %.2f MB (%.2f MB is purgeable)\n",
+                     bytesCached, bytesCached / 1024.0f / 1024.0f,
+                     mGrContext->getResourceCachePurgeableBytes() / 1024.0f / 1024.0f);
+
+
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
new file mode 100644
index 0000000..43d58f2
--- /dev/null
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -0,0 +1,92 @@
+/*
+ * 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 CACHEMANAGER_H
+#define CACHEMANAGER_H
+
+#include <GrContext.h>
+#include <SkSurface.h>
+#include <ui/DisplayInfo.h>
+#include <utils/String8.h>
+#include <vector>
+
+namespace android {
+
+class Surface;
+
+namespace uirenderer {
+
+class RenderState;
+
+namespace renderthread {
+
+class IRenderPipeline;
+class RenderThread;
+
+struct VectorDrawableAtlas {
+    sk_sp<SkSurface> surface;
+    bool isNewAtlas = true;
+};
+
+class CacheManager {
+public:
+    enum class TrimMemoryMode {
+        Complete,
+        UiHidden
+    };
+
+    void configureContext(GrContextOptions* context);
+    void trimMemory(TrimMemoryMode mode);
+    void trimStaleResources();
+    void dumpMemoryUsage(String8& log, const RenderState* renderState = nullptr);
+
+    VectorDrawableAtlas* acquireVectorDrawableAtlas();
+    void releaseVectorDrawableAtlas(VectorDrawableAtlas*);
+
+    size_t getCacheSize() const { return mMaxResourceBytes; }
+    size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; }
+
+private:
+    friend class RenderThread;
+
+    CacheManager(const DisplayInfo& display);
+
+
+    void reset(GrContext* grContext);
+    void destroy();
+    void updateContextCacheSizes();
+
+    const size_t mMaxSurfaceArea;
+    sk_sp<GrContext> mGrContext;
+
+    int mMaxResources = 0;
+    size_t mMaxResourceBytes = 0;
+    size_t mBackgroundResourceBytes = 0;
+
+    struct PipelineProps {
+        const void* pipelineKey = nullptr;
+        size_t surfaceArea = 0;
+    };
+
+    std::unique_ptr<VectorDrawableAtlas> mVectorDrawableAtlas;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* CACHEMANAGER_H */
+
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9c80ab3..7799248 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -186,7 +186,8 @@
 
     mNativeSurface = surface;
 
-    bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior);
+    ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::Srgb;
+    bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior, colorMode);
 
     mFrameNumber = -1;
 
@@ -241,6 +242,10 @@
     mOpaque = opaque;
 }
 
+void CanvasContext::setWideGamut(bool wideGamut) {
+    mWideColorGamut = wideGamut;
+}
+
 bool CanvasContext::makeCurrent() {
     if (mStopped) return false;
 
@@ -416,7 +421,7 @@
     SkRect windowDirty = computeDirtyRect(frame, &dirty);
 
     bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
-            mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes, &(profiler()));
+            mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo, mRenderNodes, &(profiler()));
 
     waitOnFences();
 
@@ -558,7 +563,8 @@
     // purposes when the frame is actually drawn
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
-    mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue, mOpaque, mLightInfo);
+    mRenderPipeline->renderLayers(mLightGeometry, &mLayerUpdateQueue,
+            mOpaque, mWideColorGamut, mLightInfo);
 
     node->incStrong(nullptr);
     mPrefetchedLayers.insert(node);
@@ -580,15 +586,37 @@
 }
 
 void CanvasContext::trimMemory(RenderThread& thread, int level) {
-    // No context means nothing to free
-    if (!thread.eglManager().hasEglContext()) return;
-
-    ATRACE_CALL();
-    if (level >= TRIM_MEMORY_COMPLETE) {
-        thread.renderState().flush(Caches::FlushMode::Full);
-        thread.eglManager().destroy();
-    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
-        thread.renderState().flush(Caches::FlushMode::Moderate);
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL: {
+            // No context means nothing to free
+            if (!thread.eglManager().hasEglContext()) return;
+            ATRACE_CALL();
+            if (level >= TRIM_MEMORY_COMPLETE) {
+                thread.renderState().flush(Caches::FlushMode::Full);
+                thread.eglManager().destroy();
+            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+                thread.renderState().flush(Caches::FlushMode::Moderate);
+            }
+            break;
+        }
+        case RenderPipelineType::SkiaGL:
+        case RenderPipelineType::SkiaVulkan: {
+            // No context means nothing to free
+            if (!thread.getGrContext()) return;
+            ATRACE_CALL();
+            if (level >= TRIM_MEMORY_COMPLETE) {
+                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+                thread.eglManager().destroy();
+                thread.vulkanManager().destroy();
+            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
+            }
+            break;
+        }
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
     }
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 738c091..b1f4050 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -76,7 +76,7 @@
      *  @return true if the layer has been created or updated
      */
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator) {
-        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator);
+        return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut);
     }
 
     /**
@@ -128,6 +128,7 @@
             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     void setLightCenter(const Vector3& lightCenter);
     void setOpaque(bool opaque);
+    void setWideGamut(bool wideGamut);
     bool makeCurrent();
     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
             int64_t syncQueued, RenderNode* target);
@@ -194,6 +195,8 @@
 
     void waitOnFences();
 
+    IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
             IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -238,6 +241,7 @@
     nsecs_t mLastDropVsync = 0;
 
     bool mOpaque;
+    bool mWideColorGamut = false;
     BakedOpRenderer::LightInfo mLightInfo;
     FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
 
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index ed30708..0e676ee 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,12 +76,17 @@
 static struct {
     bool bufferAge = false;
     bool setDamage = false;
+    bool noConfigContext = false;
+    bool pixelFormatFloat = false;
+    bool glColorSpace = false;
+    bool scRGB = false;
 } EglExtensions;
 
 EglManager::EglManager(RenderThread& thread)
         : mRenderThread(thread)
         , mEglDisplay(EGL_NO_DISPLAY)
         , mEglConfig(nullptr)
+        , mEglConfigWideGamut(nullptr)
         , mEglContext(EGL_NO_CONTEXT)
         , mPBufferSurface(EGL_NO_SURFACE)
         , mCurrentSurface(EGL_NO_SURFACE) {
@@ -116,7 +121,7 @@
         }
     }
 
-    loadConfig();
+    loadConfigs();
     createContext();
     createPBufferSurface();
     makeCurrent(mPBufferSurface);
@@ -134,7 +139,7 @@
 
         GrContextOptions options;
         options.fGpuPathRenderers &= ~GrContextOptions::GpuPathRenderers::kDistanceField;
-        options.fAllowPathMaskCaching = true;
+        mRenderThread.cacheManager().configureContext(&options);
         mRenderThread.setGrContext(GrContext::Create(GrBackend::kOpenGL_GrBackend,
                 (GrBackendContext)glInterface.get(), options));
     }
@@ -143,6 +148,7 @@
 void EglManager::initExtensions() {
     auto extensions = StringUtils::split(
             eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+
     // For our purposes we don't care if EGL_BUFFER_AGE is a result of
     // EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
     // under EGL_KHR_partial_update and we don't need the expanded scope
@@ -152,13 +158,22 @@
     EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
     LOG_ALWAYS_FATAL_IF(!extensions.has("EGL_KHR_swap_buffers_with_damage"),
             "Missing required extension EGL_KHR_swap_buffers_with_damage");
+
+    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() {
     return mEglDisplay != EGL_NO_DISPLAY;
 }
 
-void EglManager::loadConfig() {
+void EglManager::loadConfigs() {
     ALOGD("Swap behavior %d", static_cast<int>(mSwapBehavior));
     EGLint swapBehavior = (mSwapBehavior == SwapBehavior::Preserved)
             ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
@@ -175,19 +190,44 @@
             EGL_NONE
     };
 
-    EGLint num_configs = 1;
-    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs)
-            || num_configs != 1) {
+    EGLint numConfigs = 1;
+    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, numConfigs, &numConfigs)
+            || numConfigs != 1) {
         if (mSwapBehavior == SwapBehavior::Preserved) {
             // Try again without dirty regions enabled
             ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...");
             mSwapBehavior = SwapBehavior::Discard;
-            loadConfig();
+            loadConfigs();
+            return; // the call to loadConfigs() we just made picks the wide gamut config
         } else {
             // Failed to get a valid config
             LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
         }
     }
+
+    if (EglExtensions.pixelFormatFloat) {
+        // If we reached this point, we have a valid swap behavior
+        EGLint attribs16F[] = {
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+                EGL_RED_SIZE, 16,
+                EGL_GREEN_SIZE, 16,
+                EGL_BLUE_SIZE, 16,
+                EGL_ALPHA_SIZE, 16,
+                EGL_DEPTH_SIZE, 0,
+                EGL_STENCIL_SIZE, Stencil::getStencilSize(),
+                EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+                EGL_NONE
+        };
+
+        numConfigs = 1;
+        if (!eglChooseConfig(mEglDisplay, attribs16F, &mEglConfigWideGamut, numConfigs, &numConfigs)
+                || numConfigs != 1) {
+            LOG_ALWAYS_FATAL(
+                    "Device claims wide gamut support, cannot find matching config, error = %s",
+                    eglErrorString());
+        }
+    }
 }
 
 void EglManager::createContext() {
@@ -195,7 +235,9 @@
             EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION,
             EGL_NONE
     };
-    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs);
+    mEglContext = eglCreateContext(mEglDisplay,
+            EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig,
+            EGL_NO_CONTEXT, attribs);
     LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT,
         "Failed to create context, error = %s", eglErrorString());
 }
@@ -210,18 +252,58 @@
     }
 }
 
-EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
+EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
     initialize();
 
+    wideColorGamut = wideColorGamut && EglExtensions.glColorSpace && EglExtensions.scRGB
+            && EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
+
+    // The color space we want to use depends on whether linear blending is turned
+    // on and whether the app has requested wide color gamut rendering. When wide
+    // color gamut rendering is off, the app simply renders in the display's native
+    // color gamut.
+    //
+    // When wide gamut rendering is off:
+    // - Blending is done by default in gamma space, which requires using a
+    //   linear EGL color space (the GPU uses the color values as is)
+    // - If linear blending is on, we must use the sRGB EGL color space (the
+    //   GPU will perform sRGB to linear and linear to SRGB conversions before
+    //   and after blending)
+    //
+    // When wide gamut rendering is on we cannot rely on the GPU performing
+    // linear blending for us. We use two different color spaces to tag the
+    // surface appropriately for SurfaceFlinger:
+    // - Gamma blending (default) requires the use of the scRGB-nl color space
+    // - Linear blending requires the use of the scRGB color space
+
+    // Not all Android targets support the EGL_GL_COLOR_SPACE_KHR extension
+    // We insert to placeholders to set EGL_GL_COLORSPACE_KHR and its value.
+    // According to section 3.4.1 of the EGL specification, the attributes
+    // list is considered empty if the first entry is EGL_NONE
     EGLint attribs[] = {
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
-            EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR,
-            EGL_COLORSPACE, EGL_COLORSPACE_sRGB,
-#endif
+            EGL_NONE, EGL_NONE,
             EGL_NONE
     };
 
-    EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, attribs);
+    if (EglExtensions.glColorSpace) {
+        attribs[0] = EGL_GL_COLORSPACE_KHR;
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+        if (wideColorGamut) {
+            attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
+        } else {
+            attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
+        }
+#else
+        if (wideColorGamut) {
+            attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
+        } else {
+            attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+        }
+#endif
+    }
+
+    EGLSurface surface = eglCreateWindowSurface(mEglDisplay,
+            wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
     LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
             "Failed to create EGLSurface for window %p, eglErr = %s",
             (void*) window, eglErrorString());
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 0251925..2982c23 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -39,7 +39,7 @@
 
     bool hasEglContext();
 
-    EGLSurface createSurface(EGLNativeWindowType window);
+    EGLSurface createSurface(EGLNativeWindowType window, bool wideColorGamut);
     void destroySurface(EGLSurface surface);
 
     void destroy();
@@ -68,7 +68,7 @@
 
     void initExtensions();
     void createPBufferSurface();
-    void loadConfig();
+    void loadConfigs();
     void createContext();
     EGLint queryBufferAge(EGLSurface surface);
 
@@ -76,6 +76,7 @@
 
     EGLDisplay mEglDisplay;
     EGLConfig mEglConfig;
+    EGLConfig mEglConfigWideGamut;
     EGLContext mEglContext;
     EGLSurface mPBufferSurface;
 
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 45f6718..f9b6e38 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -44,6 +44,12 @@
     Succeeded
 };
 
+enum class ColorMode {
+    Srgb,
+    WideColorGamut,
+    // Hdr
+};
+
 class Frame;
 
 class IRenderPipeline {
@@ -53,7 +59,7 @@
     virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) = 0;
@@ -61,17 +67,17 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
     virtual bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) = 0;
     virtual DeferredLayerUpdater* createTextureLayer() = 0;
-    virtual bool setSurface(Surface* window, SwapBehavior swapBehavior) = 0;
+    virtual bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) = 0;
     virtual void onStop() = 0;
     virtual bool isSurfaceReady() = 0;
     virtual bool isContextReady() = 0;
     virtual void onDestroyHardwareResources() = 0;
     virtual void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) = 0;
     virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) = 0;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) = 0;
     virtual bool pinImages(std::vector<SkImage*>& mutableImages) = 0;
     virtual bool pinImages(LsaVector<sk_sp<Bitmap>>& images) = 0;
     virtual void unpinImages() = 0;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index e1ae585..7283eb1 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -58,7 +58,7 @@
 bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
         const FrameBuilder::LightGeometry& lightGeometry,
         LayerUpdateQueue* layerUpdateQueue,
-        const Rect& contentDrawBounds, bool opaque,
+        const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo,
         const std::vector< sp<RenderNode> >& renderNodes,
         FrameInfoVisualizer* profiler) {
@@ -77,7 +77,7 @@
     frameBuilder.deferRenderNodeScene(renderNodes, contentDrawBounds);
 
     BakedOpRenderer renderer(caches, mRenderThread.renderState(),
-            opaque, lightInfo);
+            opaque, wideColorGamut, lightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
     ProfileRenderer profileRenderer(renderer);
     profiler->draw(profileRenderer);
@@ -146,7 +146,7 @@
     }
 }
 
-bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior, ColorMode colorMode) {
 
     if (mEglSurface != EGL_NO_SURFACE) {
         mEglManager.destroySurface(mEglSurface);
@@ -154,7 +154,8 @@
     }
 
     if (surface) {
-        mEglSurface = mEglManager.createSurface(surface);
+        const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+        mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
 
     if (mEglSurface != EGL_NO_SURFACE) {
@@ -183,14 +184,14 @@
 }
 
 void OpenGLPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-        LayerUpdateQueue* layerUpdateQueue, bool opaque,
+        LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
         const BakedOpRenderer::LightInfo& lightInfo) {
     static const std::vector< sp<RenderNode> > emptyNodeList;
     auto& caches = Caches::getInstance();
     FrameBuilder frameBuilder(*layerUpdateQueue, lightGeometry, caches);
     layerUpdateQueue->clear();
-    BakedOpRenderer renderer(caches, mRenderThread.renderState(),
-            opaque, lightInfo);
+    // TODO: Handle wide color gamut contexts
+    BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut, lightInfo);
     LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
@@ -204,12 +205,13 @@
 }
 
 bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
-        const DamageAccumulator& damageAccumulator) {
+        const DamageAccumulator& damageAccumulator, bool wideColorGamut) {
     RenderState& renderState = mRenderThread.renderState();
     OffscreenBufferPool& layerPool = renderState.layerPool();
     bool transformUpdateNeeded = false;
     if (node->getLayer() == nullptr) {
-        node->setLayer(layerPool.get(renderState, node->getWidth(), node->getHeight()));
+        node->setLayer(layerPool.get(renderState,
+                node->getWidth(), node->getHeight(), wideColorGamut));
         transformUpdateNeeded = true;
     } else if (!layerMatchesWH(node->getLayer(), node->getWidth(), node->getHeight())) {
         // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering)
@@ -267,6 +269,171 @@
     thread.renderState().invokeFunctor(functor, mode, nullptr);
 }
 
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+    AutoEglFence(EGLDisplay display)
+            : mDisplay(display) {
+        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+    }
+
+    ~AutoEglFence() {
+        if (fence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, fence);
+        }
+    }
+
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+            : mDisplay(display) {
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+    }
+
+    ~AutoEglImage() {
+        if (image != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mDisplay, image);
+        }
+    }
+
+    EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoGlTexture {
+public:
+    AutoGlTexture(uirenderer::Caches& caches)
+            : mCaches(caches) {
+        glGenTextures(1, &mTexture);
+        caches.textureState().bindTexture(mTexture);
+    }
+
+    ~AutoGlTexture() {
+        mCaches.textureState().deleteTexture(mTexture);
+    }
+
+private:
+    uirenderer::Caches& mCaches;
+    GLuint mTexture = 0;
+};
+
+static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
+        GraphicBuffer& buffer, GLint format, GLint type) {
+    EGLDisplay display = eglGetCurrentDisplay();
+    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+    // We use an EGLImage to access the content of the GraphicBuffer
+    // The EGL image is later bound to a 2D texture
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
+    AutoEglImage autoImage(display, clientBuffer);
+    if (autoImage.image == EGL_NO_IMAGE_KHR) {
+        ALOGW("Could not create EGL image, err =%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+        return false;
+    }
+    AutoGlTexture glTexture(caches);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+
+    GL_CHECKPOINT(MODERATE);
+
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+            format, type, bitmap.getPixels());
+
+    GL_CHECKPOINT(MODERATE);
+
+    // The fence is used to wait for the texture upload to finish
+    // properly. We cannot rely on glFlush() and glFinish() as
+    // some drivers completely ignore these API calls
+    AutoEglFence autoFence(display);
+    if (autoFence.fence == EGL_NO_SYNC_KHR) {
+        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+        return false;
+    }
+    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+    // pipeline flush (similar to what a glFlush() would do.)
+    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+        return false;
+    }
+    return true;
+}
+
+// TODO: handle SRGB sanely
+static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
+    switch (internalFormat) {
+    case GL_LUMINANCE:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_SRGB8_ALPHA8:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_RGBA:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_RGB:
+        return PIXEL_FORMAT_RGB_565;
+    case GL_RGBA16F:
+        return PIXEL_FORMAT_RGBA_FP16;
+    default:
+        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
+        return PIXEL_FORMAT_UNKNOWN;
+    }
+}
+
+sk_sp<Bitmap> OpenGLPipeline::allocateHardwareBitmap(RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    renderThread.eglManager().initialize();
+    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
+
+    const SkImageInfo& info = skBitmap.info();
+    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
+        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+        return nullptr;
+    }
+
+    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
+    bool hasLinearBlending = caches.extensions().hasLinearBlending();
+    GLint format, type, internalFormat;
+    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
+            needSRGB && hasLinearBlending, &internalFormat, &format, &type);
+
+    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
+    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_SW_WRITE_NEVER |
+            GraphicBuffer::USAGE_SW_READ_NEVER,
+            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+    status_t error = buffer->initCheck();
+    if (error < 0) {
+        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    SkBitmap bitmap;
+    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
+            hasLinearBlending))) {
+        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
+        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
+    } else {
+        bitmap = skBitmap;
+    }
+
+    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
+        return nullptr;
+    }
+    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 6df8be4..4ca19fb 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -36,7 +36,7 @@
     bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
             const FrameBuilder::LightGeometry& lightGeometry,
             LayerUpdateQueue* layerUpdateQueue,
-            const Rect& contentDrawBounds, bool opaque,
+            const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo,
             const std::vector< sp<RenderNode> >& renderNodes,
             FrameInfoVisualizer* profiler) override;
@@ -44,23 +44,25 @@
             FrameInfo* currentFrameInfo, bool* requireSwap) override;
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
     DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, SwapBehavior swapBehavior) override;
+    bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) override;
     void onStop() override;
     bool isSurfaceReady() override;
     bool isContextReady() override;
     void onDestroyHardwareResources() override;
     void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
             const BakedOpRenderer::LightInfo& lightInfo) override;
     TaskManager* getTaskManager() override;
     bool createOrUpdateLayer(RenderNode* node,
-            const DamageAccumulator& damageAccumulator) override;
+            const DamageAccumulator& damageAccumulator, bool wideColorGamut) override;
     bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
     bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
     void unpinImages() override;
     static void destroyLayer(RenderNode* node);
     static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
     static void invokeFunctor(const RenderThread& thread, Functor* functor);
+    static sk_sp<Bitmap> allocateHardwareBitmap(RenderThread& thread,
+            SkBitmap& skBitmap);
 
 private:
     EglManager& mEglManager;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index d842be9..80c2955 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -228,6 +228,18 @@
     post(task);
 }
 
+CREATE_BRIDGE2(setWideGamut, CanvasContext* context, bool wideGamut) {
+    args->context->setWideGamut(args->wideGamut);
+    return nullptr;
+}
+
+void RenderProxy::setWideGamut(bool wideGamut) {
+    SETUP_TASK(setWideGamut);
+    args->context = mContext;
+    args->wideGamut = wideGamut;
+    post(task);
+}
+
 int64_t* RenderProxy::frameInfo() {
     return mDrawFrameTask.frameInfo();
 }
@@ -458,18 +470,7 @@
 }
 
 CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
-    args->thread->jankTracker().dump(args->fd);
-
-    FILE *file = fdopen(args->fd, "a");
-    if (Caches::hasInstance()) {
-        String8 cachesLog;
-        Caches::getInstance().dumpMemoryUsage(cachesLog);
-        fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
-    } else {
-        fprintf(file, "\nNo caches instance.\n");
-    }
-    fprintf(file, "\nPipeline=FrameBuilder\n");
-    fflush(file);
+    args->thread->dumpGraphicsMemory(args->fd);
     return nullptr;
 }
 
@@ -665,7 +666,7 @@
 }
 
 CREATE_BRIDGE2(allocateHardwareBitmap, RenderThread* thread, SkBitmap* bitmap) {
-    sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(*args->thread, *args->bitmap);
+    sk_sp<Bitmap> hardwareBitmap = args->thread->allocateHardwareBitmap(*args->bitmap);
     return hardwareBitmap.release();
 }
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 6f4e8ce..31f0ce6 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -69,7 +69,7 @@
  */
 class ANDROID_API RenderProxy {
 public:
-    ANDROID_API RenderProxy(bool translucent, RenderNode* rootNode, IContextFactory* contextFactory);
+    ANDROID_API RenderProxy(bool opaque, RenderNode* rootNode, IContextFactory* contextFactory);
     ANDROID_API virtual ~RenderProxy();
 
     // Won't take effect until next EGLSurface creation
@@ -85,6 +85,7 @@
             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     ANDROID_API void setLightCenter(const Vector3& lightCenter);
     ANDROID_API void setOpaque(bool opaque);
+    ANDROID_API void setWideGamut(bool wideGamut);
     ANDROID_API int64_t* frameInfo();
     ANDROID_API int syncAndDrawFrame();
     ANDROID_API void destroy();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 1450ec9..13af2c4 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,8 +16,12 @@
 
 #include "RenderThread.h"
 
-#include "../renderstate/RenderState.h"
-#include "../pipeline/skia/SkiaOpenGLReadback.h"
+#include "hwui/Bitmap.h"
+#include "renderstate/RenderState.h"
+#include "renderthread/OpenGLPipeline.h"
+#include "pipeline/skia/SkiaOpenGLReadback.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
+#include "pipeline/skia/SkiaVulkanPipeline.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
 #include "OpenGLReadback.h"
@@ -198,6 +202,45 @@
     mRenderState = new RenderState(*this);
     mJankTracker = new JankTracker(mDisplayInfo);
     mVkManager = new VulkanManager(*this);
+    mCacheManager = new CacheManager(mDisplayInfo);
+}
+
+void RenderThread::dumpGraphicsMemory(int fd) {
+    jankTracker().dump(fd);
+
+    String8 cachesOutput;
+    String8 pipeline;
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL: {
+            if (Caches::hasInstance()) {
+                cachesOutput.appendFormat("Caches:\n");
+                Caches::getInstance().dumpMemoryUsage(cachesOutput);
+            } else {
+                cachesOutput.appendFormat("No caches instance.");
+            }
+            pipeline.appendFormat("FrameBuilder");
+            break;
+        }
+        case RenderPipelineType::SkiaGL: {
+            mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
+            pipeline.appendFormat("Skia (OpenGL)");
+            break;
+        }
+        case RenderPipelineType::SkiaVulkan: {
+            mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
+            pipeline.appendFormat("Skia (Vulkan)");
+            break;
+        }
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+
+    FILE *file = fdopen(fd, "a");
+    fprintf(file, "\n%s\n", cachesOutput.string());
+    fprintf(file, "\nPipeline=%s\n", pipeline.string());
+    fflush(file);
 }
 
 Readback& RenderThread::readback() {
@@ -224,6 +267,14 @@
     return *mReadback;
 }
 
+void RenderThread::setGrContext(GrContext* context) {
+    mCacheManager->reset(context);
+    if (mGrContext.get()) {
+        mGrContext->releaseResourcesAndAbandonContext();
+    }
+    mGrContext.reset(context);
+}
+
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
         ALOGE("Display event receiver pipe was closed or an error occurred.  "
@@ -433,6 +484,22 @@
     return next;
 }
 
+sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            return OpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+        case RenderPipelineType::SkiaGL:
+            return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+        case RenderPipelineType::SkiaVulkan:
+            return skiapipeline::SkiaVulkanPipeline::allocateHardwareBitmap(*this, skBitmap);
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+    return nullptr;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 9bc5985..d984257 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -20,10 +20,12 @@
 #include "RenderTask.h"
 
 #include "../JankTracker.h"
+#include "CacheManager.h"
 #include "TimeLord.h"
 
 #include <GrContext.h>
 #include <cutils/compiler.h>
+#include <SkBitmap.h>
 #include <ui/DisplayInfo.h>
 #include <utils/Looper.h>
 #include <utils/Thread.h>
@@ -33,6 +35,7 @@
 
 namespace android {
 
+class Bitmap;
 class DisplayEventReceiver;
 
 namespace uirenderer {
@@ -100,10 +103,14 @@
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
 
     GrContext* getGrContext() const { return mGrContext.get(); }
-    void setGrContext(GrContext* cxt) { mGrContext.reset(cxt); }
+    void setGrContext(GrContext* cxt);
 
+    CacheManager& cacheManager() { return *mCacheManager; }
     VulkanManager& vulkanManager() { return *mVkManager; }
 
+    sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
+    void dumpGraphicsMemory(int fd);
+
 protected:
     virtual bool threadLoop() override;
 
@@ -157,6 +164,7 @@
     Readback* mReadback = nullptr;
 
     sk_sp<GrContext> mGrContext;
+    CacheManager* mCacheManager;
     VulkanManager* mVkManager;
 };
 
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index c2c2f22..a745320 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -54,7 +54,8 @@
 
     auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
 
-    mBackendContext.reset(GrVkBackendContext::Create(&mPresentQueueIndex, canPresent));
+    mBackendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr, vkGetDeviceProcAddr,
+            &mPresentQueueIndex, canPresent));
 
     // Get all the addresses of needed vulkan functions
     VkInstance instance = mBackendContext->fInstance;
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index 1d4ed7e..978a1f3 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -19,7 +19,7 @@
 #include "JankTracker.h"
 
 #include <frameworks/base/core/proto/android/service/graphicsstats.pb.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <log/log.h>
 
 #include <errno.h>
@@ -28,6 +28,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <sys/mman.h>
 
 namespace android {
 namespace uirenderer {
@@ -47,10 +48,74 @@
         const ProfileData* data);
 static void dumpAsTextToFd(service::GraphicsStatsProto* proto, int outFd);
 
+class FileDescriptor {
+public:
+    FileDescriptor(int fd) : mFd(fd) {}
+    ~FileDescriptor() {
+        if (mFd != -1) {
+            close(mFd);
+            mFd = -1;
+        }
+    }
+    bool valid() { return mFd != -1; }
+    operator int() { return mFd; }
+private:
+    int mFd;
+};
+
+class FileOutputStreamLite : public io::ZeroCopyOutputStream {
+public:
+    FileOutputStreamLite(int fd) : mCopyAdapter(fd), mImpl(&mCopyAdapter) {}
+    virtual ~FileOutputStreamLite() {}
+
+    int GetErrno() { return mCopyAdapter.mErrno; }
+
+    virtual bool Next(void** data, int* size) override {
+        return mImpl.Next(data, size);
+    }
+
+    virtual void BackUp(int count) override {
+        mImpl.BackUp(count);
+    }
+
+    virtual int64 ByteCount() const override {
+        return mImpl.ByteCount();
+    }
+
+    bool Flush() {
+        return mImpl.Flush();
+    }
+
+private:
+    struct FDAdapter : public io::CopyingOutputStream {
+        int mFd;
+        int mErrno = 0;
+
+        FDAdapter(int fd) : mFd(fd) {}
+        virtual ~FDAdapter() {}
+
+        virtual bool Write(const void* buffer, int size) override {
+            int ret;
+            while (size) {
+                ret = TEMP_FAILURE_RETRY( write(mFd, buffer, size) );
+                if (ret <= 0) {
+                    mErrno = errno;
+                    return false;
+                }
+                size -= ret;
+            }
+            return true;
+        }
+    };
+
+    FileOutputStreamLite::FDAdapter mCopyAdapter;
+    io::CopyingOutputStreamAdaptor mImpl;
+};
+
 bool GraphicsStatsService::parseFromFile(const std::string& path, service::GraphicsStatsProto* output) {
 
-    int fd = open(path.c_str(), O_RDONLY);
-    if (fd == -1) {
+    FileDescriptor fd{open(path.c_str(), O_RDONLY)};
+    if (!fd.valid()) {
         int err = errno;
         // The file not existing is normal for addToDump(), so only log if
         // we get an unexpected error
@@ -59,26 +124,41 @@
         }
         return false;
     }
-    uint32_t file_version;
-    ssize_t bytesRead = read(fd, &file_version, sHeaderSize);
-    if (bytesRead != sHeaderSize || file_version != sCurrentFileVersion) {
-        ALOGW("Failed to read '%s', bytesRead=%zd file_version=%d", path.c_str(), bytesRead,
-                file_version);
-        close(fd);
+    struct stat sb;
+    if (fstat(fd, &sb) || sb.st_size < sHeaderSize) {
+        int err = errno;
+        // The file not existing is normal for addToDump(), so only log if
+        // we get an unexpected error
+        if (err != ENOENT) {
+            ALOGW("Failed to fstat '%s', errno=%d (%s) (st_size %d)", path.c_str(), err,
+                    strerror(err), (int) sb.st_size);
+        }
+        return false;
+    }
+    void* addr = mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (!addr) {
+        int err = errno;
+        // The file not existing is normal for addToDump(), so only log if
+        // we get an unexpected error
+        if (err != ENOENT) {
+            ALOGW("Failed to mmap '%s', errno=%d (%s)", path.c_str(), err, strerror(err));
+        }
+        return false;
+    }
+    uint32_t file_version = *reinterpret_cast<uint32_t*>(addr);
+    if (file_version != sCurrentFileVersion) {
+        ALOGW("file_version mismatch! expected %d got %d", sCurrentFileVersion, file_version);
         return false;
     }
 
-    io::FileInputStream input(fd);
+    void* data = reinterpret_cast<uint8_t*>(addr) + sHeaderSize;
+    int dataSize = sb.st_size - sHeaderSize;
+    io::ArrayInputStream input{data, dataSize};
     bool success = output->ParseFromZeroCopyStream(&input);
-    if (input.GetErrno() != 0) {
-        ALOGW("Error reading from fd=%d, path='%s' err=%d (%s)",
-                fd, path.c_str(), input.GetErrno(), strerror(input.GetErrno()));
-        success = false;
-    } else if (!success) {
+    if (!success) {
         ALOGW("Parse failed on '%s' error='%s'",
                 path.c_str(), output->InitializationErrorString().c_str());
     }
-    close(fd);
     return success;
 }
 
@@ -213,7 +293,7 @@
         return;
     }
     {
-        io::FileOutputStream output(outFd);
+        FileOutputStreamLite output(outFd);
         bool success = statsProto.SerializeToZeroCopyStream(&output) && output.Flush();
         if (output.GetErrno() != 0) {
             ALOGW("Error writing to fd=%d, path='%s' err=%d (%s)",
@@ -278,7 +358,7 @@
 
 void GraphicsStatsService::finishDump(Dump* dump) {
     if (dump->type() == DumpType::Protobuf) {
-        io::FileOutputStream stream(dump->fd());
+        FileOutputStreamLite stream(dump->fd());
         dump->proto().SerializeToZeroCopyStream(&stream);
     }
     delete dump;
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index dd45786..98d5fb3 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -365,8 +365,15 @@
         }
         auto displayList = node->getDisplayList();
         if (displayList) {
-            for (auto&& childOp : displayList->getChildren()) {
-                syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
+            if (displayList->isSkiaDL()) {
+                for (auto&& childDr : static_cast<skiapipeline::SkiaDisplayList*>(
+                        const_cast<DisplayList*>(displayList))->mChildNodes) {
+                    syncHierarchyPropertiesAndDisplayListImpl(childDr.getRenderNode());
+                }
+            } else {
+                for (auto&& childOp : displayList->getChildren()) {
+                    syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
+                }
             }
         }
     }
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index a7ebb68..4797dec 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -45,10 +45,8 @@
             skCanvas.drawRect(SkRect::MakeXYWH(100, 100, 100, 100), skPaint);
         });
 
-        SkBitmap bitmap;
         SkPaint paint;
-        hwuiBitmap->getSkBitmapForShaders(&bitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+        sk_sp<SkImage> image = hwuiBitmap->makeImage();
         sk_sp<SkShader> repeatShader = image->makeShader(
                 SkShader::TileMode::kRepeat_TileMode,
                 SkShader::TileMode::kRepeat_TileMode,
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index a461426..c246eba 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -75,9 +75,7 @@
     void doFrame(int frameNr) override { }
 
     sk_sp<SkShader> createBitmapShader(Bitmap& bitmap) {
-        SkBitmap skBitmap;
-        bitmap.getSkBitmapForShaders(&skBitmap);
-        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+        sk_sp<SkImage> image = bitmap.makeImage();
         return image->makeShader(SkShader::TileMode::kClamp_TileMode,
                 SkShader::TileMode::kClamp_TileMode);
     }
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index 398e7a8..a5e85df 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -83,7 +83,7 @@
                     sLightGeometry, caches);
             frameBuilder.deferRenderNode(*node);
 
-            BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
             benchmark::DoNotOptimize(&renderer);
         }
@@ -142,7 +142,7 @@
                     sLightGeometry, Caches::getInstance());
             frameBuilder.deferRenderNode(*node);
 
-            BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
             frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
             benchmark::DoNotOptimize(&renderer);
         }
diff --git a/libs/hwui/tests/scripts/process_systrace.py b/libs/hwui/tests/scripts/process_systrace.py
new file mode 100755
index 0000000..f497bf5
--- /dev/null
+++ b/libs/hwui/tests/scripts/process_systrace.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+import codecs, httplib, json, os, urllib, shutil, subprocess, sys, argparse
+
+upstream_git = 'https://github.com/catapult-project/catapult.git'
+
+script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
+catapult_src_dir = os.path.join(script_dir, 'catapult-upstream')
+
+parser = argparse.ArgumentParser()
+parser.add_argument('trace_file_or_dir',
+      help='Path to trace file or directory of trace files.')
+parser.add_argument('--output_file', dest='outfile', default=os.path.join(os.getcwd(), 'mapper_output.json'),
+      help='Path to output file to store results.')
+parser.add_argument('--mapper_func', dest='func', default='AvgDrawFrame',
+      help='Name of javascript mapper function in systrace_parser.html.')
+args = parser.parse_args()
+
+# Update the source if needed.
+if not os.path.exists(catapult_src_dir):
+  # Pull the latest source from the upstream git.
+  git_args = ['git', 'clone', upstream_git, catapult_src_dir]
+  p = subprocess.Popen(git_args, stdout=subprocess.PIPE, cwd=script_dir)
+  p.communicate()
+  if p.wait() != 0:
+    print 'Failed to checkout source from upstream git.'
+    sys.exit(1)
+
+mapper_func_file = os.path.join(script_dir, 'systrace_parser.html')
+path_to_process_traces = os.path.join(catapult_src_dir, 'trace_processor/bin/process_traces')
+run_command = path_to_process_traces + " --mapper_handle " + mapper_func_file + ":" + args.func + " --output_file " + args.outfile + " " + args.trace_file_or_dir
+print run_command
+sys.exit(os.system(run_command))
+
diff --git a/libs/hwui/tests/scripts/systrace_parser.html b/libs/hwui/tests/scripts/systrace_parser.html
new file mode 100644
index 0000000..4c66ae2
--- /dev/null
+++ b/libs/hwui/tests/scripts/systrace_parser.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+
+<script>
+'use strict';
+
+const RENDER_THREAD_NAME = "RenderThread";
+const UI_THREAD_NAME = "UI Thread";
+const DRAW_FRAME_SLICE_TITLE = "DrawFrame";
+const BINDER_SLICE_TITLE = "binder transaction";
+const RECORD_SLICE_TITLE = "Record View#draw()";
+const DEQUEUE_BUFFER_SLICE_TITLE = "dequeueBuffer";
+
+function getTimeInBinder(slice) {
+    if (slice.title === BINDER_SLICE_TITLE) {
+        return slice.duration;
+    }
+    let result = 0.0;
+    for (let subslice of slice.subSlices) {
+        result += getTimeInBinder(subslice);
+    }
+    return result;
+}
+
+function getTimeInDequeueBuffer(slice) {
+    if (slice.title === DEQUEUE_BUFFER_SLICE_TITLE) {
+        return slice.duration;
+    }
+    let result = 0.0;
+    for (let subslice of slice.subSlices) {
+        result += getTimeInDequeueBuffer(subslice);
+    }
+    return result;
+}
+
+tr.mre.FunctionRegistry.register(
+    function AvgDrawFrame(result, model) {
+        let canonicalUrl = model.canonicalUrl;
+
+        for (let p of model.getAllProcesses()) {
+            //calc stats for processes that have UI and render threads and at least 10 frames
+            let renderThread = p.findAtMostOneThreadNamed(RENDER_THREAD_NAME);
+            let UIThread = p.findAtMostOneThreadNamed(UI_THREAD_NAME);
+            if (renderThread && UIThread)
+            {
+                let numDrawFrames = 0;
+                let drawFramesWallDuration = 0.0;
+                let binderDuration = 0.0;
+                let dequeueBufferDuration = 0.0;
+
+                let numRecordViewDraw = 0;
+                let recordViewDrawWallDuration = 0.0;
+
+                renderThread.sliceGroup.slices.forEach(function(slice) {
+                    if (slice.title === DRAW_FRAME_SLICE_TITLE) {
+                        drawFramesWallDuration += slice.duration;
+                        numDrawFrames++;
+                        binderDuration += getTimeInBinder(slice);
+                        dequeueBufferDuration += getTimeInDequeueBuffer(slice);
+                    }
+                });
+                if (numDrawFrames < 10) continue;
+                UIThread.sliceGroup.slices.forEach(function(slice) {
+                    if (slice.title === RECORD_SLICE_TITLE) {
+                        recordViewDrawWallDuration += slice.duration;
+                        numRecordViewDraw++;
+                    }
+                });
+
+                let avgDrawFrameDuration = undefined;
+                if (numDrawFrames > 0) {
+                    avgDrawFrameDuration = (drawFramesWallDuration-dequeueBufferDuration)/numDrawFrames;
+                }
+                let avgRecordViewDrawDuration = undefined;
+                if (numRecordViewDraw > 0) {
+                    avgRecordViewDrawDuration = recordViewDrawWallDuration/numRecordViewDraw;
+                }
+
+                result.addPair('result', {
+                    canonicalUrl: canonicalUrl,
+                    processName: p.name,
+                    avgDrawFrameDuration: Number(avgDrawFrameDuration).toFixed(3),
+                    avgRecordViewDrawDuration: Number(avgRecordViewDrawDuration).toFixed(3),
+                    avgRecordAndPlay: Number(avgDrawFrameDuration+avgRecordViewDrawDuration).toFixed(3)
+                });
+            }
+        }
+    });
+
+</script>
diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
index c46592c..b0ef11f 100644
--- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
@@ -37,7 +37,7 @@
 class ValidatingBakedOpRenderer : public BakedOpRenderer {
 public:
     ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator)
-            : BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo)
+            : BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo)
             , mValidator(validator) {
         mGlopReceiver = ValidatingGlopReceiver;
     }
diff --git a/libs/hwui/tests/unit/BakedOpRendererTests.cpp b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
index 380062a..603599c 100644
--- a/libs/hwui/tests/unit/BakedOpRendererTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
@@ -24,7 +24,8 @@
 const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
 
 RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, startRepaintLayer_clear) {
-    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo);
+    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(),
+            true, false, sLightInfo);
     OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
 
     layer.dirty(Rect(200, 200));
diff --git a/libs/hwui/tests/unit/BitmapTests.cpp b/libs/hwui/tests/unit/BitmapTests.cpp
index 8c7e081..ed689bd 100644
--- a/libs/hwui/tests/unit/BitmapTests.cpp
+++ b/libs/hwui/tests/unit/BitmapTests.cpp
@@ -29,16 +29,15 @@
 
 TEST(Bitmap, colorTableRefCounting) {
     const SkPMColor c[] = { SkPackARGB32(0x80, 0x80, 0, 0) };
-    SkColorTable* ctable = new SkColorTable(c, SK_ARRAY_COUNT(c));
+    sk_sp<SkColorTable> ctable = SkColorTable::Make(c, SK_ARRAY_COUNT(c));
 
     SkBitmap* bm = new SkBitmap();
     bm->allocPixels(SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType),
-            nullptr, ctable);
+            ctable);
     sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(bm, ctable);
     EXPECT_FALSE(ctable->unique());
     delete bm;
     bitmap.reset();
     EXPECT_TRUE(ctable->unique());
-    ctable->unref();
 }
 
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
new file mode 100644
index 0000000..6115162
--- /dev/null
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include "renderthread/CacheManager.h"
+#include "renderthread/EglManager.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+static size_t getCacheUsage(GrContext* grContext) {
+    size_t cacheUsage;
+    grContext->getResourceCacheUsage(nullptr, &cacheUsage);
+    return cacheUsage;
+}
+
+RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
+    DisplayInfo displayInfo = renderThread.mainDisplayInfo();
+    GrContext* grContext = renderThread.getGrContext();
+    ASSERT_TRUE(grContext != nullptr);
+
+    // create pairs of offscreen render targets and images until we exceed the backgroundCacheSizeLimit
+    std::vector<sk_sp<SkSurface>> surfaces;
+
+    while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
+        SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+        sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
+        surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
+
+        grContext->flush();
+
+        surfaces.push_back(surface);
+    }
+
+    ASSERT_TRUE(1 < surfaces.size());
+
+    // attempt to trim all memory while we still hold strong refs
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+    ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
+
+    // free the surfaces
+    for (size_t i = 0; i < surfaces.size(); i++) {
+        ASSERT_TRUE(surfaces[i]->unique());
+        surfaces[i].reset();
+    }
+
+    // verify that we have enough purgeable bytes
+    const size_t purgeableBytes = grContext->getResourceCachePurgeableBytes();
+    ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() < purgeableBytes);
+
+    // UI hidden and make sure only some got purged
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
+    ASSERT_TRUE(0 < grContext->getResourceCachePurgeableBytes());
+    ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() > getCacheUsage(grContext));
+
+    // complete and make sure all get purged
+    renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+    ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
+}
diff --git a/libs/hwui/tests/unit/FontRendererTests.cpp b/libs/hwui/tests/unit/FontRendererTests.cpp
index 773a7ea..ee20236 100644
--- a/libs/hwui/tests/unit/FontRendererTests.cpp
+++ b/libs/hwui/tests/unit/FontRendererTests.cpp
@@ -28,7 +28,7 @@
     return true;
 }
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, DISABLED_renderDropShadow) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, renderDropShadow) {
     SkPaint paint;
     paint.setTextSize(10);
     paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
diff --git a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
index cfe1134..f6f7337 100644
--- a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
+++ b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
@@ -50,7 +50,11 @@
 
 // No code left untested
 TEST(GraphicsStats, findRootPath) {
+#ifdef __LP64__
+    std::string expected = "/data/nativetest64/hwui_unit_tests";
+#else
     std::string expected = "/data/nativetest/hwui_unit_tests";
+#endif
     EXPECT_EQ(expected, findRootPath());
 }
 
@@ -156,4 +160,4 @@
         EXPECT_EQ(expectedCount, loadedProto.histogram().Get(i).frame_count());
         EXPECT_EQ(expectedBucket, loadedProto.histogram().Get(i).render_millis());
     }
-}
\ No newline at end of file
+}
diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp
index 6c42ca1..19d7ef5 100644
--- a/libs/hwui/tests/unit/LeakCheckTests.cpp
+++ b/libs/hwui/tests/unit/LeakCheckTests.cpp
@@ -45,7 +45,7 @@
     FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
             sLightGeometery, Caches::getInstance());
     frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
 
@@ -62,6 +62,6 @@
     FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
             sLightGeometery, Caches::getInstance());
     frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, sLightInfo);
+    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
 }
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index 6cd595a..919852f 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -41,6 +41,19 @@
     EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes());
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, constructWideColorGamut) {
+    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u, true);
+    EXPECT_EQ(49u, layer.viewportWidth);
+    EXPECT_EQ(149u, layer.viewportHeight);
+
+    EXPECT_EQ(64u, layer.texture.width());
+    EXPECT_EQ(192u, layer.texture.height());
+
+    EXPECT_TRUE(layer.wideColorGamut);
+
+    EXPECT_EQ(64u * 192u * 8u, layer.getSizeInBytes());
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, getTextureCoordinates) {
     OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u);
     EXPECT_EQ(Rect(0, 1, 1, 0),
@@ -88,6 +101,47 @@
     EXPECT_EQ(0u, pool.getCount());
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClearWideColorGamut) {
+    OffscreenBufferPool pool;
+
+    auto layer = pool.get(renderThread.renderState(), 100u, 200u, true);
+    EXPECT_EQ(100u, layer->viewportWidth);
+    EXPECT_EQ(200u, layer->viewportHeight);
+    EXPECT_TRUE(layer->wideColorGamut);
+
+    ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
+
+    pool.putOrDelete(layer);
+    ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
+
+    auto layer2 = pool.get(renderThread.renderState(), 102u, 202u, true);
+    EXPECT_EQ(layer, layer2) << "layer should be recycled";
+    ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
+
+    pool.putOrDelete(layer2);
+    EXPECT_EQ(1u, pool.getCount());
+    pool.clear();
+    EXPECT_EQ(0u, pool.getSize());
+    EXPECT_EQ(0u, pool.getCount());
+
+    // add non wide gamut layer
+    auto layer3 = pool.get(renderThread.renderState(), 100u, 200u);
+    EXPECT_FALSE(layer3->wideColorGamut);
+    pool.putOrDelete(layer3);
+    EXPECT_EQ(1u, pool.getCount());
+
+    auto layer4 = pool.get(renderThread.renderState(), 100u, 200u, true);
+    EXPECT_TRUE(layer4->wideColorGamut);
+    EXPECT_EQ(1u, pool.getCount());
+    ASSERT_NE(layer3, layer4);
+
+    pool.putOrDelete(layer4);
+
+    pool.clear();
+    EXPECT_EQ(0u, pool.getSize());
+    EXPECT_EQ(0u, pool.getCount());
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) {
     OffscreenBufferPool pool;
 
@@ -123,6 +177,43 @@
     pool.putOrDelete(layer2);
 }
 
+RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resizeWideColorGamut) {
+    OffscreenBufferPool pool;
+
+    auto layer = pool.get(renderThread.renderState(), 64u, 64u, true);
+
+    // resize in place
+    ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
+    EXPECT_EQ(60u, layer->viewportWidth);
+    EXPECT_EQ(55u, layer->viewportHeight);
+    EXPECT_EQ(64u, layer->texture.width());
+    EXPECT_EQ(64u, layer->texture.height());
+
+    EXPECT_TRUE(layer->wideColorGamut);
+    EXPECT_EQ(64u * 64u * 8u, layer->getSizeInBytes());
+
+    // resized to use different object in pool
+    auto layer2 = pool.get(renderThread.renderState(), 128u, 128u, true);
+    pool.putOrDelete(layer2);
+    ASSERT_EQ(1u, pool.getCount());
+
+    // add a non-wide gamut layer
+    auto layer3 = pool.get(renderThread.renderState(), 128u, 128u);
+    pool.putOrDelete(layer3);
+    ASSERT_EQ(2u, pool.getCount());
+
+    ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
+    EXPECT_EQ(120u, layer2->viewportWidth);
+    EXPECT_EQ(125u, layer2->viewportHeight);
+    EXPECT_EQ(128u, layer2->texture.width());
+    EXPECT_EQ(128u, layer2->texture.height());
+
+    EXPECT_TRUE(layer2->wideColorGamut);
+    EXPECT_EQ(128u * 128u * 8u, layer2->getSizeInBytes());
+
+    pool.putOrDelete(layer2);
+}
+
 RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, putAndDestroy) {
     OffscreenBufferPool pool;
     // layer too big to return to the pool
@@ -153,3 +244,4 @@
 
     EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
 }
+
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 686d06f..4c3e182 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -450,7 +450,7 @@
     LayerUpdateQueue layerUpdateQueue;
     layerUpdateQueue.enqueueLayerWithDamage(child.get(),
             android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
-    SkiaPipeline::renderLayersImpl(layerUpdateQueue, true);
+    SkiaPipeline::renderLayersImpl(layerUpdateQueue, true, false);
     EXPECT_EQ(1, drawCounter);  //assert index 0 is drawn on the layer
 
     RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index dafa074..a3d5079 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -17,6 +17,7 @@
 #include "tests/common/TestUtils.h"
 
 #include <gtest/gtest.h>
+#include <SkBlurDrawLooper.h>
 #include <SkColorMatrixFilter.h>
 #include <SkColorSpace.h>
 #include <SkImagePriv.h>
@@ -106,3 +107,16 @@
     sk_sp<SkColorSpace> sRGB2 = SkColorSpace::MakeSRGB();
     ASSERT_EQ(sRGB1.get(), sRGB2.get());
 }
+
+TEST(SkiaBehavior, blurDrawLooper) {
+    sk_sp<SkDrawLooper> looper = SkBlurDrawLooper::Make(SK_ColorRED, 5.0f, 3.0f, 4.0f);
+
+    SkDrawLooper::BlurShadowRec blur;
+    bool success = looper->asABlurShadow(&blur);
+    ASSERT_TRUE(success);
+
+    ASSERT_EQ(SK_ColorRED, blur.fColor);
+    ASSERT_EQ(5.0f, blur.fSigma);
+    ASSERT_EQ(3.0f, blur.fOffset.fX);
+    ASSERT_EQ(4.0f, blur.fOffset.fY);
+}
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 0aecb85..c048dda 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -89,7 +89,6 @@
     sk_sp<Bitmap> adobeBitmap = Bitmap::allocateHeapBitmap(adobeInfo);
     SkBitmap adobeSkBitmap;
     adobeBitmap->getSkBitmap(&adobeSkBitmap);
-    adobeSkBitmap.lockPixels();
     *adobeSkBitmap.getAddr32(0, 0) = 0xFF0000F0; // Opaque, almost fully-red
 
     SkImageInfo info = adobeInfo.makeColorSpace(nullptr);
@@ -101,7 +100,6 @@
     SkiaCanvas canvas(skBitmap);
     canvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
     // The result should be fully red, since we convert to sRGB at draw time.
-    skBitmap.lockPixels();
     ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
 
     // Create a software canvas with an Adobe color space.
@@ -116,7 +114,6 @@
     SkiaCanvas deferCanvas(&skCanvas, Canvas::XformToSRGB::kDefer);
     deferCanvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
     // The result should be as before, since we deferred the conversion to sRGB.
-    skBitmap.lockPixels();
     ASSERT_EQ(0xFF0000DC, *skBitmap.getAddr32(0, 0));
 
     // Test picture recording.  We will kDefer the xform at recording time, but handle it when
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index a895cba..b397b15 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -51,7 +51,8 @@
     auto surface = SkSurface::MakeRasterN32Premul(1, 1);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            opaque, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
 }
 
@@ -72,10 +73,12 @@
     auto surface = SkSurface::MakeRasterN32Premul(2, 2);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            true, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            false, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
 }
@@ -94,7 +97,8 @@
     auto surface = SkSurface::MakeRasterN32Premul(2, 2);
     surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes,
+            true, false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
@@ -135,7 +139,7 @@
     lightGeometry.center = { 0.0f, 0.0f, 0.0f };
     BakedOpRenderer::LightInfo lightInfo;
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
-    pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
+    pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, false, lightInfo);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
@@ -166,32 +170,38 @@
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
 
     // Single draw, should be white.
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
 
     // 1 Overdraw, should be blue blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0d0ff);
 
     // 2 Overdraw, should be green blended onto white
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffd0ffd0);
 
     // 3 Overdraw, should be pink blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffffc0c0);
 
     // 4 Overdraw, should be red blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
 
     // 5 Overdraw, should be red blended onto white.
     renderNodes.push_back(whiteNode);
-    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque,
+            false, contentDrawBounds, surface);
     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned) 0xffff8080);
 }
 
@@ -278,7 +288,7 @@
     SkRect dirty = SkRect::MakeWH(800, 600);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<DeferTestCanvas>> surface(new DeferLayer<DeferTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, contentDrawBounds, surface);
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false, contentDrawBounds, surface);
     EXPECT_EQ(4, surface->canvas()->mDrawCounter);
 }
 
@@ -308,7 +318,7 @@
     SkRect dirty = SkRect::MakeLTRB(10, 20, 30, 40);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<ClippedTestCanvas>> surface(new DeferLayer<ClippedTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
             SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
@@ -339,7 +349,7 @@
     SkRect dirty = SkRect::MakeLTRB(10, 10, 40, 40);
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     sk_sp<DeferLayer<ClipReplaceTestCanvas>> surface(new DeferLayer<ClipReplaceTestCanvas>());
-    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true,
+    pipeline->renderFrame(layerUpdateQueue, dirty, nodes, true, false,
             SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), surface);
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
index 5383e57..8312bda 100644
--- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
@@ -26,7 +26,7 @@
 using namespace android;
 using namespace android::uirenderer;
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, DISABLED_addRemove) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, addRemove) {
     SkPaint paint;
     paint.setTextSize(20);
 
diff --git a/libs/hwui/tests/unit/TextureCacheTests.cpp b/libs/hwui/tests/unit/TextureCacheTests.cpp
index 72384bf..ab740dd 100644
--- a/libs/hwui/tests/unit/TextureCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextureCacheTests.cpp
@@ -31,7 +31,7 @@
     SkBitmap skBitmap;
     SkImageInfo info = SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType);
     skBitmap.setInfo(info);
-    sk_sp<Bitmap> hwBitmap(Bitmap::allocateHardwareBitmap(renderThread, skBitmap));
+    sk_sp<Bitmap> hwBitmap(renderThread.allocateHardwareBitmap(skBitmap));
     cache.get(hwBitmap.get());
     ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount + 1);
     cache.clear();
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 6f264e1..1c21567 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -382,47 +382,24 @@
 
 }
 
-static SkShader* createShader(bool* isDestroyed) {
-    class TestShader : public SkShader {
-    public:
-        TestShader(bool* isDestroyed) : SkShader(), mDestroyed(isDestroyed) {
-        }
-        ~TestShader() {
-            *mDestroyed = true;
-        }
-
-        Factory getFactory() const override { return nullptr; }
-    private:
-        bool* mDestroyed;
-    };
-    return new TestShader(isDestroyed);
-}
-
 TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) {
     VectorDrawable::FullPath path("m1 1", 4);
     SkBitmap bitmap;
-    SkImageInfo info = SkImageInfo::Make(5, 5, kN32_SkColorType, kPremul_SkAlphaType);
-    bitmap.setInfo(info);
-    bitmap.allocPixels(info);
+    bitmap.allocN32Pixels(5, 5, false);
     SkCanvas canvas(bitmap);
 
-    bool shaderIsDestroyed = false;
-
+    sk_sp<SkShader> shader = SkShader::MakeColorShader(SK_ColorBLACK);
     // Initial ref count is 1
-    SkShader* shader = createShader(&shaderIsDestroyed);
+    EXPECT_TRUE(shader->unique());
 
     // Setting the fill gradient increments the ref count of the shader by 1
-    path.mutateStagingProperties()->setFillGradient(shader);
+    path.mutateStagingProperties()->setFillGradient(shader.get());
+    EXPECT_FALSE(shader->unique());
     path.draw(&canvas, true);
     // Resetting the fill gradient decrements the ref count of the shader by 1
     path.mutateStagingProperties()->setFillGradient(nullptr);
 
-    // Expect ref count to be 1 again, i.e. nothing else to have a ref to the shader now. Unref()
-    // again should bring the ref count to zero and consequently trigger detor.
-    shader->unref();
-
-    // Verify that detor is called.
-    EXPECT_TRUE(shaderIsDestroyed);
+    EXPECT_TRUE(shader->unique());
 }
 
 }; // namespace uirenderer
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index 4991f04..ed31b12 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -220,13 +220,13 @@
 
                 if (outBuffer.width > update.state.icon.bitmap.width()) {
                     paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
-                            outBuffer.width, update.state.icon.bitmap.height(), paint);
+                    surfaceCanvas.drawRect(SkRect::MakeLTRB(update.state.icon.bitmap.width(), 0,
+                            outBuffer.width, update.state.icon.bitmap.height()), paint);
                 }
                 if (outBuffer.height > update.state.icon.bitmap.height()) {
                     paint.setColor(0); // transparent fill color
-                    surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
-                            outBuffer.width, outBuffer.height, paint);
+                    surfaceCanvas.drawRect(SkRect::MakeLTRB(0, update.state.icon.bitmap.height(),
+                            outBuffer.width, outBuffer.height), paint);
                 }
 
                 status = surface->unlockAndPost();
@@ -405,7 +405,11 @@
 
     uint32_t dirty;
     if (icon.isValid()) {
-        icon.bitmap.copyTo(&mLocked.state.icon.bitmap, kN32_SkColorType);
+        SkBitmap* bitmapCopy = &mLocked.state.icon.bitmap;
+        if (bitmapCopy->tryAllocPixels(icon.bitmap.info().makeColorType(kN32_SkColorType))) {
+            icon.bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
+                    bitmapCopy->rowBytes(), 0, 0);
+        }
 
         if (!mLocked.state.icon.isValid()
                 || mLocked.state.icon.hotSpotX != icon.hotSpotX
diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h
index 7fc8d6f..31e43e9 100644
--- a/libs/input/SpriteController.h
+++ b/libs/input/SpriteController.h
@@ -65,7 +65,10 @@
 
     inline SpriteIcon copy() const {
         SkBitmap bitmapCopy;
-        bitmap.copyTo(&bitmapCopy, kN32_SkColorType);
+        if (bitmapCopy.tryAllocPixels(bitmap.info().makeColorType(kN32_SkColorType))) {
+            bitmap.readPixels(bitmapCopy.info(), bitmapCopy.getPixels(), bitmapCopy.rowBytes(),
+                    0, 0);
+        }
         return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
     }
 
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index de85c16..d24a477 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -436,8 +436,8 @@
      *     E1BC code lock       : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
      *     E1C 2nd code lock    : [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
      *     E1B page             : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
-     *     Time of week decoded : [ 0 1week ]  : STATE_GAL_TOW_DECODED is set
-     *     Time of week known   : [ 0 1week ]  : STATE_GAL_TOW_KNOWN set</pre>
+     *     Time of week decoded : [ 0 1week ]  : STATE_TOW_DECODED is set
+     *     Time of week known   : [ 0 1week ]  : STATE_TOW_KNOWN set</pre>
      *
      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 912551f..b2903c4 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -97,13 +97,12 @@
             CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
     public @interface ConstellationType {}
 
-    /* These package private values are modified by the LocationManager class */
-    /* package */ int[] mSvidWithFlags;
-    /* package */ float[] mCn0DbHz;
-    /* package */ float[] mElevations;
-    /* package */ float[] mAzimuths;
-    /* package */ int mSvCount;
-    /* package */ float[] mCarrierFrequencies;
+    final int[] mSvidWithFlags;
+    final float[] mCn0DbHz;
+    final float[] mElevations;
+    final float[] mAzimuths;
+    final int mSvCount;
+    final float[] mCarrierFrequencies;
 
     GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
             float[] azimuths, float[] carrierFrequencies) {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 26ac2a2..968f596 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -74,7 +74,8 @@
             new HashMap<>();
     private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
             new HashMap<>();
-    private GnssStatus mGnssStatus;
+    // volatile + GnssStatus final-fields pattern to avoid a partially published object
+    private volatile GnssStatus mGnssStatus;
     private int mTimeToFirstFix;
 
     /**
@@ -1563,7 +1564,7 @@
                 float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFreqs) {
             if (mGnssCallback != null) {
                 mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
-                    carrierFreqs);
+                        carrierFreqs);
 
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
@@ -1949,7 +1950,7 @@
             status = new GpsStatus();
         }
         // When mGnssStatus is null, that means that this method is called outside
-        // onGpsStatusChanged().  Return an empty status  to maintain backwards compatibility.
+        // onGpsStatusChanged().  Return an empty status to maintain backwards compatibility.
         if (mGnssStatus != null) {
             status.setStatus(mGnssStatus, mTimeToFirstFix);
         }
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
new file mode 100644
index 0000000..833376c
--- /dev/null
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -0,0 +1,268 @@
+/*
+ * 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.location.gnssmetrics;
+
+import android.os.SystemClock;
+
+import android.util.Base64;
+import android.util.TimeUtils;
+
+import java.util.Arrays;
+
+import com.android.internal.location.nano.GnssLogsProto.GnssLog;
+
+/**
+ * GnssMetrics: Is used for logging GNSS metrics
+ * @hide
+ */
+public class GnssMetrics {
+
+  /** Default time between location fixes (in millisecs) */
+  private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
+
+  /* The time since boot when logging started */
+  private String logStartInElapsedRealTime;
+
+  /** Constructor */
+  public GnssMetrics() {
+    locationFailureStatistics = new Statistics();
+    timeToFirstFixSecStatistics = new Statistics();
+    positionAccuracyMeterStatistics = new Statistics();
+    topFourAverageCn0Statistics = new Statistics();
+    reset();
+  }
+
+  /**
+   * Logs the status of a location report received from the HAL
+   *
+   * @param isSuccessful
+   */
+  public void logReceivedLocationStatus(boolean isSuccessful) {
+    if (!isSuccessful) {
+      locationFailureStatistics.addItem(1.0);
+      return;
+    }
+    locationFailureStatistics.addItem(0.0);
+    return;
+  }
+
+  /**
+   * Logs missed reports
+   *
+   * @param desiredTimeBetweenFixesMilliSeconds
+   * @param actualTimeBetweenFixesMilliSeconds
+   */
+  public void logMissedReports(int desiredTimeBetweenFixesMilliSeconds,
+      int actualTimeBetweenFixesMilliSeconds) {
+    int numReportMissed = (actualTimeBetweenFixesMilliSeconds /
+        Math.max(DEFAULT_TIME_BETWEEN_FIXES_MILLISECS, desiredTimeBetweenFixesMilliSeconds)) - 1;
+    if (numReportMissed > 0) {
+      for (int i = 0; i < numReportMissed; i++) {
+        locationFailureStatistics.addItem(1.0);
+      }
+    }
+    return;
+  }
+
+  /**
+   * Logs time to first fix
+   *
+   * @param timeToFirstFixMilliSeconds
+   */
+  public void logTimeToFirstFixMilliSecs(int timeToFirstFixMilliSeconds) {
+    timeToFirstFixSecStatistics.addItem((double) (timeToFirstFixMilliSeconds/1000));
+    return;
+  }
+
+  /**
+   * Logs position accuracy
+   *
+   * @param positionAccuracyMeters
+   */
+  public void logPositionAccuracyMeters(float positionAccuracyMeters) {
+    positionAccuracyMeterStatistics.addItem((double) positionAccuracyMeters);
+    return;
+  }
+
+  /*
+  * Logs CN0 when at least 4 SVs are available
+  *
+  */
+  public void logCn0(float[] cn0s, int numSv) {
+    if (numSv < 4) {
+      return;
+    }
+    float[] cn0Array = Arrays.copyOf(cn0s, numSv);
+    Arrays.sort(cn0Array);
+    if (cn0Array[numSv - 4] > 0.0) {
+      double top4AvgCn0 = 0.0;
+      for (int i = numSv - 4; i < numSv; i++) {
+        top4AvgCn0 += (double) cn0Array[i];
+      }
+      top4AvgCn0 /= 4;
+      topFourAverageCn0Statistics.addItem(top4AvgCn0);
+    }
+    return;
+  }
+
+  /**
+   * Dumps GNSS metrics as a proto string
+   * @return
+   */
+  public String dumpGnssMetricsAsProtoString() {
+    GnssLog msg = new GnssLog();
+    if (locationFailureStatistics.getCount() > 0) {
+      msg.numLocationReportProcessed = locationFailureStatistics.getCount();
+      msg.percentageLocationFailure = (int) (100.0 * locationFailureStatistics.getMean());
+    }
+    if (timeToFirstFixSecStatistics.getCount() > 0) {
+      msg.numTimeToFirstFixProcessed = timeToFirstFixSecStatistics.getCount();
+      msg.meanTimeToFirstFixSecs = (int) timeToFirstFixSecStatistics.getMean();
+      msg.standardDeviationTimeToFirstFixSecs
+          = (int) timeToFirstFixSecStatistics.getStandardDeviation();
+    }
+    if (positionAccuracyMeterStatistics.getCount() > 0) {
+      msg.numPositionAccuracyProcessed = positionAccuracyMeterStatistics.getCount();
+      msg.meanPositionAccuracyMeters = (int) positionAccuracyMeterStatistics.getMean();
+      msg.standardDeviationPositionAccuracyMeters
+          = (int) positionAccuracyMeterStatistics.getStandardDeviation();
+    }
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      msg.numTopFourAverageCn0Processed = topFourAverageCn0Statistics.getCount();
+      msg.meanTopFourAverageCn0DbHz = topFourAverageCn0Statistics.getMean();
+      msg.standardDeviationTopFourAverageCn0DbHz
+          = topFourAverageCn0Statistics.getStandardDeviation();
+    }
+    String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
+    reset();
+    return s;
+  }
+
+  /**
+   * Dumps GNSS Metrics as text
+   *
+   * @return GNSS Metrics
+   */
+  public String dumpGnssMetricsAsText() {
+    StringBuilder s = new StringBuilder();
+    s.append("GNSS_KPI_START").append('\n');
+    s.append("  KPI logging start time: ").append(logStartInElapsedRealTime).append("\n");
+    s.append("  KPI logging end time: ");
+    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+    s.append("\n");
+    s.append("  Number of location reports: ").append(
+        locationFailureStatistics.getCount()).append("\n");
+    if (locationFailureStatistics.getCount() > 0) {
+      s.append("  Percentage location failure: ").append(
+          100.0 * locationFailureStatistics.getMean()).append("\n");
+    }
+    s.append("  Number of TTFF reports: ").append(
+        timeToFirstFixSecStatistics.getCount()).append("\n");
+    if (timeToFirstFixSecStatistics.getCount() > 0) {
+      s.append("  TTFF mean (sec): ").append(timeToFirstFixSecStatistics.getMean()).append("\n");
+      s.append("  TTFF standard deviation (sec): ").append(
+          timeToFirstFixSecStatistics.getStandardDeviation()).append("\n");
+    }
+    s.append("  Number of position accuracy reports: ").append(
+        positionAccuracyMeterStatistics.getCount()).append("\n");
+    if (positionAccuracyMeterStatistics.getCount() > 0) {
+      s.append("  Position accuracy mean (m): ").append(
+          positionAccuracyMeterStatistics.getMean()).append("\n");
+      s.append("  Position accuracy standard deviation (m): ").append(
+          positionAccuracyMeterStatistics.getStandardDeviation()).append("\n");
+    }
+    s.append("  Number of CN0 reports: ").append(
+        topFourAverageCn0Statistics.getCount()).append("\n");
+    if (topFourAverageCn0Statistics.getCount() > 0) {
+      s.append("  Top 4 Avg CN0 mean (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getMean()).append("\n");
+      s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
+          topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
+    }
+    s.append("GNSS_KPI_END").append("\n");
+    return s.toString();
+  }
+
+   /** Class for storing statistics */
+  private class Statistics {
+
+    /** Resets statistics */
+    public void reset() {
+      count = 0;
+      sum = 0.0;
+      sumSquare = 0.0;
+    }
+
+    /** Adds an item */
+    public void addItem(double item) {
+      count++;
+      sum += item;
+      sumSquare += item * item;
+    }
+
+    /** Returns number of items added */
+    public int getCount() {
+      return count;
+    }
+
+    /** Returns mean */
+    public double getMean() {
+      return sum/count;
+    }
+
+    /** Returns standard deviation */
+    public double getStandardDeviation() {
+      double m = sum/count;
+      m = m * m;
+      double v = sumSquare/count;
+      if (v > m) {
+        return Math.sqrt(v - m);
+      }
+      return 0;
+    }
+
+    private int count;
+    private double sum;
+    private double sumSquare;
+  }
+
+  /** Location failure statistics */
+  private Statistics locationFailureStatistics;
+
+  /** Time to first fix statistics */
+  private Statistics timeToFirstFixSecStatistics;
+
+  /** Position accuracy statistics */
+  private Statistics positionAccuracyMeterStatistics;
+
+  /** Top 4 average CN0 statistics */
+  private Statistics topFourAverageCn0Statistics;
+
+  /**
+   * Resets GNSS metrics
+   */
+  private void reset() {
+    StringBuilder s = new StringBuilder();
+    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+    logStartInElapsedRealTime = s.toString();
+    locationFailureStatistics.reset();
+    timeToFirstFixSecStatistics.reset();
+    positionAccuracyMeterStatistics.reset();
+    topFourAverageCn0Statistics.reset();
+    return;
+  }
+}
\ No newline at end of file
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c1e81c5..f403988 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -218,6 +218,7 @@
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
     }
 
     /**
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 20deeb16..05be088 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1501,7 +1501,9 @@
         if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"")
                 == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
             AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"")
-                == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
+                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
+            AudioSystem.getDeviceConnectionState(DEVICE_OUT_USB_HEADSET, "")
+              == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
             return false;
         } else {
             return true;
@@ -3324,6 +3326,9 @@
      * The audio output device code for a wired headphone without attached microphone */
     public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
     /** @hide
+     * The audio output device code for a USB headphone with attached microphone */
+    public static final int DEVICE_OUT_USB_HEADSET = AudioSystem.DEVICE_OUT_USB_HEADSET;
+    /** @hide
      * The audio output device code for generic Bluetooth SCO, for voice */
     public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
     /** @hide
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 0a1de33..2b5ac5e 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -59,4 +59,15 @@
 
         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/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 47ecf32..ea4d802 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -424,7 +424,8 @@
                                                   DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                                   DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
     public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
-                                                  DEVICE_OUT_USB_DEVICE);
+                                                  DEVICE_OUT_USB_DEVICE |
+                                                  DEVICE_OUT_USB_HEADSET);
     public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE |
                                                                 DEVICE_OUT_HDMI_ARC |
                                                                 DEVICE_OUT_SPDIF);
@@ -486,7 +487,8 @@
                                              DEVICE_IN_DEFAULT);
     public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
-                                                 DEVICE_IN_USB_DEVICE);
+                                                 DEVICE_IN_USB_DEVICE |
+                                                 DEVICE_IN_USB_HEADSET);
 
     // device states, must match AudioSystem::device_connection_state
     public static final int DEVICE_STATE_UNAVAILABLE = 0;
@@ -758,6 +760,8 @@
 
     public static native int systemReady();
 
+    public static native float getStreamVolumeDB(int stream, int index, int device);
+
     // Items shared with audio service
 
     /**
@@ -799,14 +803,14 @@
         4,  // STREAM_VOICE_CALL
         7,  // STREAM_SYSTEM
         5,  // STREAM_RING
-        11, // STREAM_MUSIC
+        5, // STREAM_MUSIC
         6,  // STREAM_ALARM
         5,  // STREAM_NOTIFICATION
         7,  // STREAM_BLUETOOTH_SCO
         7,  // STREAM_SYSTEM_ENFORCED
-        11, // STREAM_DTMF
-        11, // STREAM_TTS
-        11, // STREAM_ACCESSIBILITY
+        5, // STREAM_DTMF
+        5, // STREAM_TTS
+        5, // STREAM_ACCESSIBILITY
     };
 
     public static String streamToString(int stream) {
diff --git a/media/java/android/media/IMediaRouterClient.aidl b/media/java/android/media/IMediaRouterClient.aidl
index 9640dcb..08344f1 100644
--- a/media/java/android/media/IMediaRouterClient.aidl
+++ b/media/java/android/media/IMediaRouterClient.aidl
@@ -21,4 +21,5 @@
  */
 oneway interface IMediaRouterClient {
     void onStateChanged();
+    void onRestoreRoute();
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f8f5fdf..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -27,6 +27,7 @@
     void unregisterClient(IMediaRouterClient client);
 
     MediaRouterClientState getState(IMediaRouterClient client);
+    boolean isPlaybackActive(IMediaRouterClient client);
 
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index abf6b20..2a0e04e 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -62,6 +62,7 @@
             case ImageFormat.RAW12:
             case ImageFormat.DEPTH16:
             case ImageFormat.DEPTH_POINT_CLOUD:
+            case ImageFormat.RAW_DEPTH:
                 return 1;
             case ImageFormat.PRIVATE:
                 return 0;
@@ -103,6 +104,10 @@
             throw new IllegalArgumentException(
                     "Copy of RAW_OPAQUE format has not been implemented");
         }
+        if (src.getFormat() == ImageFormat.RAW_DEPTH) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_DEPTH format has not been implemented");
+        }
         if (!(dst.getOwner() instanceof ImageWriter)) {
             throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
                     + " the images from ImageWriter are writable");
@@ -206,6 +211,7 @@
             case PixelFormat.RGB_565:
             case ImageFormat.YUY2:
             case ImageFormat.Y16:
+            case ImageFormat.RAW_DEPTH:
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
             case ImageFormat.DEPTH16:
@@ -253,6 +259,7 @@
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW10:
             case ImageFormat.RAW12:
+            case ImageFormat.RAW_DEPTH:
                 return new Size(image.getWidth(), image.getHeight());
             case ImageFormat.PRIVATE:
                 return new Size(0, 0);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2de69e7..9b74656 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -339,6 +339,12 @@
         (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
    </tr>
    <tr>
+    <td>FLAC</td>
+    <td>Metadata blocks</td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
     <td>MPEG-4</td>
     <td>Decoder-specific information from ESDS<sup>*</sup></td>
     <td class=NA>Not Used</td>
@@ -2440,6 +2446,8 @@
             }
         };
 
+        private final Pattern zeroPattern = new Pattern(0, 0);
+
         /**
          * The pattern applicable to the protected data in each subsample.
          */
@@ -2462,7 +2470,7 @@
             key = newKey;
             iv = newIV;
             mode = newMode;
-            pattern = new Pattern(0, 0);
+            pattern = zeroPattern;
         }
 
         /**
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index dd731df..aae1f51 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -61,9 +61,9 @@
     private final static int MAX_REDIRECTS = 20;
 
     public MediaHTTPConnection() {
-        CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
-        if (cookieManager == null) {
-            Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieManager found.");
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler == null) {
+            Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieHandler found.");
         }
 
         native_setup();
diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java
index b678630..3a0e58a 100644
--- a/media/java/android/media/MediaHTTPService.java
+++ b/media/java/android/media/MediaHTTPService.java
@@ -41,34 +41,40 @@
         synchronized (mCookieStoreInitialized) {
             // Only need to do it once for all connections
             if ( !mCookieStoreInitialized )  {
-                CookieManager cookieManager = (CookieManager)CookieHandler.getDefault();
-                if (cookieManager == null) {
-                    cookieManager = new CookieManager();
-                    CookieHandler.setDefault(cookieManager);
-                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieManager);
-                }
-                else {
-                    Log.v(TAG, "makeHTTPConnection: CookieManager(" + cookieManager + ") exists.");
+                CookieHandler cookieHandler = CookieHandler.getDefault();
+                if (cookieHandler == null) {
+                    cookieHandler = new CookieManager();
+                    CookieHandler.setDefault(cookieHandler);
+                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieHandler);
+                } else {
+                    Log.v(TAG, "makeHTTPConnection: CookieHandler (" + cookieHandler + ") exists.");
                 }
 
                 // Applying the bootstrapping cookies
                 if ( mCookies != null ) {
-                    CookieStore store = cookieManager.getCookieStore();
-                    for ( HttpCookie cookie : mCookies ) {
-                        try {
-                            store.add(null, cookie);
-                        } catch ( Exception e ) {
-                            Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
+                    if ( cookieHandler instanceof CookieManager ) {
+                        CookieManager cookieManager = (CookieManager)cookieHandler;
+                        CookieStore store = cookieManager.getCookieStore();
+                        for ( HttpCookie cookie : mCookies ) {
+                            try {
+                                store.add(null, cookie);
+                            } catch ( Exception e ) {
+                                Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
+                            }
+                            //for extended debugging when needed
+                            //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
+                            //        "]: " + cookie);
                         }
-                        //for extended debugging when needed
-                        //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
-                        //        "]: " + cookie);
+                    } else {
+                        Log.w(TAG, "makeHTTPConnection: The installed CookieHandler is not a "
+                                + "CookieManager. Can’t add the provided cookies to the cookie "
+                                + "store.");
                     }
                 }   // mCookies
 
                 mCookieStoreInitialized = true;
 
-                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieManager: " + cookieManager +
+                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieHandler: " + cookieHandler +
                         " Cookies: " + mCookies);
             }   // mCookieStoreInitialized
         }   // synchronized
@@ -92,5 +98,4 @@
 
         return null;
     }
-
 }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 5cbccea..5a16c36 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -73,6 +73,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.net.CookieHandler;
+import java.net.CookieManager;
 import java.net.HttpCookie;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
@@ -1004,19 +1006,28 @@
     /**
      * Sets the data source as a content Uri.
      *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param headers the headers to be sent together with the request for the data
-     *                The headers must not include cookies. Instead, use the cookies param.
-     * @param cookies the cookies to be sent together with the request
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws NullPointerException  if context or uri is null
-     * @throws IOException           if uri has a file scheme and an I/O error occurs
+     * To provide cookies for the subsequent HTTP requests, you can install your own default cookie
+     * handler and use other variants of setDataSource APIs instead. Alternatively, you can use
+     * this API to pass the cookies as a list of HttpCookie. If the app has not installed
+     * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with
+     * the provided cookies. If the app has installed its own handler already, this API requires the
+     * handler to be of CookieManager type such that the API can update the manager’s CookieStore.
      *
      * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
      * but that can be changed with key/value pairs through the headers parameter with
      * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
      * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     *                The headers must not include cookies. Instead, use the cookies param.
+     * @param cookies the cookies to be sent together with the request
+     * @throws IllegalArgumentException if cookies are provided and the installed handler is not
+     *                                  a CookieManager
+     * @throws IllegalStateException    if it is called in an invalid state
+     * @throws NullPointerException     if context or uri is null
+     * @throws IOException              if uri has a file scheme and an I/O error occurs
      */
     public void setDataSource(@NonNull Context context, @NonNull Uri uri,
             @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
@@ -1029,6 +1040,14 @@
             throw new NullPointerException("uri param can not be null.");
         }
 
+        if (cookies != null) {
+            CookieHandler cookieHandler = CookieHandler.getDefault();
+            if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) {
+                throw new IllegalArgumentException("The cookie handler has to be of CookieManager "
+                        + "type when cookies are provided.");
+            }
+        }
+
         // The context and URI usually belong to the calling user. Get a resolver for that user
         // and strip out the userId from the URI if present.
         final ContentResolver resolver = context.getContentResolver();
@@ -1064,15 +1083,15 @@
     /**
      * Sets the data source as a content Uri.
      *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param headers the headers to be sent together with the request for the data
-     * @throws IllegalStateException if it is called in an invalid state
-     *
      * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
      * but that can be changed with key/value pairs through the headers parameter with
      * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
      * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(@NonNull Context context, @NonNull Uri uri,
             @Nullable Map<String, String> headers)
@@ -1093,15 +1112,15 @@
     /**
      * Sets the data source (file-path or http/rtsp URL) to use.
      *
-     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
-     * @throws IllegalStateException if it is called in an invalid state
-     *
      * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
      * process other than the calling application.  This implies that the pathname
      * should be an absolute path (as any other process runs with unspecified current working
      * directory), and that the pathname should reference a world-readable file.
      * As an alternative, the application could first open the file for reading,
      * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
+     *
+     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+     * @throws IllegalStateException if it is called in an invalid state
      */
     public void setDataSource(String path)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
@@ -1332,7 +1351,7 @@
     private native int _getAudioStreamType() throws IllegalStateException;
 
     /**
-     * Stops playback after playback has been stopped or paused.
+     * Stops playback after playback has been started or paused.
      *
      * @throws IllegalStateException if the internal player engine has not been
      * initialized.
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 91dada7..80a0315 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -88,6 +88,7 @@
         RouteInfo mBluetoothA2dpRoute;
 
         RouteInfo mSelectedRoute;
+        RouteInfo mSystemAudioRoute;
 
         final boolean mCanConfigureWifiDisplays;
         boolean mActivelyScanningWifiDisplays;
@@ -149,6 +150,7 @@
             }
 
             addRouteStatic(mDefaultAudioVideo);
+            mSystemAudioRoute = mDefaultAudioVideo;
 
             // This will select the active wifi display route if there is one.
             updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
@@ -197,8 +199,8 @@
                 } else {
                     name = com.android.internal.R.string.default_audio_route_name;
                 }
-                sStatic.mDefaultAudioVideo.mNameResId = name;
-                dispatchRouteChanged(sStatic.mDefaultAudioVideo);
+                mDefaultAudioVideo.mNameResId = name;
+                dispatchRouteChanged(mDefaultAudioVideo);
                 updated = true;
             }
 
@@ -207,22 +209,28 @@
             if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
                 mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
                 if (mCurAudioRoutesInfo.bluetoothName != null) {
-                    if (sStatic.mBluetoothA2dpRoute == null) {
-                        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
+                    if (mBluetoothA2dpRoute == null) {
+                        // BT connected
+                        final RouteInfo info = new RouteInfo(mSystemCategory);
                         info.mName = mCurAudioRoutesInfo.bluetoothName;
-                        info.mDescription = sStatic.mResources.getText(
+                        info.mDescription = mResources.getText(
                                 com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                         info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH;
-                        sStatic.mBluetoothA2dpRoute = info;
-                        addRouteStatic(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute = info;
+                        addRouteStatic(mBluetoothA2dpRoute);
+                        mSystemAudioRoute = mBluetoothA2dpRoute;
+                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                     } else {
-                        sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
-                        dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
+                        mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.bluetoothName;
+                        dispatchRouteChanged(mBluetoothA2dpRoute);
                     }
-                } else if (sStatic.mBluetoothA2dpRoute != null) {
-                    removeRouteStatic(sStatic.mBluetoothA2dpRoute);
-                    sStatic.mBluetoothA2dpRoute = null;
+                } else if (mBluetoothA2dpRoute != null) {
+                    // BT disconnected
+                    removeRouteStatic(mBluetoothA2dpRoute);
+                    mBluetoothA2dpRoute = null;
+                    mSystemAudioRoute = mDefaultAudioVideo;
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mSystemAudioRoute, false);
                 }
                 updated = true;
             }
@@ -230,11 +238,13 @@
             if (mBluetoothA2dpRoute != null) {
                 final boolean a2dpEnabled = isBluetoothA2dpOn();
                 if (mSelectedRoute == mBluetoothA2dpRoute && !a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
+                    // A2DP off
+                    mSystemAudioRoute = mDefaultAudioVideo;
                     updated = true;
                 } else if ((mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
                         a2dpEnabled) {
-                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
+                    // A2DP on or BT connected
+                    mSystemAudioRoute = mBluetoothA2dpRoute;
                     updated = true;
                 }
             }
@@ -417,8 +427,6 @@
             }
             final ArrayList<MediaRouterClientState.RouteInfo> globalRoutes =
                     mClientState != null ? mClientState.routes : null;
-            final String globallySelectedRouteId = mClientState != null ?
-                    mClientState.globallySelectedRouteId : null;
 
             // Add or update routes.
             final int globalRouteCount = globalRoutes != null ? globalRoutes.size() : 0;
@@ -433,25 +441,6 @@
                 }
             }
 
-            // Synchronize state with the globally selected route.
-            if (globallySelectedRouteId != null) {
-                final RouteInfo route = findGlobalRoute(globallySelectedRouteId);
-                if (route == null) {
-                    Log.w(TAG, "Could not find new globally selected route: "
-                            + globallySelectedRouteId);
-                } else if (route != mSelectedRoute) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Selecting new globally selected route: " + route);
-                    }
-                    selectRouteStatic(route.mSupportedTypes, route, false);
-                }
-            } else if (mSelectedRoute != null && mSelectedRoute.mGlobalRouteId != null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Unselecting previous globally selected route: " + mSelectedRoute);
-                }
-                selectDefaultRouteStatic();
-            }
-
             // Remove defunct routes.
             outer: for (int i = mRoutes.size(); i-- > 0; ) {
                 final RouteInfo route = mRoutes.get(i);
@@ -492,7 +481,7 @@
         }
 
         RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) {
-            RouteInfo route = new RouteInfo(sStatic.mSystemCategory);
+            RouteInfo route = new RouteInfo(mSystemCategory);
             route.mGlobalRouteId = globalRoute.id;
             route.mName = globalRoute.name;
             route.mDescription = globalRoute.description;
@@ -588,6 +577,17 @@
             return null;
         }
 
+        boolean isPlaybackActive() {
+            if (mClient != null) {
+                try {
+                    return mMediaRouterService.isPlaybackActive(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to retrieve playback active state.", ex);
+                }
+            }
+            return false;
+        }
+
         final class Client extends IMediaRouterClient.Stub {
             @Override
             public void onStateChanged() {
@@ -600,6 +600,19 @@
                     }
                 });
             }
+
+            @Override
+            public void onRestoreRoute() {
+                if ((mSelectedRoute != mDefaultAudioVideo && mSelectedRoute != mBluetoothA2dpRoute)
+                        || mSelectedRoute == mSystemAudioRoute) {
+                    return;
+                }
+                try {
+                    sStatic.mAudioService.setBluetoothA2dpOn(mSelectedRoute == mBluetoothA2dpRoute);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error changing Bluetooth A2DP state", e);
+                }
+            }
         }
     }
 
@@ -753,6 +766,15 @@
     }
 
     /**
+     * Returns a Bluetooth route if available, otherwise the default route.
+     * @hide
+     */
+    public RouteInfo getFallbackRoute() {
+        return (sStatic.mBluetoothA2dpRoute != null)
+                ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo;
+    }
+
+    /**
      * @hide for use by framework routing UI
      */
     public RouteCategory getSystemCategory() {
@@ -921,7 +943,12 @@
         Log.v(TAG, "Selecting route: " + route);
         assert(route != null);
         final RouteInfo oldRoute = sStatic.mSelectedRoute;
-        if (oldRoute == route) return;
+        boolean wasDefaultOrBluetoothRoute = (oldRoute == sStatic.mDefaultAudioVideo
+                || oldRoute == sStatic.mBluetoothA2dpRoute);
+        if (oldRoute == route
+                && (!wasDefaultOrBluetoothRoute || oldRoute == sStatic.mSystemAudioRoute)) {
+            return;
+        }
         if (!route.matchesTypes(types)) {
             Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
                     typesToString(route.getSupportedTypes()) + " into route types " +
@@ -930,10 +957,23 @@
         }
 
         final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
-        if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
-                (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
+        if (sStatic.isPlaybackActive() && btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0
+                && (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
             try {
                 sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
+                // TODO: Remove the following logging when no longer needed.
+                if (route != btRoute) {
+                    StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+                    StringBuffer sb = new StringBuffer();
+                    // callStack[3] is the caller of this method.
+                    for (int i = 3; i < callStack.length; i++) {
+                        StackTraceElement caller = callStack[i];
+                        sb.append(caller.getClassName() + "." + caller.getMethodName()
+                                + ":" + caller.getLineNumber()).append("  ");
+                    }
+                    Log.w(TAG, "Default route is selected while a BT route is available: pkgName="
+                            + sStatic.mPackageName + ", callers=" + sb.toString());
+                }
             } catch (RemoteException e) {
                 Log.e(TAG, "Error changing Bluetooth A2DP state", e);
             }
@@ -2020,6 +2060,11 @@
         }
 
         /** @hide */
+        public boolean isBluetooth() {
+            return this == sStatic.mBluetoothA2dpRoute;
+        }
+
+        /** @hide */
         public void select() {
             selectRouteStatic(mSupportedTypes, this, true);
         }
diff --git a/media/java/android/media/MediaRouterClientState.java b/media/java/android/media/MediaRouterClientState.java
index 34e18f6..7643924 100644
--- a/media/java/android/media/MediaRouterClientState.java
+++ b/media/java/android/media/MediaRouterClientState.java
@@ -34,20 +34,12 @@
      */
     public final ArrayList<RouteInfo> routes;
 
-    /**
-     * The id of the current globally selected route, or null if none.
-     * Globally selected routes override any other route selections that applications
-     * may have made.  Used for remote displays.
-     */
-    public String globallySelectedRouteId;
-
     public MediaRouterClientState() {
         routes = new ArrayList<RouteInfo>();
     }
 
     MediaRouterClientState(Parcel src) {
         routes = src.createTypedArrayList(RouteInfo.CREATOR);
-        globallySelectedRouteId = src.readString();
     }
 
     public RouteInfo getRoute(String id) {
@@ -69,13 +61,11 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeTypedList(routes);
-        dest.writeString(globallySelectedRouteId);
     }
 
     @Override
     public String toString() {
-        return "MediaRouterClientState{ globallySelectedRouteId="
-                + globallySelectedRouteId + ", routes=" + routes.toString() + " }";
+        return "MediaRouterClientState{ routes=" + routes.toString() + " }";
     }
 
     public static final Parcelable.Creator<MediaRouterClientState> CREATOR =
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index ddfa025..cb4e46f 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1958,7 +1958,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index dbbbfc6..26e65dd 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -57,10 +57,10 @@
  * SoundPool will automatically stop a previously playing stream based first
  * on priority and then by age within that priority. Limiting the maximum
  * number of streams helps to cap CPU loading and reducing the likelihood that
- * audio mixing will impact visuals or UI performance.</p> 
+ * audio mixing will impact visuals or UI performance.</p>
  *
  * <p>Sounds can be looped by setting a non-zero loop value. A value of -1
- * causes the sound to loop forever. In this case, the application must 
+ * causes the sound to loop forever. In this case, the application must
  * explicitly call the stop() function to stop the sound. Any other non-zero
  * value will cause the sound to repeat the specified number of times, e.g.
  * a value of 3 causes the sound to play a total of 4 times.</p>
@@ -101,7 +101,7 @@
  * <p>Note that since streams can be stopped due to resource constraints, the
  * streamID is a reference to a particular instance of a stream. If the stream
  * is stopped to allow a higher priority stream to play, the stream is no
- * longer be valid. However, the application is allowed to call methods on
+ * longer valid. However, the application is allowed to call methods on
  * the streamID without error. This may help simplify program logic since
  * the application need not concern itself with the stream lifecycle.</p>
  *
@@ -137,7 +137,7 @@
      *
      * @param maxStreams the maximum number of simultaneous streams for this
      *                   SoundPool object
-     * @param streamType the audio stream type as described in AudioManager 
+     * @param streamType the audio stream type as described in AudioManager
      *                   For example, game applications will normally use
      *                   {@link AudioManager#STREAM_MUSIC}.
      * @param srcQuality the sample-rate converter quality. Currently has no
@@ -213,7 +213,7 @@
      * "R.raw.explosion" as the resource ID. Note that this means you cannot
      * have both an "explosion.wav" and an "explosion.mp3" in the res/raw
      * directory.
-     * 
+     *
      * @param context the application context
      * @param resId the resource ID
      * @param priority the priority of the sound. Currently has no effect. Use
@@ -287,7 +287,7 @@
     /**
      * Play a sound from a sound ID.
      *
-     * Play the sound specified by the soundID. This is the value 
+     * Play the sound specified by the soundID. This is the value
      * returned by the load() function. Returns a non-zero streamID
      * if successful, zero if it fails. The streamID can be used to
      * further control playback. Note that calling play() may cause
@@ -509,7 +509,7 @@
         }
     }
 
-    private native final int _load(FileDescriptor fd, long offset, long length, int priority); 
+    private native final int _load(FileDescriptor fd, long offset, long length, int priority);
 
     private native final int native_setup(Object weakRef, int maxStreams,
             Object/*AudioAttributes*/ attributes);
diff --git a/media/java/android/media/midi/IMidiDeviceServer.aidl b/media/java/android/media/midi/IMidiDeviceServer.aidl
index fbd3510..59f0f23 100644
--- a/media/java/android/media/midi/IMidiDeviceServer.aidl
+++ b/media/java/android/media/midi/IMidiDeviceServer.aidl
@@ -24,12 +24,14 @@
     FileDescriptor openInputPort(IBinder token, int portNumber);
     FileDescriptor openOutputPort(IBinder token, int portNumber);
     void closePort(IBinder token);
-    void closeDevice();
+    oneway void closeDevice();
 
     // connects the input port pfd to the specified output port
     // Returns the PID of the called process.
     int connectPorts(IBinder token, in FileDescriptor fd, int outputPortNumber);
 
     MidiDeviceInfo getDeviceInfo();
-    void setDeviceInfo(in MidiDeviceInfo deviceInfo);
+
+    // For use by MidiService.
+    oneway void setDeviceInfo(in MidiDeviceInfo deviceInfo);
 }
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index f7dd0b3..a995736 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -103,7 +103,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mGuard.warnIfOpen();
+                if (mGuard != null) {
+                    mGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
@@ -285,7 +288,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java
index eaa8654..51d5520 100644
--- a/media/java/android/media/midi/MidiDeviceServer.java
+++ b/media/java/android/media/midi/MidiDeviceServer.java
@@ -429,7 +429,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java
index 98ec779..a300886 100644
--- a/media/java/android/media/midi/MidiInputPort.java
+++ b/media/java/android/media/midi/MidiInputPort.java
@@ -159,7 +159,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             // not safe to make binder calls from finalize()
             mDeviceServer = null;
             close();
diff --git a/media/java/android/media/midi/MidiOutputPort.java b/media/java/android/media/midi/MidiOutputPort.java
index ce0402c..511f6cd 100644
--- a/media/java/android/media/midi/MidiOutputPort.java
+++ b/media/java/android/media/midi/MidiOutputPort.java
@@ -145,7 +145,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mGuard.warnIfOpen();
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
             // not safe to make binder calls from finalize()
             mDeviceServer = null;
             close();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 9536d3d..1291dfb 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -43,6 +43,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.ViewConfiguration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -201,8 +202,7 @@
                 return;
             }
             if (mCallback != null) {
-                // We're updating the callback, clear the session from the old
-                // one.
+                // We're updating the callback, clear the session from the old one.
                 mCallback.mCallback.mSession = null;
             }
             if (handler == null) {
@@ -736,6 +736,8 @@
      */
     public abstract static class Callback {
         private MediaSession mSession;
+        private CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
 
         public Callback() {
         }
@@ -767,13 +769,41 @@
          * @return True if the event was handled, false otherwise.
          */
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
-            if (mSession != null
+            if (mSession != null && mHandler != null
                     && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
                 KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                 if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
                     PlaybackState state = mSession.mPlaybackState;
                     long validActions = state == null ? 0 : state.getActions();
                     switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mHandler.sendEmptyMessageDelayed(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                                        ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
                         case KeyEvent.KEYCODE_MEDIA_PLAY:
                             if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
                                 onPlay();
@@ -816,28 +846,33 @@
                                 return true;
                             }
                             break;
-                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                        case KeyEvent.KEYCODE_HEADSETHOOK:
-                            boolean isPlaying = state == null ? false
-                                    : state.getState() == PlaybackState.STATE_PLAYING;
-                            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PLAY)) != 0;
-                            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                                    | PlaybackState.ACTION_PAUSE)) != 0;
-                            if (isPlaying && canPause) {
-                                onPause();
-                                return true;
-                            } else if (!isPlaying && canPlay) {
-                                onPlay();
-                                return true;
-                            }
-                            break;
                     }
                 }
             }
             return false;
         }
 
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSession.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                        | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
         /**
          * Override to handle requests to prepare playback. During the preparation, a session should
          * not hold audio focus in order to allow other sessions play seamlessly. The state of
@@ -1317,12 +1352,14 @@
         private static final int MSG_CUSTOM_ACTION = 20;
         private static final int MSG_ADJUST_VOLUME = 21;
         private static final int MSG_SET_VOLUME = 22;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
 
         private MediaSession.Callback mCallback;
 
         public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
             super(looper, null, true);
             mCallback = callback;
+            mCallback.mHandler = this;
         }
 
         public void post(int what, Object obj, Bundle bundle) {
@@ -1424,6 +1461,9 @@
                         vp.onSetVolumeTo((int) msg.obj);
                     }
                     break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
             }
         }
     }
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
index a48abff..7969ee7 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -138,7 +138,7 @@
         }
 
         /**
-         * Gets the raw audio that triggered the keyphrase.
+         * Gets the raw audio that triggered the detector.
          * This may be null if the trigger audio isn't available.
          * If non-null, the format of the audio can be obtained by calling
          * {@link #getCaptureAudioFormat()}.
@@ -155,6 +155,24 @@
         }
 
         /**
+         * Gets the opaque data passed from the detection engine for the event.
+         * This may be null if it was not populated by the engine, or if the data is known to
+         * contain the trigger audio.
+         *
+         * @see #getTriggerAudio
+         *
+         * @hide
+         */
+        @Nullable
+        public byte[] getData() {
+            if (!mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
          * Gets the session ID to start a capture from the DSP.
          * This may be null if streaming capture isn't possible.
          * If non-null, the format of the audio that can be captured can be
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index 7f8140a..92ffae0 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -15,7 +15,9 @@
  */
 
 package android.media.soundtrigger;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
 
+import android.app.PendingIntent;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -23,6 +25,10 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
@@ -178,4 +184,144 @@
             return mGenericSoundModel;
         }
     }
+
+
+    /**
+     * Default message type.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_UNKNOWN = -1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a RecognitionEvent.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_EVENT = 0;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition error events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_ERROR = 1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a recognition paused events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED = 2;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition resumed events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED = 3;
+
+    /**
+     * Extra key in the intent for the type of the message.
+     * @hide
+     */
+    public static final String EXTRA_MESSAGE_TYPE = "android.media.soundtrigger.MESSAGE_TYPE";
+    /**
+     * Extra key in the intent that holds the RecognitionEvent parcelable.
+     * @hide
+     */
+    public static final String EXTRA_RECOGNITION_EVENT = "android.media.soundtrigger.RECOGNITION_EVENT";
+    /**
+     * Extra key in the intent that holds the status in an error message.
+     * @hide
+     */
+    public static final String EXTRA_STATUS = "android.media.soundtrigger.STATUS";
+
+    /**
+     * Loads a given sound model into the sound trigger. Note the model will be unloaded if there is
+     * an error/the system service is restarted.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int loadSoundModel(SoundModel soundModel) {
+        if (soundModel == null) {
+            return STATUS_ERROR;
+        }
+
+        try {
+            switch (soundModel.type) {
+                case SoundModel.TYPE_GENERIC_SOUND:
+                    return mSoundTriggerService.loadGenericSoundModel(
+                            (GenericSoundModel) soundModel);
+                case SoundModel.TYPE_KEYPHRASE:
+                    return mSoundTriggerService.loadKeyphraseSoundModel(
+                            (KeyphraseSoundModel) soundModel);
+                default:
+                    Slog.e(TAG, "Unkown model type");
+                    return STATUS_ERROR;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Starts recognition on the given model id. All events from the model will be sent to the
+     * PendingIntent.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int startRecognition(UUID soundModelId, PendingIntent callbackIntent,
+            RecognitionConfig config) {
+        if (soundModelId == null || callbackIntent == null || config == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.startRecognitionForIntent(new ParcelUuid(soundModelId),
+                    callbackIntent, config);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stops the given model's recognition.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int stopRecognition(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.stopRecognitionForIntent(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the given model from memory. Will also stop any pending recognitions.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int unloadSoundModel(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerService.unloadSoundModel(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if the given model has had detection started on it.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public boolean isRecognitionActive(UUID soundModelId) {
+        if (soundModelId == null) {
+            return false;
+        }
+        try {
+            return mSoundTriggerService.isRecognitionActive(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 07cfbda..df87e0f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -367,7 +367,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (mTvInputSessionImpl == null) {
                 // The session has been finished.
                 finishInputEvent(event, false);
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index e7da20b..102e02d 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -601,10 +601,12 @@
      * given time frame.
      *
      * @param channelId The ID of the channel to return programs for.
-     * @param startTime The start time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
-     * @param endTime The end time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     * @param startTime The start time used to filter programs. The returned programs will have a
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than or equal to
+                  {@code startTime}.
+     * @param endTime The end time used to filter programs. The returned programs will have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than or equal to
+     *            {@code endTime}.
      */
     public static Uri buildProgramsUriForChannel(long channelId, long startTime,
             long endTime) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7b5f778..e24124d 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -974,7 +974,7 @@
          * seek to a position earlier than the start position.
          *
          * <p>For playback of a recorded program initiated by {@link #onTimeShiftPlay(Uri)}, the
-         * start position is the time when playback starts. It does not change.
+         * start position should be 0 and does not change.
          *
          * @see #onTimeShiftPlay(Uri)
          * @see #onTimeShiftResume()
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 8437d03..9f00828 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -233,7 +233,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d6958b3..e8b04ed 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -123,7 +123,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             close();
         } finally {
             super.finalize();
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 4f1a145..71f3856 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -302,13 +302,11 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(env, jBitmap, &bitmap);
 
-    bitmap.lockPixels();
     rotate((uint16_t*)bitmap.getPixels(),
            (uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
            videoFrame->mWidth,
            videoFrame->mHeight,
            videoFrame->mRotationAngle);
-    bitmap.unlockPixels();
 
     if (videoFrame->mDisplayWidth  != videoFrame->mWidth ||
         videoFrame->mDisplayHeight != videoFrame->mHeight) {
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
index 7a3ed24..21c350be 100644
--- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -20,14 +20,11 @@
 
 public class EGLSurfaceImpl extends EGLSurface {
     long mEGLSurface;
-    private long mNativePixelRef;
     public EGLSurfaceImpl() {
         mEGLSurface = 0;
-        mNativePixelRef = 0;
     }
     public EGLSurfaceImpl(long surface) {
         mEGLSurface = surface;
-        mNativePixelRef = 0;
     }
 
     @Override
diff --git a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
index 53b0bce..e4852ed 100644
--- a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
@@ -17,23 +17,23 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Napraviti potpunu rezervnu kopiju"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Izvrši potpuno obnavljanje"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Izvrši potpuno vraćanje"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zatraženo je pravljenje potpune rezervne kopije svih podataka na povezani računar. Da li želite da dozvolite to?\n\nPrekinite radnju ukoliko to niste sami zatražili."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi rezervnu kopiju mojih podataka"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nemoj napraviti rezervnu kopiju"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Sa povezanog računara je upućen zahtjev za potpuno obnavljanje svih podataka. Želite li to dozvoliti?\n\nUkoliko niste uputili zahtjev za obnavljanje, prekinite radnju. Ovim će zamijeniti svi podaci koji su trenutno na uređaju!"</string>
-    <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovi moje podatke"</string>
-    <string name="deny_restore_button_label" msgid="1724367334453104378">"Prekinuti obnavljanje podataka"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Ispod unesite svoju trenutnu lozinku za rezervnu kopiju:"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Ispod unesite svoju trenutnu lozinku za sigurnosnu kopiju:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Ispod unesite svoju lozinku za šifriranje uređaja."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Molimo vas unesite svoju lozinku za šifriranje uređaja ispod. Ona će se koristiti i za šifriranje arhive rezervnih kopija."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku za šifriranje potpune rezervne kopije podataka. Ukoliko ne unesete lozinku, primijenit će se vaša trenutna lozinka za rezervnu kopiju:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ukoliko želite šifrirati potpunu rezervnu kopiju podataka, unesite lozinku ispod:"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"Pošto je vaš uređaj šifriran, potrebno je šifrirati rezervnu kopiju. Unesite šifru ispod:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ukoliko su podaci za obnavljanje šifrirani, unesite lozinku ispod:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Molimo vas unesite svoju lozinku za šifriranje uređaja ispod. Ona će se koristiti i za šifriranje arhive sigurnosnih kopija."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite lozinku za šifriranje potpune sigurnosne kopije podataka. Ukoliko ne unesete lozinku, primijenit će se vaša trenutna lozinka za sigurnosnu kopiju:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ukoliko želite šifrirati potpunu sigurnosnu kopiju podataka, unesite lozinku ispod:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"Pošto je vaš uređaj šifriran, potrebno je šifrirati sigurnosnu kopiju. Unesite šifru ispod:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Ukoliko su podaci za vraćanje šifrirani, unesite lozinku ispod:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Pravljenje rezervne kopije..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Pravljenje rezervne kopije završeno"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Počinje obnavljanje podataka..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Obnavljanje podatka završeno"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Pokretanje vraćanja..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Vraćanje završeno"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"Isteklo je vrijeme za izvršenje radnje"</string>
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-da/strings.xml b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
index 3a74915..28aea33 100644
--- a/packages/BackupRestoreConfirmation/res/values-da/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
@@ -19,7 +19,7 @@
     <string name="backup_confirm_title" msgid="827563724209303345">"Fuld sikkerhedskopiering"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Fuld genoprettelse"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopiér mine data"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopier mine data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Undlad at sikkerhedskopiere"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Gendan mine data"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hy/strings.xml b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml
index 285c15d..a054068 100644
--- a/packages/BackupRestoreConfirmation/res/values-hy/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml
@@ -25,12 +25,12 @@
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Վերականգնել իմ տվյալները"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Չվերականգնել"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Խնդրում ենք մուտքագրել ձեր ընթացիկ պահուստային գաղտնաբառը ներքևում`"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Խնդրում ենք մուտքագրել ձեր սարքի գաղտնագրման գաղտնաբառը ներքևում:"</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Խնդրում ենք մուտքագրել ձեր սարքի գաղտնագրման գաղտնաբառը ներքևում: Այն նաև կօգտագործվի պահուստային արխիվի գաղտնագրման համար:"</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Խնդրում ենք մուտքագրել գաղտնաբառը` ամբողջական պահուստավորվող տվյալները գաղտնագրելու համար: Եթե ​​այն դատարկ թողնեք, ապա կօգտագործվի ձեր առկա պահուստավորման գաղտնաբառը`"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Եթե ​​ցանկանում եք գաղտնագրել ամբողջական պահուստավորված տվյալները, մուտքագրեք գաղտնաբառ ստորև`"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"Քանի որ ձեր սարքը գաղտնագրված է, դուք պետք է գաղտնագրեք նաև ձեր պահուստը: Խնդրում ենք ստորև սահմանել գաղտնաբառը՝"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Եթե ​​վերականգնվող տվյալները գաղտնագրված են, խնդրում ենք մուտքագրել գաղտնաբառը ստորև`"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Խնդրում ենք մուտքագրել ձեր սարքի կոդավորված գաղտնաբառը ներքևում:"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Խնդրում ենք մուտքագրել ձեր սարքի կոդավորված գաղտնաբառը ներքևում: Այն նաև կօգտագործվի պահուստային արխիվի կոդավորման համար:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Խնդրում ենք մուտքագրել գաղտնաբառը` ամբողջական պահուստավորվող տվյալները կոդավորելու համար: Եթե ​​այն դատարկ թողնեք, ապա կօգտագործվի ձեր առկա պահուստավորման գաղտնաբառը`"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Եթե ​​ցանկանում եք կոդավորել ամբողջական պահուստավորված տվյալները, մուտքագրեք գաղտնաբառ ստորև`"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"Քանի որ ձեր սարքը կոդավորված է, դուք պետք է կոդավորեք նաև ձեր պահուստը: Խնդրում ենք ստորև սահմանել գաղտնաբառը՝"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Եթե ​​վերականգնվող տվյալները կոդավորված են, խնդրում ենք մուտքագրել գաղտնաբառը ստորև`"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Պահուստավորումը սկսվում է..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Պահուստավորումն ավարտվեց"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Վերականգնումը մեկնարկեց..."</string>
diff --git a/packages/CaptivePortalLogin/res/values-af/strings.xml b/packages/CaptivePortalLogin/res/values-af/strings.xml
index fa6f3fa..0c48b76 100644
--- a/packages/CaptivePortalLogin/res/values-af/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-af/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Gebruik hierdie netwerk nes dit is"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Moenie hierdie netwerk gebruik nie"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Meld by netwerk aan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Meld aan by %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Gaan in elk geval deur blaaier voort"</string>
diff --git a/packages/CaptivePortalLogin/res/values-am/strings.xml b/packages/CaptivePortalLogin/res/values-am/strings.xml
index 36d5e19..f126a86 100644
--- a/packages/CaptivePortalLogin/res/values-am/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-am/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ይህን አውታረ መረብ እንዳለ ተጠቀምበት"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ይህን አውታረ መረብ አትጠቀምበት"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ወደ %1$s ይግቡ"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ar/strings.xml b/packages/CaptivePortalLogin/res/values-ar/strings.xml
index 3b2fd00..76ae5f1 100644
--- a/packages/CaptivePortalLogin/res/values-ar/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ar/strings.xml
@@ -5,9 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"استخدام هذه الشبكة كما هي"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"عدم استخدام هذه الشبكة"</string>
     <string name="action_bar_label" msgid="917235635415966620">"تسجيل الدخول إلى الشبكة"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for action_bar_title (5645564790486983117) -->
-    <skip />
     <string name="ssl_error_warning" msgid="6653188881418638872">"الشبكة التي تحاول الانضمام إليها بها مشكلات أمنية."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المنظمة المعروضة."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"المتابعة على أي حال عبر المتصفح"</string>
diff --git a/packages/CaptivePortalLogin/res/values-az/strings.xml b/packages/CaptivePortalLogin/res/values-az/strings.xml
index 44b406d..f723384 100644
--- a/packages/CaptivePortalLogin/res/values-az/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-az/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Bu şəbəkəni olduğu kimi istifadə edin"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu şəbəkəni istifadə etməyin"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Şəbəkəyə daxil olun"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Daxil olun: %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Hər bir halda brazuer ilə davam edin"</string>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
index 8ce9deb..a85191f 100644
--- a/packages/CaptivePortalLogin/res/values-bg/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bg/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Директно използване на тази мрежа"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Вход в мрежата"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Влезте в/ъв %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Например страницата за вход може да не принадлежи на показаната организация."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Продължаване през браузър въпреки това"</string>
diff --git a/packages/CaptivePortalLogin/res/values-bn/strings.xml b/packages/CaptivePortalLogin/res/values-bn/strings.xml
index c6a044d..24cbfbd 100644
--- a/packages/CaptivePortalLogin/res/values-bn/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bn/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
     <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s তে সাইন-ইন করুন"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
diff --git a/packages/CaptivePortalLogin/res/values-bs/strings.xml b/packages/CaptivePortalLogin/res/values-bs/strings.xml
index 3237e5e..0b36cd0 100644
--- a/packages/CaptivePortalLogin/res/values-bs/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bs/strings.xml
@@ -4,7 +4,7 @@
     <string name="app_name" msgid="5934709770924185752">"Prijava na zaštitnom portalu"</string>
     <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu kakva jeste"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavi me na mrežu"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Naprimjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko preglednika"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
index fe189ed..9d8f6cc 100644
--- a/packages/CaptivePortalLogin/res/values-ca/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ca/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Fes servir aquesta xarxa tal com està."</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
     <string name="action_bar_label" msgid="917235635415966620">"Inicia la sessió a la xarxa"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia la sessió a %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"La xarxa a què et vols connectar té problemes de seguretat."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continua igualment mitjançant el navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-cs/strings.xml b/packages/CaptivePortalLogin/res/values-cs/strings.xml
index 09dcc5f..aee71d9 100644
--- a/packages/CaptivePortalLogin/res/values-cs/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-cs/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Použít tuto síť tak, jak je"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Přihlásit se k síti"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Přihlaste se k síti %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Například přihlašovací stránka nemusí patřit do zobrazované organizace."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Přesto pokračovat prostřednictvím prohlížeče"</string>
diff --git a/packages/CaptivePortalLogin/res/values-da/strings.xml b/packages/CaptivePortalLogin/res/values-da/strings.xml
index dc0dd17..712d9a1 100644
--- a/packages/CaptivePortalLogin/res/values-da/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-da/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Brug dette netværk, som det er"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Brug ikke dette netværk"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Log ind på netværk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log ind på %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsæt alligevel via browseren"</string>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
index e64fb76..52c9dc8 100644
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-de/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Dieses Netzwerk im Istzustand verwenden"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Dieses Netzwerk nicht verwenden"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"In %1$s anmelden"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
diff --git a/packages/CaptivePortalLogin/res/values-el/strings.xml b/packages/CaptivePortalLogin/res/values-el/strings.xml
index cb61710..3e8ea44 100644
--- a/packages/CaptivePortalLogin/res/values-el/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-el/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Χρήση αυτού του δικτύου ως έχει"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Να μη χρησιμοποιείται αυτό το δίκτυο"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Σύνδεση στο δίκτυο"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Συνδεθείτε στο %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
diff --git a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
index 2e8d1f0..7d599e7 100644
--- a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml b/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
index 2e8d1f0..7d599e7 100644
--- a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
index 2e8d1f0..7d599e7 100644
--- a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
index 5d7ba91..55e06ab 100644
--- a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Usar esta red como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"No usar esta red"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Acceder a la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Acceder a %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos desde el navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
index da2eae9..c7e2d0b 100644
--- a/packages/CaptivePortalLogin/res/values-es/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-es/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta red tal cual"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Iniciar sesión en la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia sesión en %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas unirte tiene problemas de seguridad."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos a través del navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-et/strings.xml b/packages/CaptivePortalLogin/res/values-et/strings.xml
index 41fcb9a..768a5ec 100644
--- a/packages/CaptivePortalLogin/res/values-et/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-et/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Kasuta seda võrku olemasoleval kujul"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ära kasuta seda võrku"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Logi võrku sisse"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logige sisse: %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Jätka siiski brauseris"</string>
diff --git a/packages/CaptivePortalLogin/res/values-eu/strings.xml b/packages/CaptivePortalLogin/res/values-eu/strings.xml
index 8925aac..a46768f 100644
--- a/packages/CaptivePortalLogin/res/values-eu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-eu/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s sarean"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Jarraitu arakatzailearen bidez, halere"</string>
diff --git a/packages/CaptivePortalLogin/res/values-fa/strings.xml b/packages/CaptivePortalLogin/res/values-fa/strings.xml
index 2e4cc51..9408e9b 100644
--- a/packages/CaptivePortalLogin/res/values-fa/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-fa/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"از این شبکه همانطور که هست استفاده شود"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"از این شبکه استفاده نشود"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ورود به سیستم شبکه"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏ورود به سیستم %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"در هر صورت از طریق مرورگر ادامه یابد"</string>
diff --git a/packages/CaptivePortalLogin/res/values-fi/strings.xml b/packages/CaptivePortalLogin/res/values-fi/strings.xml
index 1976f7d..4e6e526 100644
--- a/packages/CaptivePortalLogin/res/values-fi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-fi/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Käytä tätä verkkoa sellaisenaan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Älä käytä tätä verkkoa"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Kirjaudu verkkoon"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Kirjaudu sisään kohteeseen %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Verkossa, johon yrität muodostaa yhteyttä, on turvallisuusongelmia."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Jatka silti selaimen kautta."</string>
diff --git a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
index a7525a5..7cbfd0a 100644
--- a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Connectez-vous au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Connexion à %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans un navigateur"</string>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
index 8f98bb5..d90f530 100644
--- a/packages/CaptivePortalLogin/res/values-fr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-fr/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Se connecter au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Se connecter à %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans le navigateur"</string>
diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml
index 6578285..10f1f9d 100644
--- a/packages/CaptivePortalLogin/res/values-gl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-gl/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede tal como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Inicia sesión na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sesión en %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"A rede á que tentas unirte ten problemas de seguranza."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar igualmente co navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-gu/strings.xml b/packages/CaptivePortalLogin/res/values-gu/strings.xml
index c15eca4..8214865 100644
--- a/packages/CaptivePortalLogin/res/values-gu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-gu/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"આ નેટવર્કનો જેમનો તેમ ઉપયોગ કરો"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"આ નેટવર્કનો ઉપયોગ કરશો નહીં"</string>
     <string name="action_bar_label" msgid="917235635415966620">"નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sમાં સઇન ઇન કરો"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"તમે જોડાવાનો પ્રયાસ કરી રહ્યાં છો તે નેટવર્કમાં સુરક્ષા સમસ્યાઓ છે."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ દર્શાવેલ સંસ્થાનું હોઈ શકતું નથી."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"બ્રાઉઝર મારફતે કોઈપણ રીતે ચાલુ રાખો"</string>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
index 1bc6879..05fb4f4 100644
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hi/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
     <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में प्रवेश करें"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में प्रवेश करें"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"आप जिस नेटवर्क में शामिल होने का प्रयास कर रहे हैं उसमें सुरक्षा समस्‍याएं हैं."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"उदाहरण के लिए, हो सकता है कि लॉगिन पृष्‍ठ दिखाए गए संगठन से संबद्ध ना हो."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउज़र के द्वारा फिर जारी रखें"</string>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
index e44cd3b..c252b37 100644
--- a/packages/CaptivePortalLogin/res/values-hr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hr/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se na %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi putem preglednika"</string>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
index f15fb49..1f08c52 100644
--- a/packages/CaptivePortalLogin/res/values-hu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hu/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Hálózat használata jelen állapotában"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne használja ezt a hálózatot"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Bejelentkezés a hálózatba"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Bejelentkezés a következőbe: %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Például lehet, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Folytatás ennek ellenére böngészőn keresztül"</string>
diff --git a/packages/CaptivePortalLogin/res/values-hy/strings.xml b/packages/CaptivePortalLogin/res/values-hy/strings.xml
index a0ee862..cf79b8c 100644
--- a/packages/CaptivePortalLogin/res/values-hy/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-hy/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Օգտագործել այս ցանցն ինչպես կա"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Մուտք գործել ցանց"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Մուտք գործել %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Շարունակել այնուամենայնիվ դիտարկիչի միջոցով"</string>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
index 7fa3a0a..ff957c4 100644
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-in/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Gunakan jaringan ini sebagaimana adanya"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Masuk ke jaringan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, laman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Tetap lanjutkan melalui browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-is/strings.xml b/packages/CaptivePortalLogin/res/values-is/strings.xml
index 8fde24b..8c886d2 100644
--- a/packages/CaptivePortalLogin/res/values-is/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-is/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Nota þetta net óbreytt"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ekki nota þetta net"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Skrá inn á net"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Skrá inn á %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Halda samt áfram í vafra"</string>
diff --git a/packages/CaptivePortalLogin/res/values-it/strings.xml b/packages/CaptivePortalLogin/res/values-it/strings.xml
index a01a553..23ed415 100644
--- a/packages/CaptivePortalLogin/res/values-it/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-it/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utilizza questa rete così com\'è"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizzare questa rete"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Accedi alla rete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Accedi a %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continua comunque dal browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-iw/strings.xml b/packages/CaptivePortalLogin/res/values-iw/strings.xml
index 8e7915d..fe7333f 100644
--- a/packages/CaptivePortalLogin/res/values-iw/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-iw/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"השתמש ברשת זו כפי שהיא"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"אל תשתמש ברשת זו"</string>
     <string name="action_bar_label" msgid="917235635415966620">"היכנס לרשת"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏כניסה אל %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"המשך בכל זאת באמצעות דפדפן"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
index e275b95..b369b65 100644
--- a/packages/CaptivePortalLogin/res/values-ja/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ja/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"このネットワークをそのまま使用する"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ネットワークにログイン"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s にログイン"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ブラウザから続行"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ka/strings.xml b/packages/CaptivePortalLogin/res/values-ka/strings.xml
index 1ccff12..2913178 100644
--- a/packages/CaptivePortalLogin/res/values-ka/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ka/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ამ ქსელის გამოყენება, როგორც არის"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ქსელში შესვლა"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-ში შესვლა"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ქსელს, რომელზედაც მიერთებას ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ბრაუზერში გაგრძელება"</string>
diff --git a/packages/CaptivePortalLogin/res/values-kk/strings.xml b/packages/CaptivePortalLogin/res/values-kk/strings.xml
index a904dea..d1fb849 100644
--- a/packages/CaptivePortalLogin/res/values-kk/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-kk/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Осы желіні бар күйінде пайдалану"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Желіге кіру"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s жүйесіне кіру"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Қосылайын деп жатқан желіңіз қауіпсіз болуы мүмкін."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Бәрібір браузер арқылы жалғастыру"</string>
diff --git a/packages/CaptivePortalLogin/res/values-km/strings.xml b/packages/CaptivePortalLogin/res/values-km/strings.xml
index a0497f8..32098ae 100644
--- a/packages/CaptivePortalLogin/res/values-km/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-km/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ចូលទៅបណ្ដាញ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ចូលទៅ %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ឧបករណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករក"</string>
diff --git a/packages/CaptivePortalLogin/res/values-kn/strings.xml b/packages/CaptivePortalLogin/res/values-kn/strings.xml
index 3084504..b3f937a 100644
--- a/packages/CaptivePortalLogin/res/values-kn/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-kn/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್ ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿರುವುದಿಲ್ಲ."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ಹೇಗಾದರೂ ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
index 75f2b48..9756042 100644
--- a/packages/CaptivePortalLogin/res/values-ko/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ko/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"현재 상태로 이 네트워크 사용"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
     <string name="action_bar_label" msgid="917235635415966620">"네트워크에 로그인"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s에 로그인"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"브라우저를 통해 계속하기"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ky/strings.xml b/packages/CaptivePortalLogin/res/values-ky/strings.xml
index af81ce3..ab1c7ff 100644
--- a/packages/CaptivePortalLogin/res/values-ky/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ky/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Тармакка кирүү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s каттоо эсебине кириңиз"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Баары бир серепчи аркылуу улантуу"</string>
diff --git a/packages/CaptivePortalLogin/res/values-lo/strings.xml b/packages/CaptivePortalLogin/res/values-lo/strings.xml
index ee2b263..c50aaa9 100644
--- a/packages/CaptivePortalLogin/res/values-lo/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-lo/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້​ຕາມ​ທີ່​ມັນ​ເປັນ"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ບໍ່​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ເຂົ້າສູ່ລະບົບ %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ເຄືອ​ຂ່າຍ​ທີ່​ທ່ານ​ກຳ​ລັງ​ເຂົ້າ​ຮ່ວມ​ມີ​ບັນ​ຫາ​ຄວາມ​ປອດ​ໄພ."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ຕົວ​ຢ່າງ, ໜ້າ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ອາດ​ຈະ​ບໍ່​ເປັນ​ຂອງ​ອົງ​ການ​ທີ່​ສະ​ແດງ​ຂຶ້ນ."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ແນວ​ໃດ​ກໍ່​ສືບ​ຕໍ່​ຜ່ານບ​ຣາວ​ເຊີ"</string>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
index 17da83f..6cdd5ba6 100644
--- a/packages/CaptivePortalLogin/res/values-lt/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-lt/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Naudoti šį tinklą tokį, koks yra"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Prisijungti prie tinklo"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prisijungimas prie „%1$s“"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Kilo tinklo, prie kurio bandote prisijungti, problemų."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Vis tiek tęsti naudojant naršyklę"</string>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
index 95b8558..b33293f 100644
--- a/packages/CaptivePortalLogin/res/values-lv/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-lv/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Pierakstīties tīklā"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Pierakstieties produktā %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Tīklam, kuram mēģināt pievienoties, ir drošības problēmas."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Tik un tā turpināt, izmantojot pārlūkprogrammu"</string>
diff --git a/packages/CaptivePortalLogin/res/values-mk/strings.xml b/packages/CaptivePortalLogin/res/values-mk/strings.xml
index 2ae32c8..63428e7 100644
--- a/packages/CaptivePortalLogin/res/values-mk/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mk/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Користи ја мрежата во оваа состојба"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Најавете се на мрежа"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Најавете се на %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"На пример, страницата за најавување може да не припаѓа на организацијата што е прикажана."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Сепак продолжи преку прелистувач"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ml/strings.xml b/packages/CaptivePortalLogin/res/values-ml/strings.xml
index 79551f8..911b99882 100644
--- a/packages/CaptivePortalLogin/res/values-ml/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ml/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
     <string name="action_bar_label" msgid="917235635415966620">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
diff --git a/packages/CaptivePortalLogin/res/values-mn/strings.xml b/packages/CaptivePortalLogin/res/values-mn/strings.xml
index 67670915..2489e9c 100644
--- a/packages/CaptivePortalLogin/res/values-mn/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mn/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Энэ сүлжээг ашиглана уу"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Сүлжээнд нэвтэрнэ үү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-д нэвтрэх"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Таны нэгдэх гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Жишээлбэл нэвтрэх хуудас нь харагдах байгууллагынх биш байж болзошгүй."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Ямартаа ч хөтчөөр үргэлжлүүлэх"</string>
diff --git a/packages/CaptivePortalLogin/res/values-mr/strings.xml b/packages/CaptivePortalLogin/res/values-mr/strings.xml
index fac0a08..9521c8d 100644
--- a/packages/CaptivePortalLogin/res/values-mr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-mr/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"हे नेटवर्क जसेच्या तसे वापरा"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
     <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sमध्‍ये साइन इन करा"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये आपण सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणार्थ, लॉगिन पृष्‍ठ कदाचित दर्शविलेल्या संस्थेच्या मालकीचे नसावे."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउझरद्वारे तरीही सुरु ठेवा"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ms/strings.xml b/packages/CaptivePortalLogin/res/values-ms/strings.xml
index 933721a..829c55a 100644
--- a/packages/CaptivePortalLogin/res/values-ms/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ms/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Gunakan rangkaian ini"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan rangkaian ini"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Log masuk ke rangkaian"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log masuk ke %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Rangkaian yang anda cuba sertai mempunyai isu keselamatan."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Teruskan juga melalui penyemak imbas"</string>
diff --git a/packages/CaptivePortalLogin/res/values-my/strings.xml b/packages/CaptivePortalLogin/res/values-my/strings.xml
index 902834b..e25570d 100644
--- a/packages/CaptivePortalLogin/res/values-my/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-my/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ဒီကွန်ရက်ကို လက်ရှိအတိုင်း သုံးရန်"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်သည် လုံခြုံရေးပြဿနာ ရှိနေသည်။"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ဥပမာ၊ ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှု မရှိနိုင်ပါ။"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ဘရောက်ဇာမှတစ်ဆင့် ဆက်လုပ်ရန်"</string>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
index 0dd5b6c..b9d3349 100644
--- a/packages/CaptivePortalLogin/res/values-nb/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-nb/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Bruk dette nettverket som det er"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Logg på nettverk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logg på %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Det er for eksempel mulig at påloggingssiden kanskje ikke tilhører organisasjonen som vises."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsett likevel via nettleseren"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ne/strings.xml b/packages/CaptivePortalLogin/res/values-ne/strings.xml
index 87a30c0..02c2cf3 100644
--- a/packages/CaptivePortalLogin/res/values-ne/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ne/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"यो सञ्जाल जस्तो छ प्रयोग गर्नुहोस्"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"यो सञ्जाल प्रयोग नगर्नुहोस्"</string>
     <string name="action_bar_label" msgid="917235635415966620">"सञ्जालमा साइन इन गर्नुहोस्"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s मा साइन इन गर्नुहोस्"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"तपाईँले सामेल हुन प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा मुद्दाहरू छन्।"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
index 1c59601..af1de0a 100644
--- a/packages/CaptivePortalLogin/res/values-nl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-nl/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Dit netwerk in de huidige staat gebruiken"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Inloggen bij netwerk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inloggen bij %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Het netwerk waarmee u verbinding probeert te maken, heeft beveiligingsproblemen."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Toch doorgaan via browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-pa/strings.xml b/packages/CaptivePortalLogin/res/values-pa/strings.xml
index c1b014c..4c188fa 100644
--- a/packages/CaptivePortalLogin/res/values-pa/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pa/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ਇਸ ਨੈੱਟਵਰਕ ਨੂੰ ਉਵੇਂ ਵਰਤੋ ਜਿਵੇਂ ਇਹ ਹੈ"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ਇਹ ਨੈੱਟਵਰਕ ਨਾ ਵਰਤੋ"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ ਇਨ ਕਰੋ"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਸ਼ਾਮਿਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੇ ਜਾ ਰਹੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਉਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
index 17f20df..ee39fe5 100644
--- a/packages/CaptivePortalLogin/res/values-pl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pl/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Używaj tej sieci tak jak jest"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Zaloguj się do sieci"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Zaloguj się w aplikacji %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Kontynuuj mimo to w przeglądarce"</string>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
index 3d1064c..e1d420f 100644
--- a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
index 94b9d60..54e2a8b 100644
--- a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Não utilizar esta rede"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Início de sessão na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sessão em %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim através do navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-pt/strings.xml b/packages/CaptivePortalLogin/res/values-pt/strings.xml
index 3d1064c..e1d420f 100644
--- a/packages/CaptivePortalLogin/res/values-pt/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-pt/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ro/strings.xml b/packages/CaptivePortalLogin/res/values-ro/strings.xml
index cf1b6b5..3d69e64 100644
--- a/packages/CaptivePortalLogin/res/values-ro/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ro/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Utilizați această rețea în starea actuală"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Nu utilizați această rețea"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Conectați-vă la rețea"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Conectați-vă la %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Continuați oricum prin browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
index 6966bcd..c45a8c1 100644
--- a/packages/CaptivePortalLogin/res/values-ru/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ru/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Использовать эту сеть"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Регистрация в сети"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Войти: %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Например, страница входа в аккаунт может быть фиктивной."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Игнорировать и открыть браузер"</string>
diff --git a/packages/CaptivePortalLogin/res/values-si/strings.xml b/packages/CaptivePortalLogin/res/values-si/strings.xml
index a307913..61fd2b8 100644
--- a/packages/CaptivePortalLogin/res/values-si/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-si/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ජාලයට පුරනය වන්න"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s වෙත පුරන්න"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"කෙසේ වුවත් බ්‍රවුසරය හරහා ඉදිරියට යන්න"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sk/strings.xml b/packages/CaptivePortalLogin/res/values-sk/strings.xml
index 54763be..76af0ca 100644
--- a/packages/CaptivePortalLogin/res/values-sk/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sk/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Použiť túto sieť tak, ako je"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Túto sieť nepoužívať"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Prihlásiť sa do siete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prihláste sa do služby %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Pokračovať pomocou prehliadača"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
index 7dd0b37..158a4d3 100644
--- a/packages/CaptivePortalLogin/res/values-sl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sl/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Uporabljajte to omrežje, »kakršno je«"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Prijavite se v omrežje"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava v %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Vseeno nadaljuj v brskalniku"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sq/strings.xml b/packages/CaptivePortalLogin/res/values-sq/strings.xml
index b06da6d..674b809 100644
--- a/packages/CaptivePortalLogin/res/values-sq/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sq/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Përdore këtë rrjet siç është"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Mos e përdor këtë rrjet"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Identifikohu në rrjet"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Identifikohu në %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sr/strings.xml b/packages/CaptivePortalLogin/res/values-sr/strings.xml
index f604289..05c1d50 100644
--- a/packages/CaptivePortalLogin/res/values-sr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sr/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Користи ову мрежу такву каква је"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Пријави ме на мрежу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Пријавите се у: %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Ипак настави преко прегледача"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sv/strings.xml b/packages/CaptivePortalLogin/res/values-sv/strings.xml
index 8cf7041..700713a 100644
--- a/packages/CaptivePortalLogin/res/values-sv/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sv/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Använd det här nätverket som det är"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Använd inte det här nätverket"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Logga in på nätverket"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logga in på %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsätt ändå via webbläsaren"</string>
diff --git a/packages/CaptivePortalLogin/res/values-sw/strings.xml b/packages/CaptivePortalLogin/res/values-sw/strings.xml
index 1c8b6e1..d791955 100644
--- a/packages/CaptivePortalLogin/res/values-sw/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-sw/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Tumia mtandao huu jinsi ulivyo"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Usitumie mtandao huu"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Ingia katika mtandao"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ingia katika akaunti ya %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Endelea hata hivyo kupitia kivinjari"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ta/strings.xml b/packages/CaptivePortalLogin/res/values-ta/strings.xml
index 6a60ed7..038f05a 100644
--- a/packages/CaptivePortalLogin/res/values-ta/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ta/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
     <string name="action_bar_label" msgid="917235635415966620">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s இல் உள்நுழைக"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"நீங்கள் சேர முயற்சிக்கும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"பரவாயில்லை, உலாவி வழியாகத் தொடரவும்"</string>
diff --git a/packages/CaptivePortalLogin/res/values-te/strings.xml b/packages/CaptivePortalLogin/res/values-te/strings.xml
index c209d34..5d85568 100644
--- a/packages/CaptivePortalLogin/res/values-te/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-te/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
     <string name="action_bar_label" msgid="917235635415966620">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sకి సైన్ ఇన్ చేయండి"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించు"</string>
diff --git a/packages/CaptivePortalLogin/res/values-th/strings.xml b/packages/CaptivePortalLogin/res/values-th/strings.xml
index 9a3a626..cc3ae87 100644
--- a/packages/CaptivePortalLogin/res/values-th/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-th/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"ใช้เครือข่ายนี้ตามที่เป็นอยู่"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"ไม่ใช้เครือข่ายนี้"</string>
     <string name="action_bar_label" msgid="917235635415966620">"ลงชื่อเข้าใช้เครือข่าย"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ลงชื่อเข้าใช้ %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
index 565ef8f..bad5a1a 100644
--- a/packages/CaptivePortalLogin/res/values-tl/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-tl/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Gamitin ang network na ito nang walang pagbabago"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Huwag gamitin ang network na ito"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Mag-sign in sa network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Mag-sign in sa %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"May mga isyu sa seguridad ang network kung saan mo sinusubukang sumali."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Halimbawa, maaaring hindi sa organisasyong ipinapakita ang page sa pag-log in."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
diff --git a/packages/CaptivePortalLogin/res/values-tr/strings.xml b/packages/CaptivePortalLogin/res/values-tr/strings.xml
index 73d2455..50ea806 100644
--- a/packages/CaptivePortalLogin/res/values-tr/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-tr/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Bu ağı olduğu gibi kullan"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Ağda oturum açın"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s üzerinde oturum açın"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Yine de tarayıcıyla devam et"</string>
diff --git a/packages/CaptivePortalLogin/res/values-uk/strings.xml b/packages/CaptivePortalLogin/res/values-uk/strings.xml
index 0e818d3..5ef5426 100644
--- a/packages/CaptivePortalLogin/res/values-uk/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-uk/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Використовувати цю мережу як є"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Не використовувати цю мережу"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Увійти в мережу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увійти в обліковий запис %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Наприклад, сторінка входу може не належати вказаній організації."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Усе одно продовжити у веб-переглядачі"</string>
diff --git a/packages/CaptivePortalLogin/res/values-ur/strings.xml b/packages/CaptivePortalLogin/res/values-ur/strings.xml
index 05d8fb9..7da543f 100644
--- a/packages/CaptivePortalLogin/res/values-ur/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-ur/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
     <string name="action_bar_label" msgid="917235635415966620">"نیٹ ورک میں سائن ان کریں"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏%1$s میں سائن ان کریں"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"جس نیٹ ورک میں آپ شامل ہونے کی کوشش کر رہے ہیں اس میں سیکیورٹی کے مسائل ہیں۔"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
diff --git a/packages/CaptivePortalLogin/res/values-uz/strings.xml b/packages/CaptivePortalLogin/res/values-uz/strings.xml
index cac96ea..0cbef0a 100644
--- a/packages/CaptivePortalLogin/res/values-uz/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-uz/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Tarmoqqa kirish"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s hisobiga kirish"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"E’tiborsiz qoldirilsin va brauzer ochilsin"</string>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
index e51d2aa..a667283 100644
--- a/packages/CaptivePortalLogin/res/values-vi/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-vi/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Sử dụng mạng này"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Không sử dụng mạng này"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Đăng nhập vào mạng"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Đăng nhập vào %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Ví dụ, trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Vẫn tiếp tục qua trình duyệt"</string>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
index ce822e7..b832f6e 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"直接使用此网络"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
     <string name="action_bar_label" msgid="917235635415966620">"登录到网络"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登录%1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"您尝试加入的网络存在安全问题。"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"例如,登录页面可能并不属于页面上显示的单位。"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"仍然通过浏览器继续操作"</string>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
index 9010e1e..1232abb 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"依照現況使用這個網絡"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
     <string name="action_bar_label" msgid="917235635415966620">"登入網絡"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入「%1$s」"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"您正在嘗試加入的網絡有安全性問題。"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"例如,登入頁面並不屬於所顯示的機構。"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
index 5b535e2..bd0f4b7 100644
--- a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"依現況使用這個網路"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
     <string name="action_bar_label" msgid="917235635415966620">"登入網路"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入 %1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"你嘗試加入的網路有安全問題。"</string>
     <string name="ssl_error_example" msgid="647898534624078900">"例如,登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
diff --git a/packages/CaptivePortalLogin/res/values-zu/strings.xml b/packages/CaptivePortalLogin/res/values-zu/strings.xml
index 866ba18..3320fd4 100644
--- a/packages/CaptivePortalLogin/res/values-zu/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-zu/strings.xml
@@ -5,7 +5,6 @@
     <string name="action_use_network" msgid="6076184727448466030">"Sebenzisa le nethiwekhi njengoba injalo"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Ungasebenzisi le nethiwekhi"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Ngena ngemvume kunethiwekhi"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ngena ngemvume ku-%1$s"</string>
     <string name="ssl_error_warning" msgid="6653188881418638872">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Qhubeka noma kunjalo ngesiphequluli"</string>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index e13aba7..35c6a99 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -62,7 +62,6 @@
 import java.lang.reflect.Method;
 import java.util.Objects;
 import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 public class CaptivePortalLoginActivity extends Activity {
     private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
@@ -88,8 +87,6 @@
     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) {
@@ -186,13 +183,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:
@@ -252,8 +249,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/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index c309133..1cd7b61 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -34,6 +34,7 @@
             <intent-filter>
                 <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
                 <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+                <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
                 <action android:name="android.intent.action.LOCALE_CHANGED" />
             </intent-filter>
         </receiver>
@@ -43,10 +44,24 @@
             android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
             android:theme="@style/AppTheme"
-            android:configChanges="keyboardHidden|orientation|screenSize" >
+            android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
+
+        <activity-alias
+            android:name="com.android.carrierdefaultapp.URLHandlerActivity"
+            android:targetActivity="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+            android:enabled="false" >
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="http" />
+                <data android:scheme="https" />
+                <data android:host="*" />
+            </intent-filter>
+        </activity-alias>
     </application>
 </manifest>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index e78fca3..0492685 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posetili veb-sajt %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktirajte dobavljača usluge %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Prijavite se na mobilnu mrežu"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-be/strings.xml b/packages/CarrierDefaultApp/res/values-be/strings.xml
index c46d0da..12677f2 100644
--- a/packages/CarrierDefaultApp/res/values-be/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-be/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Перадача мабільных даных была дэактывавана"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Дакраніцеся, каб наведаць вэб-сайт %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Звярніцеся да свайго пастаўшчыка паслуг %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мабільнага трафіка"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Увайсці ў мабільную сетку"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"У сеткі, да якой вы спрабуеце далучыцца, ёсць праблемы з бяспекай."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Усё роўна працягнуць праз браўзер"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-bs/strings.xml b/packages/CarrierDefaultApp/res/values-bs/strings.xml
index ba9863f..110924f 100644
--- a/packages/CarrierDefaultApp/res/values-bs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bs/strings.xml
@@ -7,12 +7,9 @@
     <string name="no_data_notification_id" msgid="668400731803969521">"Prijenos mobilnih podataka je deaktiviran"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da posjetite %s web lokaciju"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Obratite se pružaocu usluga %s"</string>
-    <!-- no translation found for action_bar_label (4290345990334377177) -->
-    <skip />
-    <!-- no translation found for ssl_error_warning (3127935140338254180) -->
-    <skip />
-    <!-- no translation found for ssl_error_example (6188711843183058764) -->
-    <skip />
-    <!-- no translation found for ssl_error_continue (1138548463994095584) -->
-    <skip />
+    <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Prijava na mobilnu mrežu"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"Naprimjer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko preglednika"</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml
index 54859e0..4f1245c 100644
--- a/packages/CarrierDefaultApp/res/values-ca/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml
@@ -8,7 +8,7 @@
     <string name="portal_notification_detail" msgid="2295729385924660881">"Toca per visitar el lloc web de: %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Contacta amb el teu proveïdor de serveis: %s"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estat de les dades mòbils"</string>
-    <string name="action_bar_label" msgid="4290345990334377177">"Inicia la sessió a la xarxa mòbil"</string>
+    <string name="action_bar_label" msgid="4290345990334377177">"Inicia la sessió a la xarxa de telefonia mòbil"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"La xarxa a què et vols connectar té problemes de seguretat."</string>
     <string name="ssl_error_example" msgid="6188711843183058764">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"Continua igualment mitjançant el navegador"</string>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index d58316e..e908563 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
     <string name="android_system_label" msgid="2797790869522345065">"Mtoa Huduma za Simu"</string>
-    <string name="portal_notification_id" msgid="5155057562457079297">"Data ya mtandao wa simu imekwisha"</string>
+    <string name="portal_notification_id" msgid="5155057562457079297">"Data ya simu za mkononi imekwisha"</string>
     <string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"Gonga ili utembelee tovuti ya %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Tafadhali wasiliana na mtoa huduma wako %s"</string>
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index fa5c3ff..65a7cec 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -6,6 +6,8 @@
     <string name="no_data_notification_id">Your mobile data has been deactivated</string>
     <string name="portal_notification_detail">Tap to visit the %s website</string>
     <string name="no_data_notification_detail">Please contact your service provider %s</string>
+    <string name="no_mobile_data_connection_title">No mobile data connection</string>
+    <string name="no_mobile_data_connection">Add data or roaming plan through %s</string>
     <string name="mobile_data_status_notification_channel_name">Mobile data status</string>
     <string name="action_bar_label">Sign in to mobile network</string>
     <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index c79c018..8553bcf 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -20,6 +20,9 @@
 import android.app.LoadedApk;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
@@ -34,6 +37,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.TypedValue;
@@ -68,7 +72,7 @@
     private static final boolean DBG = true;
 
     private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
-    public static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
+    private static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
 
     private URL mUrl;
     private Network mNetwork;
@@ -77,6 +81,7 @@
     private WebView mWebView;
     private MyWebViewClient mWebViewClient;
     private boolean mLaunchBrowser = false;
+    private Thread mTestingThread = null;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -127,8 +132,6 @@
 
     @Override
     public void onDestroy() {
-        super.onDestroy();
-        releaseNetworkRequest();
         if (mLaunchBrowser) {
             // Give time for this network to become default. After 500ms just proceed.
             for (int i = 0; i < 5; i++) {
@@ -143,6 +146,13 @@
             if (DBG) logd("starting activity with intent ACTION_VIEW for " + url);
             startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
         }
+
+        if (mTestingThread != null) {
+            mTestingThread.interrupt();
+        }
+        mWebView.destroy();
+        releaseNetworkRequest();
+        super.onDestroy();
     }
 
     // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
@@ -183,16 +193,19 @@
             CarrierActionUtils.applyCarrierAction(
                     CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
                     getApplicationContext());
-
+            CarrierActionUtils.applyCarrierAction(
+                    CarrierActionUtils.CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER, getIntent(),
+                    getApplicationContext());
+            CarrierActionUtils.applyCarrierAction(
+                    CarrierActionUtils.CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL, getIntent(),
+                    getApplicationContext());
         }
         finishAndRemoveTask();
     }
 
     private URL getUrlForCaptivePortal() {
         String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
-        if (url.isEmpty()) {
-            url = mCm.getCaptivePortalServerUrl();
-        }
+        if (TextUtils.isEmpty(url)) url = mCm.getCaptivePortalServerUrl();
         final CarrierConfigManager configManager = getApplicationContext()
                 .getSystemService(CarrierConfigManager.class);
         final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
@@ -216,13 +229,14 @@
     }
 
     private void testForCaptivePortal() {
-        new Thread(new Runnable() {
+        mTestingThread = new Thread(new Runnable() {
             public void run() {
                 // Give time for captive portal to open.
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                 }
+                if (isFinishing() || isDestroyed()) return;
                 HttpURLConnection urlConnection = null;
                 int httpResponseCode = 500;
                 int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
@@ -245,7 +259,8 @@
                     done(true);
                 }
             }
-        }).start();
+        });
+        mTestingThread.start();
     }
 
     private Network getNetworkForCaptivePortal() {
@@ -430,6 +445,27 @@
         }
     }
 
+    /**
+     * This alias presents the target activity, CaptivePortalLoginActivity, as a independent
+     * entity with its own intent filter to handle URL links. This alias will be enabled/disabled
+     * dynamically to handle url links based on the network conditions.
+     */
+    public static String getAlias(Context context) {
+        try {
+            PackageInfo p = context.getPackageManager().getPackageInfo(context.getPackageName(),
+                    PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS);
+            for (ActivityInfo activityInfo : p.activities) {
+                String targetActivity = activityInfo.targetActivity;
+                if (CaptivePortalLoginActivity.class.getName().equals(targetActivity)) {
+                    return activityInfo.name;
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
     private static void logd(String s) {
         Rlog.d(TAG, s);
     }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 0213306..a2bf964 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -19,8 +19,10 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.telephony.SubscriptionManager;
@@ -49,6 +51,10 @@
     public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION          = 4;
     public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
     public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS          = 6;
+    public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER        = 7;
+    public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER       = 8;
+    public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL    = 9;
+    public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL  = 10;
 
     public static void applyCarrierAction(int actionIdx, Intent intent, Context context) {
         switch (actionIdx) {
@@ -73,6 +79,18 @@
             case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS:
                 onCancelAllNotifications(context);
                 break;
+            case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER:
+                onEnableDefaultURLHandler(context);
+                break;
+            case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER:
+                onDisableDefaultURLHandler(context);
+                break;
+            case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL:
+                onRegisterDefaultNetworkAvail(intent, context);
+                break;
+            case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL:
+                onDeregisterDefaultNetworkAvail(intent, context);
+                break;
             default:
                 loge("unsupported carrier action index: " + actionIdx);
         }
@@ -94,6 +112,38 @@
         telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
     }
 
+    private static void onEnableDefaultURLHandler(Context context) {
+        logd("onEnableDefaultURLHandler");
+        final PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+    }
+
+    private static void onDisableDefaultURLHandler(Context context) {
+        logd("onDisableDefaultURLHandler");
+        final PackageManager pm = context.getPackageManager();
+        pm.setComponentEnabledSetting(
+                new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+    }
+
+    private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
+        int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        logd("onRegisterDefaultNetworkAvail subId: " + subId);
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
+    }
+
+    private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
+        int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        logd("onDeregisterDefaultNetworkAvail subId: " + subId);
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
+    }
+
     private static void onDisableRadio(Intent intent, Context context) {
         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
index d5d0b79..02c61d7 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
@@ -22,7 +22,6 @@
 import android.telephony.Rlog;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.ArrayUtils;
@@ -95,6 +94,12 @@
                     configs = b.getStringArray(CarrierConfigManager
                             .KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET);
                     break;
+                case TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE:
+                    configs = b.getStringArray(CarrierConfigManager
+                            .KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE);
+                    arg1 = String.valueOf(intent.getBooleanExtra(TelephonyIntents
+                            .EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, false));
+                    break;
                 default:
                     Rlog.e(TAG, "load carrier config failure with un-configured key: " +
                             intent.getAction());
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 3b29a6c..1e26231 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -77,7 +77,7 @@
 
     private BluetoothAdapter mBluetoothAdapter;
     private WifiManager mWifiManager;
-    private BluetoothLeScanner mBLEScanner;
+    @Nullable private BluetoothLeScanner mBLEScanner;
     private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
 
     private List<DeviceFilter<?>> mFilters;
@@ -185,7 +185,7 @@
             mBluetoothAdapter.startDiscovery();
         }
 
-        if (shouldScan(mBLEFilters)) {
+        if (shouldScan(mBLEFilters) && mBLEScanner != null) {
             mBLEScanCallback = new BLEScanCallback();
             mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
         }
@@ -224,7 +224,7 @@
             unregisterReceiver(mBluetoothBroadcastReceiver);
             mBluetoothBroadcastReceiver = null;
         }
-        mBLEScanner.stopScan(mBLEScanCallback);
+        if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback);
         if (mWifiBroadcastReceiver != null) {
             unregisterReceiver(mWifiBroadcastReceiver);
             mWifiBroadcastReceiver = null;
diff --git a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
index 9d2f7bb..235b621 100644
--- a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"Spoljna memorija"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Lokalni memorijski prostor"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Interna memorija"</string>
     <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-be/strings.xml b/packages/ExternalStorageProvider/res/values-be/strings.xml
index ea8837b..911ff54 100644
--- a/packages/ExternalStorageProvider/res/values-be/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-be/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"Вонкавае сховішча"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Лакальнае сховішча"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Унутранае сховішча"</string>
     <string name="root_documents" msgid="4051252304075469250">"Дакументы"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bs/strings.xml b/packages/ExternalStorageProvider/res/values-bs/strings.xml
index 194e66b..1eb3020 100644
--- a/packages/ExternalStorageProvider/res/values-bs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bs/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7123375275748530234">"Aplikacija za vanjsku pohranu"</string>
-    <!-- no translation found for storage_description (8541974407321172792) -->
-    <skip />
+    <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Interna pohrana"</string>
     <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
 </resources>
diff --git a/packages/Osu2/Android.mk b/packages/Osu2/Android.mk
new file mode 100644
index 0000000..05586f0
--- /dev/null
+++ b/packages/Osu2/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := Osu2
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Osu2/AndroidManifest.xml b/packages/Osu2/AndroidManifest.xml
new file mode 100644
index 0000000..236b120b
--- /dev/null
+++ b/packages/Osu2/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?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.osu">
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+    android:enabled="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name">
+        <activity android:name=".MainActivity" android:exported="true">
+        </activity>
+    </application>
+
+</manifest>
diff --git a/packages/Osu2/res/layout/activity_main.xml b/packages/Osu2/res/layout/activity_main.xml
new file mode 100644
index 0000000..f9504c9
--- /dev/null
+++ b/packages/Osu2/res/layout/activity_main.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</LinearLayout>
diff --git a/packages/Osu2/res/mipmap-hdpi/ic_launcher.png b/packages/Osu2/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
--- /dev/null
+++ b/packages/Osu2/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-mdpi/ic_launcher.png b/packages/Osu2/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
--- /dev/null
+++ b/packages/Osu2/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png b/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/packages/Osu2/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/packages/Osu2/res/values-w820dp/dimens.xml b/packages/Osu2/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/packages/Osu2/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/packages/Osu2/res/values/colors.xml b/packages/Osu2/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/packages/Osu2/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml b/packages/Osu2/res/values/dimens.xml
similarity index 100%
rename from tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
rename to packages/Osu2/res/values/dimens.xml
diff --git a/packages/Osu2/res/values/strings.xml b/packages/Osu2/res/values/strings.xml
new file mode 100644
index 0000000..e5b1af6
--- /dev/null
+++ b/packages/Osu2/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Passpoint Online Sign-Up</string>
+</resources>
diff --git a/packages/Osu2/src/com/android/osu/Constants.java b/packages/Osu2/src/com/android/osu/Constants.java
new file mode 100644
index 0000000..cd046d8
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/Constants.java
@@ -0,0 +1,24 @@
+/*
+ * 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.osu;
+
+public final class Constants {
+    public static final String INTENT_EXTRA_COMMAND = "com.android.osu.extra.COMMAND";
+    public static final String INTENT_EXTRA_OSU_PROVIDER = "com.android.osu.extra.OSU_PROVIDER";
+
+    public static final String COMMAND_PROVISION = "Provision";
+}
\ No newline at end of file
diff --git a/packages/Osu2/src/com/android/osu/MainActivity.java b/packages/Osu2/src/com/android/osu/MainActivity.java
new file mode 100644
index 0000000..4e2136b
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/MainActivity.java
@@ -0,0 +1,76 @@
+/*
+ * 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.osu;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.wifi.hotspot2.OsuProvider;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Main entry point for the OSU (Online Sign-Up) app.
+ */
+public class MainActivity extends Activity {
+    private static final String TAG = "OSU_MainActivity";
+    private OsuService mService;
+
+    @Override
+    protected void onCreate(Bundle saveInstanceState) {
+        super.onCreate(saveInstanceState);
+
+        Intent intent = getIntent();
+        if (intent == null) {
+            Log.e(TAG, "Intent not provided");
+            finish();
+        }
+
+        if (!intent.hasExtra(Constants.INTENT_EXTRA_COMMAND)) {
+            Log.e(TAG, "Command not provided");
+            finish();
+        }
+
+        String command = intent.getStringExtra(Constants.INTENT_EXTRA_COMMAND);
+        switch (command) {
+            case Constants.COMMAND_PROVISION:
+                if (!startProvisionService(intent.getParcelableExtra(
+                        Constants.INTENT_EXTRA_OSU_PROVIDER))) {
+                    finish();
+                }
+                break;
+            default:
+                Log.e(TAG, "Unknown command: '" + command + "'");
+                finish();
+                break;
+        }
+    }
+
+    /**
+     * Start the {@link ProvisionService} to perform provisioning tasks.
+     *
+     * @return true if service is started
+     */
+    private boolean startProvisionService(OsuProvider provider) {
+        if (provider == null) {
+            Log.e(TAG, "OSU Provider not provided");
+            return false;
+        }
+        mService = new ProvisionService(this, provider);
+        mService.start();
+        return true;
+    }
+}
diff --git a/packages/Osu2/src/com/android/osu/NetworkConnection.java b/packages/Osu2/src/com/android/osu/NetworkConnection.java
new file mode 100644
index 0000000..9f5b929
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/NetworkConnection.java
@@ -0,0 +1,206 @@
+/*
+ * 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.osu;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Responsible for setup/monitor on a Wi-Fi connection.
+ */
+public class NetworkConnection {
+    private static final String TAG = "OSU_NetworkConnection";
+
+    private final WifiManager mWifiManager;
+    private final Callbacks mCallbacks;
+    private final int mNetworkId;
+    private boolean mConnected = false;
+
+    /**
+     * Callbacks on Wi-Fi connection state changes.
+     */
+    public interface Callbacks {
+        /**
+         * Invoked when network connection is established with IP connectivity.
+         *
+         * @param network {@link Network} associated with the connected network.
+         */
+        public void onConnected(Network network);
+
+        /**
+         * Invoked when the targeted network is disconnected.
+         */
+        public void onDisconnected();
+
+        /**
+         * Invoked when network connection is not established within the pre-defined timeout.
+         */
+        public void onTimeout();
+    }
+
+    /**
+     * Create an instance of {@link NetworkConnection} for the specified Wi-Fi network.
+     * The Wi-Fi network (specified by its SSID) will be added/enabled as part of this object
+     * creation.
+     *
+     * {@link #teardown} will need to be invoked once you're done with this connection,
+     * to remove the given Wi-Fi network from the framework.
+     *
+     * @param context The application context
+     * @param handler The handler to dispatch the processing of received broadcast intents
+     * @param ssid The SSID to connect to
+     * @param nai The network access identifier associated with the AP
+     * @param callbacks The callbacks to be invoked on network change events
+     * @throws IOException when failed to add/enable the specified Wi-Fi network
+     */
+    public NetworkConnection(Context context, Handler handler, WifiSsid ssid, String nai,
+            Callbacks callbacks) throws IOException {
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mCallbacks = callbacks;
+        mNetworkId = connect(ssid, nai);
+
+        // TODO(zqiu): setup alarm to timed out the connection attempt.
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                    handleNetworkStateChanged(
+                            intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
+                            intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO));
+                }
+            }
+        };
+        // Provide a Handler so that the onReceive call will be run on the specified handler
+        // thread instead of the main thread.
+        context.registerReceiver(receiver, filter, null, handler);
+    }
+
+    /**
+     * Teardown the network connection by removing the network.
+     */
+    public void teardown() {
+        mWifiManager.removeNetwork(mNetworkId);
+    }
+
+    /**
+     * Connect to a OSU Wi-Fi network specified by the given SSID. The security type of the Wi-Fi
+     * network is either open or OSEN (OSU Server-only authenticated layer 2 Encryption Network).
+     * When network access identifier is provided, OSEN is used.
+     *
+     * @param ssid The SSID to connect to
+     * @param nai Network access identifier of the network
+     *
+     * @return unique ID associated with the network
+     * @throws IOException
+     */
+    private int connect(WifiSsid ssid, String nai) throws IOException {
+        WifiConfiguration config = new WifiConfiguration();
+        config.SSID = "\"" + ssid.toString() + "\"";
+        if (TextUtils.isEmpty(nai)) {
+            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+        } else {
+            // TODO(zqiu): configuration setup for OSEN.
+        }
+        int networkId = mWifiManager.addNetwork(config);
+        if (networkId < 0) {
+            throw new IOException("Failed to add OSU network");
+        }
+        if (!mWifiManager.enableNetwork(networkId, true)) {
+            throw new IOException("Failed to enable OSU network");
+        }
+        return networkId;
+    }
+
+    /**
+     * Handle network state changed events.
+     *
+     * @param networkInfo {@link NetworkInfo} indicating the current network state
+     * @param wifiInfo {@link WifiInfo} associated with the current network when connected
+     */
+    private void handleNetworkStateChanged(NetworkInfo networkInfo, WifiInfo wifiInfo) {
+        if (networkInfo == null) {
+            Log.e(TAG, "NetworkInfo not provided for network state changed event");
+            return;
+        }
+        switch (networkInfo.getDetailedState()) {
+            case CONNECTED:
+                handleConnectedEvent(wifiInfo);
+                break;
+            case DISCONNECTED:
+                handleDisconnectedEvent();
+                break;
+            default:
+                Log.d(TAG, "Ignore uninterested state: " + networkInfo.getDetailedState());
+                break;
+        }
+    }
+
+    /**
+     * Handle network connected event.
+     *
+     * @param wifiInfo {@link WifiInfo} associated with the current connection
+     */
+    private void handleConnectedEvent(WifiInfo wifiInfo) {
+        if (mConnected) {
+            // No-op if already connected.
+            return;
+        }
+        if (wifiInfo == null) {
+            Log.e(TAG, "WifiInfo not provided for connected event");
+            return;
+        }
+        if (wifiInfo.getNetworkId() != mNetworkId) {
+            return;
+        }
+        Network network = mWifiManager.getCurrentNetwork();
+        if (network == null) {
+            Log.e(TAG, "Current network is not set");
+            return;
+        }
+        mConnected = true;
+        mCallbacks.onConnected(network);
+    }
+
+    /**
+     * Handle network disconnected event.
+     */
+    private void handleDisconnectedEvent() {
+        if (!mConnected) {
+            // No-op if not connected, most likely a disconnect event for a different network.
+            return;
+        }
+        mConnected = false;
+        mCallbacks.onDisconnected();
+    }
+}
diff --git a/packages/Osu2/src/com/android/osu/OsuService.java b/packages/Osu2/src/com/android/osu/OsuService.java
new file mode 100644
index 0000000..46a3c84
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/OsuService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.osu;
+
+/**
+ * Abstraction for services that can be performed by the OSU app, such as provisioning,
+ * subscription remediation, and etc.
+ */
+public interface OsuService {
+    /**
+     * Start the service.
+     */
+    public void start();
+
+    /**
+     * Stop the service.
+     */
+    public void stop();
+}
diff --git a/packages/Osu2/src/com/android/osu/ProvisionService.java b/packages/Osu2/src/com/android/osu/ProvisionService.java
new file mode 100644
index 0000000..b1d43b2
--- /dev/null
+++ b/packages/Osu2/src/com/android/osu/ProvisionService.java
@@ -0,0 +1,119 @@
+/*
+ * 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.osu;
+
+import android.content.Context;
+import android.net.Network;
+import android.net.wifi.hotspot2.OsuProvider;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * Service responsible for performing Passpoint subscription provisioning tasks.
+ * This service will run on a separate thread to avoid blocking on the Main thread.
+ */
+public class ProvisionService implements OsuService {
+    private static final String TAG = "OSU_ProvisionService";
+    private static final int COMMAND_START = 1;
+    private static final int COMMAND_STOP = 2;
+
+    private final Context mContext;
+    private final HandlerThread mHandlerThread;
+    private final ServiceHandler mServiceHandler;
+    private final OsuProvider mProvider;
+
+    private boolean mStarted = false;
+    private NetworkConnection mNetworkConnection = null;
+
+    public ProvisionService(Context context, OsuProvider provider) {
+        mContext = context;
+        mProvider = provider;
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
+    }
+
+    @Override
+    public void start() {
+        mServiceHandler.sendMessage(mServiceHandler.obtainMessage(COMMAND_START));
+    }
+
+    @Override
+    public void stop() {
+        mServiceHandler.sendMessage(mServiceHandler.obtainMessage(COMMAND_STOP));
+    }
+
+    /**
+     * Handler class for handling commands to the ProvisionService.
+     */
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case COMMAND_START:
+                    if (mStarted) {
+                        Log.e(TAG, "Service already started");
+                        return;
+                    }
+                    try {
+                        // Initiate network connection to the OSU AP.
+                        mNetworkConnection = new NetworkConnection(
+                                mContext, this, mProvider.getOsuSsid(),
+                                mProvider.getNetworkAccessIdentifier(), new NetworkCallbacks());
+                        mStarted = true;
+                    } catch (IOException e) {
+                        // TODO(zqiu): broadcast failure event via LocalBroadcastManager.
+                    }
+                    break;
+                case COMMAND_STOP:
+                    if (!mStarted) {
+                        Log.e(TAG, "Service not started");
+                        return;
+                    }
+                    Log.e(TAG, "Stop provision service");
+                    break;
+                default:
+                    Log.e(TAG, "Unknown command: " + msg.what);
+                    break;
+            }
+        }
+    }
+
+    private final class NetworkCallbacks implements NetworkConnection.Callbacks {
+        @Override
+        public void onConnected(Network network) {
+            Log.d(TAG, "Connected to OSU AP");
+        }
+
+        @Override
+        public void onDisconnected() {
+        }
+
+        @Override
+        public void onTimeout() {
+        }
+    }
+}
diff --git a/packages/Osu2/tests/Android.mk b/packages/Osu2/tests/Android.mk
new file mode 100644
index 0000000..4b6e0e6
--- /dev/null
+++ b/packages/Osu2/tests/Android.mk
@@ -0,0 +1,43 @@
+# 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_MODULE_TAGS := tests
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_JACK_FLAGS := --multi-dex native
+
+LOCAL_PACKAGE_NAME := OsuTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_INSTRUMENTATION_FOR := Osu2
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    mockito-target-minus-junit4 \
+    frameworks-base-testutils
+
+# Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
+ifeq (true,$(EMMA_INSTRUMENT))
+LOCAL_JACK_FLAGS := --multi-dex native
+LOCAL_DX_FLAGS := --multi-dex
+endif # EMMA_INSTRUMENT
+
+include $(BUILD_PACKAGE)
diff --git a/packages/Osu2/tests/AndroidManifest.xml b/packages/Osu2/tests/AndroidManifest.xml
new file mode 100644
index 0000000..e22c112
--- /dev/null
+++ b/packages/Osu2/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="com.android.osu.tests">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:label="OsuTestDummyLabel"
+                  android:name="OsuTestDummyName">
+            <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="com.android.osu"
+        android:label="OSU App Tests">
+    </instrumentation>
+
+</manifest>
diff --git a/packages/Osu2/tests/README.md b/packages/Osu2/tests/README.md
new file mode 100644
index 0000000..dbfa79c
--- /dev/null
+++ b/packages/Osu2/tests/README.md
@@ -0,0 +1,45 @@
+# OSU Unit Tests
+This package contains unit tests for the OSU app 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/packages/Osu2/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 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 com.android.osu
+runtests.sh -e class com.android.osu.NetworkConnectionTest
+```
+
+If you manually build and push the test APK to the device you can run tests using
+
+```
+adb shell am instrument -w 'com.android.osu.tests/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/packages/Osu2/tests/runtests.sh b/packages/Osu2/tests/runtests.sh
new file mode 100755
index 0000000..3513f5b
--- /dev/null
+++ b/packages/Osu2/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/packages/Osu2/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-packages-Osu2-tests
+
+set -x # print commands
+
+adb root
+adb wait-for-device
+
+adb install -r -g "$OUT/data/app/OsuTests/OsuTests.apk"
+
+adb shell am instrument -w "$@" 'com.android.osu.tests/android.support.test.runner.AndroidJUnitRunner'
diff --git a/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java b/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java
new file mode 100644
index 0000000..2753249
--- /dev/null
+++ b/packages/Osu2/tests/src/com/android/osu/NetworkConnectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.osu;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.Handler;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link com.android.osu.NetworkConnection}.
+ */
+@SmallTest
+public class NetworkConnectionTest {
+    private static final String TEST_SSID = "TEST SSID";
+    private static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
+    private static final int TEST_NETWORK_ID = 1;
+
+    @Mock Context mContext;
+    @Mock Handler mHandler;
+    @Mock WifiManager mWifiManager;
+    @Mock NetworkConnection.Callbacks mCallbacks;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+    }
+
+    /**
+     * Verify that an IOException will be thrown when failed to add the network.
+     *
+     * @throws Exception
+     */
+    @Test(expected = IOException.class)
+    public void networkAddFailed() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(-1);
+        new NetworkConnection(mContext, mHandler, WifiSsid.createFromAsciiEncoded(TEST_SSID),
+                null, mCallbacks);
+    }
+
+    /**
+     * Verify that an IOException will be thrown when failed to enable the network.
+     *
+     * @throws Exception
+     */
+    @Test(expected = IOException.class)
+    public void networkEnableFailed() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(TEST_NETWORK_ID);
+        when(mWifiManager.enableNetwork(eq(TEST_NETWORK_ID), eq(true))).thenReturn(false);
+        new NetworkConnection(mContext, mHandler, WifiSsid.createFromAsciiEncoded(TEST_SSID),
+                null, mCallbacks);
+    }
+
+    /**
+     * Verify that the connection is established after receiving a
+     * WifiManager.NETWORK_STATE_CHANGED_ACTION intent indicating that we are connected.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void openNetworkConnectionEstablished() throws Exception {
+        when(mWifiManager.addNetwork(any(WifiConfiguration.class))).thenReturn(TEST_NETWORK_ID);
+        when(mWifiManager.enableNetwork(eq(TEST_NETWORK_ID), eq(true))).thenReturn(true);
+        NetworkConnection connection = new NetworkConnection(mContext, mHandler,
+                WifiSsid.createFromAsciiEncoded(TEST_SSID), null, mCallbacks);
+
+        // Verify the WifiConfiguration being added.
+        ArgumentCaptor<WifiConfiguration> wifiConfig =
+                ArgumentCaptor.forClass(WifiConfiguration.class);
+        verify(mWifiManager).addNetwork(wifiConfig.capture());
+        assertEquals(wifiConfig.getValue().SSID, TEST_SSID_WITH_QUOTES);
+
+        // Capture the BroadcastReceiver.
+        ArgumentCaptor<BroadcastReceiver> receiver =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        verify(mContext).registerReceiver(receiver.capture(), any(), any(), any());
+
+        // Setup intent.
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(TEST_NETWORK_ID);
+        intent.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
+
+        // Send intent to the receiver.
+        Network network = new Network(0);
+        when(mWifiManager.getCurrentNetwork()).thenReturn(network);
+        receiver.getValue().onReceive(mContext, intent);
+
+        // Verify we are connected.
+        verify(mCallbacks).onConnected(eq(network));
+    }
+}
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 2b1b8ca..49fe52b 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -62,6 +62,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Još informacija o ovom štampaču"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Aktivni zadaci štampanja"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Neuspeli zadaci štampanja"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Pravljenje datoteke nije uspelo"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Pretraga štampača"</string>
diff --git a/packages/PrintSpooler/res/values-be/strings.xml b/packages/PrintSpooler/res/values-be/strings.xml
index 83d0627..c04756c 100644
--- a/packages/PrintSpooler/res/values-be/strings.xml
+++ b/packages/PrintSpooler/res/values-be/strings.xml
@@ -63,6 +63,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Больш падрабязная інфармацыя пра гэты прынтар"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Заданні друку, якія выконваюцца"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Заданні друку са збоямі"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Не ўдалося стварыць файл"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некаторыя службы друку адключаны"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук прынтараў"</string>
diff --git a/packages/PrintSpooler/res/values-bs/strings.xml b/packages/PrintSpooler/res/values-bs/strings.xml
index 2450be3..d3f1b80 100644
--- a/packages/PrintSpooler/res/values-bs/strings.xml
+++ b/packages/PrintSpooler/res/values-bs/strings.xml
@@ -62,6 +62,8 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Više informacija o ovom štampaču"</string>
+    <string name="notification_channel_progress" msgid="872788690775721436">"Tekući zadaci za štampanje"</string>
+    <string name="notification_channel_failure" msgid="9042250774797916414">"Neizvršeni zadaci za štampanje"</string>
     <string name="could_not_create_file" msgid="3425025039427448443">"Nije uspjelo kreiranje fajla"</string>
     <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge za štampanje su isključene"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index f88a453..5f116dc 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -100,7 +100,7 @@
   </string-array>
   <string-array name="orientation_labels">
     <item msgid="4061931020926489228">"Stående"</item>
-    <item msgid="3199660090246166812">"Liggende format"</item>
+    <item msgid="3199660090246166812">"Liggende"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"Der kunne ikke skrives til filen"</string>
     <string name="print_error_default_message" msgid="8602678405502922346">"Det virkede desværre ikke. Prøv igen."</string>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index eac6d36..174789f 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Selecionar impressora"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> impressora encontrada</item>
+      <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -76,7 +76,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="one">Instale para detetar <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item>
+      <item quantity="one">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
       <item quantity="other">Instale para detetar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"A imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index cb23c3c..c20a5af 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4469836075319831821">"Штампање из меморије"</string>
+    <string name="app_label" msgid="4469836075319831821">"Штамп. из мемор."</string>
     <string name="more_options_button" msgid="2243228396432556771">"Још опција"</string>
     <string name="label_destination" msgid="9132510997381599275">"Одредиште"</string>
     <string name="label_copies" msgid="3634531042822968308">"Копије"</string>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 41952df..81f7315 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -190,8 +190,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mState != STATE_DESTROYED) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (mState != STATE_DESTROYED) {
                 destroy(null);
             }
         } finally {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index bf8eb84..d592c30 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -561,8 +561,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mState != STATE_DESTROYED) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (mState != STATE_DESTROYED) {
                 destroy(null);
             }
         } finally {
diff --git a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
index 7716992..72be35b 100644
--- a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
+++ b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="PrintSpoolerOutOfProcessTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.printspooler.outofprocess.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml
new file mode 100644
index 0000000..3fe1e9e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
new file mode 100644
index 0000000..061f9fe
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?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:name="ic_rotate_to_landscape"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48"
+    android:tint="?android:attr/colorControlNormal" >
+    <group
+        android:name="device"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="device_pivot"
+            android:translateX="-24.15"
+            android:translateY="-24.25" >
+            <group
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24"
+                android:scaleX="0.909"
+                android:scaleY="0.909"
+                android:rotation="45" >
+                <path
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml b/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
index 4aa8569..4b81a3c 100644
--- a/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/SettingsLib/res/drawable/ic_lockscreen_ime.xml
@@ -18,7 +18,7 @@
     android:height="24dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0"
-    android:tint="?android:attr/colorAccent">
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FF000000"
         android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9
diff --git a/packages/SettingsLib/res/drawable/ic_mode_edit.xml b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
new file mode 100644
index 0000000..2ad3119
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
@@ -0,0 +1,25 @@
+<!--
+    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="20.0dp"
+        android:height="20.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M3,18.08v2.42c0,0.28 0.22,0.5 0.5,0.5h2.42c0.53,0 1.04,-0.21 1.41,-0.59L17.81,9.94l-3.75,-3.75L3.59,16.66c-0.38,0.38 -0.59,0.89 -0.59,1.42zM20.71,7.04a0.996,0.996 0,0 0,0 -1.41l-2.34,-2.34a0.996,0.996 0,0 0,-1.41 0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
new file mode 100644
index 0000000..8801f5d
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
@@ -0,0 +1,24 @@
+<!--
+    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="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z"
+        android:fillColor="#FFF"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml
new file mode 100644
index 0000000..2f60580
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_signal_location.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.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="0.02"
+        android:translateY="0.82">
+        <path
+            android:pathData="M12,2C8.13,2 5,5.13 5,9c0,4.17 4.42,9.92 6.24,12.11 0.4,0.48 1.13,0.48 1.53,0C14.58,18.92 19,13.17 19,9c0,-3.87 -3.13,-7 -7,-7zM12,11.5a2.5,2.5 0,0 1,0 -5,2.5 2.5,0 0,1 0,5z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/list_divider_dark.xml b/packages/SettingsLib/res/drawable/list_divider_dark.xml
new file mode 100644
index 0000000..5773d9e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/list_divider_dark.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#64000000" />
+    <size
+        android:height="1dp"
+        android:width="1dp" />
+</shape>
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings.xml b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
new file mode 100644
index 0000000..741435e
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
@@ -0,0 +1,66 @@
+<?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_category_material.xml
+     except that this supports icon -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="8dp"
+    android:layout_marginBottom="8dp"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart" >
+
+    <LinearLayout
+        android:id="@+id/icon_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="start|center_vertical"
+        android:orientation="horizontal">
+        <com.android.internal.widget.PreferenceImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:tint="?android:attr/textColorPrimary"
+            android:maxWidth="18dp"
+            android:maxHeight="18dp"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="56dp"
+        android:orientation="vertical">
+        <TextView
+            android:id="@android:id/title"
+            android:layout_marginTop="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="@android:style/TextAppearance.Material.Body2"
+            android:textColor="?android:attr/colorAccent"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"/>
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+            android:textColor="?android:attr/textColorSecondary"
+            android:ellipsize="end"
+            android:singleLine="true" />
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/preference_footer.xml b/packages/SettingsLib/res/layout/preference_footer.xml
new file mode 100644
index 0000000..d83e249
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_footer.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2016 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:id="@+id/icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="56dp"
+        android:gravity="start|top"
+        android:orientation="horizontal"
+        android:paddingEnd="12dp"
+        android:paddingTop="16dp"
+        android:paddingBottom="4dp">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <com.android.settingslib.widget.LinkTextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp"
+        android:maxLines="10"
+        android:textColor="?android:attr/textColorSecondary"
+        android:ellipsize="marquee" />
+
+</LinearLayout>
\ 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 9fb956e..2309ec6 100644
--- a/packages/SettingsLib/res/layout/preference_two_target.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target.xml
@@ -18,9 +18,10 @@
 <!-- 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/listPreferredItemHeight"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:gravity="center_vertical"
     android:background="@android:color/transparent"
     android:clipToPadding="false">
@@ -31,23 +32,27 @@
         android:layout_weight="1"
         android:background="?android:attr/selectableItemBackground"
         android:gravity="start|center_vertical"
-        android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+        android:clipToPadding="false"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
 
         <LinearLayout
-            android:id="@+id/icon_container"
+            android:id="@+id/icon_frame"
+            style="@style/preference_icon_frame"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:minWidth="56dp"
+            android:gravity="start|center_vertical"
             android:orientation="horizontal"
+            android:clipToPadding="false"
             android:paddingEnd="12dp"
             android:paddingTop="4dp"
             android:paddingBottom="4dp">
-            <com.android.internal.widget.PreferenceImageView
+            <android.support.v7.internal.widget.PreferenceImageView
                 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/layout/preference_two_target_divider.xml b/packages/SettingsLib/res/layout/preference_two_target_divider.xml
index ced6142..60efed4 100644
--- a/packages/SettingsLib/res/layout/preference_two_target_divider.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target_divider.xml
@@ -27,5 +27,5 @@
     <View
         android:layout_width="1dp"
         android:layout_height="match_parent"
-        android:background="?android:attr/dividerVertical" />
+        android:background="@drawable/list_divider_dark" />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/usage_bottom_label.xml b/packages/SettingsLib/res/layout/usage_bottom_label.xml
deleted file mode 100644
index 6c16880..0000000
--- a/packages/SettingsLib/res/layout/usage_bottom_label.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_side_label.xml b/packages/SettingsLib/res/layout/usage_side_label.xml
deleted file mode 100644
index 6c16880..0000000
--- a/packages/SettingsLib/res/layout/usage_side_label.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml
deleted file mode 100644
index da66814..0000000
--- a/packages/SettingsLib/res/layout/usage_view.xml
+++ /dev/null
@@ -1,99 +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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/graph_label_group"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        android:clipChildren="false"
-        android:clipToPadding="false">
-
-        <LinearLayout
-            android:id="@+id/label_group"
-            android:layout_width="@dimen/usage_graph_labels_width"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
-
-            <include android:id="@+id/label_top"
-                layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/space1"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_middle"
-                layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/space2"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_bottom"
-                layout="@layout/usage_side_label" />
-
-        </LinearLayout>
-
-        <com.android.settingslib.graph.UsageGraph
-            android:id="@+id/usage_graph"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:layout_marginTop="@dimen/usage_graph_margin_top_bottom"
-            android:layout_marginBottom="@dimen/usage_graph_margin_top_bottom" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/bottom_label_group"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal">
-        <Space
-            android:id="@+id/bottom_label_space"
-            android:layout_width="@dimen/usage_graph_labels_width"
-            android:layout_height="wrap_content"/>
-        <com.android.settingslib.graph.BottomLabelLayout
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:orientation="horizontal"
-            android:layoutDirection="ltr">
-            <include android:id="@+id/label_start"
-                     layout="@layout/usage_side_label" />
-
-            <Space
-                android:id="@+id/spacer"
-                android:layout_width="40dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1" />
-
-            <include android:id="@+id/label_end"
-                     layout="@layout/usage_side_label" />
-        </com.android.settingslib.graph.BottomLabelLayout>
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index bc27c30..59e5f09 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 
+<!--
 /*
 **
 ** Copyright 2015 The Android Open Source Project
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Gebruik stelselkeuse (verstek)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX-HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Aktiveer opsionele kodekke"</item>
     <item msgid="3304843301758635896">"Deaktiveer opsionele kodekke"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Gebruik stelselkeuse (verstek)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX-HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Aktiveer opsionele kodekke"</item>
     <item msgid="741805482892725657">"Deaktiveer opsionele kodekke"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 8071041..1058110 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Gekoppel, geen internet nie"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ontkoppel"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ontkoppel tans…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbind tans…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-oudio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Foonoudio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Lêeroordrag"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Invoertoestel"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internettoegang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakdeling"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gebruik vir kontakdeling"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling van internetverbinding"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Boodskaptoegang"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-toegang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gebruik hoëgehalte-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gebruik hoëgehalte-oudio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Gekoppel aan media-oudio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Gekoppel aan foonoudio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Gekoppel aan lêeroordragbediener"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">%1$s</xliff:g> oor"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor gegrond op jou gebruik"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol gelaai"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> oor"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> oor gegrond op jou gebruik"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – ongeveer <xliff:g id="TIME">%2$s</xliff:g> oor gegrond op jou gebruik"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Beheer deur administrateur"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Geaktiveer deur administrateur"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Gedeaktiveer deur administrateur"</string>
-    <string name="disabled" msgid="9206776641295849915">"Gedeaktiveer"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Toegelaat"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nie toegelaat nie"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installeer onbekende apps"</string>
     <string name="home" msgid="3256884684164448244">"Instellingstuisblad"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 79dad14..dcabc03 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 
+<!--
 /*
 **
 ** Copyright 2015 The Android Open Source Project
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"አማራጭ ኮዴኮችን አንቃ"</item>
     <item msgid="3304843301758635896">"አማራጭ ኮዴኮችን አሰናክል"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"አማራጭ ኮዴኮችን አንቃ"</item>
     <item msgid="741805482892725657">"አማራጭ ኮዴኮችን አሰናክል"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f5fc77f..dfa5aaa 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ተገናኝቷል፣ ምንም በይነመረብ የለም"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ተለያይቷል"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"በመለያየት ላይ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"በማገናኘት ላይ…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ተገናኝቷል (ምንም የመልዕክት መዳረሻ የለም)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ተያይዟል (ምንም ስልክ ወይም ማህደረ መረጃ የለም)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"የማህደረ መረጃ ኦዲዮ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"የስልክ ኦዲዮ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ፋይል ማስተላለፍ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ግቤት መሣሪያ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"የበይነመረብ ድረስ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"እውቂያ ማጋራት"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"እውቂያን ለማጋራት ተጠቀም"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"የበይነ መረብ ተያያዥ ማጋሪያ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"የመልዕክት መዳረሻ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"የሲም መዳረሻ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ከፍተኛ ጥራት ያለውን ኦዲዮ ተጠቀም፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ከፍተኛ ጥራት ያለውን ኦዲዮ ተጠቀም"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> አካባቢ ቀርቷል"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ሙሉ ኃይል እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> አካባቢ ይቀራል"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - በእርስዎ አጠቃቀም ላይ በመመስረት <xliff:g id="TIME">%2$s</xliff:g> ገደማ ቀርቷል"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"በአስተዳዳሪ ነቅቷል"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"በአስተዳዳሪ ተሰናክሏል"</string>
-    <string name="disabled" msgid="9206776641295849915">"ቦዝኗል"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ይፈቀዳል"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"አይፈቀድም"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ያልታወቁ መተግበሪያዎችን ይጫኑ"</string>
     <string name="home" msgid="3256884684164448244">"የቅንብሮች መነሻ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index ea31dbe..b6cca72 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"استخدام اختيار النظام (افتراضي)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"تمكين برامج الترميز الاختيارية"</item>
     <item msgid="3304843301758635896">"تعطيل برامج الترميز الاختيارية"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"استخدام اختيار النظام (افتراضي)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"تمكين برامج الترميز الاختيارية"</item>
     <item msgid="741805482892725657">"تعطيل برامج الترميز الاختيارية"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9b8128c..343c82f 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏تم الاتصال عبر %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏متوفرة عبر %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصلة، ولا يتوفر إنترنت"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"غير متصل"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"جارٍ قطع الاتصال..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"جارٍ الاتصال…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"تم الاتصال (يتعذر الدخول إلى الرسائل)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل (بجهاز غير الهاتف أو الوسائط)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"الإعدادات الصوتية للوسائط"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"الإعدادات الصوتية للهاتف"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"نقل الملف"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"جهاز الإرسال"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"الدخول إلى الإنترنت"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"مشاركة جهة الاتصال"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"استخدام مع مشاركة جهة الاتصال"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"مشاركة اتصال الإنترنت"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"الدخول إلى الرسائل"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏الوصول إلى شريحة SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"استخدام صوت عالي الجودة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"استخدام صوت عالي الجودة"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -101,7 +117,7 @@
     <string name="unknown" msgid="1592123443519355854">"غير معروف"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"المستخدم: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"تم تعيين بعض الإعدادات الافتراضية"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"لم يتم تعيين إعدادات تلقائية"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"لم يتم تعيين إعدادات افتراضية"</string>
     <string name="tts_settings" msgid="8186971894801348327">"إعدادات تحويل النص إلى كلام"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"إخراج تحويل النص إلى كلام"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"معدل سرعة الكلام"</string>
@@ -321,15 +337,18 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"يتبقى حوالي <xliff:g id="TIME">%1$s</xliff:g> لإتمام شحن البطارية"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا بناءً على استخدامك"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> لشحن البطارية بالكامل"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"يتبقى <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> بناءً على استخدامك"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا بناءً على استخدامك"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقى <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"جارٍ الشحن"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"جاري الشحن"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"جارٍ الشحن"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"لا يتم الشحن"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"إعدادات يتحكم فيها المشرف"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"تم تمكين الإعداد بواسطة المشرف"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"تم تعطيل الإعداد بواسطة المشرف"</string>
-    <string name="disabled" msgid="9206776641295849915">"معطل"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"مسموح به"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"غير مسموح به"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"تثبيت التطبيقات غير المعروفة"</string>
     <string name="home" msgid="3256884684164448244">"الشاشة الرئيسية للإعدادات"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"٠‏٪"</item>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index b25b382..057a5a8 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Sistem Seçimini istifadə edin (Defolt)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Şəxsi Kodekləri Aktiv edin"</item>
     <item msgid="3304843301758635896">"Şəxsi Kodekləri Deaktiv edin"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Sistem Seçimini istifadə edin (Defolt)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Şəxsi Kodekləri Aktiv edin"</item>
     <item msgid="741805482892725657">"Şəxsi Kodekləri Deaktiv edin"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 519b246..be22538 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Qoşuludur, internet yoxdur"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ayrıldı"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ayrılır..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Qoşulur..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl transferi"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Daxiletmə cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"İnternet girişi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakt paylaşımı"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kontakt paylaşımı üçün istifadə edin"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"internet bağlantı paylaşımı"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mesaj Girişi"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Girişi"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yüksək keyfiyyətli audio istifadə edin: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yüksək keyfiyyətli audio istifadə edin"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Media audioya birləşdirilib"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon audiosuna qoşulu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fayl transfer serverinə qoşulu"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"İstifadəyə əsasən təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam enerji yığmağına <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"İstifadəyə əsasən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - istifadəyə əsasən təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tam enerji yığana kimi"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Admin tərəfindən nəzarət olunur"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Admin tərəfindən aktiv edildi"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Admin tərəfindən deaktiv edildi"</string>
-    <string name="disabled" msgid="9206776641295849915">"Deaktiv"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"İcazə verilib"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"İcazə verilməyib"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Naməlum tətbiqlərin quraşdırılması"</string>
     <string name="home" msgid="3256884684164448244">"Ayarların əsas səhifəsi"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 7d09876..cc88aa9 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Koristi HDCP proveru samo za DRM sadržaj"</item>
     <item msgid="45075631231212732">"Uvek koristi HDCP proveru"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (podrazumevano)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Omogući opcionalne kodeke"</item>
+    <item msgid="3304843301758635896">"Onemogući opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Koristi izbor sistema (podrazumevano)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Omogući opcionalne kodeke"</item>
+    <item msgid="741805482892725657">"Onemogući opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Koristi izbor sistema (podrazumevano)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Optimizovano za kvalitet zvuka (990 kb/s/909 kb/s)"</item>
     <item msgid="2921767058740704969">"Ujednačen kvalitet zvuka i veze (660 kb/s/606 kb/s)"</item>
     <item msgid="8860982705384396512">"Optimizovano za kvalitet veze (330 kb/s/303 kb/s)"</item>
+    <item msgid="4414060457677684127">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Optimizovano za kvalitet zvuka"</item>
     <item msgid="4327143584633311908">"Ujednačen kvalitet zvuka i veze"</item>
     <item msgid="4681409244565426925">"Optimizovano za kvalitet veze"</item>
+    <item msgid="364670732877872677">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
@@ -188,7 +198,7 @@
     <item msgid="1069584980746680398">"Razmera animacije 10x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
-    <item msgid="1606809880904982133">"Nijedno"</item>
+    <item msgid="1606809880904982133">"Ništa"</item>
     <item msgid="9033194758688161545">"480 piksela"</item>
     <item msgid="1025306206556583600">"480 piksela (bezbedno)"</item>
     <item msgid="1853913333042744661">"720 piksela"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 24b2a13..e8fade2 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Automatsko povezivanje nije uspelo"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="4352716707126620811">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano preko %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano preko dobavljača ocene mreže"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Veza je uspostavljena, nema interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Veza je prekinuta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekidanje veze..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -49,15 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup Internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deljenje kontakata"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Koristite za deljenje kontakata"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deljenje internet veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup porukama"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM kartici"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano sa zvukom medija"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano sa zvukom telefona"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezano sa serverom za prenos datoteka"</string>
@@ -127,7 +143,7 @@
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Podešavanja za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni podešavanja mašine"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željena mašina"</string>
-    <string name="tts_general_section_title" msgid="4402572014604490502">"Opšte"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"Opšta"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Resetujte visinu tona govora"</string>
     <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Resetujte visinu tona kojom se tekst izgovara na podrazumevanu."</string>
   <string-array name="tts_rate_entries">
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Veoma ubrzano"</item>
     <item msgid="9085102246155045744">"Najbrže"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Izaberite profil"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Izaberite profil"</string>
     <string name="category_personal" msgid="1299663247844969448">"Lično"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za programera"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <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>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <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>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Izaberite verziju Bluetooth AVRCP-a"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Izaberite Bluetooth audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kad se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na mobilnu ako je Wi‑Fi signal slab"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Dozvoli/zabrani skeniranje Wi-Fi-ja u romingu na osnovu prisutnog protoka podataka na interfejsu"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Izaberite veličine po baferu evidencije"</string>
@@ -207,7 +219,7 @@
     <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 proveru atributa za pregled"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka podaci za mobilne uređaje uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</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="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>
@@ -216,6 +228,7 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije preko USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Omogućite da se melodija zvona na telefonu pušta preko Bluetooth slušalica"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući aplik. terminala za pristup lokalnom komandnom okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provera"</string>
@@ -275,6 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje pozadinskih procesa"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Prikaži dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikazuj upozorenja zbog kanala za obaveštenja"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Prinudno dozvoli aplikacije u spoljnoj"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Prinudno omogući promenu veličine aktivnosti"</string>
@@ -302,8 +317,6 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivna. Dodirnite da biste je deaktivirali."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Višeprocesni WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Pokrećite WebView prikazivače zasebno"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Primena WebView-a"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesite primenu WebView-a"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Ovaj izbor više nije važeći. Probajte ponovo."</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomalija (plavo-žuto)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boja"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na kvalitet rada."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Još oko <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Na osnovu potrošnje imate još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do potpunog punjenja"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Preostalo vreme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Na osnovu potrošnje imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ostalo je oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – na osnovu potrošnje imate još otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"Preostalo je <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje preko punjača"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Puni se"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Puni se"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Puni se"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"puni se"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontroliše administrator"</string>
-    <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio je administrator"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio je administrator"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"Administrator je onemogućio"</string>
     <string name="home" msgid="3256884684164448244">"Početna za Podešavanja"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Potrebna je lozinka"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Metode aktivnog unosa"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Koristi jezike sistema"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Otvaranje podešavanja za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspelo"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj metod unosa možda može da prikuplja sav tekst koji unosite, uključujući lične podatke, kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Želite li da koristite ovaj metod unosa?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Posle restartovanja ova aplikacija ne može da se pokrene dok ne otključate telefon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 6c883e3e..1467682 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Выкарыстанне праверкі HDCP только для змесціва, абароненага DRM"</item>
     <item msgid="45075631231212732">"Заўсёды выкарыстоўваць праверку HDCP"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (стандартная)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Выбар сістэмы (стандартны)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Уключыць дадатковыя кодэкі"</item>
+    <item msgid="3304843301758635896">"Адключыць дадатковыя кодэкі"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Выбар сістэмы (стандартны)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Уключыць дадатковыя кодэкі"</item>
+    <item msgid="741805482892725657">"Адключыць дадатковыя кодэкі"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Выбар сістэмы (стандартны)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Аптымізавана якасць гуку (990 кбіт/c / 909 кбіт/c)"</item>
     <item msgid="2921767058740704969">"Збалансаваная якасць аўдыя і падключэння (660кбіт/c / 606 кбіт/c)"</item>
     <item msgid="8860982705384396512">"Аптымізавана якасць падключэння (330 кбіт/c / 303 кбіт/c)"</item>
+    <item msgid="4414060457677684127">"Best Effort (адаптыўны бітрэйт)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Аптымізавана якасць гуку"</item>
     <item msgid="4327143584633311908">"Збалансаваная якасць аўдыя і падключэння"</item>
     <item msgid="4681409244565426925">"Аптымізавана якасць падключэння"</item>
+    <item msgid="364670732877872677">"Best Effort (адаптыўны бітрэйт)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Выкл."</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 36ebaa3..c69b314 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Не будзе аўтаматычна падключацца"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Няма доступу да інтэрнэту"</string>
     <string name="saved_network" msgid="4352716707126620811">"Хто захаваў: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Аўтаматычна падключана праз %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Аўтаматычна падключана праз пастаўшчыка паслугі ацэнкі сеткі"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Падлучана, няма інтэрнэту"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Адключана"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Адключэнне..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Злучэнне..."</string>
@@ -49,15 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Падлучана (без доступу да паведамленняў)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Падключаны (без тэлефона або носьбіта)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аўдыё медыяпрылады"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Аудыё тэлефона"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Перадача файлаў"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Прылада ўводу"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ у інтэрнэт"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Абагуленне кантактаў"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Выкарыстоўваць для абагулення кантактаў"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Прадастаўленне доступу да Інтэрнэту"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ да паведамленняў"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ да SIM-карты"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -95,7 +111,7 @@
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Партатыўная кропка доступу"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth-мадэм"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Мадэм"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Мадэм і партатыўны хотспот"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Рэжым мадэма"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Усе працоўныя праграмы"</string>
     <string name="user_guest" msgid="8475274842845401871">"Госць"</string>
     <string name="unknown" msgid="1592123443519355854">"Невядома"</string>
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Вельмі шпарка"</item>
     <item msgid="9085102246155045744">"Максімальна хутка"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Выбраць профіль"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Выбраць профіль"</string>
     <string name="category_personal" msgid="1299663247844969448">"Асабісты"</string>
     <string name="category_work" msgid="8699184680584175622">"Рабочы"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Параметры распрацоўшчыка"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога дысплея"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <string name="wifi_aggressive_handover" msgid="5309131983693661320">"Інтэнсіўны пераход з Wi‑Fi на маб. сетку"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Заўсёды дазваляць роўмінгавае сканіраванне Wi‑Fi"</string>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Адключыць абсалютны гук"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"Уключыць унутрыпалосны празвон"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Версія Bluetooth AVRCP"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Выбраць версію Bluetooth AVRCP"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Кодэк Bluetooth Audio"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Выбраць аўдыякодэк Bluetooth"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Частата дыскрэтызацыі Bluetooth Audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Перадача плынню: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Падвыс. узровень дэтал-цыі журнала Wi‑Fi у залежн. ад SSID RSSI у Wi‑Fi Picker"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Калі гэта функцыя ўключана, Wi-Fi будзе больш інтэнсіўна імкнуцца перайсці на падключ. маб. перад. даных пры слабым сігнале Wi‑Fi"</string>
     <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"Дазволіць/забараніць роўмінгавае сканіраванне Wi‑Fi ў залежнасці ад аб\'ёму трафіку даных у інтэрфейсе"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера для сродку вядзення журнала"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Выберыце памеры сродку вядзення журнала для буфераў журнала"</string>
@@ -216,6 +228,7 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Праверце прыкладаннi па USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Праверце прыкладаннi, усталяваныя з дапамогай ADB/ADT, на нестабiльныя паводзiны."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Адключыць функцыю абсалютнага гуку Bluetooth у выпадку праблем з гукам на аддаленых прыладах, напр., пры непрымальна высокай гучнасці або адсутнасці кіравання."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Дазволіць прайграванне рынгтонаў на тэлефоне праз гарнітуры Bluetooth"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Лакальны тэрмінал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Уключэнне прыкладання тэрмінала, якое прапануе доступ да лакальнай абалонкі"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Праверка HDCP"</string>
@@ -275,6 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ліміт фонавага працэсу"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Паказаць усе ANRS"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Паказаць дыялогавае акно \"Праграма не адказвае\" для фонавых прыкладанняў"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Паказваць папярэджанні канала апавяшчэннаў"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Паказвае папярэджанне на экране, калі праграма публікуе апавяшчэнне без сапраўднага канала"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Прымусова дазволіць праграмы на вонкавым сховішчы"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Робіць любую праграму даступнай для запісу на вонкавае сховішча, незалежна ад значэнняў маніфеста"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Зрабіць вокны дзеянняў даступнымі для змены памеру"</string>
@@ -302,8 +317,6 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Актыўная. Краніце, каб пераключыць."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Запушчаныя службы"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Прагляд запушчаных службаў i кіраванне iмi"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Шматпрацэсны WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Запусціць апрацоўшчыкі WebView асобна"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Рэалізацыя WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Наладзіць рэалізацыю WebView"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Гэты варыянт больш не даступны. Паспрабуйце яшчэ раз."</string>
@@ -311,7 +324,7 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Пераход..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Шыфраванне файлаў ужо дзейнічае"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Пераход на шыфраванне файлаў"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Перайдзіце з шыфравання раздзелаў даных на шыфраванне файлаў.\n !!Увага!! Гэта прывядзе да выдалення ўсіх даных.\n Гэта функцыя ў альфа-версіі, яна можа працаваць няправільна.\n Каб працягнуць, націсніце «Сцерці і перайсці...»."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Перайдзіце з шыфравання раздзелаў даных на шыфраванне файлаў.\n !!Увага!! Гэта прывядзе да выдалення ўсіх даных.\n Гэта функцыя ў альфа-версіі, яна можа працаваць няправільна.\n Каб працягнуць, націсніце \"Сцерці і перайсці...\"."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Сцерці і перайсці..."</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Каляровы рэжым выявы"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Выкарыстоўваць sRGB"</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Пратанамалія (чырвоны-зялёны)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Трытанамалія (сіні-жоўты)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Карэкцыя колеру"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэтая функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэта функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Засталося каля <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Засталося каля <xliff:g id="TIME">%1$s</xliff:g> на аснове вашага выкарыстання"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Засталося <xliff:g id="TIME">%1$s</xliff:g> на аснове вашага выкарыстання"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося каля <xliff:g id="TIME">%2$s</xliff:g> на аснове вашага выкарыстання"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зар. ад сеткі пер. току"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Зарадка"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарадка па USB"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Зарадка"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бесправадная зарадка"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Зарадка"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ідзе зарадка"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Не зараджаецца"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Кантралюецца адміністратарам"</string>
-    <string name="enabled_by_admin" msgid="2386503803463071894">"Уключана адміністратарам"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Адключана адміністратарам"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"Уключана адміністратарам"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"Адключана адміністратарам"</string>
     <string name="home" msgid="3256884684164448244">"Галоўная старонка налад"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
@@ -367,7 +368,7 @@
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандартны"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Вялікі"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Большы"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найвялікшы"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Самы вялікі"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Даведка і водгукі"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Патрабуецца пароль"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Актыўныя метады ўводу"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Выкарыстоўваць мовы сістэмы"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Не атрымалася адкрыць параметры <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Гэты метад уводу можа збіраць увесь тэкст, які ўводзіцца, у тым лiку такiя персанальныя дадзеныя, як паролі і нумары крэдытных карт. Ён выкарыстоўваецца прыкладаннем <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Выкарыстоўваць гэты метад уводу?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Заўвага. Пасля перазагрузкі гэта праграма не зможа запусціцца, пакуль вы не разблакіруеце тэлефон"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 3f25978..dc18f39 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Използване на сист. избор (стандартно)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"Разширено аудиокодиране (AAC)"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Активиране на кодеците по избор"</item>
     <item msgid="3304843301758635896">"Деактивиране на кодеците по избор"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Използване на сист. избор (стандартно)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"Разширено аудиокодиране (AAC)"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Активиране на кодеците по избор"</item>
     <item msgid="741805482892725657">"Деактивиране на кодеците по избор"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2f7412e..b7713b9 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Установена е връзка – няма достъп до интернет"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Изкл."</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Изключва се..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Установява се връзка…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Има връзка (няма достъп до съобщенията)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Свързано (без телефона или мултимедията)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Мултимедийно аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук на телефона"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Прехвърляне на файл"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Входно устройство"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Достъп до интернет"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Споделяне на контакти"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Използване за споделяне на контакти"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Споделяне на връзката с интернет"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Достъп до съобщенията"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Достъп до SIM картата"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Използване на висококачествен звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Използване на висококачествен звук"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Оставащо време: около <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Още около <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Още <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – около <xliff:g id="TIME">%2$s</xliff:g> оставащо време"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – още около <xliff:g id="TIME">%2$s</xliff:g> въз основа на използването"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролира се от администратор"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Активирано от администратора"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Деактивирано от администратора"</string>
-    <string name="disabled" msgid="9206776641295849915">"Деактивирано"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Има разрешение"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Няма разрешение"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Инст. на неизвестни прилож."</string>
     <string name="home" msgid="3256884684164448244">"Начален екран на Настройки"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 4d5c1f1..f31fd1b 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ঐচ্ছিক কোডেক সক্ষম করুন"</item>
     <item msgid="3304843301758635896">"ঐচ্ছিক কোডেক অক্ষম করুন"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ঐচ্ছিক কোডেক সক্ষম করুন"</item>
     <item msgid="741805482892725657">"ঐচ্ছিক কোডেক অক্ষম করুন"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 913345d..7b6cffe 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে সংযুক্ত হয়েছে"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"সংযুক্ত, ইন্টারনেট নেই"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"সংযোগ বিচ্ছিন্ন করা হয়েছে"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"সংযোগ বিচ্ছিন্ন হচ্ছে..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"সংযুক্ত হচ্ছে..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"সংযুক্ত (কোনো বার্তা অ্যাক্সেস নেই)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"সংযুক্ত (কোনো ফোন বা মিডিয়া নেই)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়া অডিও"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ফোন অডিও"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তর"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ইনপুট ডিভাইস"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ইন্টারনেট অ্যাক্সেস"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"পরিচিতি শেয়ার করা"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"পরিচিতি শেয়ার করার কাজে ব্যবহার করুন"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ইন্টারনেট সংযোগ শেয়ার করা হচ্ছে"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"বার্তা অ্যাক্সেস"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"সিম -এর অ্যাক্সেস"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"উচ্চ মানের অডিও ব্যবহার করুন: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"উচ্চ মানের অডিও ব্যবহার করুন"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - বর্তমান ব্যাটারি ব্যবহার অনুযায়ী আর <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"প্রশাসক দ্বারা সক্ষম করা হয়েছে"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
-    <string name="disabled" msgid="9206776641295849915">"অক্ষম হয়েছে"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"অনুমোদিত"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"অনুমোদিত নয়"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"অজানা অ্যাপ ইনস্টল করুন"</string>
     <string name="home" msgid="3256884684164448244">"সেটিংস হোম"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"০%"</item>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 58b3a47..a97d1ac 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -58,27 +58,35 @@
     <item msgid="3878793616631049349">"Koristi HDCP provjeru samo za DRM sadržaj"</item>
     <item msgid="45075631231212732">"Uvijek koristi HDCP provjeru"</item>
   </string-array>
-    <!-- no translation found for bluetooth_avrcp_versions:0 (5347678900838034763) -->
-    <!-- no translation found for bluetooth_avrcp_versions:1 (2089555299377409443) -->
-    <!-- no translation found for bluetooth_avrcp_versions:2 (2895327394279434278) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:0 (2838624067805073303) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:1 (1913619118958233129) -->
-    <!-- no translation found for bluetooth_avrcp_version_values:2 (7142710449249088270) -->
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (Zadano)"</item>
+    <item msgid="2089555299377409443">"AVRCP 1.5"</item>
+    <item msgid="2895327394279434278">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="1913619118958233129">"avrcp15"</item>
+    <item msgid="7142710449249088270">"avrcp16"</item>
+  </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
     <item msgid="7065842274271279580">"Koristi odabir sistema (Zadano)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"Omogućite opcionalne kodeke"</item>
+    <item msgid="3304843301758635896">"Onemogućite opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
     <item msgid="5062108632402595000">"Koristi odabir sistema (Zadano)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"Omogućite opcionalne kodeke"</item>
+    <item msgid="741805482892725657">"Onemogućite opcionalne kodeke"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
     <item msgid="3093023430402746802">"Koristi odabir sistema (Zadano)"</item>
@@ -120,11 +128,13 @@
     <item msgid="7158319962230727476">"Optimizirano za kvalitet zvuka (990 kbps/909 kbps)"</item>
     <item msgid="2921767058740704969">"Uravnotežen kvalitet zvuka i veze (660kbps/606kbps)"</item>
     <item msgid="8860982705384396512">"Optimizirano za kvalitet veze (330 kbps/303 kbps)"</item>
+    <item msgid="4414060457677684127">"Maksimalan napor (Prilagodljiva brzina prijenosa)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="6398189564246596868">"Optimizirano za kvalitet zvuka"</item>
     <item msgid="4327143584633311908">"Uravnotežen kvalitet zvuka i veze"</item>
     <item msgid="4681409244565426925">"Optimizirano za kvalitet veze"</item>
+    <item msgid="364670732877872677">"Maksimalan napor (Prilagodljiva brzina prijenosa)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
@@ -235,7 +245,7 @@
     <item msgid="7899496259191969307">"Najviše 4 procesa"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="488237561639712799">"Puni se"</item>
+    <item msgid="488237561639712799">"Punjenje"</item>
     <item msgid="5220695614993094977">"MTP (protokol za prijenos sadržaja medija)"</item>
     <item msgid="2086000968159047375">"PTP (protokol za prijenos slika)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index ce40282..58598a3 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -32,13 +32,23 @@
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Neće se automatski povezati"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="4352716707126620811">"Sačuvao <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for connected_via_network_scorer (5713793306870815341) -->
-    <skip />
-    <!-- no translation found for connected_via_network_scorer_default (8430960324014668989) -->
-    <skip />
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano koristeći %1$s"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano putem ocjenjivača mreže"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano. Nema interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Isključen"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekidanje veze…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -49,15 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Povezano (bez pristupa porukama)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Povezano (bez zvuka telefona ili medija)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medija"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenošenje fajla"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dijeljenje kontakta"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Koristi za dijeljenje kontakta"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Dijeljenje internet veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup poruci"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM-u"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano sa zvukom medija"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano na zvuk telefona"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezan na server za prijenos podataka"</string>
@@ -95,7 +111,7 @@
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prijenosna pristupna tačka"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Dijeljenje Bluetooth veze"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Dijeljenje veze"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Dijeljenje internetske veze i prijenosna pristupna tačka"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Povezivanje putem mobitela i prijenosna pristupna tačka"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Sve radne aplikacije"</string>
     <string name="user_guest" msgid="8475274842845401871">"Gost"</string>
     <string name="unknown" msgid="1592123443519355854">"Nepoznato"</string>
@@ -103,21 +119,21 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Neke zadane vrijednosti su postavljene"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Nema postavljenih zadanih vrijednosti"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Postavke za pretvaranje teksta u govor"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Izlaz za pretvaranje teksta u govor"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Pretvaranje teksta u govor"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Brzina govora"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Brzina kojom se izgovara tekst"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Visina"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Utječe na ton sintetiziranog govora"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Jezik"</string>
-    <string name="tts_lang_use_system" msgid="2679252467416513208">"Koristi sistemski jezik"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"Korištenje sistemskog jezika"</string>
     <string name="tts_lang_not_selected" msgid="7395787019276734765">"Jezik nije izabran"</string>
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Postavlja glas za dati jezik za izgovoreni tekst"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Poslušajte primjer"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Reproduciraj kratku demonstraciju sintetiziranja govora"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliraj glasovne podatke"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instalirajte glasovne podatke potrebne za sintetiziranje govora"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliranje glasovnih podataka"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instaliranje glasovnih podataka potrebnih za sintetiziranje govora"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Ovaj program za sintetiziranje govora u mogućnosti je da prikuplja sav tekst koji se izgovara, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Program omogućava aplikacija <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Da li želite koristiti ovaj program za sintetiziranje govora?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva mrežnu vezu radi za izlaz tekst-u-govor."</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva aktivnu mrežnu vezu za pretvaranje teksta u govor."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ovo je primjer sinteze govora"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Zadani status jezika"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> je u potpunosti podržan"</string>
@@ -126,8 +142,8 @@
     <string name="tts_status_checking" msgid="5339150797940483592">"Provjerava se…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Postavke za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Pokreni postavke programa"</string>
-    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni program"</string>
-    <string name="tts_general_section_title" msgid="4402572014604490502">"Opće"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni alat"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"Opće postavke"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Postavite visinu glasa"</string>
     <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Visinu glasa koji izgovara tekst postavite na podrazumjevanu."</string>
   <string-array name="tts_rate_entries">
@@ -141,7 +157,7 @@
     <item msgid="5194774745031751806">"Veoma ubrzano"</item>
     <item msgid="9085102246155045744">"Najbrže"</item>
   </string-array>
-    <string name="choose_profile" msgid="8229363046053568878">"Odaberite profil"</string>
+    <string name="choose_profile" msgid="6921016979430278661">"Odaberite profil"</string>
     <string name="category_personal" msgid="1299663247844969448">"Lično"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za programere"</string>
@@ -170,16 +186,13 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogućiti Wi-Fi Verbose zapisivanje"</string>
-    <!-- no translation found for wifi_aggressive_handover (5309131983693661320) -->
-    <skip />
+    <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>
-    <!-- no translation found for mobile_data_always_on (8774857027458200434) -->
-    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string>
-    <!-- no translation found for bluetooth_select_avrcp_version_string (3750059931120293633) -->
-    <skip />
-    <!-- no translation found for bluetooth_select_avrcp_version_dialog_title (7277329668298705702) -->
-    <skip />
+    <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>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Odaberite Bluetooth AVRCP verziju"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"Odaberite Bluetooth Audio kodek"</string>
     <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -193,8 +206,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string>
-    <!-- no translation found for wifi_aggressive_handover_summary (7266329646559808827) -->
-    <skip />
+    <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>
@@ -216,10 +228,11 @@
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije putem USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Provjerava da li se u aplikacijama instaliranim putem ADB-a/ADT-a javlja zlonamerno ponašanje."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava opciju Bluetooth apsolutne jačine zvuka u slučaju problema s jačinom zvuka na udaljenim uređajima, kao što je neprihvatljivo glasan zvuk ili nedostatak kontrole."</string>
+    <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Dopusti da se melodije zvona reproduciranju na Bluetooth slušalicama"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provjeravanje"</string>
-    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Pos. ponaš. kod HDCP pr."</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Postavke HDCP provjere"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"Otklanjanje grešaka"</string>
     <string name="debug_app" msgid="8349591734751384446">"Odaberi aplikaciju za otklanjanje grešaka"</string>
     <string name="debug_app_not_set" msgid="718752499586403499">"Nema postavljenih aplikac. za otklanjanje grešaka"</string>
@@ -275,18 +288,20 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje procesa u pozadini"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Prik. dijalog Aplikacija ne reagira za apl. u poz."</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikaz upozorenja na obavještenju o kanalu"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikaz upozorenja ekranu kada aplikacija pošalje obavještenje bez važećeg kanala."</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Nametni aplikacije na vanjskoj pohrani"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava da svaka aplikacija bude pogodna za upisivanje na vanjsku pohranu, bez obzira na prikazane vrijednosti"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni aktivnostima mijenjanje veličina"</string>
     <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Neka sve aktivnosti budu takve da mogu mijenjati veličinu za prikaz sa više prozora, bez obzira na prikazane vrijednosti."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Omogući prozore nepravilnih oblika"</string>
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Omogućiti podršku za eksperimentalne prozore nepravilnih oblika."</string>
-    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za rezervnu kopiju radne površine"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za sigurnosnu kopiju radne površine"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije sa radne površine"</string>
-    <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nova lozinka za rezervnu kopiju postavljena"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nova lozinka za sigurnosnu kopiju postavljena"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nova lozinka i potvrda se ne podudaraju"</string>
-    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nije uspjelo postavljanje lozinke za rezervnu kopiju"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nije uspjelo postavljanje lozinke za sigurnosnu kopiju"</string>
   <string-array name="color_mode_names">
     <item msgid="2425514299220523812">"Živopisan (zadano)"</item>
     <item msgid="8446070607501413455">"Prirodan"</item>
@@ -302,16 +317,14 @@
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivno. Dodirnite za promjenu opcije."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikažite trenutno pokrenute usluge i upravljajte njima"</string>
-    <string name="enable_webview_multiprocess" msgid="3352660896640797330">"Višeprocesni WebView"</string>
-    <string name="enable_webview_multiprocess_desc" msgid="2485604010404197724">"Pokreni odvojeno WebView rendere"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Postavljanje WebViewa"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesi WebView"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Ovaj izbor više ne vrijedi. Pokušajte ponovo."</string>
-    <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvori u šifrirani fajl"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvaranje u šifrirani fajl"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pretvaranje…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fajl je već šifriran"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Pretvaranje u šifrirane fajlove"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvori particiju sa podacima u particiju šifriranu sistemom fajlova.\n !! Upozorenje!! Ovo će izbrisati sve vaše podatke.\n Ova funkcija je u alfa fazi razvoja i možda neće ispravno raditi.\n Pritisnite \'Obriši i pretvori…\" da nastavite."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvorite particiju sa podacima u particiju šifriranu sistemom fajlova.\n !! Upozorenje!! Ovo će izbrisati sve vaše podatke.\n Ova funkcija je u alfa fazi razvoja i možda neće ispravno raditi.\n Pritisnite \"Obriši i pretvori…\" da nastavite."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Obriši i pretvori…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Režim boja Slika"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"Koristi sRGB"</string>
@@ -321,40 +334,28 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomalija (plavo-žuta)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ispravka boje"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može uticati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
-    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"Preostalo je otprilike još <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Preostalo je još oko <xliff:g id="TIME">%1$s</xliff:g>, na osnovu vašeg korištenja"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <!-- no translation found for power_discharging_duration (2843747179907396142) -->
-    <skip />
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Preostalo je još <xliff:g id="TIME">%1$s</xliff:g>, na osnovu vašeg korištenja"</string>
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - preostalo je još oko <xliff:g id="TIME">%2$s</xliff:g>, na osnovu vašeg korištenja"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration (4676999980973411875) -->
-    <skip />
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_ac (7341243578143555689) -->
-    <skip />
-    <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_usb (3720632890882121805) -->
-    <skip />
-    <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <!-- no translation found for power_charging_duration_wireless (5768338238751562058) -->
-    <skip />
-    <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
-    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Puni se na punjaču"</string>
-    <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Punjenje"</string>
-    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
-    <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Punjenje"</string>
-    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
-    <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Punjenje"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pod kontrolom administratora"</string>
-    <string name="enabled_by_admin" msgid="2386503803463071894">"Omogućio administrator"</string>
-    <string name="disabled_by_admin" msgid="3669999613095206948">"Onemogućio je administrator"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogućio administrator"</string>
     <string name="home" msgid="3256884684164448244">"Postavke početne stranice"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -366,8 +367,8 @@
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
-    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Vrlo veliko"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveći"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
@@ -377,4 +378,7 @@
     <string name="retail_demo_reset_title" msgid="696589204029930100">"Potrebna je lozinka"</string>
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Aktivne metode unosa"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Koristi jezik sistema"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Nije uspjelo otvaranje postavki za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Ovaj način unosa može prikupiti sav tekst koji otkucate, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Način omogućava aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Da li želite koristiti ovaj način unosa?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Napomena: Nakon ponovnog pokretanja, ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index bdc2cac..b883725 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Utilitza selecció del sistema (predeterminada)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Activa els còdecs opcionals"</item>
     <item msgid="3304843301758635896">"Desactiva els còdecs opcionals"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Utilitza selecció del sistema (predeterminada)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Activa els còdecs opcionals"</item>
     <item msgid="741805482892725657">"Desactiva els còdecs opcionals"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 0efc5bc..d9cfb9c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -33,10 +33,22 @@
     <string name="wifi_no_internet" msgid="3880396223819116454">"No hi ha accés a Internet"</string>
     <string name="saved_network" msgid="4352716707126620811">"Desat per <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connectada automàticament a través de: %1$s"</string>
-    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connectada automàticament a través d\'un proveïdor de valoració de xarxes"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connectada automàticament a través d\'un proveïdor de valoració de la xarxa"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connectada, sense Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconnectat"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"S\'està desconnectant..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"S\'està connectant…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Àudio del telèfon"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositiu d\'entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accés a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactes"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"S\'utilitza per compartir contactes."</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Connexió compartida a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accés al missatge"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accés a la SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilitza àudio d\'alta qualitat: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilitza àudio d\'alta qualitat"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connectat a l\'àudio del mitjà"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connectat a àudio del telèfon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connectat al servidor de transferència de fitxers"</string>
@@ -272,8 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Límita processos en segon pla"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Tots els errors sense resposta"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Informa que una aplicació en segon pla no respon"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostra avisos del canal de notificacions"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra un avís a la pantalla quan una aplicació publica una notificació sense un canal vàlid"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Avisos del canal de notificacions"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra un avís a la pantalla quan una app publica una notificació sense canal vàlid"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Força permís d\'aplicacions a l\'emmagatzem. extern"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Permet que qualsevol aplicació es pugui escriure en un dispositiu d’emmagatzematge extern, independentment dels valors definits"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Força l\'ajust de la mida de les activitats"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Temps restant segons l\'ús que en fas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> aproximadament per esgotar la bateria"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Activada per l\'administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Desactivada per l\'administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desactivat"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permeses"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"No permeses"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instal·lar aplicacions desconegudes"</string>
     <string name="home" msgid="3256884684164448244">"Pàgina d\'inici de configuració"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
@@ -364,6 +379,6 @@
     <string name="active_input_method_subtypes" msgid="3596398805424733238">"Mètodes d\'introducció actius"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Utilitza els idiomes del sistema"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"No s\'ha pogut obrir la configuració de: <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
-    <string name="ime_security_warning" msgid="4135828934735934248">"Pot ser que aquest mètode d\'introducció pugui recopilar tot el que escriviu, incloses dades personals, com ara contrasenyes i números de targetes de crèdit. Ve de l\'aplicació <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voleu utilitzar aquest mètode d\'introducció?"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"Pot ser que aquest mètode d\'entrada pugui recopilar tot el que escriviu, incloses dades personals, com ara contrasenyes i números de targetes de crèdit. Ve de l\'aplicació <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voleu utilitzar aquest mètode d\'entrada?"</string>
     <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Nota: després de reiniciar, l\'aplicació no s\'iniciarà fins que no desbloquegis el telèfon"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 7457308..57745dc 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Použít systémový výběr (výchozí)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Povolit volitelné kodeky"</item>
     <item msgid="3304843301758635896">"Zakázat volitelné kodeky"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Použít systémový výběr (výchozí)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Povolit volitelné kodeky"</item>
     <item msgid="741805482892725657">"Zakázat volitelné kodeky"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index b0a5ad7..0ea6642 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Připojeno, není k dispozici internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Odpojeno"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Odpojování..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Připojování..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk médií"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefonu"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Přenos souborů"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vstupní zařízení"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Přístup k internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Sdílení kontaktů"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Použít ke sdílení kontaktů"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Sdílení internetového připojení"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Přístup ke zprávám"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Přístup k SIM kartě"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Použít vysokou kvalitu zvuku: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Použít vysokou kvalitu zvuku"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Připojeno ke zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Připojeno k náhlavní soupravě"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Připojeno k serveru pro přenos dat"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Zbývá asi <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Při vašem obvyklém využití zbývá asi <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Plně se nabije za <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Při vašem obvyklém využití zbývá <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – při vašem obvyklém využití zbývá asi <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – plně se nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Spravováno administrátorem"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Zapnuto administrátorem"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Zakázáno administrátorem"</string>
-    <string name="disabled" msgid="9206776641295849915">"Deaktivováno"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Povoleno"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Není povoleno"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalace neznámých aplikací"</string>
     <string name="home" msgid="3256884684164448244">"Domovská stránka Nastavení"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 6c322ed..e3c338b 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Brug systemvalg (standard)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Aktivér Optional Codecs"</item>
     <item msgid="3304843301758635896">"Deaktiver Optional Codecs"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Brug systemvalg (standard)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Aktivér Optional Codecs"</item>
     <item msgid="741805482892725657">"Deaktiver Optional Codecs"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 73c7bea..5b2f75a 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilsluttet – intet internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Afbrudt"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Afbryder ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Opretter forbindelse..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonlyd"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inputenhed"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetadgang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deling af kontaktpersoner"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Brug til deling af kontaktpersoner"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling af internetforbindelse"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Adgang til meddelelse"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-adgang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Brug lyd i høj kvalitet: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Brug lyd i høj kvalitet"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Forbundet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Forbundet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Forbundet til filoverførselsserver"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Der er ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fuldt opladet"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tilbage"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Der er <xliff:g id="TIME">%1$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – der er ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolleret af administratoren"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Aktiveret af administratoren"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Deaktiveret af administratoren"</string>
-    <string name="disabled" msgid="9206776641295849915">"Deaktiveret"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Tilladt"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ikke tilladt"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installer ukendte apps"</string>
     <string name="home" msgid="3256884684164448244">"Startside for Indstillinger"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 2c441a5..20f9b3b 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Systemauswahl verwenden (Standard)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Optionale Codecs aktivieren"</item>
     <item msgid="3304843301758635896">"Optionale Codecs deaktivieren"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Systemauswahl verwenden (Standard)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Optionale Codecs aktivieren"</item>
     <item msgid="741805482892725657">"Optionale Codecs deaktivieren"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 60ef680..729d872 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbunden, kein Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Nicht verbunden"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Verbindung wird getrennt..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbindung wird hergestellt..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-Audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon-Audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dateiübertragung"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Eingabegerät"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetzugriff"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktfreigabe"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Für Kontaktfreigabe nutzen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Freigabe der Internetverbindung"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Nachrichtenzugriff"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Zugriff auf SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Hohe Audioqualität verwenden: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Hohe Audioqualität verwenden"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Verbunden mit  Audiosystem von Medien"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Verbunden mit Audiosystem des Telefons"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Mit Dateiübertragungsserver verbunden"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion, die sich auf die Leistung auswirken kann."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Ca. <xliff:g id="TIME">%1$s</xliff:g> übrig"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g>, basierend auf deiner Nutzung"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> bis zur vollständigen Aufladung"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Noch <xliff:g id="TIME">%1$s</xliff:g>, basierend auf deiner Nutzung"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ungefähr noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch ca. <xliff:g id="TIME">%2$s</xliff:g>, basierend auf deiner Nutzung"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Durch den Administrator verwaltet"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Vom Administrator aktiviert"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Vom Administrator deaktiviert"</string>
-    <string name="disabled" msgid="9206776641295849915">"Deaktiviert"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Zulässig"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nicht zulässig"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Unbek. Apps installieren"</string>
     <string name="home" msgid="3256884684164448244">"Startseite \"Einstellungen\""</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 2f86aa7..304b738 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Ενεργοποίηση προαιρετικών κωδικοποιητών"</item>
     <item msgid="3304843301758635896">"Απενεργοποίηση προαιρετικών κωδικοποιητών"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Ενεργοποίηση προαιρετικών κωδικοποιητών"</item>
     <item msgid="741805482892725657">"Απενεργοποίηση προαιρετικών κωδικοποιητών"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index e77e2f4..fb9d57d 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Συνδέθηκε, χωρίς διαδίκτυο"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Αποσυνδέθηκε"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Αποσύνδεση..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Σύνδεση..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Συνδεδεμένο (χωρίς πρόσβαση μηνύματος)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Συνδεδεμένο (χωρίς τηλέφωνο ή πολυμέσα)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Ήχος πολυμέσων"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Ήχος τηλεφώνου"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Μεταφορά αρχείου"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Συσκευή εισόδου"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Πρόσβαση στο Διαδίκτυο"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Κοινή χρήση επαφών"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Για κοινή χρήση επαφών"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Κοινή χρήση σύνδεσης στο Διαδίκτυο"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Πρόσβαση στο μήνυμα"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Πρόσβαση SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Χρήση ήχου υψηλής ποιότητας: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Χρήση ήχου υψηλής ποιότητας"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Απομένει/ουν περίπου <xliff:g id="TIME">%1$s</xliff:g> με βάση τη χρήση σας"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> έως την πλήρη φόρτιση"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Απομένει/ουν <xliff:g id="TIME">%1$s</xliff:g> με βάση τη χρήση σας"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - Απομένει/ουν περίπου <xliff:g id="TIME">%2$s</xliff:g> με βάση τη χρήση σας"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένει/ουν <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ελέγχονται από το διαχειριστή"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Ενεργοποιήθηκε από τον διαχειριστή"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Απενεργοποιήθηκε από τον διαχειριστή"</string>
-    <string name="disabled" msgid="9206776641295849915">"Απενεργοποιημένο"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Επιτρέπεται"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Δεν επιτρέπεται"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Εγκατ. άγνωστων εφ."</string>
     <string name="home" msgid="3256884684164448244">"Αρχική σελίδα ρυθμίσεων"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 77af30e..4c460db 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Enable Optional Codecs"</item>
     <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
     <item msgid="741805482892725657">"Disable Optional Codecs"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1d2a654..e9ff46b 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
-    <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
     <string name="home" msgid="3256884684164448244">"Settings Home"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 77af30e..4c460db 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Enable Optional Codecs"</item>
     <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
     <item msgid="741805482892725657">"Disable Optional Codecs"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1d2a654..e9ff46b 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
-    <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
     <string name="home" msgid="3256884684164448244">"Settings Home"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 77af30e..4c460db 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Enable Optional Codecs"</item>
     <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
     <item msgid="741805482892725657">"Disable Optional Codecs"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1d2a654..e9ff46b 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connected, no Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Phone audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Message Access"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Use high-quality audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Use high-quality audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file-transfer server"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"About <xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"About <xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> left"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – about <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Enabled by admin"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Disabled by admin"</string>
-    <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
     <string name="home" msgid="3256884684164448244">"Settings Home"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index ef69114..8d54494 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usar selección del sistema (predeterminado)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Habilitar códecs opcionales"</item>
     <item msgid="3304843301758635896">"Inhabilitar códecs opcionales"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usar selección del sistema (predeterminado)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Habilitar códecs opcionales"</item>
     <item msgid="741805482892725657">"Inhabilitar códecs opcionales"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 8d3247d..a28802b 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado a Wi-Fi, sin conexión a Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio del dispositivo"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartir conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso a mensajes"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidad: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidad"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado al servidor de transferencia de archivo"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restantes en función del uso"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> para completar la carga"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> restantes en función del uso"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> (aproximadamente <xliff:g id="TIME">%2$s</xliff:g> restantes en función del uso)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar la carga)"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"El administrador habilitó esta opción"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"El administrador inhabilitó esta opción"</string>
-    <string name="disabled" msgid="9206776641295849915">"Inhabilitadas"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permitida"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"No permitida"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar apps desconocidas"</string>
     <string name="home" msgid="3256884684164448244">"Pantalla de configuración"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 53c547d..01f65dc 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usar preferencia del sistema (predeter.)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Habilitar códecs opcionales"</item>
     <item msgid="3304843301758635896">"Inhabilitar códecs opcionales"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usar preferencia del sistema (predeter.)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Habilitar códecs opcionales"</item>
     <item msgid="741805482892725657">"Inhabilitar códecs opcionales"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 360a754..f3d6053 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conexión sin Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Estableciendo conexión…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio del teléfono"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartir conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso a mensajes"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso a tarjeta SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidad: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidad"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio del medio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado con el servidor de transferencia de archivos"</string>
@@ -91,11 +107,11 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"SO Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicaciones eliminadas"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Usuarios y aplicaciones eliminados"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Compartir conexión por USB"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Compartir por USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Zona Wi-Fi portátil"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Compartir conexión por Bluetooth"</string>
-    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Compartir conexión"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Compartir conexión y zona Wi-Fi"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Compartir por Bluetooth"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Compartir Internet"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Compartir Internet y zona Wi-Fi"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Todas las aplicaciones de trabajo"</string>
     <string name="user_guest" msgid="8475274842845401871">"Invitado"</string>
     <string name="unknown" msgid="1592123443519355854">"Desconocido"</string>
@@ -149,7 +165,7 @@
     <string name="development_settings_summary" msgid="1815795401632854041">"Establecer opciones de desarrollo de aplicaciones"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Las opciones de desarrollador no están disponibles para este usuario"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Los ajustes de VPN no están disponibles para este usuario"</string>
-    <string name="tethering_settings_not_available" msgid="6765770438438291012">"Los ajustes para compartir conexión no están disponibles para este usuario"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"Los ajustes para compartir Internet no están disponibles para este usuario"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Los ajustes del nombre de punto de acceso no están disponibles para este usuario"</string>
     <string name="enable_adb" msgid="7982306934419797485">"Depuración por USB"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"Activar el modo de depuración cuando el dispositivo esté conectado por USB"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tiempo restante hasta carga completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - tiempo aproximado restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> (tiempo restante aproximado según tu uso: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Habilitada por el administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Inhabilitada por el administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Inhabilitada"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Autorizadas"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"No autorizadas"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar aplicaciones desconocidas"</string>
     <string name="home" msgid="3256884684164448244">"Página principal de ajustes"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 7766890..daaf20d 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Süsteemi valiku kasutamine (vaikeseade)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Lubatakse valikulised kodekid"</item>
     <item msgid="3304843301758635896">"Keelatakse valikulised kodekid"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Süsteemi valiku kasutamine (vaikeseade)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Lubatakse valikulised kodekid"</item>
     <item msgid="741805482892725657">"Keelatakse valikulised kodekid"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 828b0e2..9617e61 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ühendatud, Interneti-ühendus puudub"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ühendus katkestatud"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ühenduse katkestamine ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ühendamine ..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meedia heli"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefoni heli"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failiedastus"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Sisendseade"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetti juurdepääs"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontakti jagamine"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kasutamine kontaktide jagamiseks"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneti-ühenduse jagamine"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Juurdepääs sõnumile"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kaardi juurdepääs"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Kasuta kvaliteetset heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Kasuta kvaliteetset heli"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ühendatud meediumiheliga"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ühendatud telefoniheliga"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ühendatud failiedastuse serveriga"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Teie kasutuse alusel on jäänud ligikaudu <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> täislaadimiseni"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Teie kasutuse alusel on jäänud <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – teie kasutuse alusel on jäänud ligikaudu <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Juhib administraator"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Administraatori lubatud"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Administraatori keelatud"</string>
-    <string name="disabled" msgid="9206776641295849915">"Keelatud"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Lubatud"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Pole lubatud"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Tundmatute rakenduste installimine"</string>
     <string name="home" msgid="3256884684164448244">"Seadete avaleht"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 444ffbc..e2fcc62 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Erabili sistema-hautapena (lehenetsia)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Gaitu aukerako kodekak"</item>
     <item msgid="3304843301758635896">"Desgaitu aukerako kodekak"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Erabili sistema-hautapena (lehenetsia)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Gaitu aukerako kodekak"</item>
     <item msgid="741805482892725657">"Desgaitu aukerako kodekak"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 92d5ae5..77e05ef 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Konektatuta, ez dago Interneteko konexiorik"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Deskonektatuta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Deskonektatzen…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Konektatzen…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Euskarriaren audioa"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonoaren audioa"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fitxategi-transferentzia"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Sarrerako gailua"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneterako sarbidea"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktuak partekatzea"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Erabili kontaktuak partekatzeko"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneteko konexioa partekatzea"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mezuetarako sarbidea"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM txartelerako sarbidea"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Erabili kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Erabili kalitate handiko audioa"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Euskarriaren audiora konektatuta"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefonoaren audiora konektatuta"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fitxategi-transferentziako zerbitzarira konektatuta"</string>
@@ -272,7 +288,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 kanalen abisuak"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Erakutsi jakinarazpenen kanaleko 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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> inguru gelditzen dira"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"<xliff:g id="TIME">%1$s</xliff:g> inguru gelditzen dira, erabileraren arabera"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> falta dira guztiz kargatu arte"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> gelditzen dira, erabileraren arabera"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen dira, erabileraren arabera"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administratzaileak kontrolatzen du"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Administratzaileak gaitu du"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Administratzaileak desgaitu du"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desgaituta"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Baimena dauka"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ez dauka baimenik"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalatu aplikazio ezezagunak"</string>
     <string name="home" msgid="3256884684164448244">"Ezarpenen hasierako pantaila"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"% 0"</item>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index b9fa5e4..88f891d 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"فعال کردن کدک‌های اختیاری"</item>
     <item msgid="3304843301758635896">"غیرفعال کردن کدک‌های اختیاری"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"فعال کردن کدک‌های اختیاری"</item>
     <item msgid="741805482892725657">"غیرفعال کردن کدک‌های اختیاری"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b82d1bf..4b0f39b 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏متصل از طریق %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏در دسترس از طریق %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"متصل، بدون اینترنت"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"اتصال قطع شد"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"در حال قطع اتصال..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"در حال اتصال…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"متصل (عدم دسترسی به پیام)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"متصل شد (بدون تلفن یا رسانه)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"رسانه صوتی"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"صدای تلفن"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"انتقال فایل"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"دستگاه ورودی"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"دسترسی به اینترنت"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"اشتراک‌گذاری مخاطب"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"استفاده برای اشتراک‌گذاری مخاطب"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"اشتراک‌گذاری اتصال اینترنت"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"دسترسی به پیام"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"دسترسی سیم‌کارت"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"استفاده از صوت با کیفیت بالا: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"استفاده از صوت با کیفیت بالا"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"حدود <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"براساس میزان مصرف شما، <xliff:g id="TIME">%1$s</xliff:g> باقی‌مانده است"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ شدن کامل باقی مانده است"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی مانده"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"براساس میزان مصرف شما، <xliff:g id="TIME">%1$s</xliff:g> باقی‌مانده است"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - براساس میزان مصرف شما، <xliff:g id="TIME">%2$s</xliff:g> باقی‌مانده است"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی مانده"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"توسط سرپرست سیستم کنترل می‌شود"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"فعال‌شده توسط سرپرست"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"غیرفعال‌شده توسط سرپرست"</string>
-    <string name="disabled" msgid="9206776641295849915">"غیر فعال شد"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"مجاز"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"مجاز نیست"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"نصب برنامه‌های ناشناس"</string>
     <string name="home" msgid="3256884684164448244">"صفحه اصلی تنظیمات"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"٪۰"</item>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 7a5f860..30ec7c7 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Käytä järjestelmän valintaa (oletus)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Ota valinnaiset koodekit käyttöön"</item>
     <item msgid="3304843301758635896">"Poista valinnaiset koodekit käytöstä"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Käytä järjestelmän valintaa (oletus)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Ota valinnaiset koodekit käyttöön"</item>
     <item msgid="741805482892725657">"Poista valinnaiset koodekit käytöstä"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 65e87d21..3f36ea4 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Yhdistetty, ei internetyhteyttä."</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Yhteys katkaistu"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Katkaistaan yhteyttä..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Yhdistetään…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Median ääni"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Puhelimen ääni"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Tiedostonsiirto"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Syöttölaite"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetyhteys"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Yhteystietojen jakaminen"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Käytä yhteystietojen jakamiseen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetyhteyden jakaminen"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"MAP"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kortin käyttö"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Käytä korkealaatuista ääntä: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Käytä korkealaatuista ääntä"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Yhdistetty median ääneen"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Yhdistetty puhelimen ääneen"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Yhdistetty tiedostonsiirtopalvelimeen"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä käytön perusteella"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä käytön perusteella"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä käytön perusteella"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Järjestelmänvalvojan käyttöön ottama"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Järjestelmänvalvojan estämä"</string>
-    <string name="disabled" msgid="9206776641295849915">"Pois käytöstä"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Sallittu"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ei sallittu"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Tuntemattomien sovellusten asentaminen"</string>
     <string name="home" msgid="3256884684164448244">"Asetusten etusivu"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 29348c9..9fd3a2d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Utiliser sélect. du système (par défaut)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Activer les codecs optionnels"</item>
     <item msgid="3304843301758635896">"Désactiver les codecs optionnels"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Utiliser sélect. du système (par défaut)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Activer les codecs optionnels"</item>
     <item msgid="741805482892725657">"Désactiver les codecs optionnels"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 4bbd116..b2c596c 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Déconnecté"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Déconnexion…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connexion en cours…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Paramètres audio du support"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Paramètres audio du téléphone"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contact"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utiliser pour le partage de contacts"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partage de connexion Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accès aux messages"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accès à la carte SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utiliser l\'audio de haute qualité : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utiliser l\'audio de haute qualité"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connecté aux paramètres audio du média"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connecté à l\'audio du téléphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connexion au serveur de transfert de fichiers"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre usage"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Il reste <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre usage"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> : il reste environ <xliff:g id="TIME">%2$s</xliff:g> en fonction de votre usage"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Désactivé par l\'administrateur"</string>
-    <string name="disabled" msgid="9206776641295849915">"Désactivés"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Autorisée"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Non autorisée"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installer applis inconnues"</string>
     <string name="home" msgid="3256884684164448244">"Accueil des paramètres"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 1c3605e..3b70c7a 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 
+<!--
 /*
 **
 ** Copyright 2015 The Android Open Source Project
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Utiliser sélection système (par défaut)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Activer les codecs facultatifs"</item>
     <item msgid="3304843301758635896">"Désactiver les codecs facultatifs"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Utiliser sélection système (par défaut)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Activer les codecs facultatifs"</item>
     <item msgid="741805482892725657">"Désactiver les codecs facultatifs"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 96a73ff..b726f9d 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Déconnecté"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Déconnexion…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connexion…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Appels et notifications"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contacts"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utiliser pour le partage de contacts"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partage de connexion Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accès aux messages"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accès à la carte SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utiliser le codec audio haute qualité : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utiliser un codec audio haute qualité"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connecté aux paramètres audio du média"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connecté aux paramètres audio du téléphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connexion au serveur de transfert de fichiers"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> avant charge complète"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Temps restant en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - encore environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Contrôlé par l\'administrateur"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Activé par l\'administrateur"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Désactivé par l\'administrateur"</string>
-    <string name="disabled" msgid="9206776641295849915">"Désactivée"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Autorisé"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Non autorisé"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installation d\'applis inconnues"</string>
     <string name="home" msgid="3256884684164448244">"Paramètres"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 1bfbbdf..ed89f8e 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usar selección sistema (predeterminado)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Activar códecs opcionais"</item>
     <item msgid="3304843301758635896">"Desactivar códecs opcionais"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usa selección sistema (predeterminado)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Activa os códecs opcionais"</item>
     <item msgid="741805482892725657">"Desactiva os códecs opcionais"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index cc46efd..6116f6f 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectado, pero sen Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimedia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio do teléfono"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferencia de ficheiros"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para compartir contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Uso compartido da conexión a Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acceso ás mensaxes"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso á SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar audio de alta calidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar audio de alta calidade"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferencia de ficheiros"</string>
@@ -281,7 +297,7 @@
     <string name="enable_freeform_support" msgid="1461893351278940416">"Activar ventás de forma libre"</string>
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Activa a compatibilidade con ventás de forma libre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contrasinal para copias"</string>
-    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"As copias de seguranza de ordenador completas non están protexidas"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"As copias de seguridade de ordenador completas non están protexidas"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca para cambiar ou eliminar o contrasinal para as copias de seguranza completas do escritorio"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Novo contrasinal da copia de seguranza definido"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"O contrasinal novo e a confirmación non coinciden"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo que queda aproximadamente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tempo restante aproximado en función do uso: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda ata cargar de todo: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tempo restante en función do uso: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo restante aproximado en función do uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata completar a carga"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Opción controlada polo administrador"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Activado polo administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Desactivado polo administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desactivada"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permitida"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Non permitida"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar apps descoñecidas"</string>
     <string name="home" msgid="3256884684164448244">"Inicio da configuración"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 1fc1d7c..8f73b9a9 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"વૈકલ્પિક કોડેક સક્ષમ કરો"</item>
     <item msgid="3304843301758635896">"વૈકલ્પિક કોડેક અક્ષમ કરો"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"વૈકલ્પિક કોડેક સક્ષમ કરો"</item>
     <item msgid="741805482892725657">"વૈકલ્પિક કોડેક અક્ષમ કરો"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index ac755ea..9bf91a3 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ડિસ્કનેક્ટ કર્યું"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ડિસ્કનેક્ટ થઈ રહ્યું છે..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"કનેક્ટ થઈ રહ્યું છે…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"કનેક્ટ કર્યું (કોઇ સંદેશ ઍક્સેસ નથી)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"કનેક્ટ કરેલ (કોઈ ફોન અથવા મીડિયા નથી)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"મીડિયા ઑડિઓ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ફોન ઑડિઓ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ફાઇલ સ્થાનાંતરણ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ઇનપુટ ઉપકરણ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ઇન્ટરનેટ ઍક્સેસ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"સંપર્ક શેરિંગ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"સંપર્ક શેરિંગ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ઇન્ટરનેટ કનેક્શન શેરિંગ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"સંદેશ ઍક્સેસ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ઍક્સેસ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ઉચ્ચ ગુણવત્તાવાળા ઑડિયોનો ઉપયોગ કરો: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ઉચ્ચ ગુણવત્તાવાળા ઑડિયોનો ઉપયોગ કરો"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"અંદાજે <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"તમારા વપરાશનાં આધારે લગભગ <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"સંપૂર્ણપણે ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"તમારા વપરાશનાં આધારે <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - લગભગ <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - તમારા વપરાશનાં આધારે લગભગ <xliff:g id="TIME">%2$s</xliff:g> બાકી છે"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"વ્યવસ્થાપકે સક્ષમ કરેલ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"વ્યવસ્થાપકે અક્ષમ કરેલ"</string>
-    <string name="disabled" msgid="9206776641295849915">"અક્ષમ કર્યો"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"મંજૂરી છે"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"મંજૂરી નથી"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરો"</string>
     <string name="home" msgid="3256884684164448244">"સેટિંગ્સ હોમ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index e304e90..0d6595d 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"वैकल्पिक कोडेक सक्षम करें"</item>
     <item msgid="3304843301758635896">"वैकल्पिक कोडेक अक्षम करें"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"वैकल्पिक कोडेक सक्षम करें"</item>
     <item msgid="741805482892725657">"वैकल्पिक कोडेक अक्षम करें"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 103f22b..a7a01ec 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्ट किया गया, इंटरनेट नहीं"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"डिस्कनेक्‍ट किया गया"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"डिस्‍कनेक्‍ट हो रहा है..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"कनेक्ट हो रहा है..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट किया गया (कोई संदेश एक्सेस नहीं)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्‍ट है (फ़ोन या मीडि‍या नहीं)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडियो"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फ़ोन ऑडियो"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फ़ाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिवाइस"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट पहुंच"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क साझाकरण"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क साझाकरण के लिए उपयोग करें"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन साझाकरण"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"संदेश एक्सेस"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम ऐक्सेस"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"अच्छी गुणवत्ता वाले ऑडियो का उपयोग करें: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"अच्छी गुणवत्ता वाले ऑडियो का उपयोग करें"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -205,7 +221,7 @@
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्य विशेषता निरीक्षण सक्षम करें"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"वाई-फ़ाई के सक्रिय रहने पर भी, हमेशा मोबाइल डेटा सक्रिय रखें (तेज़ी से नेटवर्क स्विच करने के लिए)."</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करने की अनुमति दें?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करने का उद्देश्‍य केवल विकास है. इसका इस्तेमाल आपके कंप्‍यूटर और आपके डिवाइस के बीच डेटा को कॉपी करने, बिना नोटिफ़िकेशन के आपके डिवाइस पर ऐप इंस्‍टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग डीबग करने का उद्देश्‍य केवल विकास है. इसका उपयोग आपके कंप्‍यूटर और आपके डिवाइस के बीच डेटा की प्रतिलिपि बनाने, बिना नोटिफिकेशन के आपके डिवाइस पर ऐप्स इंस्‍टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"आपके द्वारा पूर्व में प्राधिकृत सभी कंप्यूटर से USB डीबगिंग की पहुंच निरस्त करें?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"विकास सेटिंग की अनुमति दें?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ये सेटिंग केवल विकास संबंधी उपयोग के प्रयोजन से हैं. वे आपके डिवाइस और उस पर स्‍थित ऐप्स  को खराब कर सकती हैं या उनके दुर्व्यवहार का कारण हो सकती हैं."</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"आपके उपयोग के आधार पर लगभग <xliff:g id="TIME">%1$s</xliff:g> का समय बचा है"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूरी तरह से चार्ज होने में <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"आपके उपयोग के आधार पर <xliff:g id="TIME">%1$s</xliff:g> का समय बचा है"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - आपके उपयोग के आधार पर लगभग <xliff:g id="TIME">%2$s</xliff:g> का समय बचा है"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी तरह से चार्ज होने तक"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"व्यवस्थापक द्वारा नियंत्रित"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"व्यवस्थापक ने सक्षम किया है"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"व्यवस्थापक ने अक्षम किया है"</string>
-    <string name="disabled" msgid="9206776641295849915">"अक्षम किया गया"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति है"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति नहीं है"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"अनजान ऐप्लिकेशन इंस्टॉल करें"</string>
     <string name="home" msgid="3256884684164448244">"सेटिंग होम"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 5deba6f..a75cb79 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Upotreba odabira sustava (zadano)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Omogućivanje izbornih kodeka"</item>
     <item msgid="3304843301758635896">"Onemogućivanje izbornih kodeka"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Upotreba odabira sustava (zadano)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Omogućivanje izbornih kodeka"</item>
     <item msgid="741805482892725657">"Onemogućivanje izbornih kodeka"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 371dedc..05f13e4 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Povezano, bez interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Niste povezani"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Isključivanje…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Povezivanje…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medijski zvuk"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prijenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ulazni uređaj"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Pristup internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dijeljenje kontakata"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Upotrijebi za dijeljenje kontakata"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Dijeljenje internetske veze"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Pristup porukama"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Pristup SIM-u"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Upotrebljavaj visokokvalitetan audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Upotrebljavaj visokokvalitetan audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezano s medijskim zvukom"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezano sa telefonskim zvukom"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezano s poslužiteljem za prijenos datoteka"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g> na temelju vaše upotrebe"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Još <xliff:g id="TIME">%1$s</xliff:g> na temelju vaše upotrebe"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo je približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – još otprilike <xliff:g id="TIME">%2$s</xliff:g> na temelju vaše upotrebe"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – još <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolira administrator"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Omogućio administrator"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogućio administrator"</string>
-    <string name="disabled" msgid="9206776641295849915">"Onemogućeno"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Dopušteno"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nije dopušteno"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalacija nepoznatih aplikacija"</string>
     <string name="home" msgid="3256884684164448244">"Početni zaslon postavki"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 81d69d0..d0521b3 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Rendszerérték (alapértelmezett)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Nem kötelező kodekek engedélyezése"</item>
     <item msgid="3304843301758635896">"Nem kötelező kodekek letiltása"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Rendszerérték (alapértelmezett)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Engedélyezi a nem kötelező kodekeket"</item>
     <item msgid="741805482892725657">"Letiltja a nem kötelező kodekeket"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index c4c342c..eab7fc2 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Csatlakozva, nincs internetelérés"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Szétkapcsolva"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Szétkapcsolás..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Csatlakozás…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Média audió"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon hangja"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fájlátvitel"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Beviteli eszköz"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetelérés"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Névjegyek megosztása"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Használja a névjegyek megosztására"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetkapcsolat megosztása"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Üzenet-hozzáférés"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-elérés"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Jó audiominőség használata: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Jó audiominőség használata"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Csatlakoztatva az eszköz hangjához"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Csatlakoztatva a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Csatlakozva a fájlküldő szerverhez"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Körülbelül <xliff:g id="TIME">%1$s</xliff:g> maradt hátra"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Körülbelül <xliff:g id="TIME">%1$s</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - körülbelül <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – körülbelül <xliff:g id="TIME">%2$s</xliff:g> van hátra az eszköz igénybevétele alapján"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Rendszergazda által irányítva"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"A rendszergazda bekapcsolta"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"A rendszergazda kikapcsolta"</string>
-    <string name="disabled" msgid="9206776641295849915">"Letiltva"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Engedélyezett"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nem engedélyezett"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Ismeretlen alkalmazások telepítése"</string>
     <string name="home" msgid="3256884684164448244">"Beállítások kezdőlapja"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 22de938..f89be6c 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Միացնել լրացուցիչ կոդեկները"</item>
     <item msgid="3304843301758635896">"Անջատել լրացուցիչ կոդեկները"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Միացնել լրացուցիչ կոդեկները"</item>
     <item msgid="741805482892725657">"Անջատել լրացուցիչ կոդեկները"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0c4533e..62e3a2a 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Կապակցված է առանց համացանցի"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Անջատված է"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Անջատվում է..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Միանում է..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Միացված է (հաղորդագրությանը մուտք չկա)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Միացված է (առանց հեռախոսի և մեդիայի)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Մեդիա աուդիո"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Հեռախոսի աուդիո"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Ֆայլերի փոխանցում"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ներմուծման սարք"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ինտերնետի մուտք"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Կոնտակտի համօգտագործում"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Օգտագործել կոնտակտի համօգտագործման համար"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ինտերնետ կապի տարածում"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Մուտք հաղորդագրություն"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM քարտի հասանելիություն"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Օգտագործել բարձրորակ ձայն՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Օգտագործել բարձրորակ ձայն"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել սարքի աշխատանքի վրա:"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>՝ օգտագործման եղանակից կախված"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Մինչև լրիվ լիցքավորումը մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Մնացել է <xliff:g id="TIME">%1$s</xliff:g>՝ օգտագործման եղանակից կախված"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – մնացել է մոտ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է մոտ <xliff:g id="TIME">%2$s</xliff:g>՝ օգտագործման եղանակից կախված"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնացել է <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Միացված է ադմինիստրատորի կողմից"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Անջատվել է ադմինիստրատորի կողմից"</string>
-    <string name="disabled" msgid="9206776641295849915">"Կասեցված է"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Թույլատրված է"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Արգելված է"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Անհայտ հավելվածների տեղադրում"</string>
     <string name="home" msgid="3256884684164448244">"Կարգավորումների գլխավոր էջ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 7f02a6a..4fe124c 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Aktifkan Codec Opsional"</item>
     <item msgid="3304843301758635896">"Nonaktifkan Codec Opsional"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Gunakan Pilihan Sistem (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Aktifkan Codec Opsional"</item>
     <item msgid="741805482892725657">"Nonaktifkan Codec Opsional"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 28e9826..5b5b452 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tersambung, tidak ada internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Sambungan terputus"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Memutus sambungan..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Menyambung…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telepon"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Perangkat masukan"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Akses Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Berbagi kontak"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gunakan untuk berbagi kontak"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Berbagi sambungan internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Akses Pesan"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gunakan audio berkualitas tinggi: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gunakan audio berkualitas tinggi"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Tersambung ke media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Tersambung ke audio ponsel"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Sambungkan ke server transfer file"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Sekitar <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi hingga terisi penuh"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tersisa"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tersisa"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikontrol oleh admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Diaktifkan oleh admin"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Dinonaktifkan oleh admin"</string>
-    <string name="disabled" msgid="9206776641295849915">"Dinonaktifkan"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Diizinkan"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Tidak diizinkan"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Menginstal aplikasi yang tidak dikenal"</string>
     <string name="home" msgid="3256884684164448244">"Layar Utama Setelan"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 7f6141d..3c25224 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Nota val kerfisins (sjálfgefið)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Gera valfrjálsa kóðara virka"</item>
     <item msgid="3304843301758635896">"Gera valfrjálsa kóðara óvirka"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Nota val kerfisins (sjálfgefið)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Gera valfrjálsa kóðara virka"</item>
     <item msgid="741805482892725657">"Gera valfrjálsa kóðara óvirka"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 6bc3319..3f9aafd 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tengt, enginn internetaðgangur"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Aftengt"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Aftengist…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Tengist…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Hljóð efnis"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Hljóð síma"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Skráaflutningur"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inntakstæki"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetaðgangur"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deiling tengiliða"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Nota til að deila tengiliðum"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deiling nettengingar"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Skilaboðaaðgangur"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Aðgangur að SIM-korti"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Nota hágæðahljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Nota hágæðahljóð"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Tengt við hljóðspilun efnis"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Tengt við hljóð símans"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Tengt við skráaflutningsþjón"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"U.þ.b. <xliff:g id="TIME">%1$s</xliff:g> eftir miðað við notkun þína"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> þar til hleðslu er lokið"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> eftir"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> eftir miðað við notkun þína"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – um <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir miðað við notkun þína"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullri hleðslu er náð"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Stjórnað af kerfisstjóra"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Gert virkt af kerfisstjóra"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Gert óvirkt af kerfisstjóra"</string>
-    <string name="disabled" msgid="9206776641295849915">"Óvirkt"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Heimilað"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ekki heimilað"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Setja upp óþekkt forrit"</string>
     <string name="home" msgid="3256884684164448244">"Stillingar"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index cb6d5f7..ad35103 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usa selezione di sistema (predefinita)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Attiva codec facoltativi"</item>
     <item msgid="3304843301758635896">"Disattiva codec facoltativi"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usa selezione di sistema (predefinita)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Attiva codec facoltativi"</item>
     <item msgid="741805482892725657">"Disattiva codec facoltativi"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index dee6b42..99377e1 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connesso senza Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnesso"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnessione..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Connessione..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio multimediale"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telefono"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Trasferimento file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo di input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accesso Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Condivisione contatti"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usa per condivisione contatti"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Condivisione connessione Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Accesso ai messaggi"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Accesso alla SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizza audio di alta qualità: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizza audio di alta qualità"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Collegato ad audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Collegato ad audio telefono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Collegato al server di trasferimento file"</string>
@@ -101,7 +117,7 @@
     <string name="unknown" msgid="1592123443519355854">"Sconosciuta"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Utente: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"Alcune opzioni predefinite impostate"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna impostazione predefinita"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna app predefinita impostata"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Impostazioni di sintesi vocale"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Output sintesi vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocità voce"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Tempo approssimativo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g> circa"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo rimanente alla carica completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tempo rimanente: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ancora circa <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%2$s</xliff:g> circa"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Gestita dall\'amministratore"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Attivata dall\'amministratore"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Disattivata dall\'amministratore"</string>
-    <string name="disabled" msgid="9206776641295849915">"Disattivato"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Consentite"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Non consentite"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installa app sconosciute"</string>
     <string name="home" msgid="3256884684164448244">"Home page Impostazioni"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 917f710..614b554 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"‏הפעלה של Codecs אופציונליים"</item>
     <item msgid="3304843301758635896">"‏השבתה של Codecs אופציונליים"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"השתמש בבחירת המערכת (ברירת המחדל)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"‏הפעלה של Codecs אופציונליים"</item>
     <item msgid="741805482892725657">"‏השבתה של Codecs אופציונליים"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9371d27..3622a25 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏מחובר דרך %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏זמינה דרך %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"מחובר. אין אינטרנט"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"מנותק"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"מתנתק..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"מתחבר ..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"מחובר (אין גישה להודעות)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"מחובר (ללא טלפון או מדיה)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"אודיו של מדיה"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"אודיו של טלפון"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"העברת קבצים"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"מכשיר קלט"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"גישה לאינטרנט"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"שיתוף אנשי קשר"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"השתמש עבור שיתוף אנשי קשר"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"שיתוף חיבור לאינטרנט"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"גישה להודעות"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏גישה ל-SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"השתמש באודיו באיכות גבוהה: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"השתמש באודיו באיכות גבוהה"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"עוד <xliff:g id="TIME">%1$s</xliff:g> בקירוב"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">%1$s</xliff:g>, בקירוב"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> עד לטעינה מלאה"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"נותרו <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - הזמן הנותר: בערך <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - על סמך השימוש במכשיר, הסוללה תתרוקן בעוד <xliff:g id="TIME">%2$s</xliff:g>, בקירוב"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - נותרו <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"מופעל על ידי מנהל המכשיר"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"הושבת על ידי מנהל המכשיר"</string>
-    <string name="disabled" msgid="9206776641295849915">"מושבת"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"מורשה"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"לא מורשה"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"להתקין גם אם לא מוכר?"</string>
     <string name="home" msgid="3256884684164448244">"דף הבית של ההגדרות"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 779e2b1..7334965 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"システムの選択(デフォルト)を使用"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"オプションのコーデックの有効化"</item>
     <item msgid="3304843301758635896">"オプションのコーデックの無効化"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"システムの選択(デフォルト)を使用"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"オプションのコーデックを有効にします"</item>
     <item msgid="741805482892725657">"オプションのコーデックを無効にします"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index eb4cc10..54eedc3 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"接続済み、インターネットは利用できません"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"切断"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"切断中..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"接続中..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"接続済み(メッセージへのアクセスなし)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"接続済み(電話/メディアを除く)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"メディアの音声"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"電話の音声"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ファイル転送"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"入力デバイス"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"インターネットアクセス"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"連絡先の共有"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"連絡先の共有に使用"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"インターネット接続の共有"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"メッセージへのアクセス"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIMアクセス"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"高品質音声を使用: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"高品質音声を使用"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -101,7 +117,7 @@
     <string name="unknown" msgid="1592123443519355854">"不明"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"ユーザー: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"一部デフォルトを設定"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"デフォルトの設定なし"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"既定の設定なし"</string>
     <string name="tts_settings" msgid="8186971894801348327">"テキスト読み上げの設定"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"テキスト読み上げの出力"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"音声の速度"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"残り時間: 約 <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"フル充電まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g>(残り時間)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"残り時間: <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り時間: 約 <xliff:g id="TIME">%2$s</xliff:g>(使用状況に基づく)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>(残り時間)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -339,10 +358,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"管理者により管理されています"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"管理者により有効にされています"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"管理者により無効にされています"</string>
-    <string name="disabled" msgid="9206776641295849915">"無効"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"許可"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"許可しない"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"不明なアプリのインストール"</string>
     <string name="home" msgid="3256884684164448244">"設定のホーム"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index cf2113b6..472bb05 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"არასავალდებულო კოდეკების ჩართვა"</item>
     <item msgid="3304843301758635896">"არასავალდებულო კოდეკების გათიშვა"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"არასავალდებულო კოდეკების ჩართვა"</item>
     <item msgid="741805482892725657">"არასავალდებულო კოდეკების გათიშვა"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index e52bf30..068cfef 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"დაკავშირებულია, ინტერნეტის გარეშე"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"კავშირი გაწყვეტილია"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"მიმდინარეობს გათიშვა…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"მიმდინარეობს დაკავშირება…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"დაკავშირებულია (შეტყობინებაზე წვდომა არ არის)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"დაკავშირება (გარდა ტელეფონისა და მედიისა)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"მედია აუდიო"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ტელეფონის აუდიო"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ფაილების გადაცემა"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"შეყვანის მოწყობილობა"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ინტერნეტზე წვდომა"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"კონტაქტის გაზიარება"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"კონტაქტის გაზიარებისთვის გამოყენება"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ინტერნეტ კავშირის გაზიარება"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"შეტყობინებებზე წვდომა"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM წვდომა"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"მაღალხარისხიანი აუდიოს გამოყენება: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"მაღალხარისხიანი აუდიოს გამოყენება"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს ფუნქციონალობაზე."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"დარჩა დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"დარჩა დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"დარჩა <xliff:g id="TIME">%1$s</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"იმართება ადმინისტრატორის მიერ"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"ჩართულია ადმინისტრატორის მიერ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"გათიშულია ადმინისტრატორის მიერ"</string>
-    <string name="disabled" msgid="9206776641295849915">"გამორთული"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"დაშვებულია"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"დაუშვებელია"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"უცნობი აპების ინსტალაცია"</string>
     <string name="home" msgid="3256884684164448244">"პარამეტრების გვერდი"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index e348108..adbc815 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Жүйені таңдау (әдепкі)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Қосымша кодектерді қосу"</item>
     <item msgid="3304843301758635896">"Қосымша кодектерді өшіру"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Жүйені таңдау (әдепкі)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Қосымша кодектерді қосу"</item>
     <item msgid="741805482892725657">"Қосымша кодектерді өшіру"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 7cce073..cc52197 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Қосылған, интернет жоқ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ажыратылған"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ажыратылуда…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Жалғауда..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Жалғанған (хабарлар қол жетімсіз)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Жалғанған (телефон және медиа жоқ)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Meдиа аудиосы"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Телефон аудиосы"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл жіберу"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Кіріс құрылғысы"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернетке қосылу"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Контактіні бөлісу"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Контактіні бөлісу үшін пайдалану"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернет байланысын ортақ қолдану"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Хабарға кіру"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картасына кіру"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Жоғары сапалы аудио дыбысын пайдалану: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Жоғары сапалы аудио дыбысын пайдалану"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Қалған <xliff:g id="TIME">%1$s</xliff:g> туралы"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Пайдалану негізінде шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Толық зарядқа <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Пайдалану негізінде <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - пайдалану негізінде шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Әкімші басқарады"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Әкімші қосқан"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Әкімші өшірген"</string>
-    <string name="disabled" msgid="9206776641295849915">"Өшірілген"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Рұқсат етілген"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Рұқсат етілмеген"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Белгісіз қолданбаларды орнату"</string>
     <string name="home" msgid="3256884684164448244">"Параметрлер негізгі беті"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 27e0e59..b3b5e6d 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"បើក​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
     <item msgid="3304843301758635896">"បិទ​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"បើក​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
     <item msgid="741805482892725657">"បិទ​កូឌិក​ប្រភេទ​ស្រេច​ចិត្ត"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index e0a1337..03d8c09 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"បានភ្ជាប់ ប៉ុន្តែគ្មានអ៊ីនធឺណិតទេ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"បាន​ផ្ដាច់"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"កំពុង​ផ្ដាច់…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"កំពុង​ត​ភ្ជាប់​…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"បាន​ភ្ជាប់ (គ្មាន​ការ​ចូល​ដំណើរការ​សារ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"បាន​តភ្ជាប់ (គ្មាន​ទូរស័ព្ទ ឬ​មេឌៀ)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"សំឡេង​មេឌៀ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"សំឡេង​ទូរស័ព្ទ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ផ្ទេរ​ឯកសារ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ឧបករណ៍​បញ្ចូល"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ចូល​អ៊ីនធឺណិត"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ការ​ចែករំលែក​​ទំនាក់ទំនង"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ប្រើ​សម្រាប់​ការ​ចែករំលែក​ទំនាក់ទំនង"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ចែករំលែក​ការ​តភ្ជាប់​អ៊ីនធឺណិត"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"​​ចូល​ដំណើរការ​សារ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ការចូលដំណើរការស៊ីម"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ប្រើ​សំឡេង​គុណភាព​ខ្ពស់៖ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ប្រើ​សំឡេង​គុណភាព​ខ្ពស់"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"មុខងារនេះ​គឺ​ជា​ការ​ពិសោធន៍ ហើយ​អាច​ប៉ះពាល់​ដំណើរការ​។"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"សល់​ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"សល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"សល់ <xliff:g id="TIME">%1$s</xliff:g> ទើប​សាកថ្ម​ពេញ"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"សល់ <xliff:g id="TIME">%1$s</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - សល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀតផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញ"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"បើកដោយ​អ្នកគ្រប់គ្រង"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"បិទដោយអ្នកគ្រប់គ្រង"</string>
-    <string name="disabled" msgid="9206776641295849915">"បិទ"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"បាន​អនុញ្ញាត"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"មិន​អនុញ្ញាត​ទេ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ដំឡើងកម្មវិធីដែលមិនស្គាល់"</string>
     <string name="home" msgid="3256884684164448244">"ទំព័រដើមនៃការកំណត់"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 810aefe..e6fc9d6 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</item>
     <item msgid="3304843301758635896">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</item>
     <item msgid="741805482892725657">"ಐಚ್ಛಿಕ ಕೋಡೆಕ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index ec0bef4..893032c 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ, ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ಸಂಪರ್ಕಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ (ಯಾವುದೇ ಸಂದೇಶ ಪ್ರವೇಶವಿಲ್ಲ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ಸಂಪರ್ಕಗೊಂಡಿದೆ (ಫೋನ್ ಅಥವಾ ಮಾಧ್ಯಮವಿಲ್ಲ)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ಮಾಧ್ಯಮ ಆಡಿಯೋ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ಫೋನ್ ಆಡಿಯೋ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ಇನ್‌ಪುಟ್‌ ಸಾಧನ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ಸಂಪರ್ಕ ಹಂಚಿಕೆ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ಸಂಪರ್ಕ ಹಂಚಿಕೆಗಾಗಿ ಬಳಸಿ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ಸಂದೇಶ ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ಉನ್ನತ ಗುಣಮಟ್ಟದ ಆಡಿಯೋ ಬಳಸಿ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ಉನ್ನತ ಗುಣಮಟ್ಟದ ಆಡಿಯೋ ಬಳಸಿ"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಬಾಕಿಯಿದೆ"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಬಾಕಿಯಿದೆ"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
-    <string name="disabled" msgid="9206776641295849915">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ಅನುಮತಿಸಲಾಗಿದೆ"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ಅಪರಿಚಿತ ಆಪ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
     <string name="home" msgid="3256884684164448244">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮುಖಪುಟ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index dbbe89d..1c43db7 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"시스템 설정 사용(기본)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"선택사항 코덱 사용 설정"</item>
     <item msgid="3304843301758635896">"선택사항 코덱 사용 중지"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"시스템 설정 사용(기본)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"선택사항 코덱 사용 설정"</item>
     <item msgid="741805482892725657">"선택사항 코덱 사용 중지"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 0f4224a..74d4d1c 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"인터넷을 사용하지 않고 연결됨"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"연결 끊김"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"연결을 끊는 중…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"연결 중…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"연결됨(메시지 액세스 없음)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"연결됨(전화 또는 미디어 없음)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"미디어 오디오"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"휴대폰 오디오"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"파일 전송"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"입력 장치"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"인터넷 액세스"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"연락처 공유"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"연락처 공유용"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"인터넷 연결 공유"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"메시지 액세스"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 액세스"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"고품질 오디오 사용: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"고품질 오디오 사용"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -77,7 +93,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"페어링"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"페어링"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"취소"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"페어링하면 연결 시 연락처 및 통화 기록에 액세스할 수 있습니다."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"페어링하면 연결 시 주소록 및 통화 기록에 액세스할 수 있습니다."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 통신할 수 없습니다."</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"내 사용량을 기준으로 약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"충전 완료까지 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"내 사용량을 기준으로 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - 내 사용량을 기준으로 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"관리자가 제어"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"관리자가 사용 설정함"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"관리자가 사용 중지함"</string>
-    <string name="disabled" msgid="9206776641295849915">"사용 안함"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"허용됨"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"허용되지 않음"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"알 수 없는 앱 설치"</string>
     <string name="home" msgid="3256884684164448244">"설정 홈"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 9c8e28a..9436209 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Тутум тандаганды колдонуу (демейки)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Кошумча кодекстер иштетилсин"</item>
     <item msgid="3304843301758635896">"Кошумча кодекстер өчүрүлсүн"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Тутум тандаганды колдонуу (демейки)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Кошумча кодекстер иштетилсин"</item>
     <item msgid="741805482892725657">"Кошумча кодекстер өчүрүлсүн"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 58cf6df..9989535 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Туташып турат, Интернет жок"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ажыратылган"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ажыратылууда…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Туташууда…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Байланышта (билдирүү алмашуу жок)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Туташып турат (телефониясыз же медиасыз)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Телефон"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл алмашуу"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Киргизүү түзмөгү"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернетке мүмкүнчүлүк алуу"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Байланышты бөлүшүү"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Байланышты бөлүшүү үчүн колдонуу"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернет байланышын бөлүшүү"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Билдирүү алмашуу"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Жогорку сапаттагы аудио кодекти колдонуу: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Жогорку сапаттагы аудио кодекти колдонуу"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, түзмөктүн иштешине таасир этиши мүмкүн."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Батарея түгөнгөнгө чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Колдонушуңузга караганда болжол менен <xliff:g id="TIME">%1$s</xliff:g> калды"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Батарея толгонго чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> калды"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Колдонушуңузга караганда <xliff:g id="TIME">%1$s</xliff:g> калды"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - колдонушуңузга караганда болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Администратор тарабынан көзөмөлдөнөт"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Администратор иштетип койгон"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Администратор өчүрүп койгон"</string>
-    <string name="disabled" msgid="9206776641295849915">"Өчүрүлгөн"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Уруксат берилген"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Тыюу салынган"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Белгисиз колдонмолорду орнотуу"</string>
     <string name="home" msgid="3256884684164448244">"Жөндөөлөрдүн башкы бети"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 63889e0..2626857 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ເປີດໃຊ້ Codecs ແບບເສີມ"</item>
     <item msgid="3304843301758635896">"ປິດການໃຊ້ Codecs ແບບເສີມ"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ເປີດໃຊ້ Codecs ແບບເສີມ"</item>
     <item msgid="741805482892725657">"ປິດການໃຊ້ Codecs ແບບເສີມ"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 3411348..3c236181 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"​ເຊື່ອມຕໍ່​ຜ່ານ %1$s ​ແລ້ວ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"ມີ​ໃຫ້​ຜ່ານ %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"​ເຊື່ອມ​ຕໍ່​ແລ້ວ,​ ບໍ່​ມີ​ອິນ​ເຕີ​ເນັດ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ກຳລັງຢຸດການເຊື່ອມຕໍ່..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ກຳລັງເຊື່ອມຕໍ່..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ເຊື່ອມຕໍ່ (ບໍ່ມີການເຂົ້າເຖິງຂໍ້ຄວາມ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ເຊື່ອມຕໍ່ແລ້ວ (ບໍ່ມີໂທລະສັບ ຫຼືສື່)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ສຽງ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ສຽງໂທລະສັບ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ການໂອນຍ້າຍໄຟລ໌"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ການເຂົ້າເຖິງອິນເຕີເນັດ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"​ໃຊ້​ສຳ​ລັບການ​ແບ່ງ​ປັນ​ລາຍ​ຊື່​ຜູ່​ຕິດ​ຕໍ່"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ການແບ່ງປັນການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ການ​ເຂົ້າ​ເຖິງ​ຂໍ້​ຄວາມ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ການ​ເຂົ້າ​ເຖິງ SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ໃຊ້ສຽງຄຸນນະພາບສູງ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ໃຊ້ສຽງຄຸນນະພາບສູງ"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"​ຄຸນ​ສົມ​ບັດ​ນີ້​ກຳ​ລັງ​ຢູ່​ໃນ​ການ​ທົດ​ລອງ​ແລະ​ອາດ​ມີ​ຜົນ​ຕໍ່​ປະ​ສິດ​ທິ​ພາບ."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"ອີກປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ເຫຼືອອີກປະມານ <xliff:g id="TIME">%1$s</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ຍັງເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ເຫຼືອອີກ <xliff:g id="TIME">%1$s</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ເຫຼືອອີກປະມານ <xliff:g id="TIME">%2$s</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຍັງເຫຼືອ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"ຜູ້ເບິ່ງແຍງລະບົບເປີດໃຫ້ໃຊ້ແລ້ວ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"ຖືກຜູ້ເບິ່ງແຍງລະບົບປິດໄວ້"</string>
-    <string name="disabled" msgid="9206776641295849915">"ປິດການນຳໃຊ້"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ອະນຸຍາດແລ້ວ"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ບໍ່ອະນຸຍາດແລ້ວ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
     <string name="home" msgid="3256884684164448244">"ໜ້າທຳອິດຂອງການຕັ້ງຄ່າ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 3c325c1..be64b2d 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Naudoti sistemos pasirink. (numatytasis)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Įgalinti nebūtinus kodekus"</item>
     <item msgid="3304843301758635896">"Išjungti nebūtinus kodekus"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Naudoti sistemos pasirink. (numatytasis)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Įgalinti nebūtinus kodekus"</item>
     <item msgid="741805482892725657">"Išjungti nebūtinus kodekus"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index b05ff2c..8659754 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Prisijungta, nėra interneto"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Atsijungęs (-usi)"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Atjungiama..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Prisijungiama..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Laikmenos garsas"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefono garsas"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failo perkėlimas"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Įvesties įrenginys"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Prieiga prie interneto"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktų bendrinimas"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Naudoti kontaktams bendrinti"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneto ryšio bendrinimas"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Prieiga prie pranešimų"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM prieiga"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Naudoti aukštos kokybės garsą: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Naudoti aukštos kokybės garsą"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Prijungta prie medijos garso įrašo"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Prijungta prie telefono garso"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Prijungta prie failų perkėlimo serverio"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>, atsižvelgiant į naudojimą"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Iki visiškos įkrovos liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Liko <xliff:g id="TIME">%1$s</xliff:g>, atsižvelgiant į naudojimą"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>, atsižvelgiant į naudojimą"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Valdo administratorius"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Įgalino administratorius"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Išjungė administratorius"</string>
-    <string name="disabled" msgid="9206776641295849915">"Neleidžiama"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Leidžiama"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Neleidžiama"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Nežinomų programų diegimas"</string>
     <string name="home" msgid="3256884684164448244">"Pagrindinis Nustatymų ekranas"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 2c69c7e..41f17d3 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 
+<!--
 /*
 **
 ** Copyright 2015 The Android Open Source Project
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Sistēmas atlases izmantošana (nokl.)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Iespējot neobligātos kodekus"</item>
     <item msgid="3304843301758635896">"Atspējot neobligātos kodekus"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Sistēmas atlases izmantošana (nokl.)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Iespējot neobligātos kodekus"</item>
     <item msgid="741805482892725657">"Atspējot neobligātos kodekus"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index c24ad5c..54310a6 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Savienots, nav piekļuves internetam"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Atvienots"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Notiek atvienošana..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Notiek savienojuma izveide…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multivides audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Tālruņa audio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Failu pārsūtīšana"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Ievades ierīce"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Interneta piekļuve"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktpersonas informācijas kopīgošana"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Izmantot kontaktpersonas informācijas kopīgošanai"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Interneta savienojuma koplietošana"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Piekļuve ziņojumam"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Piekļuve SIM kartei"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Izmantot augstas kvalitātes audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Izmantot augstas kvalitātes audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Savienots ar multivides audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Savienots ar tālruņa audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Savienots ar failu pārsūtīšanas serveri"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g> (ņemot vērā lietojumu)"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Atlikušais laiks līdz pilnai uzlādei: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Atlikušais laiks: <xliff:g id="TIME">%1$s</xliff:g> (ņemot vērā lietojumu)"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - vēl apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlikušais laiks: aptuveni <xliff:g id="TIME">%2$s</xliff:g> (ņemot vērā lietojumu)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> — atlicis: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolē administrators"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Iespējoja administrators"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Atspējoja administrators"</string>
-    <string name="disabled" msgid="9206776641295849915">"Atspējots"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Atļauts"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nav atļauts"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalēt nez. lietotnes"</string>
     <string name="home" msgid="3256884684164448244">"Iestatījumu sākumekrāns"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 2da43f0..4508fa3 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Користи избор на системот (стандардно)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Овозможување на „Кодеци по избор“"</item>
     <item msgid="3304843301758635896">"Оневозможување на „Кодеци по избор“"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Користи избор на системот (стандардно)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Овозможи ја „Кодеци по избор“"</item>
     <item msgid="741805482892725657">"Оневозможи ја „Кодеци по избор“"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 1f2391d..e33e7a0 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Поврзана, нема интернет"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Исклучено"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Се исклучува..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Се поврзува..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Поврзано (без порака за пристап)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Поврзан (без телефон или медиуми)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Аудио на медиуми"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Аудио на телефон"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос на датотека"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Влезен уред"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Пристап на интернет"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Споделување контакти"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Користи за споделување контакти"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Споделување конекција на интернет"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Порака за пристап"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Користи висококвалитетно аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Користи висококвалитетно аудио"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Преостануваат околу <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Уште околу <xliff:g id="TIME">%1$s</xliff:g> според користењето"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">%1$s</xliff:g> дури се наполни целосно"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"уште <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Уште <xliff:g id="TIME">%1$s</xliff:g> според користењето"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште околу <xliff:g id="TIME">%2$s</xliff:g> според користењето"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - уште <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролирано од администраторот"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Овозможено од администраторот"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Оневозможено од администраторот"</string>
-    <string name="disabled" msgid="9206776641295849915">"Оневозможено"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Дозволено"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Не е дозволено"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Непознати апликации"</string>
     <string name="home" msgid="3256884684164448244">"Почетна страница за поставки"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 57382f1..a10f730 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</item>
     <item msgid="3304843301758635896">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനരഹിതമാക്കുക"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</item>
     <item msgid="741805482892725657">"ഓപ്ഷണൽ കോഡെകുകൾ പ്രവർത്തനരഹിതമാക്കുക"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index a7d0dde..3a9435e 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇന്റർനെറ്റില്ല"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"വിച്ഛേദിച്ചു"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"വിച്‌ഛേദിക്കുന്നു..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"കണക്‌റ്റുചെയ്യുന്നു..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"കണക്റ്റുചെയ്‌തു (സന്ദേശ ആക്‌സസ്സില്ല)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"കണ‌ക്റ്റുചെ‌യ്തു (ഫോണോ മീഡിയയോ അല്ല)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"മീഡിയ ഓഡിയോ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ഫോൺ ഓഡിയോ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ഫയൽ കൈമാറൽ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ഇൻപുട്ട് ഉപകരണം"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ഇന്റർനെറ്റ് ആക്‌സസ്സ്"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"കോൺടാക്‌റ്റ് പങ്കിടൽ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"കോൺടാക്‌റ്റ് പങ്കിടലിനായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ഇന്റർനെറ്റ് കണക്ഷൻ പങ്കിടൽ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ആക്‌സസ്സ് നിയന്ത്രിക്കുക"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ആക്സസ്"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ഉയർന്ന നിലവാരമുള്ള ഓഡിയോ ഉപയോഗിക്കുക: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ഉയർന്ന നിലവാരമുള്ള ഓഡിയോ ഉപയോഗിക്കുക"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"മുഴുവൻ ചാർജാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഫുൾ ചാർജാകാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"അഡ്‌മിൻ പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"അഡ്‌മിൻ പ്രവർത്തനരഹിതമാക്കി"</string>
-    <string name="disabled" msgid="9206776641295849915">"പ്രവർത്തനരഹിതമാക്കി"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"അനുവദനീയം"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"അനുവദിച്ചിട്ടില്ല"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"അറിഞ്ഞുകൂടാത്ത ആപ്‌സ് ഇൻസ്റ്റാളുചെയ്യുക"</string>
     <string name="home" msgid="3256884684164448244">"ക്രമീകരണ ഹോം"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index d6a0772..12e05ed 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Нэмэлт кодлогчийг идэвхжүүлэх"</item>
     <item msgid="3304843301758635896">"Нэмэлт кодлогчийг идэвхгүй болгох"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Нэмэлт кодлогчийг идэвхжүүлэх"</item>
     <item msgid="741805482892725657">"Нэмэлт кодлогчийг идэвхгүй болгох"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index d6853d0..02266da 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Холбогдсон, интернэт байхгүй байна"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Салгагдсан"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Салгаж байна…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Холбогдож байна..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Холбогдсон (зурвас хандалт байхгүй)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Холбогдсон (утас буюу медиа байхгүй)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Медиа аудио"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Утасны аудио"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл дамжуулалт"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Оруулах төхөөрөмж"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернэт хандалт"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Харилцагч хуваалцах"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Харилцагч хуваалцахад ашиглах"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернэт холболтыг хуваалцах"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Зурвас хандалт"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Хандалт"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Өндөр чанарын аудио ашиглах: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Өндөр чанарын аудио ашиглах"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Таны хэрэглээнд тулгуурлан <xliff:g id="TIME">%1$s</xliff:g> орчмын хугацаа үлдсэн байна"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Бүрэн цэнэглэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Таны хэрэглээнд тулгуурлан <xliff:g id="TIME">%1$s</xliff:g> орчмын хугацаа үлдсэн байна"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g>-с <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - таны хэрэглээнд тулгуурлан <xliff:g id="TIME">%2$s</xliff:g> орчмын хугацаа үлдсэн байна"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Админ удирдсан"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Админ идэвхжүүлсэн"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Админ цуцалсан"</string>
-    <string name="disabled" msgid="9206776641295849915">"Идэвхгүйжүүлсэн"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Зөвшөөрсөн"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Зөвшөөрөөгүй"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Тодорхойгүй апп суулгах"</string>
     <string name="home" msgid="3256884684164448244">"Тохиргооны нүүр хуудас"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 5c7b15f..bd85087 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"पर्यायी कोडेक सक्षम करा"</item>
     <item msgid="3304843301758635896">"पर्यायी कोडेक अक्षम करा"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"प्रणाली निवड वापरा (डीफॉल्ट)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"पर्यायी कोडेक सक्षम करा"</item>
     <item msgid="741805482892725657">"पर्यायी कोडेक अक्षम करा"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 0e76443..47376eb 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्‍ट केले"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्‍ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"कनेक्‍ट केले, इंटरनेट नाही"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"डिस्कनेक्ट केले"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"डिस्कनेक्ट करत आहे..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"कनेक्ट करीत आहे..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"कनेक्ट केलेले आहे (कोणत्याही संदेशामध्ये प्रवेश नाही)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"कनेक्ट केले (फोन किंवा मीडिया नाही)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फोन ऑडिओ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिव्हाइस"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट प्रवेश"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क सामायिकरण"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क सामायिकरणासाठी वापरा"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन सामायिकरण"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"संदेशात प्रवेश"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम प्रवेश"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"उच्च दर्जाचा ऑडिओ वापरा: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"उच्च दर्जाचा ऑडिओ वापरा"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्‍ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"सुमारे <xliff:g id="TIME">%1$s</xliff:g> शिल्‍लक"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"तुमच्या वापरानुसार अंदाजे <xliff:g id="TIME">%1$s</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णपणे चार्ज होण्यास <xliff:g id="TIME">%1$s</xliff:g> शिल्‍लक"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"तुमच्या वापरानुसार <xliff:g id="TIME">%1$s</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - तुमच्या वापरानुसार अंदाजे <xliff:g id="TIME">%2$s</xliff:g> पुरेल इतकी बॅटरी शिल्लक आहे"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकाने नियंत्रित केलेले"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकाने सक्षम केलेले"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"प्रशासकाने अक्षम केलेले"</string>
-    <string name="disabled" msgid="9206776641295849915">"अक्षम"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"अनुमती आहे"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमती नाही"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"अज्ञात अ‍ॅप्स स्थापित करा"</string>
     <string name="home" msgid="3256884684164448244">"सेटिंग्ज मुख्यपृष्ठ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index bab4642..a7542ea 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Gunakan Pilihan Sistem (Lalai)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Dayakan Codec Pilihan"</item>
     <item msgid="3304843301758635896">"Lumpuhkan Codec Pilihan"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Gunakan Pilihan Sistem (Lalai)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Dayakan Codec Pilihan"</item>
     <item msgid="741805482892725657">"Lumpuhkan Codec Pilihan"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 19bf62e..3f0a061 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Disambungkan, tiada Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Diputuskan sambungan"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Memutuskan sambungan..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Menyambung..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio telefon"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Pemindahan fail"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Peranti input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Akses Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Perkongsian kenalan"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gunakan untuk perkongsian kenalan"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Perkongsian sambungan Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Akses Mesej"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gunakan audio berkualiti tinggi: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gunakan audio berkualiti tinggi"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Disambungkan ke audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Disambungkan ke audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Bersambung ke pelayan pemindahan fail"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Tinggal kira-kira <xliff:g id="TIME">%1$s</xliff:g> berdasarkan penggunaan anda"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi sehingga dicas penuh"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> lagi"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Tinggal <xliff:g id="TIME">%1$s</xliff:g> berdasarkan penggunaan anda"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - tinggal kira-kira <xliff:g id="TIME">%2$s</xliff:g> berdasarkan penggunaan anda"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Dikawal oleh pentadbir"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Didayakan oleh pentadbir"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Dilumpuhkan oleh pentadbir"</string>
-    <string name="disabled" msgid="9206776641295849915">"Dilumpuhkan"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Dibenarkan"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Tidak dibenarkan"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Pasang apl yang tidak diketahui"</string>
     <string name="home" msgid="3256884684164448244">"Laman Utama Tetapan"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 97a9c53..083f475 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ဖွင့်ပါ"</item>
     <item msgid="3304843301758635896">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ပိတ်ပါ"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ဖွင့်ပါ"</item>
     <item msgid="741805482892725657">"စိတ်ကြိုက်ထည့်သွင်းနိုင်သော ကိုးဒက်ခ်များကို ပိတ်ပါ"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 6864162..89712d9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ချိတ်ဆက်ထားသည်၊ အင်တာနက်မရှိ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ချိတ်ဆက်မှုပြတ်တောက်သည်"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"အဆက်အသွယ်ဖြတ်တောက်သည်"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ချိတ်ဆက်နေသည်"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ချိတ်ဆက်မိသည် (သတင်းရယူမှုမရှိ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ချိတ်ဆက်ပြီး (ဖုန်း သို့ မီဒီယာမဟုတ်ပါ)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"မီဒီယာ အသံ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ဖုန်းအသံ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ဖိုင်လွဲပြောင်းခြင်း"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ထည့်သွင်းသော စက်"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"အင်တာနက်ချိတ်ဆက်ခြင်း"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"အဆက်အသွယ်ကို မျှဝေရန်"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"အဆက်အသွယ်ကို မျှဝေရန် အတွက် သုံးရန်"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"အင်တာနက်ဆက်သွယ်မှု မျှဝေခြင်း"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"သတင်းရယူမှု"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM အသုံးပြုခြင်း"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"အရည်အသွေးမြင့် အသံအမျိုးအစားကို သုံးရန်− <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"အရည်အသွေးမြင့် အသံအမျိုးအစားကိုသုံးရန်"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဤဝန်ဆောင်မှုမှာ စမ်းသပ်အဆင့်သာဖြစ်၍ လုပ်ဆောင်မှုအားနည်းနိုင်သည်။"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> ခန့်လိုပါသည်"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">%1$s</xliff:g> ခန့် ကျန်ပါသည်"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုပါသည်"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> − <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - သင့်အသုံးပြုမှုအရ <xliff:g id="TIME">%2$s</xliff:g> ခန့် ကျန်ပါသည်"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> − အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"စီမံခန့်ခွဲသူက ဖွင့်ထားသည်"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</string>
-    <string name="disabled" msgid="9206776641295849915">"ပိတ်ထားပြီး"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ခွင့်ပြုထားသည်"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ခွင့်ပြုမထားပါ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"အမျိုးအမည်မသိအက်ပ် ထည့်သွင်းနိုင်ခြင်း"</string>
     <string name="home" msgid="3256884684164448244">"ဆက်တင် ပင်မစာမျက်နှာ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"၀%"</item>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 287c386..1c49a93 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Bruk systemvalg (standard)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Slå på valgfrie kodeker"</item>
     <item msgid="3304843301758635896">"Slå av valgfrie kodeker"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Bruk systemvalg (standard)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Slå på valgfrie kodeker"</item>
     <item msgid="741805482892725657">"Slå av valgfrie kodeker"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index c69b1b8..d2807ce 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Tilkoblet – ingen Internett-forbindelse"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Frakoblet"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Kobler fra…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Kobler til…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonlyd"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverføring"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inndataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internett-tilgang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktdeling"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Bruk til kontaktdeling"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling av Internett-tilkobling"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Meldingstilgang"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Tilgang til SIM-kortet"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Bruk lyd av høy kvalitet: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Bruk lyd av høy kvalitet"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Koblet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Koblet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Koblet til tjener for filoverføring"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Dette er en eksperimentell funksjon som kan gjøre at telefonen ikke fungerer optimalt."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Omtrent <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Omtrent <xliff:g id="TIME">%1$s</xliff:g> igjen basert på bruken din"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fulladet"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> igjen basert på bruken din"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – omtrent <xliff:g id="TIME">%2$s</xliff:g> igjen basert på bruken din"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> gjenstår"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrollert av administratoren"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Slått på av administratoren"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Avslått av administratoren"</string>
-    <string name="disabled" msgid="9206776641295849915">"Slått av"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Tillatt"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ikke tillatt"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installer ukjente apper"</string>
     <string name="home" msgid="3256884684164448244">"Innstillinger for startsiden"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index ba7affd..883c7b3 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"वैकल्पिक कोडेकहरूलाई सक्षम पार्नुहोस्"</item>
     <item msgid="3304843301758635896">"वैकल्पिक कोडेकहरूलाई असक्षम पार्नुहोस्"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"वैकल्पिक कोडेकहरूलाई सक्षम पार्नुहोस्"</item>
     <item msgid="741805482892725657">"वैकल्पिक कोडेकहरूलाई असक्षम पार्नुहोस्"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index fe7f780..f830a87 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"जडित, इन्टरनेट चलेको छैन"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"विच्छेदन गरियो"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"जडान हटाइँदै ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"जडान हुँदै..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"जडित छ (सन्देशमा पहुँच छैन)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"जडित (फोन वा मिडिया छैन)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मिडिया अडियो"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"फोन अडियो"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानान्तरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट उपकरण"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इन्टरनेट पहुँच"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"सम्पर्क साझेदारी"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"सम्पर्क साझेदारीका लागि प्रयोग"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इन्टरनेट जडान साझेदारी गर्दै"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"सन्देश पहुँच"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM पहुँच"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"उच्च गुणस्तरको अडियो प्रयोग गर्नुहोस्‌: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"उच्च गुणस्तरको अडियो प्रयोग गर्नुहोस्‌"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"तपाईंको प्रयोगका आधारमा लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"बाँकी समय <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - करिब <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - तपाईंको प्रयोगका आधारमा लगभग <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"बाँकी समय <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"प्रशासकद्वारा नियन्त्रित"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"प्रशासकद्वारा सक्षम पारिएको छ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"प्रशासकद्वारा असक्षम पारिएको छ"</string>
-    <string name="disabled" msgid="9206776641295849915">"असक्षम पारियो"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति छ"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति छैन"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"अज्ञात अनुप्रयोगहरू स्थापना गर्नुहोस्"</string>
     <string name="home" msgid="3256884684164448244">"सेटिङहरूको गृहपृष्ठ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"०%"</item>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 25b803a..a47301d 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Systeemselectie gebruiken (standaard)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Optionele codecs inschakelen"</item>
     <item msgid="3304843301758635896">"Optionele codecs uitschakelen"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Systeemselectie gebruiken (standaard)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Optionele codecs inschakelen"</item>
     <item msgid="741805482892725657">"Optionele codecs uitschakelen"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 65a4a20..6625880 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Verbonden, geen internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Verbinding verbroken"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Verbinding verbreken..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Verbinding maken..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefoonaudio"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Bestandsoverdracht"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Invoerapparaat"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internettoegang"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contacten delen"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gebruiken voor contacten delen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internetverbinding delen"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Toegang tot berichten"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Sim-toegang"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Audio van hoge kwaliteit gebruiken: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Audio van hoge kwaliteit gebruiken"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Verbonden met audio van medium"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Verbonden met audio van telefoon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Verbonden met server voor bestandsoverdracht"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Nog ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Nog ongeveer <xliff:g id="TIME">%1$s</xliff:g> over op basis van je gebruik"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Nog <xliff:g id="TIME">%1$s</xliff:g> tot volledig opgeladen"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> resterend"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Nog <xliff:g id="TIME">%1$s</xliff:g> over op basis van je gebruik"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ongeveer <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g>: nog ongeveer <xliff:g id="TIME">%2$s</xliff:g> over op basis van je gebruik"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ingesteld door beheerder"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Ingeschakeld door beheerder"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Uitgeschakeld door beheerder"</string>
-    <string name="disabled" msgid="9206776641295849915">"Uitgeschakeld"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Toegestaan"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Niet toegestaan"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Onbekende apps installeren"</string>
     <string name="home" msgid="3256884684164448244">"Homepage voor instellingen"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 2715f9d..4211fb6 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਯੋਗ ਬਣਾਓ"</item>
     <item msgid="3304843301758635896">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਅਯੋਗ ਬਣਾਓ"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਯੋਗ ਬਣਾਓ"</item>
     <item msgid="741805482892725657">"ਵਿਕਲਪਿਕ ਕੋਡੈਕ ਅਯੋਗ ਬਣਾਓ"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 3324b19..8119ba5 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈਟ ਨਹੀਂ"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ਡਿਸਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ਡਿਸਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਸੁਨੇਹਾ ਪਹੁੰਚ ਨਹੀਂ)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"ਕਨੈਕਟ ਕੀਤਾ (ਕੋਈ ਫੋਨ ਜਾਂ ਮੀਡੀਆ ਨਹੀਂ)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ਮੀਡੀਆ ਔਡੀਓ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ਫੋਨ ਔਡੀਓ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ਇਨਪੁਟ ਡੀਵਾਈਸ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ਇੰਟਰਨੈਟ ਪਹੁੰਚ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ਸੰਪਰਕ ਸ਼ੇਅਰਿੰਗ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ਇੰਟਰਨੈਟ ਕਨੈਕਸ਼ਨ ਸ਼ੇਅਰਿੰਗ"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"ਸੁਨੇਹਾ ਪਹੁੰਚ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ਪਹੁੰਚ"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ਉੱਚ ਗੁਣਵੱਤਾ ਔਡੀਓ ਵਰਤੋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ਉੱਚ ਗੁਣਵੱਤਾ ਔਡੀਓ ਵਰਤੋ"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
-    <string name="disabled" msgid="9206776641295849915">"ਅਯੋਗ ਬਣਾਇਆ"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ਇਜਾਜ਼ਤ ਹੈ"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ਇਜਾਜ਼ਤ ਨਹੀਂ"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਿਤ ਕਰੋ"</string>
     <string name="home" msgid="3256884684164448244">"ਸੈਟਿੰਗਾਂ ਮੁੱਖ ਪੰਨਾ"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 375615f..9cf689f 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Użyj wyboru systemu (domyślnie)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Włącz opcjonalne kodeki"</item>
     <item msgid="3304843301758635896">"Wyłącz opcjonalne kodeki"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Użyj wyboru systemu (domyślnie)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Włączenie opcjonalnych kodeków"</item>
     <item msgid="741805482892725657">"Wyłączenie opcjonalnych kodeków"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 0e92353..ceee1e3 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Połączono, brak internetu"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Rozłączona"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Rozłączanie..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Łączenie..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Dźwięk multimediów"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Dźwięk telefonu"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Przesyłanie pliku"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Urządzenie wejściowe"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Dostęp do internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Udostępnianie kontaktów"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Używaj do udostępniania kontaktów"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Udostępnianie połączenia internetowego"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Dostęp do wiadomości"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostęp do karty SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Korzystaj z dźwięku wysokiej jakości: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Korzystaj z dźwięku wysokiej jakości"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Połączono z funkcją audio multimediów"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Połączono z funkcją audio telefonu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Połączono z serwerem transferu plików"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Pozostało: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Jeszcze około <xliff:g id="TIME">%1$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Jeszcze <xliff:g id="TIME">%1$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – pozostało około <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – jeszcze około <xliff:g id="TIME">%2$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolowane przez administratora"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Włączone przez administratora"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Wyłączone przez administratora"</string>
-    <string name="disabled" msgid="9206776641295849915">"Wyłączone"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Dozwolone"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Niedozwolone"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalowanie nieznanych aplikacji"</string>
     <string name="home" msgid="3256884684164448244">"Ekran główny ustawień"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index e3f287b..2d839ea 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
     <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usar seleção do sistema (padrão)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
     <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
@@ -190,9 +190,9 @@
   </string-array>
   <string-array name="animator_duration_scale_entries">
     <item msgid="6039901060648228241">"Animação desativada"</item>
-    <item msgid="1138649021950863198">"Escala de animação 0,5x"</item>
+    <item msgid="1138649021950863198">"Escala de animação 5x"</item>
     <item msgid="4394388961370833040">"Escala de animação 1x"</item>
-    <item msgid="8125427921655194973">"Escala de animação 1,5x"</item>
+    <item msgid="8125427921655194973">"Escala de animação 1.5 x"</item>
     <item msgid="3334024790739189573">"Escala de animação 2x"</item>
     <item msgid="3170120558236848008">"Escala de animação 5x"</item>
     <item msgid="1069584980746680398">"Escala de animação 10x"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e0683a8..e34c41e 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do smartphone"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar áudio de alta qualidade"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao áudio da mídia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao áudio do smartphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferência de arquivo"</string>
@@ -81,7 +97,7 @@
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g>: cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desativado"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permitido"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Não permitido"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar apps desconhecidos"</string>
     <string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 3eeade0..264300d 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Utilizar seleção do sistema (predef.)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
     <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Utilizar seleção do sistema (predef.)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
     <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 6889e01..f68fe36 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Ligado através de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ligado, sem Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desligado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"A desligar..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"A ligar..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio de multimédia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do telemóvel"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência do ficheiro"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partilha de contactos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizar para a partilha de contactos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Partilha da ligação à internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso ao SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizar áudio de alta qualidade"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ligado ao áudio de multimédia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ligado ao áudio do telefone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ligado ao servidor de transferência de ficheiros"</string>
@@ -272,8 +288,8 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Limite proc. em 2º plano"</string>
     <string name="show_all_anrs" msgid="28462979638729082">"Mostrar todos os ANR"</string>
     <string name="show_all_anrs_summary" msgid="641908614413544127">"Mostrar erro \"Aplic. não Resp.\" p/ aplic. 2º plano"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos do canal de notificações"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra um aviso no ecrã quando uma aplicação publica uma notificação sem o canal ser válido"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos do canal de notif."</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra um aviso no ecrã quando uma aplic. publica uma notific. sem um canal válido"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar perm. de aplicações no armazenamento ext."</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Torna qualquer aplicação elegível para ser gravada no armazenamento externo, independentemente dos valores do manifesto"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar as atividades a serem redimensionáveis"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Falta(m) cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Resta(m) cerca de <xliff:g id="TIME">%1$s</xliff:g> com base na sua utilização"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Falta(m) <xliff:g id="TIME">%1$s</xliff:g> para concluir o carregamento"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g> com base na sua utilização"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – falta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo administrador"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Ativada pelo administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desativada"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Autorizada"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Não autorizada"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar aplicações desconhecidas"</string>
     <string name="home" msgid="3256884684164448244">"Página inicial de definições"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index e3f287b..2d839ea 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Usar seleção do sistema (padrão)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Ativar codecs opcionais"</item>
     <item msgid="3304843301758635896">"Desativar codecs opcionais"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Usar seleção do sistema (padrão)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Ativar codecs opcionais"</item>
     <item msgid="741805482892725657">"Desativar codecs opcionais"</item>
@@ -190,9 +190,9 @@
   </string-array>
   <string-array name="animator_duration_scale_entries">
     <item msgid="6039901060648228241">"Animação desativada"</item>
-    <item msgid="1138649021950863198">"Escala de animação 0,5x"</item>
+    <item msgid="1138649021950863198">"Escala de animação 5x"</item>
     <item msgid="4394388961370833040">"Escala de animação 1x"</item>
-    <item msgid="8125427921655194973">"Escala de animação 1,5x"</item>
+    <item msgid="8125427921655194973">"Escala de animação 1.5 x"</item>
     <item msgid="3334024790739189573">"Escala de animação 2x"</item>
     <item msgid="3170120558236848008">"Escala de animação 5x"</item>
     <item msgid="1069584980746680398">"Escala de animação 10x"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e0683a8..e34c41e 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do smartphone"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Usar áudio de alta qualidade: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Usar áudio de alta qualidade"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao áudio da mídia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao áudio do smartphone"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferência de arquivo"</string>
@@ -81,7 +97,7 @@
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cerca de <xliff:g id="TIME">%1$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g>: cerca de <xliff:g id="TIME">%2$s</xliff:g> restante(s) com base no seu uso"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> restante(s)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada pelo admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Ativado pelo administrador"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string>
-    <string name="disabled" msgid="9206776641295849915">"Desativado"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permitido"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Não permitido"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalar apps desconhecidos"</string>
     <string name="home" msgid="3256884684164448244">"Página inicial das configurações"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 39ebb82..9df4759 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Folosiți selectarea sist. (prestabilit)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Activați codecurile opționale"</item>
     <item msgid="3304843301758635896">"Dezactivați codecurile opționale"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Folosiți selectarea sist. (prestabilit)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Activați codecurile opționale"</item>
     <item msgid="741805482892725657">"Dezactivați codecurile opționale"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4a4a7a0..effc008 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectată, fără internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Deconectat"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"În curs de deconectare..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Se conectează..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conținut media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Componenta audio a telefonului"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer de fișiere"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispozitiv de intrare"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acces internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Acces la Agendă"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Utilizați pentru a permite accesul la Agendă"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Distribuirea conexiunii la internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acces la mesaje"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acces la SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Utilizați conținut audio de înaltă calitate: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Utilizați conținut audio de înaltă calitate"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectat la profilul pentru conținut media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectat la componenta audio a telefonului"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectat la serverul de transfer de fișiere"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"În baza utilizării, timpul aproximativ rămas este: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Timp rămas până la încărcarea completă: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Timp rămas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"În baza utilizării, timpul rămas este: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - încă aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – în baza utilizării, timpul aproximativ rămas este: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcarea completă"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlată de administrator"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Activat de administrator"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Dezactivat de administrator"</string>
-    <string name="disabled" msgid="9206776641295849915">"Dezactivată"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Permise"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nepermise"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalare apl. necunoscute"</string>
     <string name="home" msgid="3256884684164448244">"Ecran principal Setări"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 784e48e..5a46132 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Выбор системы (по умолчанию)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Включить дополнительные кодеки"</item>
     <item msgid="3304843301758635896">"Отключить дополнительные кодеки"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Выбор системы (по умолчанию)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Включить дополнительные кодеки"</item>
     <item msgid="741805482892725657">"Отключить дополнительные кодеки"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 90d9c33..640d3b5 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Подключено, без Интернета"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Нет подключения"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Отключение..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Подключение..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Подключено (нет доступа к сообщениям)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Подключено (кроме HSP/HFP/A2DP)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Профиль A2DP"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Профиль HSP/HFP"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Профиль OPP"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Профиль HID"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ к Интернету"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернет-доступ"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Обмен контактами"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Использовать для обмена контактами"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Профиль PAN"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ к сообщениям"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ к SIM-карте"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Использовать аудио высокого качества: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Использовать аудио высокого качества"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -74,12 +90,12 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Использовать для аудиоустройства телефона"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Используется для передачи файлов"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Использовать для ввода"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Добавить"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ДОБАВИТЬ"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Подключить"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ПОДКЛЮЧИТЬ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Отмена"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Сопряжение обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает сопряжение."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi выключен"</string>
@@ -204,7 +220,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="adb_warning_title" msgid="6234463310896563253">"Разрешить отладку по USB?"</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>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Изменение настроек"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g> при текущем уровне использования"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Ещё <xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Осталось: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Осталось <xliff:g id="TIME">%1$s</xliff:g> при текущем уровне использования"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось примерно <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> (осталось примерно <xliff:g id="TIME">%2$s</xliff:g> при текущем уровне использования)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>, осталось: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролируется администратором"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Включено администратором"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Отключено администратором"</string>
-    <string name="disabled" msgid="9206776641295849915">"Отключено"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Разрешено"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Запрещено"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Установка неизвестных приложений"</string>
     <string name="home" msgid="3256884684164448244">"Настройки"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 582c248..54e1855 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"විකල්පමය කොඩෙක් සබල කරන්න"</item>
     <item msgid="3304843301758635896">"විකල්පමය කොඩෙක් අබල කරන්න"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"විකල්පමය කොඩෙක් සබල කරන්න"</item>
     <item msgid="741805482892725657">"විකල්පමය කොඩෙක් අබල කරන්න"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index a89af0a..5430b45 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"සම්බන්ධයි, අන්තර්ජාලය නැත"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"විසන්ධි වුණි"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"විසන්ධි වෙමින්…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"සම්බන්ධ වෙමින්…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"සම්බන්ධිතයි (පණිවිඩ ප්‍රවේශ නොමැත)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"සම්බන්ධිතයි (දුරකතනයක් හෝ මාධ්‍යයක් නැත)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"මාධ්‍ය ශ්‍රව්‍ය"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"දුරකථන ශ්‍රව්‍ය"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ගොනු හුවමාරුව"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ආදාන උපාංගය"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"අන්තර්ජාල ප්‍රවේශය"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"සම්බන්ධතා බෙදාගැනීම"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"සම්බන්ධතා බෙදාගැනීම සඳහා භාවිතා කිරීම"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"අන්තර්ජාල සම්බන්ධතා බෙදාගැනීම"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"පණිවිඩ ප්‍රවේශය"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ප්‍රවේශය"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ඉහළ ගුණත්වයේ ශ්‍රව්‍ය භාවිත කරන්න: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ඉහළ ගුණත්වයේ ශ්‍රව්‍ය භාවිත කරන්න"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්‍රියාකාරිත්වයට බලපෑ හැක."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"<xliff:g id="TIME">%1$s</xliff:g> පමණ ඉතිරියි"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">%1$s</xliff:g> පමණ ඉතිරිව ඇත"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"පූර්ණව ආරෝපණය වන තෙක් <xliff:g id="TIME">%1$s</xliff:g> ඉතිරියි"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"ඉතිරි <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">%1$s</xliff:g> ඉතිරිව ඇත"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>ක් පමණ ඇත"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඔබගේ භාවිතය මත පදනම්ව <xliff:g id="TIME">%2$s</xliff:g> පමණ ඉතිරිව ඇත"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - ඉතිරි <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"පරිපාලක විසින් සබල කර ඇත"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"ඔබගේ පරිපාලක විසින් අබල කර ඇත"</string>
-    <string name="disabled" msgid="9206776641295849915">"අබල කර ඇත"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"ඉඩ දුන්"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ඉඩ නොදෙන"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"නොදන්නා යෙදුම් ස්ථාපනය කරන්න"</string>
     <string name="home" msgid="3256884684164448244">"සැකසීම් මුල් පිටුව"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index b7ac435..7010c47 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Použiť voľbu systému (predvolené)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Povoliť voliteľné kodeky"</item>
     <item msgid="3304843301758635896">"Zakázať voliteľné kodeky"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Použiť voľbu systému (predvolené)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Povoliť voliteľné kodeky"</item>
     <item msgid="741805482892725657">"Zakázať voliteľné kodeky"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 89f0b1c..de17118 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Pripojené, žiadny internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Odpojený"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prebieha odpájanie..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Prebieha pripájanie…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvuk medií"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvuk telefónu"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos súborov"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vstupné zariadenie"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Prístup na Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Zdieľanie kontaktov"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Použiť na zdieľanie kontaktov"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Zdieľanie pripojenia na Internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Prístup ku správam"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Prístup k SIM karte"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Použiť zvuk s vysokou kvalitou: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Použiť zvuk s vysokou kvalitou"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Pripojené ku zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Pripojené ku zvuku telefónu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Pripojené na server pre prenos údajov"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Približný zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Zostáva približne <xliff:g id="TIME">%1$s</xliff:g> v závislosti od intenzity využitia"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zostávajúci čas: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Zostáva <xliff:g id="TIME">%1$s</xliff:g> v závislosti od intenzity využitia"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – približný zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g> v závislosti od intenzity využitia"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostávajúci čas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Ovládané správcom"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Povolené správcom"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Zakázané správcom"</string>
-    <string name="disabled" msgid="9206776641295849915">"Zakázané"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Povolené"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nie je povolené"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Inštalácia neznámych aplikácií"</string>
     <string name="home" msgid="3256884684164448244">"Domovská stránka nastavení"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 5ffdd17..e29727d 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Uporabi sistemsko izbiro (privzeto)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Omogoči izbirne kodeke"</item>
     <item msgid="3304843301758635896">"Onemogoči izbirne kodeke"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Uporabi sistemsko izbiro (privzeto)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Omogoči izbirne kodeke"</item>
     <item msgid="741805482892725657">"Onemogoči izbirne kodeke"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 6cc5904..563399a 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Vzpostavljena povezava, brez interneta"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Prekinjena povezava"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Prekinjanje povezave ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Vzpostavljanje povezave ..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Zvok predstavnosti"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Zvok telefona"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Vnosna naprava"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetni dostop"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Dajanje stikov v skupno rabo"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Uporabi za dajanje stikov v skupno rabo"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Skupna raba internetne povezave"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Dostop do sporočil"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostop do kartice SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Uporabi zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Uporabi zvok visoke kakovosti"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezan s profilom za predstavnostni zvok"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezava s profilom za zvok telefona vzpostavljena"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezava s strežnikom za prenos datotek je vzpostavljena"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Še <xliff:g id="TIME">%1$s</xliff:g> do polne napolnjenosti"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Še <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Glede na način uporabe imate na voljo še <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Nadzira skrbnik"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Omogočil skrbnik"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Onemogočil skrbnik"</string>
-    <string name="disabled" msgid="9206776641295849915">"Onemogočeno"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Dovoljene"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nedovoljene"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Nameščanje neznanih aplikacij"</string>
     <string name="home" msgid="3256884684164448244">"Začetna stran nastavitev"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 3db4250..4c22c32 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Aktivizo kodekët opsionalë"</item>
     <item msgid="3304843301758635896">"Çaktivizo kodekët opsionalë"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Aktivizo kodekët opsionalë"</item>
     <item msgid="741805482892725657">"Çaktivizo kodekët opsionalë"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 33fa56f..601ea6f 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"U lidh, nuk ka internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Shkëputur"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Po shkëputet..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Po lidhet..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audioja e klipit \"media\""</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audioja e telefonit"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferimi i skedarëve"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Pajisja e hyrjes"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Qasja në internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Ndarja e kontakteve"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Përdore për ndarjen e kontakteve"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ndarja e lidhjes së internetit"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Qasja në mesazhe"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Qasje në kartën SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Përdor audion me cilësi të lartë: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Përdor audion me cilësi të lartë"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"U lidh me audion e medias"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"U lidh me audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"U lidh me serverin e transferimit të skedarëve"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Rreth <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Rreth <xliff:g id="TIME">%1$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në ngarkimin e plotë"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kontrolluar nga administratori"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Aktivizuar nga administratori"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Çaktivizuar nga administratori"</string>
-    <string name="disabled" msgid="9206776641295849915">"Çaktivizuar"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Lejohet"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Nuk lejohet"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Instalo aplikacione të panjohura"</string>
     <string name="home" msgid="3256884684164448244">"Kreu i cilësimeve"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index ef1c9de..26ee6e5 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Користи избор система (подразумевано)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Омогући опционалне кодеке"</item>
     <item msgid="3304843301758635896">"Онемогући опционалне кодеке"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Користи избор система (подразумевано)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Омогући опционалне кодеке"</item>
     <item msgid="741805482892725657">"Онемогући опционалне кодеке"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e7dfc4c..ab6e099 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Веза је успостављена, нема интернета"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Веза је прекинута"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Прекидање везе..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Повезивање…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Повезано је (нема приступа порукама)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Повезано (без телефона или медија)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медија"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук телефона"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Пренос датотеке"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Улазни уређај"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Приступ Интернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Дељење контаката"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Користите за дељење контаката"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Дељење интернет везе"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Приступ порукама"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Приступ SIM картици"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Користи звук високог квалитета: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Користи звук високог квалитета"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на квалитет рада."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Још око <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"На основу потрошње имате још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> до потпуног пуњења"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Преостало време: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"На основу потрошње имате још <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – остало је око <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – на основу потрошње имате још отприлике <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"Преостало је <xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Контролише администратор"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Омогућио је администратор"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Администратор је онемогућио"</string>
-    <string name="disabled" msgid="9206776641295849915">"Онемогућено"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Дозвољено"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Није дозвољено"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Инсталирање непознатих апликација"</string>
     <string name="home" msgid="3256884684164448244">"Почетна за Подешавања"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 23bb797..2d62309 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Använd systemval (standardinställning)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Aktivera valfria kodekar"</item>
     <item msgid="3304843301758635896">"Inaktivera valfria kodekar"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Använd systemval (standardinställning)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Aktivera valfria kodekar"</item>
     <item msgid="741805482892725657">"Inaktivera valfria kodekar"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index e5fa8cb..bca8a0a 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ansluten, inget internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Kopplas ifrån"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Kopplar ifrån…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ansluter…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medialjud"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefonljud"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filöverföring"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Indataenhet"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetåtkomst"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktdelning"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Använd för kontaktdelning"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Delning av Internetanslutning"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Meddelandeåtkomst"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-åtkomst"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Använd högkvalitativt ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Använd högkvalitativt ljud"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ansluten till medialjud"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ansluten till telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ansluten till filöverföringsserver"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Cirka <xliff:g id="TIME">%1$s</xliff:g> återstår"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cirka <xliff:g id="TIME">%1$s</xliff:g> kvar utifrån din användning"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Batteriet är fulladdat om <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kvar"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> kvar utifrån din användning"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – cirka <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – cirka <xliff:g id="TIME">%2$s</xliff:g> kvar utifrån din användning"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills det är fulladdat"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Strys av administratören"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Aktiverad av administratör"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Inaktiverad av administratören"</string>
-    <string name="disabled" msgid="9206776641295849915">"Inaktiverad"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Tillåts"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Tillåts inte"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Installera okända appar"</string>
     <string name="home" msgid="3256884684164448244">"Startskärmen för inställningar"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0 %"</item>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index b5953a3..4045d63 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Washa Kodeki Zisizo za Lazima"</item>
     <item msgid="3304843301758635896">"Zima Kodeki Zisizo za Lazima"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Tumia Uteuzi wa Mfumo (Chaguo-msingi)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Washa Kodeki Zisizo za Lazima"</item>
     <item msgid="741805482892725657">"Zima Kodeki Zisizo za Lazima"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 7330572..780c84c 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Imeunganishwa, hakuna Intaneti"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Haijaunganishwa"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Inatenganisha..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Inaunganisha…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Sauti ya simu"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Uhamishaji wa faili"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Kifaa cha kuingiza"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ufikivu wa mtandao"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kushiriki anwani"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Tumia kwa kushiriki anwani"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Kushiriki muunganisho wa tovuti"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Ufikiaji wa Ujumbe"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Ufikiaji wa SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Tumia sauti ya ubora wa juu: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Tumia sauti ya ubora wa juu"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Imeunganishwa kwenye sikika ya njia ya mawasiliano"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Imeunganishwa kwenye sauti ya simu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Imeunganishwa kwenye seva ya kuhamisha faili"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji wa kifaa chako."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Takriban <xliff:g id="TIME">%1$s</xliff:g> zimesalia kulingana na matumizi yako"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Imebaki <xliff:g id="TIME">%1$s</xliff:g> chaji ijae"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> zimesalia kulingana na matumizi yako"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takribani <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - takriban <xliff:g id="TIME">%2$s</xliff:g> zimesalia kulingana na matumizi yako"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"Imechaji <xliff:g id="LEVEL">%1$s</xliff:g> - Zimesalia <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Imedhibitiwa na msimamizi"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Imewashwa na msimamizi"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Imezimwa na msimamizi"</string>
-    <string name="disabled" msgid="9206776641295849915">"Imezimwa"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Imeruhusiwa"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Hairuhusiwi"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Sakinisha programu ambazo hazijulikani"</string>
     <string name="home" msgid="3256884684164448244">"Ukurasa wa Kwanza wa Mipangilio"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 96c9122..33569c1 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"கட்டாயமில்லா கோடெக்குகளை இயக்கு"</item>
     <item msgid="3304843301758635896">"கட்டாயமில்லா கோடெக்குகளை முடக்கு"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"கட்டாயமில்லா கோடெக்குகளை இயக்கு"</item>
     <item msgid="741805482892725657">"கட்டாயமில்லா கோடெக்குகளை முடக்கு"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 454d43d..d3bb467 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"இணைக்கப்பட்டது, இணையம் இல்லை"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"தொடர்பு துண்டிக்கப்பட்டது"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"துண்டிக்கிறது..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"இணைக்கிறது..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"இணைக்கப்பட்டது (செய்திக்கான அணுகல் இல்லை)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"இணைக்கப்பட்டது (மொபைல் அல்லது மீடியாவுடன் அல்ல)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"மீடியா ஆடியோ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"மொபைல் ஆடியோ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"கோப்பு இடமாற்றம்"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"உள்ளீட்டுச் சாதனம்"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"இணைய அணுகல்"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"தொடர்புப் பகிர்தல்"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"தொடர்புப் பகிர்தலுக்குப் பயன்படுத்து"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"இணைய இணைப்பு பகிர்தல்"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"செய்திக்கான அணுகல்"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"சிம் அணுகல்"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"உயர்தர ஆடியோவைப் பயன்படுத்து: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"உயர்தர ஆடியோவைப் பயன்படுத்து"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"கிட்டத்தட்ட <xliff:g id="TIME">%1$s</xliff:g> உள்ளது"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - கிட்டத்தட்ட <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"நிர்வாகி இயக்கியுள்ளார்"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"நிர்வாகி முடக்கியுள்ளார்"</string>
-    <string name="disabled" msgid="9206776641295849915">"முடக்கப்பட்டது"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"அனுமதிக்கப்பட்டது"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"அனுமதிக்கப்படவில்லை"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"அறியப்படாத பயன்பாடுகளை நிறுவு"</string>
     <string name="home" msgid="3256884684164448244">"அமைப்புகள் முகப்பு"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index cc77139..428087d 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"ఐచ్ఛిక కోడెక్‌లను ప్రారంభించు"</item>
     <item msgid="3304843301758635896">"ఐచ్ఛిక కోడెక్‌లను నిలిపివేయి"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"ఐచ్ఛిక కోడెక్‌లను ప్రారంభించు"</item>
     <item msgid="741805482892725657">"ఐచ్ఛిక కోడెక్‌లను నిలిపివేయి"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 45c6cb8..2ee802a 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"కనెక్ట్ చేయబడింది, ఇంటర్నెట్ లేదు"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"డిస్‌కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"డిస్‌కనెక్ట్ చేస్తోంది..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"కనెక్ట్ చేస్తోంది..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"కనెక్ట్ చేయబడింది (సందేశ ప్రాప్యత లేదు)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"కనెక్ట్ చేయబడింది (ఫోన్ లేదా మీడియా కాకుండా)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"మీడియా ఆడియో"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"ఫోన్ ఆడియో"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ఫైల్ బదిలీ"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ఇన్‌పుట్ పరికరం"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ఇంటర్నెట్ ప్రాప్యత"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"పరిచయ భాగస్వామ్యం"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"పరిచయ భాగస్వామ్యం కోసం ఉపయోగించు"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ఇంటర్నెట్ కనెక్షన్ భాగస్వామ్యం"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"సందేశ ప్రాప్యత"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ప్రాప్యత"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"అధిక నాణ్యత ఆడియోను ఉపయోగించండి: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"అధిక నాణ్యత ఆడియోను ఉపయోగించండి"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"మిగిలి ఉన్న సమయం, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"మీ వినియోగం ఆధారంగా సుమారు <xliff:g id="TIME">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"పూర్తిగా ఛార్జ్ కావడానికి <xliff:g id="TIME">%1$s</xliff:g> పడుతుంది"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"మీ వినియోగం ఆధారంగా <xliff:g id="TIME">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - మీ వినియోగం ఆధారంగా సుమారు <xliff:g id="TIME">%2$s</xliff:g> సమయం మిగిలి ఉంది"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"నిర్వాహకులు ప్రారంభించారు"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"నిర్వాహకులు నిలిపివేసారు"</string>
-    <string name="disabled" msgid="9206776641295849915">"నిలిపివేయబడింది"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"అనుమతించినవి"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"అనుమతించబడలేదు"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"తెలియని అనువర్తనాలను ఇన్‌స్టాల్ చేయండి"</string>
     <string name="home" msgid="3256884684164448244">"సెట్టింగ్‌ల హోమ్"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index d46fc7d..389d593 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"เปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
     <item msgid="3304843301758635896">"ปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"ใช้การเลือกระบบ (ค่าเริ่มต้น)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"เปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
     <item msgid="741805482892725657">"ปิดใช้ตัวแปลงรหัสที่ไม่บังคับ"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index d31ca04..f5223e1 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"เชื่อมต่อแล้ว ไม่พบอินเทอร์เน็ต"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"ตัดการเชื่อมต่อ"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"กำลังตัดการเชื่อมต่อ..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"กำลังเชื่อมต่อ…"</string>
@@ -46,18 +58,22 @@
     <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>
-    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงของสื่อ"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"เสียงโทรศัพท์"</string>
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"เสียงสื่อ"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"การถ่ายโอนไฟล์"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"อุปกรณ์อินพุต"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"การเข้าถึงอินเทอร์เน็ต"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"การแชร์รายชื่อผู้ติดต่อ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ใช้สำหรับการแชร์รายชื่อผู้ติดต่อ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"การเข้าถึงข้อความ"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"การเข้าถึงซิม"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"ใช้เสียงคุณภาพสูง: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"ใช้เสียงคุณภาพสูง"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ฟีเจอร์นี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"อีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"เหลืออีกราว <xliff:g id="TIME">%1$s</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะชาร์จเต็ม"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"เหลืออีก <xliff:g id="TIME">%1$s</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือเวลาประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีกราว <xliff:g id="TIME">%2$s</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลืออีก <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"เปิดใช้โดยผู้ดูแลระบบ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"ปิดใช้โดยผู้ดูแลระบบ"</string>
-    <string name="disabled" msgid="9206776641295849915">"ปิดอยู่"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"อนุญาต"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"ไม่อนุญาต"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"ติดตั้งแอปที่ไม่รู้จัก"</string>
     <string name="home" msgid="3256884684164448244">"หน้าแรกของการตั้งค่า"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 2a82ab6..8375e3a 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Gamitin ang Pagpili ng System (Default)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"I-enable ang Mga Opsyonal na Codec"</item>
     <item msgid="3304843301758635896">"I-disable ang Mga Opsyonal na Codec"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Gamitin ang Pagpili ng System (Default)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"I-enable ang Mga Opsyonal na Codec"</item>
     <item msgid="741805482892725657">"I-disable ang Mga Opsyonal na Codec"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index a2e625c..96388de 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Nakakonekta, walang Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Hindi nakakonekta"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Nadidiskonekta..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Kumukonekta…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Audio ng media"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Audio ng telepono"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Paglilipat ng file"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Device sa pag-input"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Access sa internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Pagbabahagi ng contact"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Gamitin para sa pagbabahagi ng contact"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Pagbabahagi ng koneksyon sa internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Access sa Mensahe"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Access sa SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Gumamit ng mataas na kalidad na audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Gumamit ng mataas na kalidad na audio"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Konektado sa media audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Nakakonekta sa audio ng telepono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Nakakonekta sa server sa paglilipat ng file"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> ang natitira"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> ang natitira batay sa iyong paggamit"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira bago makumpleto ang charge"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> pa"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira batay sa iyong paggamit"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit-kumulang <xliff:g id="TIME">%2$s</xliff:g> pa ang natitira"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit-kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira batay sa iyong paggamit"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> pa"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa makumpleto ang charge"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Pinapamahalaan ng admin"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Na-enable ng admin"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Na-disable ng admin"</string>
-    <string name="disabled" msgid="9206776641295849915">"Naka-disable"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Pinapayagan"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Hindi pinapayagan"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Mag-install ng mga hindi alam na app"</string>
     <string name="home" msgid="3256884684164448244">"Home ng Mga Setting"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index bb43ec7..96c5738 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Sistem Seçimini Kullan (Varsayılan)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"İsteğe Bağlı Codec\'leri Etkinleştir"</item>
     <item msgid="3304843301758635896">"İsteğe Bağlı Codec\'leri Devre Dışı Bırak"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Sistem Seçimini Kullan (Varsayılan)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"İsteğe Bağlı Codec\'leri Etkinleştir"</item>
     <item msgid="741805482892725657">"İsteğe Bağlı Codec\'leri Devre Dışı Bırak"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 5316357..b8a5dab 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -37,27 +37,43 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Bağlı, İnternet yok"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Bağlantı kesildi"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Bağlantı kesiliyor…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Bağlanıyor…"</string>
     <string name="bluetooth_connected" msgid="6038755206916626419">"Bağlandı"</string>
-    <string name="bluetooth_pairing" msgid="1426882272690346242">"Eşleniyor…"</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"Eşleştiriliyor…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Bağlandı (telefon yok)"</string>
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medya sesi"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon sesi"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dosya aktarımı"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Giriş cihazı"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"İnternet erişimi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kişi paylaşma"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kişi paylaşmak için kullan"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"İnternet bağlantısı paylaşımı"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Mesaj Erişimi"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Erişimi"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yüksek kalite ses kullan: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yüksek kalite ses kullan"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Medya sesine bağlanıldı"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon sesine bağlandı"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Dosya aktarım sunucusuna bağlandı"</string>
@@ -74,14 +90,14 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Telefon sesi için kullan"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Dosya aktarımı için kullan"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Giriş için kullan"</string>
-    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşle"</string>
-    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLE"</string>
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşleştir"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLEŞTİR"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"İptal"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Eşleme işlemi, bağlantı kurulduğunda kişilerinize ve çağrı geçmişine erişim izni verir."</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşlenemedi."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN veya parola yanlış olduğundan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşlenemedi"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşleştirilemedi."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN veya parola yanlış olduğundan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşleştirilemedi"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile iletişim kurulamıyor."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Eşleme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tarafından reddedildi."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Eşleştirme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tarafından reddedildi."</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"Kablosuz kapalı."</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Kablosuz bağlantı kesildi."</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Kablosuz sinyal gücü tek çubuk."</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam olarak şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Kullanımınıza dayalı olarak <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Yönetici tarafından denetleniyor"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Yönetici tarafından etkinleştirildi"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Yönetici devre dışı bıraktı"</string>
-    <string name="disabled" msgid="9206776641295849915">"Devre dışı"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"İzin verildi"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"İzin verilmiyor"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Bilinmeyen uygulamaları yükle"</string>
     <string name="home" msgid="3256884684164448244">"Ayarlar Ana Sayfası"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"%0"</item>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index a8705e7..85d5291 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Використовувати вибір системи (за умовчанням)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Увімкнути додаткові кодеки"</item>
     <item msgid="3304843301758635896">"Вимкнути додаткові кодеки"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Використовувати вибір системи (за умовчанням)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Увімкнути додаткові кодеки"</item>
     <item msgid="741805482892725657">"Вимкнути додаткові кодеки"</item>
@@ -138,25 +138,25 @@
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Вимкнено"</item>
-    <item msgid="1593289376502312923">"64 КБ"</item>
-    <item msgid="487545340236145324">"256 КБ"</item>
-    <item msgid="2423528675294333831">"1 МБ"</item>
-    <item msgid="180883774509476541">"4 МБ"</item>
-    <item msgid="2803199102589126938">"16 МБ"</item>
+    <item msgid="1593289376502312923">"64 Кб"</item>
+    <item msgid="487545340236145324">"256 Кб"</item>
+    <item msgid="2423528675294333831">"1 Мб"</item>
+    <item msgid="180883774509476541">"4 Мб"</item>
+    <item msgid="2803199102589126938">"16 Мб"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
     <item msgid="6089470720451068364">"Вимкнено"</item>
-    <item msgid="4622460333038586791">"64 КБ"</item>
-    <item msgid="2212125625169582330">"256 КБ"</item>
-    <item msgid="1704946766699242653">"1 МБ"</item>
+    <item msgid="4622460333038586791">"64 Кб"</item>
+    <item msgid="2212125625169582330">"256 Кб"</item>
+    <item msgid="1704946766699242653">"1 Мб"</item>
   </string-array>
   <string-array name="select_logd_size_summaries">
     <item msgid="6921048829791179331">"Вимкнено"</item>
-    <item msgid="2969458029344750262">"Буфер журналу: 64 КБ"</item>
-    <item msgid="1342285115665698168">"Буфер журналу: 256 КБ"</item>
-    <item msgid="1314234299552254621">"Буфер журналу: 1 МБ"</item>
-    <item msgid="3606047780792894151">"Буфер журналу: 4 МБ"</item>
-    <item msgid="5431354956856655120">"Буфер журналу: 16 МБ"</item>
+    <item msgid="2969458029344750262">"Буфер журналу: 64 Кб"</item>
+    <item msgid="1342285115665698168">"Буфер журналу: 256 Кб"</item>
+    <item msgid="1314234299552254621">"Буфер журналу: 1 Мб"</item>
+    <item msgid="3606047780792894151">"Буфер журналу: 4 Мб"</item>
+    <item msgid="5431354956856655120">"Буфер журналу: 16 Мб"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="1744840221860799971">"Вимкнено"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5b0a6c0..0f8affd 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Під’єднано, але немає доступу до Інтернету"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Роз’єднано"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Відключення..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Підключення…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Під’єднано (без доступу до повідомлень)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Під’єднано (без телефону чи медіа)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Звук медіа-файлів"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Звук телефону"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Передавання файлів"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Пристрій введення"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Доступ до Інтернету"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Надсилання контактів"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Використовувати для надсилання контактів"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Надання доступу до Інтернету"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Доступ до повідомлень"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ до SIM-карти"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Використовувати аудіо високої якості: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Використовувати аудіо високої якості"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -91,11 +107,11 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"ОС Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Видалені програми"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Видалені програми та користувачі"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB-модем"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Прив\'язка USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Порт. точка дост."</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth-модем"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Прив\'язка Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Прив\'язка"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Точка доступу й модем"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Режим модема"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Усі робочі додатки"</string>
     <string name="user_guest" msgid="8475274842845401871">"Гість"</string>
     <string name="unknown" msgid="1592123443519355854">"Невідомо"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Залишилося близько <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"На основі використання залишилося близько <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"До повного зарядження залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"На основі використання залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – ще <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> – на основі використання залишилося близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилося <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Керується адміністратором"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Увімкнено адміністратором"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Вимкнено адміністратором"</string>
-    <string name="disabled" msgid="9206776641295849915">"Вимкнено"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Дозволено"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Заборонено"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Установлювати невідомі додатки"</string>
     <string name="home" msgid="3256884684164448244">"Головний екран налаштувань"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 6da98dc..c0f7411 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"اختیاری کوڈیکز کو فعال کریں"</item>
     <item msgid="3304843301758635896">"اختیاری کوڈیکز کو غیر فعال کریں"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"اختیاری کوڈیکز کو فعال کریں"</item>
     <item msgid="741805482892725657">"اختیاری کوڈیکز کو غیر فعال کریں"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index c683995..f6771dc 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"‏منسلک بذریعہ ‎%1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"‏دستیاب بذریعہ ‎%1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"منسلک، انٹرنیٹ نہیں ہے"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"منقطع"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"منقطع کیا جارہا ہے…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"مربوط ہو رہا ہے…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"مربوط (کسی پیغام تک رسائی نہیں ہے)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"مربوط (کوئی فون یا میڈیا نہیں ہے)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"میڈيا آڈیو"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"فون آڈیو"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"فائل کی منتقلی"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ان پٹ آلہ"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"انٹرنیٹ تک رسائی"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"رابطہ کا اشتراک"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"رابطہ کے اشتراک کیلئے استعمال کریں"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"انٹرنیٹ کنکشن کا اشتراک کرنا"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"پیغام تک رسائی"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏SIM رسائی"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"اعلی معیار کی آڈیو استعمال کریں: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"اعلی معیار کی آڈیو استعمال کریں"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"تقریبًا <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"پوری طرح چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"آپ کے استعمال کی بنیاد پر <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
     <string name="power_charging" msgid="1779532561355864267">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پوری طرح چارج ہونے تک"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"کنٹرول کردہ بذریعہ منتظم"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"منتظم کی طرف سے فعال کردہ"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"منتظم کی طرف سے غیر فعال کردہ"</string>
-    <string name="disabled" msgid="9206776641295849915">"غیر فعال"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"اجازت ہے"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"اجازت نہیں ہے"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"نامعلوم ایپس انسٹال کریں"</string>
     <string name="home" msgid="3256884684164448244">"ترتیبات ہوم"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 1d4e1e9..4468f75 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Tizim tanlovi (birlamchi)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Boshqa kodeklarni yoqish"</item>
     <item msgid="3304843301758635896">"Boshqa kodeklarni o‘chirib qo‘yish"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Tizim tanlovi (birlamchi)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Boshqa kodeklarni yoqish"</item>
     <item msgid="741805482892725657">"Boshqa kodeklarni o‘chirib qo‘yish"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index ed62041..8a61cc45 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Ulangan, lekin internet aloqasi yo‘q"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Uzildi"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Uzilyapti…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Ulanmoqda…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Telefon audiosi"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Fayl o‘tkazish"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Kiritish qurilmasi"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetga kirish"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Kontaktlarni ulashish"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Kontaktlarni ulashish uchun ishlatilsin"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet aloqasi ulashmasi"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Xabarga kirish"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kartaga kirish"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Yuqori sifatli audiodan foydalanish: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Yuqori sifatli audiodan foydalanish"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Audio qurilmasiga ulangan"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon karnayiga ulanildi"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Fayl almashinish serveriga ulanildi"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Joriy holatda taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Joriy holatda <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> (joriy holatda taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida to‘ladi"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Administrator tomonidan boshqariladi"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Administrator tomonidan yoqilgan"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Administrator tomonidan o‘chirilgan"</string>
-    <string name="disabled" msgid="9206776641295849915">"O‘chiq"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Ruxsat berilgan"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Ruxsat berilmagan"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Notanish ilovalarni o‘rnatish"</string>
     <string name="home" msgid="3256884684164448244">"Sozlamalar"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 134dc8b..3e6cc8f 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"Bật codec tùy chọn"</item>
     <item msgid="3304843301758635896">"Tắt codec tùy chọn"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Sử dụng lựa chọn hệ thống (Mặc định)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"Bật codec tùy chọn"</item>
     <item msgid="741805482892725657">"Tắt codec tùy chọn"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index c91e89c..7dd93c6 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Đã kết nối, không có Internet"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Đã ngắt kết nối"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Đang ngắt kết nối…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Đang kết nối…"</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Âm thanh của phương tiện"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Âm thanh điện thoại"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Chuyển tệp"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Thiết bị đầu vào"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Truy cập Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Chia sẻ liên hệ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Sử dụng để chia sẻ liên hệ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Chia sẻ kết nối internet"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Truy cập tin nhắn"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Quyền truy cập SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Sử dụng âm thanh chất lượng cao: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Sử dụng âm thanh chất lượng cao"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Đã kết nối với âm thanh phương tiện"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Đã kết nối với âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Đã kết nối với máy chủ chuyển tệp"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Còn <xliff:g id="TIME">%1$s</xliff:g> cho tới khi được sạc đầy"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Còn lại <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"Còn <xliff:g id="TIME">%1$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn lại <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Do quản trị viên kiểm soát"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Kích hoạt bởi quản trị viên"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Bị quản trị viên vô hiệu hóa"</string>
-    <string name="disabled" msgid="9206776641295849915">"Đã tắt"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Được phép"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Không được phép"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"C.đặt ư.dụng ko xác định"</string>
     <string name="home" msgid="3256884684164448244">"Trang chủ cài đặt"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index fadc7a9..17a55a6 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"使用系统选择(默认)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"启用可选编解码器"</item>
     <item msgid="3304843301758635896">"停用可选编解码器"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"使用系统选择(默认)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"启用可选编解码器"</item>
     <item msgid="741805482892725657">"停用可选编解码器"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 10a077b..7a932d9 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已连接,但无法访问互联网"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已断开连接"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在断开连接..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"正在连接..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已连接(无消息权限)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已连接(没有手机或媒体信号)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒体音频"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手机音频"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"文件传输"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"输入设备"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"互联网连接"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"共享联系人"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用于共享联系人"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"共享互联网连接"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"消息权限"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取权限"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用高品质音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用高品质音频"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -101,7 +117,7 @@
     <string name="unknown" msgid="1592123443519355854">"未知"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"用户:<xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"已设置部分默认选项"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"没有默认操作"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"未设置任何默认选项"</string>
     <string name="tts_settings" msgid="8186971894801348327">"文字转语音设置"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"文字转语音 (TTS) 输出"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"语速"</string>
@@ -151,9 +167,9 @@
     <string name="vpn_settings_not_available" msgid="956841430176985598">"此用户无权修改VPN设置"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"此用户无权修改网络共享设置"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"此用户无权修改接入点名称设置"</string>
-    <string name="enable_adb" msgid="7982306934419797485">"USB 调试"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"USB调试"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"连接USB后启用调试模式"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"撤消 USB 调试授权"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"撤消USB调试授权"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"错误报告快捷方式"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"在电源菜单中显示用于提交错误报告的按钮"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"不锁定屏幕"</string>
@@ -204,9 +220,9 @@
     <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="adb_warning_title" msgid="6234463310896563253">"是否允许 USB 调试?"</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>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"是否针对您之前授权的所有计算机撤消USB调试的访问权限?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"允许开发设置?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"这些设置仅适用于开发工作。一旦启用,会导致您的设备以及设备上的应用崩溃或出现异常。"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"通过USB验证应用"</string>
@@ -223,7 +239,7 @@
     <string name="debug_app_set" msgid="2063077997870280017">"调试应用:<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="select_application" msgid="5156029161289091703">"选择应用"</string>
     <string name="no_application" msgid="2813387563129153880">"无"</string>
-    <string name="wait_for_debugger" msgid="1202370874528893091">"等待调试程序"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"等待调试器"</string>
     <string name="wait_for_debugger_summary" msgid="1766918303462746804">"调试应用会在执行前等待附加调试器"</string>
     <string name="telephony_monitor_switch" msgid="1764958220062121194">"电话监控器"</string>
     <string name="telephony_monitor_switch_summary" msgid="7695552966547975635">"电话监控器会在检测到电话/调制解调器功能存在问题时收集相关日志,并向用户发出通知,提醒用户提交错误报告"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"这是实验性功能,性能可能不稳定。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根据您的使用情况,大约还可使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"还需 <xliff:g id="TIME">%1$s</xliff:g>充满电"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"还可用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根据您的使用情况,大约还可使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大约还剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - 根据您的使用情况,大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"由管理员控制"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"已被管理员启用"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"已被管理员停用"</string>
-    <string name="disabled" msgid="9206776641295849915">"已停用"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"允许"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"不允许"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"安装未知应用"</string>
     <string name="home" msgid="3256884684164448244">"设置主屏幕"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 7f4c427..ef66b3f 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"啟用選用的編解碼器"</item>
     <item msgid="3304843301758635896">"停用選用的編解碼器"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"使用系統選擇 (預設)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"啟用選用的編解碼器"</item>
     <item msgid="741805482892725657">"停用選用的編解碼器"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index accfb3f..28d5bf9 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有互聯網"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在中斷連線..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"正在連線..."</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連結 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音效"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手機音效"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"互聯網連線"</string>
-    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"共用聯絡人"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用於共用聯絡人"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"聯絡人共用"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用於聯絡人共用"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"互聯網連線分享"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"訊息存取權"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用優質音訊編解碼器:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用優質音訊編解碼器"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是實驗性功能,效能尚待改善。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根據您的使用情況,剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g>後就能充滿電"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"尚餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根據您的使用情況,剩餘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - 根據您的使用情況,剩餘約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能充滿電"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"已由管理員停用"</string>
-    <string name="disabled" msgid="9206776641295849915">"已停用"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"允許"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"不允許"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"安裝不明的應用程式"</string>
     <string name="home" msgid="3256884684164448244">"主設定畫面"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 0f3bf23..ced1a51 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"使用系統選擇 (預設)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"LDAC"</item>
     <item msgid="723675059572222462">"啟用選用的轉碼器"</item>
     <item msgid="3304843301758635896">"停用選用的轉碼器"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"使用系統選擇 (預設)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"LDAC"</item>
     <item msgid="2209680154067241740">"啟用選用的轉碼器"</item>
     <item msgid="741805482892725657">"停用選用的轉碼器"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 9a0b1bf..d839cf4 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"已連線,沒有網際網路"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已中斷連線"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在中斷連線…"</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"連線中…"</string>
@@ -47,17 +59,21 @@
     <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"已連線 (無訊息存取權)"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"已連線 (無手機或媒體音訊)"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"媒體音訊"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"手機音訊"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"檔案傳輸"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"輸入裝置"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"網際網路連線"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"聯絡人共用"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"用於聯絡人共用"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"網際網路連線分享"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"訊息存取權"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取權"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"使用高品質音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"使用高品質音訊"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <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>
@@ -79,7 +95,7 @@
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"配對完成後,所配對的裝置即可在連線後存取你的聯絡人和通話紀錄。"</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對。"</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對,因為 PIN 碼或密碼金鑰不正確。"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對,因為 PIN 或密碼金鑰不正確。"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 通訊。"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」拒絕配對要求。"</string>
     <string name="accessibility_wifi_off" msgid="1166761729660614716">"已關閉 Wi-Fi。"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"還有大約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"根據你的使用情形,剩餘時間大約還有 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"再過 <xliff:g id="TIME">%1$s</xliff:g>就能完成充電"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"還剩 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"根據你的使用情形,剩餘時間還有 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - 約剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - 根據你的使用情形,剩餘時間大約還有 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"已由管理員停用"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"已由管理員啟用"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"已由管理員停用"</string>
-    <string name="disabled" msgid="9206776641295849915">"已停用"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"允許"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"不允許"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"安裝不明應用程式"</string>
     <string name="home" msgid="3256884684164448244">"設定主畫面"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index d7449f1..06a23f6 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -72,8 +72,8 @@
     <item msgid="7065842274271279580">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"I-AAC"</item>
-    <item msgid="8910200421843557332">"aptX"</item>
-    <item msgid="8434403964359457768">"aptX HD"</item>
+    <item msgid="8910200421843557332">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="8434403964359457768">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="6751080638867012696">"I-LDAC"</item>
     <item msgid="723675059572222462">"Nika amandla amakhodekhi akhethekayo"</item>
     <item msgid="3304843301758635896">"Khubaza amakhodekhi akhethekayo"</item>
@@ -82,8 +82,8 @@
     <item msgid="5062108632402595000">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"I-AAC"</item>
-    <item msgid="2279916056363477395">"aptX"</item>
-    <item msgid="6641171061200063516">"aptX HD"</item>
+    <item msgid="2279916056363477395">"<xliff:g id="APTX">Qualcomm(R) aptX(TM) audio</xliff:g>"</item>
+    <item msgid="6641171061200063516">"<xliff:g id="APTX_HD">Qualcomm(R) aptX(TM) HD audio</xliff:g>"</item>
     <item msgid="7950781694447359344">"I-LDAC"</item>
     <item msgid="2209680154067241740">"Nika amandla amakhodekhi akhethekayo"</item>
     <item msgid="741805482892725657">"Khubaza amakhodekhi akhethekayo"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index bdd4bf2..15fbbc5 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -37,6 +37,18 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Kuxhumekile, ayikho i-inthanethi"</string>
+    <!-- no translation found for speed_label_very_slow (1867055264243608530) -->
+    <skip />
+    <!-- no translation found for speed_label_slow (813109590815810235) -->
+    <skip />
+    <!-- no translation found for speed_label_okay (5941436233638654215) -->
+    <skip />
+    <!-- no translation found for speed_label_medium (3175763313268941953) -->
+    <skip />
+    <!-- no translation found for speed_label_fast (7715732164050975057) -->
+    <skip />
+    <!-- no translation found for speed_label_very_fast (2265363430784523409) -->
+    <skip />
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ayixhunyiwe"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Inqamula uxhumano kwi-inthanethi..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Iyaxhuma..."</string>
@@ -47,17 +59,21 @@
     <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>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Umsindo wemidiya"</string>
-    <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Umsindo wefoni"</string>
+    <!-- no translation found for bluetooth_profile_headset (7815495680863246034) -->
+    <skip />
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Dlulisa ifayela"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Idivaysi yokufakwayo"</string>
     <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Ukufinyelela i-Inthanethi"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Ukwabelana kokuxhumana"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Sebenzisela ukwabelana kokuxhumana"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Ukwabelana ngoxhumano lwe-Inthanethi"</string>
-    <string name="bluetooth_profile_map" msgid="5465271250454324383">"Ukufinyelela umlayezo"</string>
+    <!-- no translation found for bluetooth_profile_map (1019763341565580450) -->
+    <skip />
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Ukufinyelela kwe-SIM"</string>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Sebenzisa umsindo wekhwalithi ephezulu: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Sebenzisa umsindo wekhwalithi ephezulu"</string>
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality (5444517801472820055) -->
+    <skip />
+    <!-- no translation found for bluetooth_profile_a2dp_high_quality_unknown_codec (8510588052415438887) -->
+    <skip />
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ixhume emsindweni wemidiya"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ixhunywe kumsindo wefoni"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ixhunywe kwiseva yokudlulisa ifayela"</string>
@@ -321,9 +337,12 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Cishe u-<xliff:g id="TIME">%1$s</xliff:g> osele"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"Cishe kusele okungu-<xliff:g id="TIME">%1$s</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kushiywe ishaja"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> esisele"</string>
+    <string name="power_remaining_duration_only_short_enhanced" msgid="7450425624026394823">"<xliff:g id="TIME">%1$s</xliff:g> esele kusukela ekusetshenzisweni kwakho"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - cishe ngu-<xliff:g id="TIME">%2$s</xliff:g> osele"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - cishe ngu-<xliff:g id="TIME">%2$s</xliff:g> osele kusukela ekusetshenzisweni kwakho"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele"</string>
@@ -337,10 +356,6 @@
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Kulawulwa umqondisi"</string>
     <string name="enabled_by_admin" msgid="5302986023578399263">"Kunikwe amandla umlawuli"</string>
     <string name="disabled_by_admin" msgid="8505398946020816620">"Kukhutshazwe umlawuli"</string>
-    <string name="disabled" msgid="9206776641295849915">"Akusebenzi"</string>
-    <string name="external_source_trusted" msgid="2707996266575928037">"Kuvumelekile"</string>
-    <string name="external_source_untrusted" msgid="2677442511837596726">"Akuvumelekile"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"Faka izinhlelo zokusebenza ezingaziwa"</string>
     <string name="home" msgid="3256884684164448244">"Ikhaya lezilungiselelo"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index d90665a..9704bd6 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -123,8 +123,8 @@
         <item>Use System Selection (Default)</item>
         <item>SBC</item>
         <item>AAC</item>
-        <item>aptX</item>
-        <item>aptX HD</item>
+        <item><xliff:g id="aptx">Qualcomm(R) aptX(TM) audio</xliff:g></item>
+        <item><xliff:g id="aptx_hd">Qualcomm(R) aptX(TM) HD audio</xliff:g></item>
         <item>LDAC</item>
         <item>Enable Optional Codecs</item>
         <item>Disable Optional Codecs</item>
@@ -147,8 +147,8 @@
         <item>Use System Selection (Default)</item>
         <item>SBC</item>
         <item>AAC</item>
-        <item>aptX</item>
-        <item>aptX HD</item>
+        <item><xliff:g id="aptx">Qualcomm(R) aptX(TM) audio</xliff:g></item>
+        <item><xliff:g id="aptx_hd">Qualcomm(R) aptX(TM) HD audio</xliff:g></item>
         <item>LDAC</item>
         <item>Enable Optional Codecs</item>
         <item>Disable Optional Codecs</item>
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index ea538fb..6d852df 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -46,12 +46,11 @@
     <attr name="wifi_signal" format="reference" />
     <attr name="wifi_friction" format="reference" />
 
-    <declare-styleable name="UsageView">
-        <attr name="android:colorAccent" />
-        <attr name="sideLabels" format="reference" />
-        <attr name="bottomLabels" format="reference" />
-        <attr name="textColor" format="color" />
-        <attr name="android:gravity" />
+    <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/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 8f7a3dd..064cc84 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -64,6 +64,14 @@
     <!-- Status for networks disabled from authentication failure (wrong password
          or certificate). -->
     <string name="wifi_disabled_password_failure">Authentication problem</string>
+
+    <!-- Status detail for a network that can't be connected to for some reason -->
+    <string name="wifi_cant_connect">Can\'t connect</string>
+    <!-- Status for a named network that can't be connected to for some reason-->
+    <string name="wifi_cant_connect_to_ap">Can\'t connect to \'<xliff:g id="ap_name">%1$s</xliff:g>\'</string>
+    <!-- Message shown when the user likely entered an incorrect password for a wifi network -->
+    <string name="wifi_check_password_try_again">Check password and try again</string>
+
     <!-- Summary for the remembered network but currently not in range. -->
     <string name="wifi_not_in_range">Not in range</string>
     <!-- Summary for the network but no internet connection was detected. -->
@@ -89,6 +97,19 @@
     <!-- Summary for Connected wifi network without internet -->
     <string name="wifi_connected_no_internet">Connected, no Internet</string>
 
+    <!-- Speed label for very slow network speed -->
+    <string name="speed_label_very_slow">Very Slow</string>
+    <!-- Speed label for slow network speed -->
+    <string name="speed_label_slow">Slow</string>
+    <!-- Speed label for okay network speed -->
+    <string name="speed_label_okay">OK</string>
+    <!-- Speed label for medium network speed -->
+    <string name="speed_label_medium">Medium</string>
+    <!-- Speed label for fast network speed -->
+    <string name="speed_label_fast">Fast</string>
+    <!-- Speed label for very fast network speed -->
+    <string name="speed_label_very_fast">Very Fast</string>
+
     <!-- Bluetooth settings.  Message when a device is disconnected -->
     <string name="bluetooth_disconnected">Disconnected</string>
     <!-- Bluetooth settings.  Message when disconnecting from a device -->
@@ -109,10 +130,19 @@
     <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio. [CHAR LIMIT=40] -->
     <string name="bluetooth_connected_no_headset_no_a2dp">Connected (no phone or media)</string>
 
+    <!-- Bluetooth settings.  Message when connected to a device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_battery_level">Connected (no phone), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_a2dp_battery_level">Connected (no media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+    <!-- Bluetooth settings.  Message when connected to a device, except for phone/media audio, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_connected_no_headset_no_a2dp_battery_level">Connected (no phone or media), battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
+
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the A2DP profile. -->
     <string name="bluetooth_profile_a2dp">Media audio</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the headset or handsfree profile. -->
-    <string name="bluetooth_profile_headset">Phone audio</string>
+    <string name="bluetooth_profile_headset">Phone calls</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the OPP profile. -->
     <string name="bluetooth_profile_opp">File transfer</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the HID profile. -->
@@ -126,15 +156,15 @@
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the PAN profile (sharing this device's Internet connection). [CHAR LIMIT=40] -->
     <string name="bluetooth_profile_pan_nap">Internet connection sharing</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the map profile. -->
-    <string name="bluetooth_profile_map">Message Access</string>
+    <string name="bluetooth_profile_map">Text Messages</string>
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the SAP profile (sharing SIM card). -->
     <string name="bluetooth_profile_sap">SIM Access</string>
 
     <!-- Bluetooth settings. The user-visible string for the setting controlling whether to use a high-quality codec if the device supports it, along with the name of the codec (eg AAC, LDAC, aptX) -->
-    <string name="bluetooth_profile_a2dp_high_quality">Use high quality audio: <xliff:g id="codec_name">%1$s</xliff:g></string>
+    <string name="bluetooth_profile_a2dp_high_quality">HD audio: <xliff:g id="codec_name">%1$s</xliff:g></string>
 
     <!-- Bluetooth settings. Similar to bluetooth_profile_a2dp_high_quality, but used when the device supports high quality audio but we don't know which codec that will be used. -->
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec">Use high quality audio</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec">HD audio</string>
 
     <!-- Bluetooth settings.  Connection options screen.  The summary for the A2DP checkbox preference when A2DP is connected. -->
     <string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
@@ -435,6 +465,8 @@
     <string name="wifi_allow_scan_with_traffic">Always allow Wi\u2011Fi Roam Scans</string>
     <!-- Setting Checkbox title whether to always keep mobile data active. [CHAR LIMIT=80] -->
     <string name="mobile_data_always_on">Mobile data always active</string>
+    <!-- Setting Checkbox title whether to enable hardware acceleration for tethering. [CHAR LIMIT=80] -->
+    <string name="tethering_hardware_offload">Tethering hardware acceleration</string>
     <!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
     <string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
     <!-- Setting Checkbox title for enabling Bluetooth inband ringing -->
@@ -504,6 +536,7 @@
     <!-- Setting Checkbox title whether to enable view attribute inspection -->
     <string name="debug_view_attributes">Enable view attribute inspection</string>
     <string name="mobile_data_always_on_summary">Always keep mobile data active, even when Wi\u2011Fi is active (for fast network switching).</string>
+    <string name="tethering_hardware_offload_summary">Use tethering hardware acceleration if available</string>
     <!-- Title of warning dialog about the implications of enabling USB debugging -->
     <string name="adb_warning_title">Allow USB debugging?</string>
     <!-- Warning text to user about the implications of enabling USB debugging -->
@@ -794,30 +827,31 @@
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
     <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
-    <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
+    <string name="power_remaining_duration_only">About <xliff:g id="time">^1</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
+    <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">^1</xliff:g> left based on your usage</string>
     <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
-    <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
+    <string name="power_remaining_charging_duration_only"><xliff:g id="time">^1</xliff:g> left until fully charged</string>
 
     <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
-    <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
+    <string name="power_remaining_duration_only_short"><xliff:g id="time">^1</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Short label for estimated remaining duration of battery charging/discharging -->
+    <string name="power_remaining_duration_only_short_enhanced"><xliff:g id="time">^1</xliff:g> left based on your usage</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
-    <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g>
-        - about <xliff:g id="time">%2$s</xliff:g> left</string>
+    <string name="power_discharging_duration"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
+    <string name="power_discharging_duration_enhanced"><xliff:g id="level">^1</xliff:g> - about <xliff:g id="time">^2</xliff:g> left based on your usage</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
-    <string name="power_discharging_duration_short"><xliff:g id="level">%1$s</xliff:g>
-        - <xliff:g id="time">%2$s</xliff:g> left</string>
+    <string name="power_discharging_duration_short"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> left</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
-    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> -
-            <xliff:g id="state">%2$s</xliff:g></string>
+    <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
-    <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> -
-            <xliff:g id="time">%2$s</xliff:g> until fully charged</string>
+    <string name="power_charging_duration"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g> until fully charged</string>
     <!-- [CHAR_LIMIT=40] Short label for battery level chart when charging with duration -->
-    <string name="power_charging_duration_short"><xliff:g id="level">%1$s</xliff:g> -
-        <xliff:g id="time">%2$s</xliff:g></string>
+    <string name="power_charging_duration_short"><xliff:g id="level">^1</xliff:g> - <xliff:g id="time">^2</xliff:g></string>
 
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SettingsLib/res/values/styles.xml b/packages/SettingsLib/res/values/styles.xml
index 3f312f4..b7ea1d4 100644
--- a/packages/SettingsLib/res/values/styles.xml
+++ b/packages/SettingsLib/res/values/styles.xml
@@ -21,4 +21,9 @@
     <style name="TextAppearanceMedium">
         <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
     </style>
+
+    <style name="preference_icon_frame">
+        <item name="android:layout_marginStart">-4dp</item>
+        <item name="android:minWidth">60dp</item>
+    </style>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
deleted file mode 100644
index 2d8defa..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
+++ /dev/null
@@ -1,298 +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.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.BatteryStats.HistoryItem;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.text.format.Formatter;
-import android.util.SparseIntArray;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settingslib.graph.UsageView;
-
-public class BatteryInfo {
-
-    public String chargeLabelString;
-    public int batteryLevel;
-    public boolean discharging = true;
-    public long remainingTimeUs = 0;
-    public String batteryPercentString;
-    public String remainingLabel;
-    public String statusLabel;
-    private boolean mCharging;
-    private BatteryStats mStats;
-    private long timePeriod;
-
-    public interface Callback {
-        void onBatteryInfoLoaded(BatteryInfo info);
-    }
-
-    public void bindHistory(final UsageView view, BatteryDataParser... parsers) {
-        BatteryDataParser parser = new BatteryDataParser() {
-            SparseIntArray points = new SparseIntArray();
-
-            @Override
-            public void onParsingStarted(long startTime, long endTime) {
-                timePeriod = endTime - startTime - remainingTimeUs / 1000;
-                view.clearPaths();
-                view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0,
-                        mCharging);
-            }
-
-            @Override
-            public void onDataPoint(long time, HistoryItem record) {
-                points.put((int) time, record.batteryLevel);
-            }
-
-            @Override
-            public void onDataGap() {
-                if (points.size() > 1) {
-                    view.addPath(points);
-                }
-                points.clear();
-            }
-
-            @Override
-            public void onParsingDone() {
-                if (points.size() > 1) {
-                    view.addPath(points);
-                }
-            }
-        };
-        BatteryDataParser[] parserList = new BatteryDataParser[parsers.length + 1];
-        for (int i = 0; i < parsers.length; i++) {
-            parserList[i] = parsers[i];
-        }
-        parserList[parsers.length] = parser;
-        parse(mStats, remainingTimeUs, parserList);
-        final Context context = view.getContext();
-        String timeString = context.getString(R.string.charge_length_format,
-                Formatter.formatShortElapsedTime(context, timePeriod));
-        String remaining = "";
-        if (remainingTimeUs != 0) {
-            remaining = context.getString(R.string.remaining_length_format,
-                    Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000));
-        }
-        view.setBottomLabels(new CharSequence[]{timeString, remaining});
-    }
-
-    public static void getBatteryInfo(final Context context, final Callback callback) {
-        BatteryInfo.getBatteryInfo(context, callback, false /* shortString */);
-    }
-
-    public static void getBatteryInfo(final Context context, final Callback callback,
-            boolean shortString) {
-        new AsyncTask<Void, Void, BatteryStats>() {
-            @Override
-            protected BatteryStats doInBackground(Void... params) {
-                BatteryStatsHelper statsHelper = new BatteryStatsHelper(context, true);
-                statsHelper.create((Bundle) null);
-                return statsHelper.getStats();
-            }
-
-            @Override
-            protected void onPostExecute(BatteryStats batteryStats) {
-                final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
-                Intent batteryBroadcast = context.registerReceiver(null,
-                        new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-                BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast,
-                        batteryStats, elapsedRealtimeUs, shortString);
-                callback.onBatteryInfoLoaded(batteryInfo);
-            }
-        }.execute();
-    }
-
-    public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
-                                             BatteryStats stats, long elapsedRealtimeUs) {
-        return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs,
-                false /* shortString */);
-    }
-
-    public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
-            BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
-        BatteryInfo info = new BatteryInfo();
-        info.mStats = stats;
-        info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
-        info.batteryPercentString = Utils.formatPercentage(info.batteryLevel);
-        info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
-        final Resources resources = context.getResources();
-
-        info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast);
-        if (!info.mCharging) {
-            final long drainTime = stats.computeBatteryTimeRemaining(elapsedRealtimeUs);
-            if (drainTime > 0) {
-                info.remainingTimeUs = drainTime;
-                String timeString = Formatter.formatShortElapsedTime(context,
-                        drainTime / 1000);
-                info.remainingLabel = resources.getString(
-                        shortString ? R.string.power_remaining_duration_only_short
-                                : R.string.power_remaining_duration_only,
-                        timeString);
-                info.chargeLabelString = resources.getString(
-                        shortString ? R.string.power_discharging_duration_short
-                                : R.string.power_discharging_duration,
-                        info.batteryPercentString, timeString);
-            } else {
-                info.remainingLabel = null;
-                info.chargeLabelString = info.batteryPercentString;
-            }
-        } else {
-            final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
-            final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
-                    BatteryManager.BATTERY_STATUS_UNKNOWN);
-            info.discharging = false;
-            if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
-                info.remainingTimeUs = chargeTime;
-                String timeString = Formatter.formatShortElapsedTime(context,
-                        chargeTime / 1000);
-                int resId = shortString ? R.string.power_charging_duration_short
-                        : R.string.power_charging_duration;
-                info.remainingLabel = resources.getString(
-                        R.string.power_remaining_charging_duration_only, timeString);
-                info.chargeLabelString = resources.getString(
-                        resId, info.batteryPercentString, timeString);
-            } else {
-                final String chargeStatusLabel = resources.getString(
-                        R.string.battery_info_status_charging_lower);
-                info.remainingLabel = null;
-                info.chargeLabelString = resources.getString(
-                        R.string.power_charging, info.batteryPercentString, chargeStatusLabel);
-            }
-        }
-        return info;
-    }
-
-    public interface BatteryDataParser {
-        void onParsingStarted(long startTime, long endTime);
-
-        void onDataPoint(long time, HistoryItem record);
-
-        void onDataGap();
-
-        void onParsingDone();
-    }
-
-    private static void parse(BatteryStats stats, long remainingTimeUs,
-            BatteryDataParser... parsers) {
-        long startWalltime = 0;
-        long endDateWalltime = 0;
-        long endWalltime = 0;
-        long historyStart = 0;
-        long historyEnd = 0;
-        byte lastLevel = -1;
-        long curWalltime = startWalltime;
-        long lastWallTime = 0;
-        long lastRealtime = 0;
-        int lastInteresting = 0;
-        int pos = 0;
-        boolean first = true;
-        if (stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec)) {
-                pos++;
-                if (first) {
-                    first = false;
-                    historyStart = rec.time;
-                }
-                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
-                        || rec.cmd == HistoryItem.CMD_RESET) {
-                    // If there is a ridiculously large jump in time, then we won't be
-                    // able to create a good chart with that data, so just ignore the
-                    // times we got before and pretend like our data extends back from
-                    // the time we have now.
-                    // Also, if we are getting a time change and we are less than 5 minutes
-                    // since the start of the history real time, then also use this new
-                    // time to compute the base time, since whatever time we had before is
-                    // pretty much just noise.
-                    if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L))
-                            || rec.time < (historyStart + (5 * 60 * 1000L))) {
-                        startWalltime = 0;
-                    }
-                    lastWallTime = rec.currentTime;
-                    lastRealtime = rec.time;
-                    if (startWalltime == 0) {
-                        startWalltime = lastWallTime - (lastRealtime - historyStart);
-                    }
-                }
-                if (rec.isDeltaData()) {
-                    if (rec.batteryLevel != lastLevel || pos == 1) {
-                        lastLevel = rec.batteryLevel;
-                    }
-                    lastInteresting = pos;
-                    historyEnd = rec.time;
-                }
-            }
-        }
-        stats.finishIteratingHistoryLocked();
-        endDateWalltime = lastWallTime + historyEnd - lastRealtime;
-        endWalltime = endDateWalltime + (remainingTimeUs / 1000);
-
-        int i = 0;
-        final int N = lastInteresting;
-
-        for (int j = 0; j < parsers.length; j++) {
-            parsers[j].onParsingStarted(startWalltime, endWalltime);
-        }
-        if (endDateWalltime > startWalltime && stats.startIteratingHistoryLocked()) {
-            final HistoryItem rec = new HistoryItem();
-            while (stats.getNextHistoryLocked(rec) && i < N) {
-                if (rec.isDeltaData()) {
-                    curWalltime += rec.time - lastRealtime;
-                    lastRealtime = rec.time;
-                    long x = (curWalltime - startWalltime);
-                    if (x < 0) {
-                        x = 0;
-                    }
-                    for (int j = 0; j < parsers.length; j++) {
-                        parsers[j].onDataPoint(x, rec);
-                    }
-                } else {
-                    long lastWalltime = curWalltime;
-                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
-                            || rec.cmd == HistoryItem.CMD_RESET) {
-                        if (rec.currentTime >= startWalltime) {
-                            curWalltime = rec.currentTime;
-                        } else {
-                            curWalltime = startWalltime + (rec.time - historyStart);
-                        }
-                        lastRealtime = rec.time;
-                    }
-
-                    if (rec.cmd != HistoryItem.CMD_OVERFLOW
-                            && (rec.cmd != HistoryItem.CMD_CURRENT_TIME
-                            || Math.abs(lastWalltime - curWalltime) > (60 * 60 * 1000))) {
-                        for (int j = 0; j < parsers.length; j++) {
-                            parsers[j].onDataGap();
-                        }
-                    }
-                }
-                i++;
-            }
-        }
-
-        stats.finishIteratingHistoryLocked();
-
-        for (int j = 0; j < parsers.length; j++) {
-            parsers[j].onParsingDone();
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
new file mode 100644
index 0000000..9554e81
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomDialogPreference.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class CustomDialogPreference extends DialogPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomDialogPreference(Context context) {
+        super(context);
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomDialogPreference getCustomizablePreference() {
+            return (CustomDialogPreference) getPreference();
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
new file mode 100644
index 0000000..692d211
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.EditTextPreferenceDialogFragment;
+import android.support.v7.preference.EditTextPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+
+public class CustomEditTextPreference extends EditTextPreference {
+
+    private CustomPreferenceDialogFragment mFragment;
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public CustomEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public CustomEditTextPreference(Context context) {
+        super(context);
+    }
+
+    public EditText getEditText() {
+        return mFragment != null ? (EditText) mFragment.getDialog().findViewById(android.R.id.edit)
+                : null;
+    }
+
+    public boolean isDialogOpen() {
+        return getDialog() != null && getDialog().isShowing();
+    }
+
+    public Dialog getDialog() {
+        return mFragment != null ? mFragment.getDialog() : null;
+    }
+
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+            DialogInterface.OnClickListener listener) {
+    }
+
+    protected void onDialogClosed(boolean positiveResult) {
+    }
+
+    protected void onClick(DialogInterface dialog, int which) {
+    }
+
+    protected void onBindDialogView(View view) {
+    }
+
+    private void setFragment(CustomPreferenceDialogFragment fragment) {
+        mFragment = fragment;
+    }
+
+    public static class CustomPreferenceDialogFragment extends EditTextPreferenceDialogFragment {
+
+        public static CustomPreferenceDialogFragment newInstance(String key) {
+            final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+            final Bundle b = new Bundle(1);
+            b.putString(ARG_KEY, key);
+            fragment.setArguments(b);
+            return fragment;
+        }
+
+        private CustomEditTextPreference getCustomizablePreference() {
+            return (CustomEditTextPreference) getPreference();
+        }
+
+        @Override
+        protected void onBindDialogView(View view) {
+            super.onBindDialogView(view);
+            getCustomizablePreference().onBindDialogView(view);
+        }
+
+        @Override
+        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+            super.onPrepareDialogBuilder(builder);
+            getCustomizablePreference().setFragment(this);
+            getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+        }
+
+        @Override
+        public void onDialogClosed(boolean positiveResult) {
+            super.onDialogClosed(positiveResult);
+            getCustomizablePreference().onDialogClosed(positiveResult);
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            super.onClick(dialog, which);
+            getCustomizablePreference().onClick(dialog, which);
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
deleted file mode 100644
index 4b0ab59..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ /dev/null
@@ -1,461 +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.settingslib;
-
-import android.Manifest;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Xml;
-import android.view.InflateException;
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class SuggestionParser {
-
-    private static final String TAG = "SuggestionParser";
-
-    // If defined, only returns this suggestion if the feature is supported.
-    public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
-
-    // If defined, only display this optional step if an account of that type exists.
-    private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
-
-    // If defined and not true, do not should optional step.
-    private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
-
-    // If defined, only display this optional step if the current user is of that type.
-    private static final String META_DATA_REQUIRE_USER_TYPE =
-            "com.android.settings.require_user_type";
-
-    // If defined, only display this optional step if a connection is available.
-    private static final String META_DATA_IS_CONNECTION_REQUIRED =
-            "com.android.settings.require_connection";
-
-    // The valid values that setup wizard recognizes for differentiating user types.
-    private static final String META_DATA_PRIMARY_USER_TYPE_VALUE = "primary";
-    private static final String META_DATA_ADMIN_USER_TYPE_VALUE = "admin";
-    private static final String META_DATA_GUEST_USER_TYPE_VALUE = "guest";
-    private static final String META_DATA_RESTRICTED_USER_TYPE_VALUE = "restricted";
-
-    /**
-     * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
-     * For instance:
-     * 0,10
-     * Will appear immediately, but if the user removes it, it will come back after 10 days.
-     *
-     * Another example:
-     * 10,30
-     * Will only show up after 10 days, and then again after 30.
-     */
-    public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
-
-    // Shared prefs keys for storing dismissed state.
-    // Index into current dismissed state.
-    private static final String DISMISS_INDEX = "_dismiss_index";
-    private static final String SETUP_TIME = "_setup_time";
-    private static final String IS_DISMISSED = "_is_dismissed";
-
-    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
-
-    // Default dismiss control for smart suggestions.
-    private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
-
-    private final Context mContext;
-    private final List<SuggestionCategory> mSuggestionList;
-    private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
-    private final SharedPreferences mSharedPrefs;
-    private final String mSmartDismissControl;
-
-
-    public SuggestionParser(
-        Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
-        mContext = context;
-        mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
-                .parse(orderXml);
-        mSharedPrefs = sharedPrefs;
-        mSmartDismissControl = smartDismissControl;
-    }
-
-    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
-       this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
-    }
-
-    @VisibleForTesting
-    public SuggestionParser(Context context, SharedPreferences sharedPrefs) {
-        mContext = context;
-        mSuggestionList = new ArrayList<SuggestionCategory>();
-        mSharedPrefs = sharedPrefs;
-        mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL;
-        Log.wtf(TAG, "Only use this constructor for testing");
-    }
-
-    public List<Tile> getSuggestions() {
-        return getSuggestions(false);
-    }
-
-    public List<Tile> getSuggestions(boolean isSmartSuggestionEnabled) {
-        List<Tile> suggestions = new ArrayList<>();
-        final int N = mSuggestionList.size();
-        for (int i = 0; i < N; i++) {
-            readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled);
-        }
-        return suggestions;
-    }
-
-    public boolean dismissSuggestion(Tile suggestion) {
-        return dismissSuggestion(suggestion, false);
-    }
-
-    /**
-     * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
-     * be disabled.
-     */
-    public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        String keyBase = suggestion.intent.getComponent().flattenToShortString();
-        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
-        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
-        if (dismissControl == null || parseDismissString(dismissControl).length == index) {
-            return true;
-        }
-        mSharedPrefs.edit()
-                .putBoolean(keyBase + IS_DISMISSED, true)
-                .commit();
-        return false;
-    }
-
-    @VisibleForTesting
-    public void filterSuggestions(
-        List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
-        for (int i = countBefore; i < suggestions.size(); i++) {
-            if (!isAvailable(suggestions.get(i)) ||
-                    !isSupported(suggestions.get(i)) ||
-                    !satisifesRequiredUserType(suggestions.get(i)) ||
-                    !satisfiesRequiredAccount(suggestions.get(i)) ||
-                    !satisfiesConnectivity(suggestions.get(i)) ||
-                    isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
-                suggestions.remove(i--);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void readSuggestions(
-        SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
-        int countBefore = suggestions.size();
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(category.category);
-        if (category.pkg != null) {
-            intent.setPackage(category.pkg);
-        }
-        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
-                mAddCache, null, suggestions, true, false);
-        filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
-        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
-            // If there are too many, remove them all and only re-add the one with the highest
-            // priority.
-            Tile item = suggestions.remove(suggestions.size() - 1);
-            while (suggestions.size() > countBefore) {
-                Tile last = suggestions.remove(suggestions.size() - 1);
-                if (last.priority > item.priority) {
-                    item = last;
-                }
-            }
-            // If category is marked as done, do not add any item.
-            if (!isCategoryDone(category.category)) {
-                suggestions.add(item);
-            }
-        }
-    }
-
-    private boolean isAvailable(Tile suggestion) {
-        final String featuresRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
-        if (featuresRequired != null) {
-            for (String feature : featuresRequired.split(",")) {
-                if (TextUtils.isEmpty(feature)) {
-                    Log.w(TAG, "Found empty substring when parsing required features: "
-                            + featuresRequired);
-                } else if (!mContext.getPackageManager().hasSystemFeature(feature)) {
-                    Log.i(TAG, suggestion.title + " requires unavailable feature " + feature);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @RequiresPermission(Manifest.permission.MANAGE_USERS)
-    private boolean satisifesRequiredUserType(Tile suggestion) {
-        final String requiredUser = suggestion.metaData.getString(META_DATA_REQUIRE_USER_TYPE);
-        if (requiredUser != null) {
-            final UserManager userManager = mContext.getSystemService(UserManager.class);
-            UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
-            for (String userType : requiredUser.split("\\|")) {
-                final boolean primaryUserCondtionMet = userInfo.isPrimary()
-                        && META_DATA_PRIMARY_USER_TYPE_VALUE.equals(userType);
-                final boolean adminUserConditionMet = userInfo.isAdmin()
-                        && META_DATA_ADMIN_USER_TYPE_VALUE.equals(userType);
-                final boolean guestUserCondtionMet = userInfo.isGuest()
-                        && META_DATA_GUEST_USER_TYPE_VALUE.equals(userType);
-                final boolean restrictedUserCondtionMet = userInfo.isRestricted()
-                        && META_DATA_RESTRICTED_USER_TYPE_VALUE.equals(userType);
-                if (primaryUserCondtionMet || adminUserConditionMet || guestUserCondtionMet
-                        || restrictedUserCondtionMet) {
-                    return true;
-                }
-            }
-            Log.i(TAG, suggestion.title + " requires user type " + requiredUser);
-            return false;
-        }
-        return true;
-    }
-
-    public boolean satisfiesRequiredAccount(Tile suggestion) {
-        final String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
-        if (requiredAccountType == null) {
-            return true;
-        }
-        AccountManager accountManager = AccountManager.get(mContext);
-        Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
-        boolean satisfiesRequiredAccount = accounts.length > 0;
-        if (!satisfiesRequiredAccount) {
-            Log.i(TAG, suggestion.title + " requires unavailable account type "
-                    + requiredAccountType);
-        }
-        return satisfiesRequiredAccount;
-    }
-
-    public boolean isSupported(Tile suggestion) {
-        final int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
-        try {
-            if (suggestion.intent == null) {
-                return false;
-            }
-            final Resources res = mContext.getPackageManager().getResourcesForActivity(
-                    suggestion.intent.getComponent());
-            boolean isSupported =
-                    isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
-            if (!isSupported) {
-                Log.i(TAG, suggestion.title + " requires unsupported resource "
-                        + isSupportedResource);
-            }
-            return isSupported;
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
-            return false;
-        } catch (Resources.NotFoundException e) {
-            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent(), e);
-            return false;
-        }
-    }
-
-    private boolean satisfiesConnectivity(Tile suggestion) {
-        final boolean isConnectionRequired =
-                suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
-        if (!isConnectionRequired) {
-          return true;
-        }
-        ConnectivityManager cm =
-                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkInfo netInfo = cm.getActiveNetworkInfo();
-        boolean satisfiesConnectivity = netInfo != null && netInfo.isConnectedOrConnecting();
-        if (!satisfiesConnectivity) {
-            Log.i(TAG, suggestion.title + " is missing required connection.");
-        }
-        return satisfiesConnectivity;
-    }
-
-    public boolean isCategoryDone(String category) {
-        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
-        return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
-    }
-
-    public void markCategoryDone(String category) {
-        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
-        Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
-    }
-
-    private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
-        if (dismissControl == null) {
-            return false;
-        }
-        String keyBase = suggestion.intent.getComponent().flattenToShortString();
-        if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
-            mSharedPrefs.edit()
-                    .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
-                    .commit();
-        }
-        // Default to dismissed, so that we can have suggestions that only first appear after
-        // some number of days.
-        if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
-            return false;
-        }
-        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
-        int currentDismiss = parseDismissString(dismissControl)[index];
-        long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
-        if (System.currentTimeMillis() >= time) {
-            // Dismiss timeout has passed, undismiss it.
-            mSharedPrefs.edit()
-                    .putBoolean(keyBase + IS_DISMISSED, false)
-                    .putInt(keyBase + DISMISS_INDEX, index + 1)
-                    .commit();
-            return false;
-        }
-        return true;
-    }
-
-    private long getEndTime(long startTime, int daysDelay) {
-        long days = daysDelay * MILLIS_IN_DAY;
-        return startTime + days;
-    }
-
-    private int[] parseDismissString(String dismissControl) {
-        String[] dismissStrs = dismissControl.split(",");
-        int[] dismisses = new int[dismissStrs.length];
-        for (int i = 0; i < dismissStrs.length; i++) {
-            dismisses[i] = Integer.parseInt(dismissStrs[i]);
-        }
-        return dismisses;
-    }
-
-    private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
-        if (isSmartSuggestionEnabled) {
-            return mSmartDismissControl;
-        } else {
-            return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
-        }
-    }
-
-    @VisibleForTesting
-    static class SuggestionCategory {
-        public String category;
-        public String pkg;
-        public boolean multiple;
-    }
-
-    private static class SuggestionOrderInflater {
-        private static final String TAG_LIST = "optional-steps";
-        private static final String TAG_ITEM = "step";
-
-        private static final String ATTR_CATEGORY = "category";
-        private static final String ATTR_PACKAGE = "package";
-        private static final String ATTR_MULTIPLE = "multiple";
-
-        private final Context mContext;
-
-        public SuggestionOrderInflater(Context context) {
-            mContext = context;
-        }
-
-        public Object parse(int resource) {
-            XmlPullParser parser = mContext.getResources().getXml(resource);
-            final AttributeSet attrs = Xml.asAttributeSet(parser);
-            try {
-                // Look for the root node.
-                int type;
-                do {
-                    type = parser.next();
-                } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
-
-                if (type != XmlPullParser.START_TAG) {
-                    throw new InflateException(parser.getPositionDescription()
-                            + ": No start tag found!");
-                }
-
-                // Temp is the root that was found in the xml
-                Object xmlRoot = onCreateItem(parser.getName(), attrs);
-
-                // Inflate all children under temp
-                rParse(parser, xmlRoot, attrs);
-                return xmlRoot;
-            } catch (XmlPullParserException | IOException e) {
-                Log.w(TAG, "Problem parser resource " + resource, e);
-                return null;
-            }
-        }
-
-        /**
-         * Recursive method used to descend down the xml hierarchy and instantiate
-         * items, instantiate their children.
-         */
-        private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
-                throws XmlPullParserException, IOException {
-            final int depth = parser.getDepth();
-
-            int type;
-            while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-                if (type != XmlPullParser.START_TAG) {
-                    continue;
-                }
-
-                final String name = parser.getName();
-
-                Object item = onCreateItem(name, attrs);
-                onAddChildItem(parent, item);
-                rParse(parser, item, attrs);
-            }
-        }
-
-        protected void onAddChildItem(Object parent, Object child) {
-            if (parent instanceof List<?> && child instanceof SuggestionCategory) {
-                ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
-            } else {
-                throw new IllegalArgumentException("Parent was not a list");
-            }
-        }
-
-        protected Object onCreateItem(String name, AttributeSet attrs) {
-            if (name.equals(TAG_LIST)) {
-                return new ArrayList<SuggestionCategory>();
-            } else if (name.equals(TAG_ITEM)) {
-                SuggestionCategory category = new SuggestionCategory();
-                category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
-                category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
-                String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
-                category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
-                return category;
-            } else {
-                throw new IllegalArgumentException("Unknown item " + name);
-            }
-        }
-    }
-}
-
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 151e0ea..abbef70 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -17,13 +17,19 @@
 
 import android.content.Context;
 import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
 import android.telephony.CarrierConfigManager;
 
 public class TetherUtil {
 
-    private static boolean isEntitlementCheckRequired(Context context) {
+    @VisibleForTesting
+    static boolean isEntitlementCheckRequired(Context context) {
         final CarrierConfigManager configManager = (CarrierConfigManager) context
              .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager == null || configManager.getConfig() == null) {
+            // return service default
+            return true;
+        }
         return configManager.getConfig().getBoolean(CarrierConfigManager
              .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
index bea6e8f..945cb57 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TronUtils.java
@@ -16,48 +16,18 @@
 package com.android.settingslib;
 
 import android.content.Context;
-import android.net.NetworkBadging;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.wifi.AccessPoint.Speed;
 
 /** Utilites for Tron Logging. */
 public final class TronUtils {
 
+    private static final String TAG = "TronUtils";
+
     private TronUtils() {};
 
-    public static void logWifiSettingsBadge(Context context, int badgeEnum) {
-        logNetworkBadgeMetric(context, "settings_wifibadging", badgeEnum);
-    }
-
-    /**
-     * Logs an occurrence of the given network badge to a Histogram.
-     *
-     * @param context Context
-     * @param histogram the Tron histogram name to write to
-     * @param badgeEnum the {@link NetworkBadging.Badging} badge value
-     * @throws IllegalArgumentException if the given badge enum is not supported
-     */
-    private static void logNetworkBadgeMetric(
-            Context context, String histogram, int badgeEnum)
-            throws IllegalArgumentException {
-        int bucket;
-        switch (badgeEnum) {
-            case NetworkBadging.BADGING_NONE:
-                bucket = 0;
-                break;
-            case NetworkBadging.BADGING_SD:
-                bucket = 1;
-                break;
-            case NetworkBadging.BADGING_HD:
-                bucket = 2;
-                break;
-            case NetworkBadging.BADGING_4K:
-                bucket = 3;
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported badge enum: " + badgeEnum);
-        }
-
-        MetricsLogger.histogram(context, histogram, bucket);
+    public static void logWifiSettingsSpeed(Context context, @Speed int speedEnum) {
+        MetricsLogger.histogram(context, "settings_wifi_speed_labels", speedEnum);
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 3135f1d..dee5a93 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -21,6 +21,7 @@
 import android.os.BatteryManager;
 import android.os.UserManager;
 import android.print.PrintManager;
+import android.provider.Settings;
 import android.view.View;
 
 import com.android.internal.util.UserIcons;
@@ -34,7 +35,7 @@
     private static String sServicesSystemSharedLibPackageName;
     private static String sSharedSystemSharedLibPackageName;
 
-    public static final int[] WIFI_PIE_FOR_BADGING = {
+    static final int[] WIFI_PIE_FOR_BADGING = {
           com.android.internal.R.drawable.ic_signal_wifi_badged_0_bars,
           com.android.internal.R.drawable.ic_signal_wifi_badged_1_bar,
           com.android.internal.R.drawable.ic_signal_wifi_badged_2_bars,
@@ -129,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);
     }
 
@@ -293,12 +294,7 @@
                 });
     }
 
-    /**
-     * Returns the resource id for the given badge or {@link View.NO_ID} if no badge is to be shown.
-     *
-     * @throws IllegalArgumentException if the given badge value is not supported.
-     */
-    public static int getWifiBadgeResource(int badge) {
+    private static int getWifiBadgeResource(int badge) {
         switch (badge) {
             case NetworkBadging.BADGING_NONE:
                 return View.NO_ID;
@@ -313,4 +309,20 @@
                     "No badge resource found for badge value: " + badge);
         }
     }
+
+    public static int getDefaultStorageManagerDaysToRetain(Resources resources) {
+        int defaultDays = Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_DEFAULT;
+        try {
+            defaultDays =
+                    resources.getInteger(
+                            com.android
+                                    .internal
+                                    .R
+                                    .integer
+                                    .config_storageManagerDaystoRetainDefault);
+        } catch (Resources.NotFoundException e) {
+            // We are likely in a test environment.
+        }
+        return defaultDays;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index b06b032..7357fe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -107,4 +107,20 @@
         return false;
     }
 
+    /** Returns the label for a given package. */
+    public static CharSequence getApplicationLabel(
+            PackageManager packageManager, String packageName) {
+        try {
+            final ApplicationInfo appInfo =
+                    packageManager.getApplicationInfo(
+                            packageName,
+                            PackageManager.MATCH_DISABLED_COMPONENTS
+                                    | PackageManager.MATCH_ANY_USER);
+            return appInfo.loadLabel(packageManager);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Unable to find info for package: " + packageName);
+        }
+        return null;
+    }
+
 }
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/applications/PackageManagerWrapper.java b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
index caa7929..6c79a61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapper.java
@@ -123,4 +123,9 @@
      * @return the label as a CharSequence
      */
     CharSequence loadLabel(ApplicationInfo app);
+
+    /**
+     * Retrieve all activities that can be performed for the given intent.
+     */
+    List<ResolveInfo> queryIntentActivities(Intent intent, int flags);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
index 9b2cd7c..dcb40b2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PackageManagerWrapperImpl.java
@@ -113,4 +113,9 @@
     public CharSequence loadLabel(ApplicationInfo app) {
         return app.loadLabel(mPm);
     }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        return mPm.queryIntentActivities(intent, flags);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 80b943c..7d4bc83 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -97,11 +97,11 @@
 
         // Pairing broadcasts
         addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
-        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());
 
         // Fine-grained state broadcasts
         addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
         addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());
+        addHandler(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED, new BatteryLevelChangedHandler());
 
         // Dock event broadcasts
         addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());
@@ -343,24 +343,6 @@
         }
     }
 
-    private class PairingCancelHandler implements Handler {
-        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
-            if (device == null) {
-                Log.e(TAG, "ACTION_PAIRING_CANCEL with no EXTRA_DEVICE");
-                return;
-            }
-            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
-            if (cachedDevice == null) {
-                Log.e(TAG, "ACTION_PAIRING_CANCEL with no cached device");
-                return;
-            }
-            int errorMsg = R.string.bluetooth_pairing_error_message;
-            if (context != null && cachedDevice != null) {
-                Utils.showError(context, cachedDevice.getName(), errorMsg);
-            }
-        }
-    }
-
     private class DockEventHandler implements Handler {
         public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             // Remove if unpair device upon undocking
@@ -376,6 +358,17 @@
             }
         }
     }
+
+    private class BatteryLevelChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice != null) {
+                cachedDevice.refresh();
+            }
+        }
+    }
+
     boolean readPairedDevices() {
         Set<BluetoothDevice> bondedDevices = mLocalAdapter.getBondedDevices();
         if (bondedDevices == null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 5f302c6..bfa8de9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -367,6 +367,15 @@
         return mDevice;
     }
 
+    /**
+     * Convenience method that can be mocked - it lets tests avoid having to call getDevice() which
+     * causes problems in tests since BluetoothDevice is final and cannot be mocked.
+     * @return the address of this device
+     */
+    public String getAddress() {
+        return mDevice.getAddress();
+    }
+
     public String getName() {
         return mName;
     }
@@ -409,6 +418,14 @@
         }
     }
 
+    /**
+     * Get battery level from remote device
+     * @return battery level in percentage [0-100], or {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
+     */
+    public int getBatteryLevel() {
+        return mDevice.getBatteryLevel();
+    }
+
     void refresh() {
         dispatchAttributesChanged();
     }
@@ -827,7 +844,7 @@
     /**
      * @return resource for string that discribes the connection state of this device.
      */
-    public int getConnectionSummary() {
+    public String getConnectionSummary() {
         boolean profileConnected = false;       // at least one profile is connected
         boolean a2dpNotConnected = false;       // A2DP is preferred but not connected
         boolean hfpNotConnected = false;    // HFP is preferred but not connected
@@ -838,7 +855,7 @@
             switch (connectionStatus) {
                 case BluetoothProfile.STATE_CONNECTING:
                 case BluetoothProfile.STATE_DISCONNECTING:
-                    return Utils.getConnectionStateSummary(connectionStatus);
+                    return mContext.getString(Utils.getConnectionStateSummary(connectionStatus));
 
                 case BluetoothProfile.STATE_CONNECTED:
                     profileConnected = true;
@@ -858,18 +875,54 @@
             }
         }
 
+        String batteryLevelPercentageString = null;
+        // Android framework should only set mBatteryLevel to valid range [0-100] or
+        // BluetoothDevice.BATTERY_LEVEL_UNKNOWN, any other value should be a framework bug.
+        // Thus assume here that if value is not BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must
+        // be valid
+        final int batteryLevel = getBatteryLevel();
+        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+            // TODO: name com.android.settingslib.bluetooth.Utils something different
+            batteryLevelPercentageString =
+                    com.android.settingslib.Utils.formatPercentage(batteryLevel);
+        }
+
         if (profileConnected) {
             if (a2dpNotConnected && hfpNotConnected) {
-                return R.string.bluetooth_connected_no_headset_no_a2dp;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(
+                            R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp);
+                }
+
             } else if (a2dpNotConnected) {
-                return R.string.bluetooth_connected_no_a2dp;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp);
+                }
+
             } else if (hfpNotConnected) {
-                return R.string.bluetooth_connected_no_headset;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset);
+                }
             } else {
-                return R.string.bluetooth_connected;
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_battery_level,
+                            batteryLevelPercentageString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected);
+                }
             }
         }
 
-        return getBondState() == BluetoothDevice.BOND_BONDING ? R.string.bluetooth_pairing : 0;
+        return getBondState() == BluetoothDevice.BOND_BONDING ?
+                mContext.getString(R.string.bluetooth_pairing) : null;
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 5529866..d45fe1a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -34,7 +34,7 @@
 /**
  * HeadsetProfile handles Bluetooth HFP and Headset profiles.
  */
-public final class HeadsetProfile implements LocalBluetoothProfile {
+public class HeadsetProfile implements LocalBluetoothProfile {
     private static final String TAG = "HeadsetProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index a9e8db5..d1621da 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -31,7 +31,7 @@
 /**
  * HidProfile handles Bluetooth HID profile.
  */
-public final class HidProfile implements LocalBluetoothProfile {
+public class HidProfile implements LocalBluetoothProfile {
     private static final String TAG = "HidProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
index 2fb6843..22674cb 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -90,6 +90,10 @@
         return mAdapter.disable();
     }
 
+    public String getAddress() {
+        return mAdapter.getAddress();
+    }
+
     void getProfileProxy(Context context,
             BluetoothProfile.ServiceListener listener, int profile) {
         mAdapter.getProfileProxy(context, listener, profile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index e6a152f..0b45f51 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -34,7 +34,7 @@
 /**
  * MapProfile handles Bluetooth MAP profile.
  */
-public final class MapProfile implements LocalBluetoothProfile {
+public class MapProfile implements LocalBluetoothProfile {
     private static final String TAG = "MapProfile";
     private static boolean V = true;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index bd37abe..28137ff 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -32,7 +32,7 @@
 import java.util.Collection;
 import java.util.List;
 
-final class PbapClientProfile implements LocalBluetoothProfile {
+public final class PbapClientProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapClientProfile";
     private static boolean V = false;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index 9e76933..f3b6912 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -25,19 +25,21 @@
 import android.os.ParcelUuid;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
 /**
  * PBAPServer Profile
  */
-public final class PbapServerProfile implements LocalBluetoothProfile {
+public class PbapServerProfile implements LocalBluetoothProfile {
     private static final String TAG = "PbapServerProfile";
     private static boolean V = true;
 
     private BluetoothPbap mService;
     private boolean mIsProfileReady;
 
-    static final String NAME = "PBAP Server";
+    @VisibleForTesting
+    public static final String NAME = "PBAP Server";
 
     // Order of this profile in device profiles list
     private static final int ORDINAL = 6;
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
new file mode 100644
index 0000000..b2351a9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
@@ -0,0 +1,171 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.UiThread;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.settingslib.core.lifecycle.events.OnAttach;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Dispatcher for lifecycle events.
+ */
+public class Lifecycle {
+
+    protected final List<LifecycleObserver> mObservers = new ArrayList<>();
+
+    /**
+     * Registers a new observer of lifecycle events.
+     */
+    @UiThread
+    public <T extends LifecycleObserver> T addObserver(T observer) {
+        ThreadUtils.ensureMainThread();
+        mObservers.add(observer);
+        return observer;
+    }
+
+    public void onAttach(Context context) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnAttach) {
+                ((OnAttach) observer).onAttach(context);
+            }
+        }
+    }
+
+    public void onCreate(Bundle savedInstanceState) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnCreate) {
+                ((OnCreate) observer).onCreate(savedInstanceState);
+            }
+        }
+    }
+
+    public void onStart() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnStart) {
+                ((OnStart) observer).onStart();
+            }
+        }
+    }
+
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof SetPreferenceScreen) {
+                ((SetPreferenceScreen) observer).setPreferenceScreen(preferenceScreen);
+            }
+        }
+    }
+
+    public void onResume() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnResume) {
+                ((OnResume) observer).onResume();
+            }
+        }
+    }
+
+    public void onPause() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnPause) {
+                ((OnPause) observer).onPause();
+            }
+        }
+    }
+
+    public void onSaveInstanceState(Bundle outState) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnSaveInstanceState) {
+                ((OnSaveInstanceState) observer).onSaveInstanceState(outState);
+            }
+        }
+    }
+
+    public void onStop() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnStop) {
+                ((OnStop) observer).onStop();
+            }
+        }
+    }
+
+    public void onDestroy() {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnDestroy) {
+                ((OnDestroy) observer).onDestroy();
+            }
+        }
+    }
+
+    public void onCreateOptionsMenu(final Menu menu, final @Nullable MenuInflater inflater) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnCreateOptionsMenu) {
+                ((OnCreateOptionsMenu) observer).onCreateOptionsMenu(menu, inflater);
+            }
+        }
+    }
+
+    public void onPrepareOptionsMenu(final Menu menu) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnPrepareOptionsMenu) {
+                ((OnPrepareOptionsMenu) observer).onPrepareOptionsMenu(menu);
+            }
+        }
+    }
+
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        for (int i = 0, size = mObservers.size(); i < size; i++) {
+            final LifecycleObserver observer = mObservers.get(i);
+            if (observer instanceof OnOptionsItemSelected) {
+                if (((OnOptionsItemSelected) observer).onOptionsItemSelected(menuItem)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
new file mode 100644
index 0000000..6c41072
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
@@ -0,0 +1,22 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+/**
+ * Observer of lifecycle events.
+ */
+public interface LifecycleObserver {
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
new file mode 100644
index 0000000..727bec7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
@@ -0,0 +1,105 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * {@link Activity} that has hooks to observe activity lifecycle events.
+ */
+public class ObservableActivity extends Activity {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        mLifecycle.onAttach(this);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState,
+            @Nullable PersistableBundle persistentState) {
+        mLifecycle.onAttach(this);
+        super.onCreate(savedInstanceState, persistentState);
+    }
+
+    @Override
+    protected void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @Override
+    protected void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        if (super.onCreateOptionsMenu(menu)) {
+            mLifecycle.onCreateOptionsMenu(menu, null);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(final Menu menu) {
+        if (super.onPrepareOptionsMenu(menu)) {
+            mLifecycle.onPrepareOptionsMenu(menu);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
new file mode 100644
index 0000000..315bedc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
@@ -0,0 +1,94 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.app.DialogFragment;
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+/**
+ * {@link DialogFragment} that has hooks to observe fragment lifecycle events.
+ */
+public class ObservableDialogFragment extends DialogFragment {
+
+    protected final Lifecycle mLifecycle = createLifecycle();
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+    /** @return a new lifecycle. */
+    public static Lifecycle createLifecycle() {
+        return new Lifecycle();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
new file mode 100644
index 0000000..3a00eba
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
@@ -0,0 +1,114 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.annotation.CallSuper;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+public class ObservableFragment extends Fragment {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @CallSuper
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @CallSuper
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mLifecycle.onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @CallSuper
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mLifecycle.onSaveInstanceState(outState);
+    }
+
+    @CallSuper
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @CallSuper
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @CallSuper
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @CallSuper
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @CallSuper
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @CallSuper
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @CallSuper
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
new file mode 100644
index 0000000..76e5c85
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.core.lifecycle;
+
+
+import android.annotation.CallSuper;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+/**
+ * {@link PreferenceFragment} that has hooks to observe fragment lifecycle events.
+ */
+public abstract class ObservablePreferenceFragment extends PreferenceFragment {
+
+    private final Lifecycle mLifecycle = new Lifecycle();
+
+    protected Lifecycle getLifecycle() {
+        return mLifecycle;
+    }
+
+    @CallSuper
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mLifecycle.onAttach(context);
+    }
+
+    @CallSuper
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mLifecycle.onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        mLifecycle.setPreferenceScreen(preferenceScreen);
+        super.setPreferenceScreen(preferenceScreen);
+    }
+
+    @CallSuper
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mLifecycle.onSaveInstanceState(outState);
+    }
+
+    @CallSuper
+    @Override
+    public void onStart() {
+        mLifecycle.onStart();
+        super.onStart();
+    }
+
+    @CallSuper
+    @Override
+    public void onStop() {
+        mLifecycle.onStop();
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
+    public void onResume() {
+        mLifecycle.onResume();
+        super.onResume();
+    }
+
+    @CallSuper
+    @Override
+    public void onPause() {
+        mLifecycle.onPause();
+        super.onPause();
+    }
+
+    @CallSuper
+    @Override
+    public void onDestroy() {
+        mLifecycle.onDestroy();
+        super.onDestroy();
+    }
+
+    @CallSuper
+    @Override
+    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+        mLifecycle.onCreateOptionsMenu(menu, inflater);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @CallSuper
+    @Override
+    public void onPrepareOptionsMenu(final Menu menu) {
+        mLifecycle.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
+    }
+
+    @CallSuper
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem menuItem) {
+        boolean lifecycleHandled = mLifecycle.onOptionsItemSelected(menuItem);
+        if (!lifecycleHandled) {
+            return super.onOptionsItemSelected(menuItem);
+        }
+        return lifecycleHandled;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
new file mode 100644
index 0000000..152cbac
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
@@ -0,0 +1,22 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.content.Context;
+
+public interface OnAttach {
+    void onAttach(Context context);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
new file mode 100644
index 0000000..44cbf8d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+
+import android.os.Bundle;
+
+public interface OnCreate {
+    void onCreate(Bundle savedInstanceState);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java
new file mode 100644
index 0000000..c14b7d7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreateOptionsMenu.java
@@ -0,0 +1,24 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.view.Menu;
+import android.view.MenuInflater;
+
+public interface OnCreateOptionsMenu {
+    void onCreateOptionsMenu(Menu menu, MenuInflater inflater);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
new file mode 100644
index 0000000..ffa3d16
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnDestroy {
+    void onDestroy();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java
new file mode 100644
index 0000000..bcb3032
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnOptionsItemSelected.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.view.MenuItem;
+
+public interface OnOptionsItemSelected {
+    boolean onOptionsItemSelected(MenuItem menuItem);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
new file mode 100644
index 0000000..4a71105
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnPause {
+    void onPause();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java
new file mode 100644
index 0000000..b9f1371
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPrepareOptionsMenu.java
@@ -0,0 +1,24 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.view.Menu;
+import android.view.MenuInflater;
+
+public interface OnPrepareOptionsMenu {
+    void onPrepareOptionsMenu(Menu menu);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
new file mode 100644
index 0000000..8dd24e9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
@@ -0,0 +1,20 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnResume {
+    void onResume();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java
new file mode 100644
index 0000000..9d46110
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnSaveInstanceState.java
@@ -0,0 +1,23 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.os.Bundle;
+
+
+public interface OnSaveInstanceState {
+    void onSaveInstanceState(Bundle outState);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
new file mode 100644
index 0000000..c88ddaa
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
@@ -0,0 +1,21 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnStart {
+
+    void onStart();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
new file mode 100644
index 0000000..32f61d9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
@@ -0,0 +1,21 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+public interface OnStop {
+
+    void onStop();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java
new file mode 100644
index 0000000..cdd72fb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/SetPreferenceScreen.java
@@ -0,0 +1,24 @@
+/*
+ * 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.settingslib.core.lifecycle.events;
+
+import android.support.v7.preference.PreferenceScreen;
+
+public interface SetPreferenceScreen {
+
+    void setPreferenceScreen(PreferenceScreen preferenceScreen);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 9d09737..e067de1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -34,6 +34,8 @@
     public static final String CATEGORY_SOUND = "com.android.settings.category.ia.sound";
     public static final String CATEGORY_STORAGE = "com.android.settings.category.ia.storage";
     public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security";
+    public static final String CATEGORY_SECURITY_LOCKSCREEN =
+            "com.android.settings.category.ia.lockscreen";
     public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts";
     public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system";
     public static final String CATEGORY_SYSTEM_LANGUAGE =
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/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index c7efb07..f1d43bf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 
@@ -50,6 +51,12 @@
     public Icon icon;
 
     /**
+     * Whether the icon can be tinted. This should be set to true for monochrome (single-color)
+     * icons that can be tinted to match the design.
+     */
+    public boolean isIconTintable;
+
+    /**
      * Intent to launch when the preference is selected.
      */
     public Intent intent;
@@ -84,6 +91,11 @@
      */
     public String key;
 
+    /**
+     * Optional remote view which will be displayed instead of the regular title-summary item.
+     */
+    public RemoteViews remoteViews;
+
     public Tile() {
         // Empty
     }
@@ -119,6 +131,8 @@
         dest.writeInt(priority);
         dest.writeBundle(metaData);
         dest.writeString(key);
+        dest.writeParcelable(remoteViews, flags);
+        dest.writeBoolean(isIconTintable);
     }
 
     public void readFromParcel(Parcel in) {
@@ -139,6 +153,8 @@
         priority = in.readInt();
         metaData = in.readBundle();
         key = in.readString();
+        remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
+        isIconTintable = in.readBoolean();
     }
 
     Tile(Parcel in) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index fb48054..9620a91 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -21,7 +21,6 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -35,6 +34,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
+import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -133,15 +133,25 @@
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
-     * to specify the title that should be displayed for the preference.
+     * to specify whether the icon is tintable. This should be a boolean value {@code true} or
+     * {@code false}, set using {@code android:value}
      */
-    @Deprecated
-    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+    public static final String META_DATA_PREFERENCE_ICON_TINTABLE =
+            "com.android.settings.icon_tintable";
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
      * to specify the title that should be displayed for the preference.
+     *
+     * <p>Note: It is preferred to provide this value using {@code android:resource} with a string
+     * resource for localization.
      */
+    public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+
+    /**
+     * @deprecated Use {@link #META_DATA_PREFERENCE_TITLE} with {@code android:resource}
+     */
+    @Deprecated
     public static final String META_DATA_PREFERENCE_TITLE_RES_ID =
             "com.android.settings.title.resid";
 
@@ -161,6 +171,17 @@
     public static final String META_DATA_PREFERENCE_SUMMARY_URI =
             "com.android.settings.summary_uri";
 
+    /**
+     * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the
+     * custom view which should be displayed for the preference. The custom view will be inflated
+     * as a remote view.
+     *
+     * This also can be used with {@link META_DATA_PREFERENCE_SUMMARY_URI} above, by setting the id
+     * of the summary TextView to '@android:id/summary'.
+     */
+    public static final String META_DATA_PREFERENCE_CUSTOM_VIEW =
+            "com.android.settings.custom_view";
+
     public static final String SETTING_PKG = "com.android.settings";
 
     /**
@@ -298,15 +319,17 @@
             intent.setPackage(settingPkg);
         }
         getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
-                usePriority, true);
+                usePriority, true, true);
     }
 
-    public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
+    public static void getTilesForIntent(
+            Context context, UserHandle user, Intent intent,
             Map<Pair<String, String>, Tile> addedCache, String defaultCategory, List<Tile> outTiles,
-            boolean usePriority, boolean checkCategory) {
+            boolean usePriority, boolean checkCategory, boolean forceTintExternalIcon) {
         PackageManager pm = context.getPackageManager();
         List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
                 PackageManager.GET_META_DATA, user.getIdentifier());
+        Map<String, IContentProvider> providerMap = new HashMap<>();
         for (ResolveInfo resolved : results) {
             if (!resolved.system) {
                 // Do not allow any app to add to settings, only system ones.
@@ -338,7 +361,7 @@
                 tile.priority = usePriority ? resolved.priority : 0;
                 tile.metaData = activityInfo.metaData;
                 updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
-                        pm);
+                        pm, providerMap, forceTintExternalIcon);
                 if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);
 
                 addedCache.put(key, tile);
@@ -353,25 +376,41 @@
     }
 
     private static boolean updateTileData(Context context, Tile tile,
-            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm) {
+            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm,
+            Map<String, IContentProvider> providerMap, boolean forceTintExternalIcon) {
         if (applicationInfo.isSystemApp()) {
+            boolean forceTintIcon = false;
             int icon = 0;
             Pair<String, Integer> iconFromUri = null;
             CharSequence title = null;
             String summary = null;
             String keyHint = null;
-            Uri uri = null;
+            boolean isIconTintable = false;
+            RemoteViews remoteViews = null;
 
             // Get the activity's meta-data
             try {
-                Resources res = pm.getResourcesForApplication(
-                        applicationInfo.packageName);
+                Resources res = pm.getResourcesForApplication(applicationInfo.packageName);
                 Bundle metaData = activityInfo.metaData;
 
+                if (forceTintExternalIcon
+                        && !context.getPackageName().equals(applicationInfo.packageName)) {
+                    isIconTintable = true;
+                    forceTintIcon = true;
+                }
+
                 if (res != null && metaData != null) {
                     if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
                         icon = metaData.getInt(META_DATA_PREFERENCE_ICON);
                     }
+                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON_TINTABLE)) {
+                        if (forceTintIcon) {
+                            Log.w(LOG_TAG, "Ignoring icon tintable for " + activityInfo);
+                        } else {
+                            isIconTintable =
+                                    metaData.getBoolean(META_DATA_PREFERENCE_ICON_TINTABLE);
+                        }
+                    }
                     int resId = 0;
                     if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) {
                         resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID);
@@ -379,8 +418,6 @@
                             title = res.getString(resId);
                         }
                     }
-                    // Fallback to legacy title extraction if we couldn't get the title through
-                    // res id.
                     if ((resId == 0) && metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
                         if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
                             title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
@@ -402,6 +439,19 @@
                             keyHint = metaData.getString(META_DATA_PREFERENCE_KEYHINT);
                         }
                     }
+                    if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
+                        int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
+                        remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
+                        if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+                            String uriString = metaData.getString(
+                                    META_DATA_PREFERENCE_SUMMARY_URI);
+                            String overrideSummary = getTextFromUri(context, uriString, providerMap,
+                                    META_DATA_PREFERENCE_SUMMARY);
+                            if (overrideSummary != null) {
+                                remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
+                            }
+                        }
+                    }
                 }
             } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
                 if (DEBUG) Log.d(LOG_TAG, "Couldn't find info", e);
@@ -431,6 +481,8 @@
                     activityInfo.name);
             // Suggest a key for this tile
             tile.key = keyHint;
+            tile.isIconTintable = isIconTintable;
+            tile.remoteViews = remoteViews;
 
             return true;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index e5cdc85..988060e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.dream;
 
+import android.annotation.IntDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -35,6 +36,8 @@
 import android.util.Log;
 import android.util.Xml;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -68,6 +71,15 @@
         }
     }
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({WHILE_CHARGING, WHILE_DOCKED, EITHER, NEVER})
+    public @interface WhenToDream{}
+
+    public static final int WHILE_CHARGING = 0;
+    public static final int WHILE_DOCKED = 1;
+    public static final int EITHER = 2;
+    public static final int NEVER = 3;
+
     private final Context mContext;
     private final IDreamManager mDreamManager;
     private final DreamInfoComparator mComparator;
@@ -75,6 +87,15 @@
     private final boolean mDreamsActivatedOnSleepByDefault;
     private final boolean mDreamsActivatedOnDockByDefault;
 
+    private static DreamBackend sInstance;
+
+    public static DreamBackend getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new DreamBackend(context);
+        }
+        return sInstance;
+    }
+
     public DreamBackend(Context context) {
         mContext = context;
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -138,6 +159,42 @@
         return null;
     }
 
+    public @WhenToDream int getWhenToDreamSetting() {
+        if (!isEnabled()) {
+            return NEVER;
+        }
+        return isActivatedOnDock() && isActivatedOnSleep() ? EITHER
+                : isActivatedOnDock() ? WHILE_DOCKED
+                : isActivatedOnSleep() ? WHILE_CHARGING
+                : NEVER;
+    }
+
+    public void setWhenToDream(@WhenToDream int whenToDream) {
+        setEnabled(whenToDream != NEVER);
+
+        switch (whenToDream) {
+            case WHILE_CHARGING:
+                setActivatedOnDock(false);
+                setActivatedOnSleep(true);
+                break;
+
+            case WHILE_DOCKED:
+                setActivatedOnDock(true);
+                setActivatedOnSleep(false);
+                break;
+
+            case EITHER:
+                setActivatedOnDock(true);
+                setActivatedOnSleep(true);
+                break;
+
+            case NEVER:
+            default:
+                break;
+        }
+
+    }
+
     public boolean isEnabled() {
         return getBoolean(Settings.Secure.SCREENSAVER_ENABLED, mDreamsEnabledByDefault);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 3d50f23..426dc7c 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -26,6 +26,9 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Path.FillType;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -36,8 +39,9 @@
 
 public class BatteryMeterDrawableBase extends Drawable {
 
-    private static final float ASPECT_RATIO = 9.5f / 14.5f;
+    private static final float ASPECT_RATIO = .58f;
     public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName();
+    private static final float RADIUS_RATIO = 1.0f / 17f;
 
     protected final Context mContext;
     protected final Paint mFramePaint;
@@ -79,6 +83,7 @@
     private final float[] mPlusPoints;
     private final Path mPlusPath = new Path();
 
+    private final Rect mPadding = new Rect();
     private final RectF mFrame = new RectF();
     private final RectF mButtonFrame = new RectF();
     private final RectF mBoltFrame = new RectF();
@@ -216,12 +221,40 @@
     @Override
     public void setBounds(int left, int top, int right, int bottom) {
         super.setBounds(left, top, right, bottom);
-        mHeight = bottom - top;
-        mWidth = right - left;
+        updateSize();
+    }
+
+    private void updateSize() {
+        final Rect bounds = getBounds();
+
+        mHeight = (bounds.bottom - mPadding.bottom) - (bounds.top + mPadding.top);
+        mWidth = (bounds.right - mPadding.right) - (bounds.left + mPadding.left);
         mWarningTextPaint.setTextSize(mHeight * 0.75f);
         mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
     }
 
+    @Override
+    public boolean getPadding(Rect padding) {
+        if (mPadding.left == 0
+            && mPadding.top == 0
+            && mPadding.right == 0
+            && mPadding.bottom == 0) {
+            return super.getPadding(padding);
+        }
+
+        padding.set(mPadding);
+        return true;
+    }
+
+    public void setPadding(int left, int top, int right, int bottom) {
+        mPadding.left = left;
+        mPadding.top = top;
+        mPadding.right = right;
+        mPadding.bottom = bottom;
+
+        updateSize();
+    }
+
     private int getColorForLevel(int percent) {
         // If we are in power save mode, always use the normal color.
         if (mPowerSaveEnabled) {
@@ -248,10 +281,15 @@
         mIconTint = fillColor;
         mFramePaint.setColor(backgroundColor);
         mBoltPaint.setColor(fillColor);
+        mPlusPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidateSelf();
     }
 
+    protected int batteryColorForLevel(int level) {
+        return mCharging ? mChargeColor : getColorForLevel(level);
+    }
+
     @Override
     public void draw(Canvas c) {
         final int level = mLevel;
@@ -261,33 +299,24 @@
         float drawFrac = (float) level / 100f;
         final int height = mHeight;
         final int width = (int) (ASPECT_RATIO * mHeight);
-        int px = (mWidth - width) / 2;
+        final int px = (mWidth - width) / 2;
+        final int buttonHeight = Math.round(height * mButtonHeightFraction);
 
-        final int buttonHeight = (int) (height * mButtonHeightFraction);
-
-        mFrame.set(0, 0, width, height);
+        mFrame.set(mPadding.left, mPadding.top, width + mPadding.left, height + mPadding.top);
         mFrame.offset(px, 0);
 
         // button-frame: area above the battery body
         mButtonFrame.set(
-                mFrame.left + Math.round(width * 0.25f),
+                mFrame.left + Math.round(width * 0.28f),
                 mFrame.top,
-                mFrame.right - Math.round(width * 0.25f),
+                mFrame.right - Math.round(width * 0.28f),
                 mFrame.top + buttonHeight);
 
-        mButtonFrame.top += mSubpixelSmoothingLeft;
-        mButtonFrame.left += mSubpixelSmoothingLeft;
-        mButtonFrame.right -= mSubpixelSmoothingRight;
-
         // frame: battery body area
         mFrame.top += buttonHeight;
-        mFrame.left += mSubpixelSmoothingLeft;
-        mFrame.top += mSubpixelSmoothingLeft;
-        mFrame.right -= mSubpixelSmoothingRight;
-        mFrame.bottom -= mSubpixelSmoothingRight;
 
         // set the battery charging color
-        mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
+        mBatteryPaint.setColor(batteryColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
@@ -300,21 +329,17 @@
 
         // define the battery shape
         mShapePath.reset();
-        mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
+        final float radius = RADIUS_RATIO * (mFrame.height() + buttonHeight);
+        mShapePath.setFillType(FillType.WINDING);
+        mShapePath.addRoundRect(mFrame, radius, radius, Direction.CW);
+        mShapePath.addRect(mButtonFrame, Direction.CW);
 
         if (mCharging) {
             // define the bolt shape
-            final float bl = mFrame.left + mFrame.width() / 4f;
+            // Shift right by 1px for maximal bolt-goodness
+            final float bl = mFrame.left + mFrame.width() / 4f + 1;
             final float bt = mFrame.top + mFrame.height() / 6f;
-            final float br = mFrame.right - mFrame.width() / 4f;
+            final float br = mFrame.right - mFrame.width() / 4f + 1;
             final float bb = mFrame.bottom - mFrame.height() / 10f;
             if (mBoltFrame.left != bl || mBoltFrame.top != bt
                     || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
deleted file mode 100644
index 8161dd4..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
+++ /dev/null
@@ -1,97 +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.
- *
- *
- */
-
-package com.android.settingslib.graph;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.support.annotation.VisibleForTesting;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.settingslib.R;
-
-/**
- * An extension of LinearLayout that automatically switches to vertical
- * orientation when it can't fit its child views horizontally.
- *
- * Main logic in this class comes from {@link android.support.v7.widget.ButtonBarLayout}.
- * Compared with {@link android.support.v7.widget.ButtonBarLayout}, this layout won't reverse
- * children's order and won't update the minimum height
- */
-public class BottomLabelLayout extends LinearLayout {
-    private static final String TAG = "BottomLabelLayout";
-
-    public BottomLabelLayout(Context context,
-            @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        final boolean isStacked = isStacked();
-        boolean needsRemeasure = false;
-
-        // If we're not stacked, make sure the measure spec is AT_MOST rather
-        // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we
-        // know to stack the buttons.
-        final int initialWidthMeasureSpec;
-        if (!isStacked && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
-            initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
-
-            // We'll need to remeasure again to fill excess space.
-            needsRemeasure = true;
-        } else {
-            initialWidthMeasureSpec = widthMeasureSpec;
-        }
-
-        super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec);
-        if (!isStacked) {
-            final int measuredWidth = getMeasuredWidthAndState();
-            final int measuredWidthState = measuredWidth & View.MEASURED_STATE_MASK;
-
-            if (measuredWidthState == View.MEASURED_STATE_TOO_SMALL) {
-                setStacked(true);
-                // Measure again in the new orientation.
-                needsRemeasure = true;
-            }
-        }
-
-        if (needsRemeasure) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-
-    }
-
-    @VisibleForTesting
-    void setStacked(boolean stacked) {
-        setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
-        setGravity(stacked ? Gravity.START : Gravity.BOTTOM);
-
-        final View spacer = findViewById(R.id.spacer);
-        if (spacer != null) {
-            spacer.setVisibility(stacked ? View.GONE : View.VISIBLE);
-        }
-    }
-
-    private boolean isStacked() {
-        return getOrientation() == LinearLayout.VERTICAL;
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
deleted file mode 100644
index 1fff0fb..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
+++ /dev/null
@@ -1,277 +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.settingslib.graph;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.CornerPathEffect;
-import android.graphics.DashPathEffect;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint.Style;
-import android.graphics.Path;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.SparseIntArray;
-import android.util.TypedValue;
-import android.view.View;
-import com.android.settingslib.R;
-
-public class UsageGraph extends View {
-
-    private static final int PATH_DELIM = -1;
-
-    private final Paint mLinePaint;
-    private final Paint mFillPaint;
-    private final Paint mDottedPaint;
-
-    private final Drawable mDivider;
-    private final Drawable mTintedDivider;
-    private final int mDividerSize;
-
-    private final Path mPath = new Path();
-
-    // Paths in coordinates they are passed in.
-    private final SparseIntArray mPaths = new SparseIntArray();
-    // Paths in local coordinates for drawing.
-    private final SparseIntArray mLocalPaths = new SparseIntArray();
-    private final int mCornerRadius;
-
-    private int mAccentColor;
-    private boolean mShowProjection;
-    private boolean mProjectUp;
-
-    private float mMaxX = 100;
-    private float mMaxY = 100;
-
-    private float mMiddleDividerLoc = .5f;
-    private int mMiddleDividerTint = -1;
-    private int mTopDividerTint = -1;
-
-    public UsageGraph(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        final Resources resources = context.getResources();
-
-        mLinePaint = new Paint();
-        mLinePaint.setStyle(Style.STROKE);
-        mLinePaint.setStrokeCap(Cap.ROUND);
-        mLinePaint.setStrokeJoin(Join.ROUND);
-        mLinePaint.setAntiAlias(true);
-        mCornerRadius = resources.getDimensionPixelSize(R.dimen.usage_graph_line_corner_radius);
-        mLinePaint.setPathEffect(new CornerPathEffect(mCornerRadius));
-        mLinePaint.setStrokeWidth(resources.getDimensionPixelSize(R.dimen.usage_graph_line_width));
-
-        mFillPaint = new Paint(mLinePaint);
-        mFillPaint.setStyle(Style.FILL);
-
-        mDottedPaint = new Paint(mLinePaint);
-        mDottedPaint.setStyle(Style.STROKE);
-        float dots = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_size);
-        float interval = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_interval);
-        mDottedPaint.setStrokeWidth(dots * 3);
-        mDottedPaint.setPathEffect(new DashPathEffect(new float[] {dots, interval}, 0));
-        mDottedPaint.setColor(context.getColor(R.color.usage_graph_dots));
-
-        TypedValue v = new TypedValue();
-        context.getTheme().resolveAttribute(com.android.internal.R.attr.listDivider, v, true);
-        mDivider = context.getDrawable(v.resourceId);
-        mTintedDivider = context.getDrawable(v.resourceId);
-        mDividerSize = resources.getDimensionPixelSize(R.dimen.usage_graph_divider_size);
-    }
-
-    void clearPaths() {
-        mPaths.clear();
-    }
-
-    void setMax(int maxX, int maxY) {
-        mMaxX = maxX;
-        mMaxY = maxY;
-    }
-
-    void setDividerLoc(int height) {
-        mMiddleDividerLoc = 1 - height / mMaxY;
-    }
-
-    void setDividerColors(int middleColor, int topColor) {
-        mMiddleDividerTint = middleColor;
-        mTopDividerTint = topColor;
-    }
-
-    public void addPath(SparseIntArray points) {
-        for (int i = 0; i < points.size(); i++) {
-            mPaths.put(points.keyAt(i), points.valueAt(i));
-        }
-        mPaths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM);
-        calculateLocalPaths();
-        postInvalidate();
-    }
-
-    void setAccentColor(int color) {
-        mAccentColor = color;
-        mLinePaint.setColor(mAccentColor);
-        updateGradient();
-        postInvalidate();
-    }
-
-    void setShowProjection(boolean showProjection, boolean projectUp) {
-        mShowProjection = showProjection;
-        mProjectUp = projectUp;
-        postInvalidate();
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        updateGradient();
-        calculateLocalPaths();
-    }
-
-    private void calculateLocalPaths() {
-        if (getWidth() == 0) return;
-        mLocalPaths.clear();
-        int pendingXLoc = 0;
-        int pendingYLoc = PATH_DELIM;
-        for (int i = 0; i < mPaths.size(); i++) {
-            int x = mPaths.keyAt(i);
-            int y = mPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                if (i == mPaths.size() - 1 && pendingYLoc != PATH_DELIM) {
-                    // Connect to the end of the graph.
-                    mLocalPaths.put(pendingXLoc, pendingYLoc);
-                }
-                // Clear out any pending points.
-                pendingYLoc = PATH_DELIM;
-                mLocalPaths.put(pendingXLoc + 1, PATH_DELIM);
-            } else {
-                final int lx = getX(x);
-                final int ly = getY(y);
-                pendingXLoc = lx;
-                if (mLocalPaths.size() > 0) {
-                    int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1);
-                    int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1);
-                    if (lastY != PATH_DELIM && !hasDiff(lastX, lx) && !hasDiff(lastY, ly)) {
-                        pendingYLoc = ly;
-                        continue;
-                    }
-                }
-                mLocalPaths.put(lx, ly);
-            }
-        }
-    }
-
-    private boolean hasDiff(int x1, int x2) {
-        return Math.abs(x2 - x1) >= mCornerRadius;
-    }
-
-    private int getX(float x) {
-        return (int) (x / mMaxX * getWidth());
-    }
-
-    private int getY(float y) {
-        return (int) (getHeight() * (1 - (y / mMaxY)));
-    }
-
-    private void updateGradient() {
-        mFillPaint.setShader(new LinearGradient(0, 0, 0, getHeight(),
-                getColor(mAccentColor, .2f), 0, TileMode.CLAMP));
-    }
-
-    private int getColor(int color, float alphaScale) {
-        return (color & (((int) (0xff * alphaScale) << 24) | 0xffffff));
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        // Draw lines across the top, middle, and bottom.
-        if (mMiddleDividerLoc != 0) {
-            drawDivider(0, canvas, mTopDividerTint);
-        }
-        drawDivider((int) ((canvas.getHeight() - mDividerSize) * mMiddleDividerLoc), canvas,
-                mMiddleDividerTint);
-        drawDivider(canvas.getHeight() - mDividerSize, canvas, -1);
-
-        if (mLocalPaths.size() == 0) {
-            return;
-        }
-        if (mShowProjection) {
-            drawProjection(canvas);
-        }
-        drawFilledPath(canvas);
-        drawLinePath(canvas);
-    }
-
-    private void drawProjection(Canvas canvas) {
-        mPath.reset();
-        int x = mLocalPaths.keyAt(mLocalPaths.size() - 2);
-        int y = mLocalPaths.valueAt(mLocalPaths.size() - 2);
-        mPath.moveTo(x, y);
-        mPath.lineTo(canvas.getWidth(), mProjectUp ? 0 : canvas.getHeight());
-        canvas.drawPath(mPath, mDottedPaint);
-    }
-
-    private void drawLinePath(Canvas canvas) {
-        mPath.reset();
-        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
-        for (int i = 1; i < mLocalPaths.size(); i++) {
-            int x = mLocalPaths.keyAt(i);
-            int y = mLocalPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                if (++i < mLocalPaths.size()) {
-                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
-                }
-            } else {
-                mPath.lineTo(x, y);
-            }
-        }
-        canvas.drawPath(mPath, mLinePaint);
-    }
-
-    private void drawFilledPath(Canvas canvas) {
-        mPath.reset();
-        float lastStartX = mLocalPaths.keyAt(0);
-        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
-        for (int i = 1; i < mLocalPaths.size(); i++) {
-            int x = mLocalPaths.keyAt(i);
-            int y = mLocalPaths.valueAt(i);
-            if (y == PATH_DELIM) {
-                mPath.lineTo(mLocalPaths.keyAt(i - 1), getHeight());
-                mPath.lineTo(lastStartX, getHeight());
-                mPath.close();
-                if (++i < mLocalPaths.size()) {
-                    lastStartX = mLocalPaths.keyAt(i);
-                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
-                }
-            } else {
-                mPath.lineTo(x, y);
-            }
-        }
-        canvas.drawPath(mPath, mFillPaint);
-    }
-
-    private void drawDivider(int y, Canvas canvas, int tintColor) {
-        Drawable d = mDivider;
-        if (tintColor != -1) {
-            mTintedDivider.setTint(tintColor);
-            d = mTintedDivider;
-        }
-        d.setBounds(0, y, canvas.getWidth(), y + mDividerSize);
-        d.draw(canvas);
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
deleted file mode 100644
index e2c05a1..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
+++ /dev/null
@@ -1,141 +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.settingslib.graph;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.util.SparseIntArray;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.android.settingslib.R;
-
-public class UsageView extends FrameLayout {
-
-    private final UsageGraph mUsageGraph;
-    private final TextView[] mLabels;
-    private final TextView[] mBottomLabels;
-
-    public UsageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        LayoutInflater.from(context).inflate(R.layout.usage_view, this);
-        mUsageGraph = findViewById(R.id.usage_graph);
-        mLabels = new TextView[] {
-                findViewById(R.id.label_bottom),
-                findViewById(R.id.label_middle),
-                findViewById(R.id.label_top),
-        };
-        mBottomLabels = new TextView[] {
-                findViewById(R.id.label_start),
-                findViewById(R.id.label_end),
-        };
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UsageView, 0, 0);
-        if (a.hasValue(R.styleable.UsageView_sideLabels)) {
-            setSideLabels(a.getTextArray(R.styleable.UsageView_sideLabels));
-        }
-        if (a.hasValue(R.styleable.UsageView_bottomLabels)) {
-            setBottomLabels(a.getTextArray(R.styleable.UsageView_bottomLabels));
-        }
-        if (a.hasValue(R.styleable.UsageView_textColor)) {
-            int color = a.getColor(R.styleable.UsageView_textColor, 0);
-            for (TextView v : mLabels) {
-                v.setTextColor(color);
-            }
-            for (TextView v : mBottomLabels) {
-                v.setTextColor(color);
-            }
-        }
-        if (a.hasValue(R.styleable.UsageView_android_gravity)) {
-            int gravity = a.getInt(R.styleable.UsageView_android_gravity, 0);
-            if (gravity == Gravity.END) {
-                LinearLayout layout = findViewById(R.id.graph_label_group);
-                LinearLayout labels = findViewById(R.id.label_group);
-                // Swap the children order.
-                layout.removeView(labels);
-                layout.addView(labels);
-                // Set gravity.
-                labels.setGravity(Gravity.END);
-                // Swap the bottom space order.
-                LinearLayout bottomLabels = findViewById(R.id.bottom_label_group);
-                View bottomSpace = bottomLabels.findViewById(R.id.bottom_label_space);
-                bottomLabels.removeView(bottomSpace);
-                bottomLabels.addView(bottomSpace);
-            } else if (gravity != Gravity.START) {
-                throw new IllegalArgumentException("Unsupported gravity " + gravity);
-            }
-        }
-        mUsageGraph.setAccentColor(a.getColor(R.styleable.UsageView_android_colorAccent, 0));
-    }
-
-    public void clearPaths() {
-        mUsageGraph.clearPaths();
-    }
-
-    public void addPath(SparseIntArray points) {
-        mUsageGraph.addPath(points);
-    }
-
-    public void configureGraph(int maxX, int maxY, boolean showProjection, boolean projectUp) {
-        mUsageGraph.setMax(maxX, maxY);
-        mUsageGraph.setShowProjection(showProjection, projectUp);
-    }
-
-    public void setAccentColor(int color) {
-        mUsageGraph.setAccentColor(color);
-    }
-
-    public void setDividerLoc(int dividerLoc) {
-        mUsageGraph.setDividerLoc(dividerLoc);
-    }
-
-    public void setDividerColors(int middleColor, int topColor) {
-        mUsageGraph.setDividerColors(middleColor, topColor);
-    }
-
-    public void setSideLabelWeights(float before, float after) {
-        setWeight(R.id.space1, before);
-        setWeight(R.id.space2, after);
-    }
-
-    private void setWeight(int id, float weight) {
-        View v = findViewById(id);
-        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
-        params.weight = weight;
-        v.setLayoutParams(params);
-    }
-
-    public void setSideLabels(CharSequence[] labels) {
-        if (labels.length != mLabels.length) {
-            throw new IllegalArgumentException("Invalid number of labels");
-        }
-        for (int i = 0; i < mLabels.length; i++) {
-            mLabels[i].setText(labels[i]);
-        }
-    }
-
-    public void setBottomLabels(CharSequence[] labels) {
-        if (labels.length != mBottomLabels.length) {
-            throw new IllegalArgumentException("Invalid number of labels");
-        }
-        for (int i = 0; i < mBottomLabels.length; i++) {
-            mBottomLabels[i].setText(labels[i]);
-        }
-    }
-
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
new file mode 100644
index 0000000..19e556a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionCategory.java
@@ -0,0 +1,25 @@
+/*
+ * 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.settingslib.suggestions;
+
+public class SuggestionCategory {
+    public String category;
+    public String pkg;
+    public boolean multiple;
+    public boolean exclusive;
+    public long exclusiveExpireDaysInMillis;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
new file mode 100644
index 0000000..2151ba0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionList.java
@@ -0,0 +1,95 @@
+/*
+ * 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.settingslib.suggestions;
+
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.settingslib.drawer.Tile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class SuggestionList {
+    // Category -> list of suggestion map
+    private final Map<SuggestionCategory, List<Tile>> mSuggestions;
+
+    // A flatten list of all suggestions.
+    private List<Tile> mSuggestionList;
+
+    public SuggestionList() {
+        mSuggestions = new ArrayMap<>();
+    }
+
+    public void addSuggestions(SuggestionCategory category, List<Tile> suggestions) {
+        mSuggestions.put(category, suggestions);
+    }
+
+    public List<Tile> getSuggestions() {
+        if (mSuggestionList != null) {
+            return mSuggestionList;
+        }
+        mSuggestionList = new ArrayList<>();
+        for (List<Tile> suggestions : mSuggestions.values()) {
+            mSuggestionList.addAll(suggestions);
+        }
+        dedupeSuggestions(mSuggestionList);
+        return mSuggestionList;
+    }
+
+    public boolean isExclusiveSuggestionCategory() {
+        if (mSuggestions.size() != 1) {
+            // If there is no category, or more than 1 category, it's not exclusive by definition.
+            return false;
+        }
+        for (SuggestionCategory category : mSuggestions.keySet()) {
+            if (category.exclusive) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<Tile> getSuggestionForCategory(String category) {
+        for (Map.Entry<SuggestionCategory, List<Tile>> entry : mSuggestions.entrySet()) {
+            if (TextUtils.equals(entry.getKey().category, category)) {
+                return entry.getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Filter suggestions list so they are all unique.
+     */
+    private void dedupeSuggestions(List<Tile> suggestions) {
+        final Set<String> intents = new ArraySet<>();
+        for (int i = suggestions.size() - 1; i >= 0; i--) {
+            final Tile suggestion = suggestions.get(i);
+            final String intentUri = suggestion.intent.toUri(Intent.URI_INTENT_SCHEME);
+            if (intents.contains(intentUri)) {
+                suggestions.remove(i);
+            } else {
+                intents.add(intentUri);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
new file mode 100644
index 0000000..7f82a1ca
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -0,0 +1,515 @@
+/*
+ * 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.settingslib.suggestions;
+
+import android.Manifest;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Xml;
+import android.view.InflateException;
+
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SuggestionParser {
+
+    private static final String TAG = "SuggestionParser";
+
+    // If defined, only returns this suggestion if the feature is supported.
+    public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
+
+    // If defined, only display this optional step if an account of that type exists.
+    private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
+
+    // If defined and not true, do not should optional step.
+    private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
+
+    // If defined, only display this optional step if the current user is of that type.
+    private static final String META_DATA_REQUIRE_USER_TYPE =
+            "com.android.settings.require_user_type";
+
+    // If defined, only display this optional step if a connection is available.
+    private static final String META_DATA_IS_CONNECTION_REQUIRED =
+            "com.android.settings.require_connection";
+
+    // The valid values that setup wizard recognizes for differentiating user types.
+    private static final String META_DATA_PRIMARY_USER_TYPE_VALUE = "primary";
+    private static final String META_DATA_ADMIN_USER_TYPE_VALUE = "admin";
+    private static final String META_DATA_GUEST_USER_TYPE_VALUE = "guest";
+    private static final String META_DATA_RESTRICTED_USER_TYPE_VALUE = "restricted";
+
+    /**
+     * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
+     * For instance:
+     * 0,10
+     * Will appear immediately, but if the user removes it, it will come back after 10 days.
+     *
+     * Another example:
+     * 10,30
+     * Will only show up after 10 days, and then again after 30.
+     */
+    public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
+
+    // Shared prefs keys for storing dismissed state.
+    // Index into current dismissed state.
+    @VisibleForTesting
+    static final String DISMISS_INDEX = "_dismiss_index";
+    private static final String SETUP_TIME = "_setup_time";
+    private static final String IS_DISMISSED = "_is_dismissed";
+
+    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+
+    // Default dismiss control for smart suggestions.
+    private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
+
+    private final Context mContext;
+    private final List<SuggestionCategory> mSuggestionList;
+    private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
+    private final SharedPreferences mSharedPrefs;
+    private final String mSmartDismissControl;
+
+
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml,
+            String smartDismissControl) {
+        this(
+                context,
+                sharedPrefs,
+                (List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
+                smartDismissControl);
+    }
+
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
+        this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
+    }
+
+    @VisibleForTesting
+    public SuggestionParser(
+            Context context,
+            SharedPreferences sharedPrefs,
+            List<SuggestionCategory> suggestionList,
+            String smartDismissControl) {
+        mContext = context;
+        mSuggestionList = suggestionList;
+        mSharedPrefs = sharedPrefs;
+        mSmartDismissControl = smartDismissControl;
+    }
+
+    public SuggestionList getSuggestions(boolean isSmartSuggestionEnabled) {
+        final SuggestionList suggestionList = new SuggestionList();
+        final int N = mSuggestionList.size();
+        for (int i = 0; i < N; i++) {
+            final SuggestionCategory category = mSuggestionList.get(i);
+            if (category.exclusive && !isExclusiveCategoryExpired(category)) {
+                // If suggestions from an exclusive category are present, parsing is stopped
+                // and only suggestions from that category are displayed. Note that subsequent
+                // exclusive categories are also ignored.
+                final List<Tile> exclusiveSuggestions = new ArrayList<>();
+
+                // Read suggestion and force isSmartSuggestion to be false so the rule defined
+                // from each suggestion itself is used.
+                readSuggestions(category, exclusiveSuggestions, false /* isSmartSuggestion */);
+                if (!exclusiveSuggestions.isEmpty()) {
+                    final SuggestionList exclusiveList = new SuggestionList();
+                    exclusiveList.addSuggestions(category, exclusiveSuggestions);
+                    return exclusiveList;
+                }
+            } else {
+                // Either the category is not exclusive, or the exclusiveness expired so we should
+                // treat it as a normal category.
+                final List<Tile> suggestions = new ArrayList<>();
+                readSuggestions(category, suggestions, isSmartSuggestionEnabled);
+                suggestionList.addSuggestions(category, suggestions);
+            }
+        }
+        return suggestionList;
+    }
+
+    public boolean dismissSuggestion(Tile suggestion) {
+        return dismissSuggestion(suggestion, false);
+    }
+
+    /**
+     * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
+     * be disabled.
+     */
+    public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
+        if (dismissControl == null || parseDismissString(dismissControl).length == index) {
+            return true;
+        }
+        mSharedPrefs.edit()
+                .putBoolean(keyBase + IS_DISMISSED, true)
+                .commit();
+        return false;
+    }
+
+    @VisibleForTesting
+    public void filterSuggestions(
+            List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
+        for (int i = countBefore; i < suggestions.size(); i++) {
+            if (!isAvailable(suggestions.get(i)) ||
+                    !isSupported(suggestions.get(i)) ||
+                    !satisifesRequiredUserType(suggestions.get(i)) ||
+                    !satisfiesRequiredAccount(suggestions.get(i)) ||
+                    !satisfiesConnectivity(suggestions.get(i)) ||
+                    isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
+                suggestions.remove(i--);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void readSuggestions(
+            SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
+        int countBefore = suggestions.size();
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(category.category);
+        if (category.pkg != null) {
+            intent.setPackage(category.pkg);
+        }
+        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
+                mAddCache, null, suggestions, true, false, false);
+        filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
+        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
+            // If there are too many, remove them all and only re-add the one with the highest
+            // priority.
+            Tile item = suggestions.remove(suggestions.size() - 1);
+            while (suggestions.size() > countBefore) {
+                Tile last = suggestions.remove(suggestions.size() - 1);
+                if (last.priority > item.priority) {
+                    item = last;
+                }
+            }
+            // If category is marked as done, do not add any item.
+            if (!isCategoryDone(category.category)) {
+                suggestions.add(item);
+            }
+        }
+    }
+
+    private boolean isAvailable(Tile suggestion) {
+        final String featuresRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
+        if (featuresRequired != null) {
+            for (String feature : featuresRequired.split(",")) {
+                if (TextUtils.isEmpty(feature)) {
+                    Log.w(TAG, "Found empty substring when parsing required features: "
+                            + featuresRequired);
+                } else if (!mContext.getPackageManager().hasSystemFeature(feature)) {
+                    Log.i(TAG, suggestion.title + " requires unavailable feature " + feature);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
+    private boolean satisifesRequiredUserType(Tile suggestion) {
+        final String requiredUser = suggestion.metaData.getString(META_DATA_REQUIRE_USER_TYPE);
+        if (requiredUser != null) {
+            final UserManager userManager = mContext.getSystemService(UserManager.class);
+            UserInfo userInfo = userManager.getUserInfo(UserHandle.myUserId());
+            for (String userType : requiredUser.split("\\|")) {
+                final boolean primaryUserCondtionMet = userInfo.isPrimary()
+                        && META_DATA_PRIMARY_USER_TYPE_VALUE.equals(userType);
+                final boolean adminUserConditionMet = userInfo.isAdmin()
+                        && META_DATA_ADMIN_USER_TYPE_VALUE.equals(userType);
+                final boolean guestUserCondtionMet = userInfo.isGuest()
+                        && META_DATA_GUEST_USER_TYPE_VALUE.equals(userType);
+                final boolean restrictedUserCondtionMet = userInfo.isRestricted()
+                        && META_DATA_RESTRICTED_USER_TYPE_VALUE.equals(userType);
+                if (primaryUserCondtionMet || adminUserConditionMet || guestUserCondtionMet
+                        || restrictedUserCondtionMet) {
+                    return true;
+                }
+            }
+            Log.i(TAG, suggestion.title + " requires user type " + requiredUser);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean satisfiesRequiredAccount(Tile suggestion) {
+        final String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
+        if (requiredAccountType == null) {
+            return true;
+        }
+        AccountManager accountManager = AccountManager.get(mContext);
+        Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
+        boolean satisfiesRequiredAccount = accounts.length > 0;
+        if (!satisfiesRequiredAccount) {
+            Log.i(TAG, suggestion.title + " requires unavailable account type "
+                    + requiredAccountType);
+        }
+        return satisfiesRequiredAccount;
+    }
+
+    public boolean isSupported(Tile suggestion) {
+        final int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
+        try {
+            if (suggestion.intent == null) {
+                return false;
+            }
+            final Resources res = mContext.getPackageManager().getResourcesForActivity(
+                    suggestion.intent.getComponent());
+            boolean isSupported =
+                    isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
+            if (!isSupported) {
+                Log.i(TAG, suggestion.title + " requires unsupported resource "
+                        + isSupportedResource);
+            }
+            return isSupported;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
+            return false;
+        } catch (Resources.NotFoundException e) {
+            Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent(), e);
+            return false;
+        }
+    }
+
+    private boolean satisfiesConnectivity(Tile suggestion) {
+        final boolean isConnectionRequired =
+                suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
+        if (!isConnectionRequired) {
+            return true;
+        }
+        ConnectivityManager cm =
+                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo netInfo = cm.getActiveNetworkInfo();
+        boolean satisfiesConnectivity = netInfo != null && netInfo.isConnectedOrConnecting();
+        if (!satisfiesConnectivity) {
+            Log.i(TAG, suggestion.title + " is missing required connection.");
+        }
+        return satisfiesConnectivity;
+    }
+
+    public boolean isCategoryDone(String category) {
+        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+        return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
+    }
+
+    public void markCategoryDone(String category) {
+        String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+        Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
+    }
+
+    /**
+     * Whether or not the category's exclusiveness has expired.
+     */
+    private boolean isExclusiveCategoryExpired(SuggestionCategory category) {
+        final String keySetupTime = category.category + SETUP_TIME;
+        final long currentTime = System.currentTimeMillis();
+        if (!mSharedPrefs.contains(keySetupTime)) {
+            mSharedPrefs.edit()
+                    .putLong(keySetupTime, currentTime)
+                    .commit();
+        }
+        if (category.exclusiveExpireDaysInMillis < 0) {
+            // negative means never expires
+            return false;
+        }
+        final long setupTime = mSharedPrefs.getLong(keySetupTime, 0);
+        final long elapsedTime = currentTime - setupTime;
+        Log.d(TAG, "Day " + elapsedTime / DateUtils.DAY_IN_MILLIS + " for " + category.category);
+        return elapsedTime > category.exclusiveExpireDaysInMillis;
+    }
+
+    @VisibleForTesting
+    boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
+        if (dismissControl == null) {
+            return false;
+        }
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
+            mSharedPrefs.edit()
+                    .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
+                    .commit();
+        }
+        // Default to dismissed, so that we can have suggestions that only first appear after
+        // some number of days.
+        if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
+            return false;
+        }
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        int[] dismissRules = parseDismissString(dismissControl);
+        if (dismissRules.length <= index) {
+            return true;
+        }
+        int currentDismiss = dismissRules[index];
+        long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
+        if (System.currentTimeMillis() >= time) {
+            // Dismiss timeout has passed, undismiss it.
+            mSharedPrefs.edit()
+                    .putBoolean(keyBase + IS_DISMISSED, false)
+                    .putInt(keyBase + DISMISS_INDEX, index + 1)
+                    .commit();
+            return false;
+        }
+        return true;
+    }
+
+    private long getEndTime(long startTime, int daysDelay) {
+        long days = daysDelay * MILLIS_IN_DAY;
+        return startTime + days;
+    }
+
+    private int[] parseDismissString(String dismissControl) {
+        String[] dismissStrs = dismissControl.split(",");
+        int[] dismisses = new int[dismissStrs.length];
+        for (int i = 0; i < dismissStrs.length; i++) {
+            dismisses[i] = Integer.parseInt(dismissStrs[i]);
+        }
+        return dismisses;
+    }
+
+    private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
+        if (isSmartSuggestionEnabled) {
+            return mSmartDismissControl;
+        } else {
+            return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+        }
+    }
+
+    private static class SuggestionOrderInflater {
+        private static final String TAG_LIST = "optional-steps";
+        private static final String TAG_ITEM = "step";
+
+        private static final String ATTR_CATEGORY = "category";
+        private static final String ATTR_PACKAGE = "package";
+        private static final String ATTR_MULTIPLE = "multiple";
+        private static final String ATTR_EXCLUSIVE = "exclusive";
+        private static final String ATTR_EXCLUSIVE_EXPIRE_DAYS = "exclusiveExpireDays";
+
+        private final Context mContext;
+
+        public SuggestionOrderInflater(Context context) {
+            mContext = context;
+        }
+
+        public Object parse(int resource) {
+            XmlPullParser parser = mContext.getResources().getXml(resource);
+            final AttributeSet attrs = Xml.asAttributeSet(parser);
+            try {
+                // Look for the root node.
+                int type;
+                do {
+                    type = parser.next();
+                } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
+
+                if (type != XmlPullParser.START_TAG) {
+                    throw new InflateException(parser.getPositionDescription()
+                            + ": No start tag found!");
+                }
+
+                // Temp is the root that was found in the xml
+                Object xmlRoot = onCreateItem(parser.getName(), attrs);
+
+                // Inflate all children under temp
+                rParse(parser, xmlRoot, attrs);
+                return xmlRoot;
+            } catch (XmlPullParserException | IOException e) {
+                Log.w(TAG, "Problem parser resource " + resource, e);
+                return null;
+            }
+        }
+
+        /**
+         * Recursive method used to descend down the xml hierarchy and instantiate
+         * items, instantiate their children.
+         */
+        private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
+                throws XmlPullParserException, IOException {
+            final int depth = parser.getDepth();
+
+            int type;
+            while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+                if (type != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                final String name = parser.getName();
+
+                Object item = onCreateItem(name, attrs);
+                onAddChildItem(parent, item);
+                rParse(parser, item, attrs);
+            }
+        }
+
+        protected void onAddChildItem(Object parent, Object child) {
+            if (parent instanceof List<?> && child instanceof SuggestionCategory) {
+                ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
+            } else {
+                throw new IllegalArgumentException("Parent was not a list");
+            }
+        }
+
+        protected Object onCreateItem(String name, AttributeSet attrs) {
+            if (name.equals(TAG_LIST)) {
+                return new ArrayList<SuggestionCategory>();
+            } else if (name.equals(TAG_ITEM)) {
+                SuggestionCategory category = new SuggestionCategory();
+                category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
+                category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
+                String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
+                category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
+                String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
+                category.exclusive =
+                        !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
+                String expireDaysAttr = attrs.getAttributeValue(null,
+                        ATTR_EXCLUSIVE_EXPIRE_DAYS);
+                long expireDays = !TextUtils.isEmpty(expireDaysAttr)
+                        ? Integer.parseInt(expireDaysAttr)
+                        : -1;
+                category.exclusiveExpireDaysInMillis = DateUtils.DAY_IN_MILLIS * expireDays;
+                return category;
+            } else {
+                throw new IllegalArgumentException("Unknown item " + name);
+            }
+        }
+    }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
new file mode 100644
index 0000000..2024991
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
@@ -0,0 +1,42 @@
+/*
+ * 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.settingslib.utils;
+
+import android.os.Looper;
+
+public class ThreadUtils {
+    private static volatile Thread sMainThread;
+
+    /**
+     * Returns true if the current thread is the UI thread.
+     */
+    public static boolean isMainThread() {
+        if (sMainThread == null) {
+            sMainThread = Looper.getMainLooper().getThread();
+        }
+        return Thread.currentThread() == sMainThread;
+    }
+
+    /**
+     * Checks that the current thread is the UI thread. Otherwise throws an exception.
+     */
+    public static void ensureMainThread() {
+        if (!isMainThread()) {
+            throw new RuntimeException("Must be called on the UI thread");
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
new file mode 100644
index 0000000..0c3a5e9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
@@ -0,0 +1,63 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v4.content.res.TypedArrayUtils;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+
+/**
+ * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
+ * to screen as the last preference.
+ */
+public class FooterPreference extends Preference {
+
+    static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
+    static final String KEY_FOOTER = "footer_preference";
+
+    public FooterPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, TypedArrayUtils.getAttr(
+                context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
+        init();
+    }
+
+    public FooterPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        TextView title = holder.itemView.findViewById(android.R.id.title);
+        title.setMovementMethod(new LinkMovementMethod());
+        title.setClickable(false);
+        title.setLongClickable(false);
+    }
+
+    private void init() {
+        setIcon(R.drawable.ic_info_outline_24dp);
+        setKey(KEY_FOOTER);
+        setOrder(ORDER_FOOTER);
+        setSelectable(false);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java
new file mode 100644
index 0000000..2edcd9e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreferenceMixin.java
@@ -0,0 +1,71 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen;
+
+public class FooterPreferenceMixin implements LifecycleObserver, SetPreferenceScreen {
+
+    private final PreferenceFragment mFragment;
+    private FooterPreference mFooterPreference;
+
+    public FooterPreferenceMixin(PreferenceFragment fragment, Lifecycle lifecycle) {
+        mFragment = fragment;
+        lifecycle.addObserver(this);
+    }
+
+    @Override
+    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+        if (mFooterPreference != null) {
+            preferenceScreen.addPreference(mFooterPreference);
+        }
+    }
+
+    /**
+     * Creates a new {@link FooterPreference}.
+     */
+    public FooterPreference createFooterPreference() {
+        final PreferenceScreen screen = mFragment.getPreferenceScreen();
+        if (mFooterPreference != null && screen != null) {
+            screen.removePreference(mFooterPreference);
+        }
+        mFooterPreference = new FooterPreference(getPrefContext());
+
+        if (screen != null) {
+            screen.addPreference(mFooterPreference);
+        }
+        return mFooterPreference;
+    }
+
+    /**
+     * Returns an UI context with theme properly set for new Preference objects.
+     */
+    private Context getPrefContext() {
+        return mFragment.getPreferenceManager().getContext();
+    }
+
+    public boolean hasFooter() {
+        return mFooterPreference != null;
+    }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 0ea9d96..306f9ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -16,13 +16,14 @@
 
 package com.android.settingslib.wifi;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -53,6 +54,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
@@ -82,6 +85,30 @@
      */
     public static final int HIGHER_FREQ_5GHZ = 5900;
 
+    @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Speed {
+        /**
+         * Constant value representing an unlabeled / unscored network.
+         */
+        int NONE = 0;
+        /**
+         * Constant value representing a slow speed network connection.
+         */
+        int SLOW = 5;
+        /**
+         * Constant value representing a medium speed network connection.
+         */
+        int MODERATE = 10;
+        /**
+         * Constant value representing a fast speed network connection.
+         */
+        int FAST = 20;
+        /**
+         * Constant value representing a very fast speed network connection.
+         */
+        int VERY_FAST = 30;
+    }
 
     /**
      * Experimental: we should be able to show the user the list of BSSIDs and bands
@@ -91,6 +118,7 @@
      */
     private final ConcurrentHashMap<String, ScanResult> mScanResultCache =
             new ConcurrentHashMap<String, ScanResult>(32);
+    /** Maximum age of scan results to hold onto while actively scanning. **/
     private static final long MAX_SCAN_RESULT_AGE_MS = 15000;
 
     static final String KEY_NETWORKINFO = "key_networkinfo";
@@ -148,7 +176,7 @@
     private Object mTag;
 
     private int mRankingScore = Integer.MIN_VALUE;
-    private int mBadge = NetworkBadging.BADGING_NONE;
+    private int mSpeed = Speed.NONE;
     private boolean mIsScoredNetworkMetered = false;
 
     // used to co-relate internal vs returned accesspoint.
@@ -195,6 +223,8 @@
             mProviderFriendlyName = savedState.getString(KEY_PROVIDER_FRIENDLY_NAME);
         }
         update(mConfig, mInfo, mNetworkInfo);
+
+        // Do not evict old scan results on initial creation
         updateRssi();
         updateSeen();
         mId = sLastId.incrementAndGet();
@@ -248,7 +278,7 @@
         this.mScanResultCache.clear();
         this.mScanResultCache.putAll(that.mScanResultCache);
         this.mId = that.mId;
-        this.mBadge = that.mBadge;
+        this.mSpeed = that.mSpeed;
         this.mIsScoredNetworkMetered = that.mIsScoredNetworkMetered;
         this.mRankingScore = that.mRankingScore;
     }
@@ -293,8 +323,15 @@
         if (difference != 0) {
             return difference;
         }
+
         // Sort by ssid.
-        return getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        difference = getSsidStr().compareToIgnoreCase(other.getSsidStr());
+        if (difference != 0) {
+            return difference;
+        }
+
+        // Do a case sensitive comparison to distinguish SSIDs that differ in case only
+        return getSsidStr().compareTo(other.getSsidStr());
     }
 
     @Override
@@ -335,13 +372,12 @@
         if (security != SECURITY_NONE) {
             builder.append(',').append(securityToString(security, pskType));
         }
-        builder.append(",mRssi=").append(mRssi);
         builder.append(",level=").append(getLevel());
         if (mRankingScore != Integer.MIN_VALUE) {
             builder.append(",rankingScore=").append(mRankingScore);
         }
-        if (mBadge != NetworkBadging.BADGING_NONE) {
-            builder.append(",badge=").append(mBadge);
+        if (mSpeed != Speed.NONE) {
+            builder.append(",speed=").append(mSpeed);
         }
         builder.append(",metered=").append(isMetered());
 
@@ -349,7 +385,7 @@
     }
 
     /**
-     * Updates the AccessPoint rankingScore, metering, and badge, returning true if the data has
+     * Updates the AccessPoint rankingScore, metering, and speed, returning true if the data has
      * changed.
      *
      * @param scoreCache The score cache to use to retrieve scores.
@@ -364,14 +400,14 @@
     }
 
     /**
-     * Updates the AccessPoint rankingScore and badge, returning true if the data has changed.
+     * Updates the AccessPoint rankingScore and speed, returning true if the data has changed.
      *
      * @param scoreCache The score cache to use to retrieve scores.
      */
     private boolean updateScores(WifiNetworkScoreCache scoreCache) {
-        int oldBadge = mBadge;
+        int oldSpeed = mSpeed;
         int oldRankingScore = mRankingScore;
-        mBadge = NetworkBadging.BADGING_NONE;
+        mSpeed = Speed.NONE;
         mRankingScore = Integer.MIN_VALUE;
 
         for (ScanResult result : mScanResultCache.values()) {
@@ -383,10 +419,11 @@
             if (score.hasRankingScore()) {
                 mRankingScore = Math.max(mRankingScore, score.calculateRankingScore(result.level));
             }
-            mBadge = Math.max(mBadge, score.calculateBadge(result.level));
+            // TODO(sghuman): Rename calculateBadge API
+            mSpeed = Math.max(mSpeed, score.calculateBadge(result.level));
         }
 
-        return (oldBadge != mBadge || oldRankingScore != mRankingScore);
+        return (oldSpeed != mSpeed || oldRankingScore != mRankingScore);
     }
 
     /**
@@ -470,12 +507,8 @@
      * results, returning the best RSSI for all matching AccessPoints averaged with the previous
      * value. If the access point is not connected and there are no scan results, the rssi will be
      * set to {@link #UNREACHABLE_RSSI}.
-     *
-     * <p>Old scan results will be evicted from the cache when this method is invoked.
      */
     private void updateRssi() {
-        evictOldScanResults();
-
         if (this.isActive()) {
             return;
         }
@@ -494,14 +527,8 @@
         }
     }
 
-    /**
-     * Updates {@link #mSeen} based on the scan result cache.
-     *
-     * <p>Old scan results will be evicted from the cache when this method is invoked.
-     */
+    /** Updates {@link #mSeen} based on the scan result cache. */
     private void updateSeen() {
-        evictOldScanResults();
-
         // TODO(sghuman): Set to now if connected
 
         long seen = 0;
@@ -643,6 +670,13 @@
         // Update to new summary
         StringBuilder summary = new StringBuilder();
 
+        // TODO(b/62354743): Standardize and international delimiter usage
+        final String concatenator = " / ";
+
+        if (mSpeed != Speed.NONE) {
+            summary.append(getSpeedLabel() + concatenator);
+        }
+
         if (isActive() && config != null && config.isPasspoint()) {
             // This is the active connection on passpoint
             summary.append(getSummary(mContext, getDetailedState(),
@@ -667,6 +701,9 @@
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
                     break;
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
+                    summary.append(mContext.getString(R.string.wifi_check_password_try_again));
+                    break;
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
                 case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
@@ -722,6 +759,14 @@
                 }
             }
         }
+
+        // Strip trailing delimiter if applicable
+        int concatLength = concatenator.length();
+        if (summary.length() >= concatLength && summary.substring(
+                summary.length() - concatLength, summary.length()).equals(concatenator)) {
+            summary.delete(summary.length() - concatLength, summary.length());
+        }
+
         return summary.toString();
     }
 
@@ -750,10 +795,10 @@
             visibility.append(" ");
             visibility.append(" score=").append(mInfo.score);
             if (mRankingScore != Integer.MIN_VALUE) {
-              visibility.append(" rankingScore=").append(getRankingScore());
+                visibility.append(" rankingScore=").append(getRankingScore());
             }
-            if (mBadge != NetworkBadging.BADGING_NONE) {
-              visibility.append(" badge=").append(getBadge());
+            if (mSpeed != Speed.NONE) {
+                visibility.append(" speed=").append(getSpeedLabel());
             }
             visibility.append(String.format(" tx=%.1f,", mInfo.txSuccessRate));
             visibility.append(String.format("%.1f,", mInfo.txRetriesRate));
@@ -973,12 +1018,22 @@
         mAccessPointListener = listener;
     }
 
-    boolean update(ScanResult result) {
+    /**
+     * Update the AP with the given scan result.
+     *
+     * @param result the ScanResult to add to the AccessPoint scan cache
+     * @param evictOldScanResults whether stale scan results should be removed
+     *         from the cache during this update process
+     * @return true if the scan result update caused a change in state which would impact ranking
+     *     or AccessPoint rendering (e.g. wifi level, security)
+     */
+    boolean update(ScanResult result, boolean evictOldScanResults) {
         if (matches(result)) {
             int oldLevel = getLevel();
 
             /* Add or update the scan result for the BSSID */
             mScanResultCache.put(result.BSSID, result);
+            if (evictOldScanResults) evictOldScanResults();
             updateSeen();
             updateRssi();
             int newLevel = getLevel();
@@ -1001,12 +1056,19 @@
     }
 
     /** Attempt to update the AccessPoint and return true if an update occurred. */
-    public boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
+    public boolean update(
+            @Nullable WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
         boolean updated = false;
         final int oldLevel = getLevel();
         if (info != null && isInfoForThisAccessPoint(config, info)) {
             updated = (mInfo == null);
-            if (mRssi != info.getRssi()) {
+            if (mConfig != config) {
+                // We do not set updated = true as we do not want to increase the amount of sorting
+                // and copying performed in WifiTracker at this time. If issues involving refresh
+                // are still seen, we will investigate further.
+                update(config); // Notifies the AccessPointListener of the change
+            }
+            if (mRssi != info.getRssi() && info.getRssi() != WifiInfo.INVALID_RSSI) {
                 mRssi = info.getRssi();
                 updated = true;
             } else if (mNetworkInfo != null && networkInfo != null
@@ -1030,9 +1092,9 @@
         return updated;
     }
 
-    void update(WifiConfiguration config) {
+    void update(@Nullable WifiConfiguration config) {
         mConfig = config;
-        networkId = config.networkId;
+        networkId = config != null ? config.networkId : WifiConfiguration.INVALID_NETWORK_ID;
         if (mAccessPointListener != null) {
             mAccessPointListener.onAccessPointChanged(this);
         }
@@ -1052,8 +1114,23 @@
         return mRankingScore;
     }
 
-    int getBadge() {
-        return mBadge;
+    int getSpeed() { return mSpeed;}
+
+    @Nullable
+    String getSpeedLabel() {
+        switch (mSpeed) {
+            case Speed.VERY_FAST:
+                return mContext.getString(R.string.speed_label_very_fast);
+            case Speed.FAST:
+                return mContext.getString(R.string.speed_label_fast);
+            case Speed.MODERATE:
+                return mContext.getString(R.string.speed_label_okay);
+            case Speed.SLOW:
+                return mContext.getString(R.string.speed_label_slow);
+            case Speed.NONE:
+            default:
+                return null;
+        }
     }
 
     /** Return true if the current RSSI is reachable, and false otherwise. */
@@ -1096,8 +1173,9 @@
 
             if (nc != null) {
                 if (nc.hasCapability(nc.NET_CAPABILITY_CAPTIVE_PORTAL)) {
-                    return context.getString(
-                        com.android.internal.R.string.network_available_sign_in);
+                    int id = context.getResources()
+                            .getIdentifier("network_available_sign_in", "string", "android");
+                    return context.getString(id);
                 } else if (!nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                     return context.getString(R.string.wifi_connected_no_internet);
                 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 7f95379..92995a8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -60,15 +60,29 @@
     private int mLevel;
     private CharSequence mContentDescription;
     private int mDefaultIconResId;
-    private int mWifiBadge = NetworkBadging.BADGING_NONE;
+    private int mWifiSpeed = NetworkBadging.BADGING_NONE;
 
     static final int[] WIFI_CONNECTION_STRENGTH = {
+            R.string.accessibility_no_wifi,
             R.string.accessibility_wifi_one_bar,
             R.string.accessibility_wifi_two_bars,
             R.string.accessibility_wifi_three_bars,
             R.string.accessibility_wifi_signal_full
     };
 
+    public static String generatePreferenceKey(AccessPoint accessPoint) {
+        StringBuilder builder = new StringBuilder();
+
+        if (TextUtils.isEmpty(accessPoint.getBssid())) {
+            builder.append(accessPoint.getSsidStr());
+        } else {
+            builder.append(accessPoint.getBssid());
+        }
+
+        builder.append(',').append(accessPoint.getSecurity());
+        return builder.toString();
+    }
+
     // Used for dummy pref.
     public AccessPointPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -160,8 +174,11 @@
             safeSetDefaultIcon();
             return;
         }
-        TronUtils.logWifiSettingsBadge(context, mWifiBadge);
-        Drawable drawable = NetworkBadging.getWifiIcon(level, mWifiBadge, getContext().getTheme());
+        TronUtils.logWifiSettingsSpeed(context, mWifiSpeed);
+
+        // TODO(b/62355275): Revert this to N code after deleting NetworkBadging API
+        Drawable drawable = NetworkBadging.getWifiIcon(
+                level, NetworkBadging.BADGING_NONE, getContext().getTheme());
         if (!mForSavedNetworks && drawable != null) {
             drawable.setTint(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
             setIcon(drawable);
@@ -219,10 +236,10 @@
 
         final Context context = getContext();
         int level = mAccessPoint.getLevel();
-        int wifiBadge = mAccessPoint.getBadge();
-        if (level != mLevel || wifiBadge != mWifiBadge) {
+        int wifiSpeed = mAccessPoint.getSpeed();
+        if (level != mLevel || wifiSpeed != mWifiSpeed) {
             mLevel = level;
-            mWifiBadge = wifiBadge;
+            mWifiSpeed = wifiSpeed;
             updateIcon(mLevel, context);
             notifyChanged();
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
new file mode 100644
index 0000000..3413f24
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
@@ -0,0 +1,205 @@
+/*
+ * 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.settingslib.wifi;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.os.Bundle;
+import android.support.annotation.Keep;
+
+/**
+* Build and return a valid AccessPoint.
+*
+* Only intended for testing the AccessPoint class or creating Access points to be used in testing
+* applications. AccessPoints were designed to only be populated by the mechanisms of scan results
+* and wifi configurations.
+*/
+@Keep
+public class TestAccessPointBuilder {
+    // match the private values in WifiManager
+    private static final int MIN_RSSI = -100;
+    private static final int MAX_RSSI = -55;
+
+    // set some sensible defaults
+    private String mBssid = null;
+    private int mRssi = AccessPoint.UNREACHABLE_RSSI;
+    private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+    private String ssid = "TestSsid";
+    private NetworkInfo mNetworkInfo = null;
+    private String mFqdn = null;
+    private String mProviderFriendlyName = null;
+    private int mSecurity = AccessPoint.SECURITY_NONE;
+    private WifiConfiguration mWifiConfig;
+    private WifiInfo mWifiInfo;
+
+    Context mContext;
+
+    @Keep
+    public TestAccessPointBuilder(Context context) {
+        mContext = context;
+    }
+
+    @Keep
+    public AccessPoint build() {
+        Bundle bundle = new Bundle();
+
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        wifiConfig.networkId = mNetworkId;
+        wifiConfig.BSSID = mBssid;
+
+        bundle.putString(AccessPoint.KEY_SSID, ssid);
+        bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
+        bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
+        bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
+        if (mFqdn != null) {
+            bundle.putString(AccessPoint.KEY_FQDN, mFqdn);
+        }
+        if (mProviderFriendlyName != null) {
+            bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
+        }
+        bundle.putInt(AccessPoint.KEY_SECURITY, mSecurity);
+
+        AccessPoint ap = new AccessPoint(mContext, bundle);
+        ap.setRssi(mRssi);
+        return ap;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setActive(boolean active) {
+        if (active) {
+            mNetworkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_DUMMY,
+                ConnectivityManager.TYPE_DUMMY,
+                "TestNetwork",
+                "TestNetwork");
+        } else {
+            mNetworkInfo = null;
+        }
+        return this;
+    }
+
+    /**
+     * Set the rssi based upon the desired signal level.
+     *
+     * <p>Side effect: if this AccessPoint was previously unreachable,
+     * setting the level will also make it reachable.
+     */
+    @Keep
+    public TestAccessPointBuilder setLevel(int level) {
+        // Reversal of WifiManager.calculateSignalLevels
+        if (level == 0) {
+            mRssi = MIN_RSSI;
+        } else if (level >= AccessPoint.SIGNAL_LEVELS) {
+            mRssi = MAX_RSSI;
+        } else {
+            float inputRange = MAX_RSSI - MIN_RSSI;
+            float outputRange = AccessPoint.SIGNAL_LEVELS - 1;
+            mRssi = (int) (level * inputRange / outputRange + MIN_RSSI);
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
+        mNetworkInfo = info;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setRssi(int rssi) {
+        mRssi = rssi;
+        return this;
+    }
+
+    /**
+    * Set whether the AccessPoint is reachable.
+    * Side effect: if the signal level was not previously set,
+    * making an AccessPoint reachable will set the signal to the minimum level.
+    */
+    @Keep
+    public TestAccessPointBuilder setReachable(boolean reachable) {
+        if (reachable) {
+            // only override the mRssi if it hasn't been set yet
+            if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
+                mRssi = MIN_RSSI;
+            }
+        } else {
+            mRssi = AccessPoint.UNREACHABLE_RSSI;
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSaved(boolean saved){
+        if (saved) {
+             mNetworkId = 1;
+        } else {
+             mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+        }
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSecurity(int security) {
+        mSecurity = security;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setSsid(String newSsid) {
+        ssid = newSsid;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setFqdn(String fqdn) {
+        mFqdn = fqdn;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
+        mProviderFriendlyName = friendlyName;
+        return this;
+    }
+
+    @Keep
+    public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
+        mWifiInfo = info;
+        return this;
+    }
+
+    /**
+     * Set the networkId in the WifiConfig.
+     *
+     * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
+     * AccessPoint a saved network.
+     */
+    @Keep
+    public TestAccessPointBuilder setNetworkId(int networkId) {
+        mNetworkId = networkId;
+        return this;
+    }
+
+    public TestAccessPointBuilder setBssid(String bssid) {
+        mBssid = bssid;
+        return this;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index ec94841..0d67ad0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -12,17 +12,13 @@
 
 import android.content.Intent;
 import android.net.NetworkInfo;
-import android.net.NetworkKey;
-import android.net.WifiKey;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.util.Log;
 
 import java.util.List;
 
 public class WifiStatusTracker {
-    private static final String TAG = "WifiStatusTracker";
 
     private final WifiManager mWifiManager;
     public boolean enabled;
@@ -32,7 +28,6 @@
     public String ssid;
     public int rssi;
     public int level;
-    public NetworkKey networkKey;
 
     public WifiStatusTracker(WifiManager wifiManager) {
         mWifiManager = wifiManager;
@@ -54,32 +49,19 @@
             connecting = networkInfo != null && !networkInfo.isConnected()
                     && networkInfo.isConnectedOrConnecting();
             connected = networkInfo != null && networkInfo.isConnected();
-            WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
-                    ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
-                    : mWifiManager.getConnectionInfo();
-
             // If Connected grab the signal strength and ssid.
-            if (connected && info != null) {
-                ssid = getSsid(info);
-                String bssid = info.getBSSID();
-                if ((ssid != null) && (bssid != null)) {
-                    // Reuse existing network key object if possible.
-                    if ((networkKey == null)
-                            || !networkKey.wifiKey.ssid.equals(ssid)
-                            || !networkKey.wifiKey.bssid.equals(bssid)) {
-                        try {
-                            networkKey = new NetworkKey(
-                                    new WifiKey(ssid, bssid));
-                        } catch (IllegalArgumentException e) {
-                            Log.e(TAG, "Cannot create NetworkKey", e);
-                        }
-                    }
+            if (connected) {
+                // try getting it out of the intent first
+                WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
+                        ? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
+                        : mWifiManager.getConnectionInfo();
+                if (info != null) {
+                    ssid = getSsid(info);
                 } else {
-                    networkKey = null;
+                    ssid = null;
                 }
-            } else {
+            } else if (!connected) {
                 ssid = null;
-                networkKey = null;
             }
         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
             // Default to -200 as its below WifiManager.MIN_RSSI.
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index fcc9090..f8e2f8b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -36,7 +36,6 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
 import android.net.wifi.WifiNetworkScoreCache.CacheListener;
-import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -91,7 +90,7 @@
     private final boolean mIncludeScans;
     private final boolean mIncludePasspoints;
     @VisibleForTesting final MainHandler mMainHandler;
-    private final WorkHandler mWorkHandler;
+    @VisibleForTesting final WorkHandler mWorkHandler;
 
     private WifiTrackerNetworkCallback mNetworkCallback;
 
@@ -136,13 +135,17 @@
 
     private final NetworkScoreManager mNetworkScoreManager;
     private final WifiNetworkScoreCache mScoreCache;
+    private boolean mNetworkScoringUiEnabled;
+    private final ContentObserver mObserver;
 
     @GuardedBy("mLock")
     private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
 
     @VisibleForTesting
     Scanner mScanner;
-    private boolean mStaleScanResults = false;
+
+    @GuardedBy("mLock")
+    private boolean mStaleScanResults = true;
 
     public WifiTracker(Context context, WifiListener wifiListener,
             boolean includeSaved, boolean includeScans) {
@@ -224,18 +227,30 @@
                 updateNetworkScores();
             }
         });
+
+        mObserver = new ContentObserver(mWorkHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mNetworkScoringUiEnabled =
+                        Settings.Global.getInt(
+                                mContext.getContentResolver(),
+                                Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
+            }
+        };
     }
 
-    /**
-     * Synchronously update the list of access points with the latest information.
-     */
+    /** Synchronously update the list of access points with the latest information. */
     @MainThread
     public void forceUpdate() {
         synchronized (mLock) {
             mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             mLastInfo = mWifiManager.getConnectionInfo();
             mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-            updateAccessPointsLocked();
+
+            final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+            List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+            mInternalAccessPoints.clear();
+            updateAccessPointsLocked(newScanResults, configs);
 
             if (DBG) {
                 Log.d(TAG, "force update - internal access point list:\n" + mInternalAccessPoints);
@@ -297,6 +312,12 @@
         synchronized (mLock) {
             registerScoreCache();
 
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
+                    false /* notifyForDescendants */,
+                    mObserver);
+            mObserver.onChange(false /* selfChange */); // Set mScoringUiEnabled
+
             resumeScanning();
             if (!mRegistered) {
                 mContext.registerReceiver(mReceiver, mFilter);
@@ -345,20 +366,24 @@
                 mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
                 mRegistered = false;
             }
-            unregisterAndClearScoreCache();
+            unregisterScoreCache();
             pauseScanning();
+            mContext.getContentResolver().unregisterContentObserver(mObserver);
 
             mWorkHandler.removePendingMessages();
             mMainHandler.removePendingMessages();
+            mStaleScanResults = true;
         }
-        mStaleScanResults = true;
     }
 
-    private void unregisterAndClearScoreCache() {
+    private void unregisterScoreCache() {
         mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, mScoreCache);
-        mScoreCache.clearScores();
 
-        // Synchronize on mLock to avoid concurrent modification during updateAccessPointsLocked
+        // We do not want to clear the existing scores in the cache, as this method is called during
+        // stop tracking on activity pause. Hence, on resumption we want the ability to show the
+        // last known, potentially stale, scores. However, by clearing requested scores, the scores
+        // will be requested again upon resumption of tracking, and if any changes have occurred
+        // the listeners (UI) will be updated accordingly.
         synchronized (mLock) {
             mRequestedScores.clear();
         }
@@ -408,9 +433,8 @@
         mScanId = 0;
     }
 
-    private Collection<ScanResult> fetchScanResults() {
+    private Collection<ScanResult> updateScanResultCache(final List<ScanResult> newResults) {
         mScanId++;
-        final List<ScanResult> newResults = mWifiManager.getScanResults();
         for (ScanResult newResult : newResults) {
             if (newResult.SSID == null || newResult.SSID.isEmpty()) {
                 continue;
@@ -438,8 +462,8 @@
         return mScanResultCache.values();
     }
 
-    private WifiConfiguration getWifiConfigurationForNetworkId(int networkId) {
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+    private WifiConfiguration getWifiConfigurationForNetworkId(
+            int networkId, final List<WifiConfiguration> configs) {
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (mLastInfo != null && networkId == config.networkId &&
@@ -451,20 +475,37 @@
         return null;
     }
 
-    /** Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. */
-    private void updateAccessPointsLocked() {
+    /**
+     * Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first.
+     *
+     * <p>Will not perform the update if {@link #mStaleScanResults} is true
+     */
+    private void updateAccessPoints() {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        final List<ScanResult> newScanResults = mWifiManager.getScanResults();
+
         synchronized (mLock) {
-            updateAccessPoints();
+            if(!mStaleScanResults) {
+                updateAccessPointsLocked(newScanResults, configs);
+            }
         }
     }
 
     /**
      * Update the internal list of access points.
      *
-     * <p>Should never be called directly, use {@link #updateAccessPointsLocked()} instead.
+     * <p>Do not called directly (except for forceUpdate), use {@link #updateAccessPoints()} which
+     * respects {@link #mStaleScanResults}.
      */
     @GuardedBy("mLock")
-    private void updateAccessPoints() {
+    private void updateAccessPointsLocked(final List<ScanResult> newScanResults,
+            List<WifiConfiguration> configs) {
+        WifiConfiguration connectionConfig = null;
+        if (mLastInfo != null) {
+            connectionConfig = getWifiConfigurationForNetworkId(
+                    mLastInfo.getNetworkId(), mWifiManager.getConfiguredNetworks());
+        }
+
         // Swap the current access points into a cached list.
         List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
         ArrayList<AccessPoint> accessPoints = new ArrayList<>();
@@ -477,14 +518,9 @@
     /* Lookup table to more quickly update AccessPoints by only considering objects with the
      * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
-        WifiConfiguration connectionConfig = null;
-        if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
-        }
 
-        final Collection<ScanResult> results = fetchScanResults();
+        final Collection<ScanResult> results = updateScanResultCache(newScanResults);
 
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 if (config.selfAdded && config.numAssociation == 0) {
@@ -533,7 +569,8 @@
 
                 boolean found = false;
                 for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {
-                    if (accessPoint.update(result)) {
+                    // We want to evict old scan results if are current results are not stale
+                    if (accessPoint.update(result, !mStaleScanResults)) {
                         found = true;
                         break;
                     }
@@ -567,7 +604,7 @@
 
         requestScoresForNetworkKeys(scoresToRequest);
         for (AccessPoint ap : accessPoints) {
-            ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */);
+            ap.update(mScoreCache, mNetworkScoringUiEnabled);
         }
 
         // Pre-sort accessPoints to speed preference insertion
@@ -606,7 +643,8 @@
         for (int i = 0; i < N; i++) {
             if (cache.get(i).matches(result)) {
                 AccessPoint ret = cache.remove(i);
-                ret.update(result);
+                // evict old scan results only if we have fresh results
+                ret.update(result, !mStaleScanResults);
                 return ret;
             }
         }
@@ -634,6 +672,7 @@
         /* sticky broadcasts can call this when wifi is disabled */
         if (!mWifiManager.isWifiEnabled()) {
             mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING);
+            clearAccessPointsAndConditionallyUpdate();
             return;
         }
 
@@ -651,7 +690,8 @@
         WifiConfiguration connectionConfig = null;
         mLastInfo = mWifiManager.getConnectionInfo();
         if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
+            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(),
+                    mWifiManager.getConfiguredNetworks());
         }
 
         boolean updated = false;
@@ -665,7 +705,7 @@
                     updated = true;
                     if (previouslyConnected != ap.isActive()) reorder = true;
                 }
-                if (ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */)) {
+                if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
                     reorder = true;
                     updated = true;
                 }
@@ -677,6 +717,17 @@
         }
     }
 
+    private void clearAccessPointsAndConditionallyUpdate() {
+        synchronized (mLock) {
+            if (!mInternalAccessPoints.isEmpty()) {
+                mInternalAccessPoints.clear();
+                if (!mMainHandler.hasMessages(MainHandler.MSG_ACCESS_POINT_CHANGED)) {
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
+                }
+            }
+        }
+    }
+
     /**
      * Update all the internal access points rankingScores, badge and metering.
      *
@@ -688,8 +739,7 @@
         synchronized (mLock) {
             boolean updated = false;
             for (int i = 0; i < mInternalAccessPoints.size(); i++) {
-                if (mInternalAccessPoints.get(i).update(
-                        mScoreCache, false /* mNetworkScoringUiEnabled */)) {
+                if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
                     updated = true;
                 }
             }
@@ -702,6 +752,9 @@
 
     private void updateWifiState(int state) {
         mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_WIFI_STATE, state, 0).sendToTarget();
+        if (!mWifiManager.isWifiEnabled()) {
+            clearAccessPointsAndConditionallyUpdate();
+        }
     }
 
     public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
@@ -719,23 +772,26 @@
         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);
-                mConnected.set(info.isConnected());
+                NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
 
-                mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);
+                if(mConnected.get() != info.isConnected()) {
+                    mConnected.set(info.isConnected());
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_CONNECTED_CHANGED);
+                }
 
                 mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
                         .sendToTarget();
@@ -785,8 +841,15 @@
                     mListener.onWifiStateChanged(msg.arg1);
                     break;
                 case MSG_ACCESS_POINT_CHANGED:
-                    copyAndNotifyListeners(true /*notifyListeners*/);
-                    mListener.onAccessPointsChanged();
+                    // Only notify listeners of changes if we have fresh scan results, otherwise the
+                    // UI will be updated with stale results. We want to copy the APs regardless,
+                    // for instances where forceUpdate was invoked by the caller.
+                    if (mStaleScanResults) {
+                        copyAndNotifyListeners(false /*notifyListeners*/);
+                    } else {
+                        copyAndNotifyListeners(true /*notifyListeners*/);
+                        mListener.onAccessPointsChanged();
+                    }
                     break;
                 case MSG_RESUME_SCANNING:
                     if (mScanner != null) {
@@ -810,12 +873,15 @@
         }
     }
 
-    private final class WorkHandler extends Handler {
+    @VisibleForTesting
+    final class WorkHandler extends Handler {
         private static final int MSG_UPDATE_ACCESS_POINTS = 0;
         private static final int MSG_UPDATE_NETWORK_INFO = 1;
         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);
         }
@@ -827,15 +893,15 @@
             }
         }
 
-        @GuardedBy("mLock")
         private void processMessage(Message msg) {
             if (!mRegistered) return;
 
             switch (msg.what) {
                 case MSG_UPDATE_ACCESS_POINTS:
-                    if (!mStaleScanResults) {
-                        updateAccessPointsLocked();
+                    if (msg.arg1 == CLEAR_STALE_SCAN_RESULTS) {
+                        mStaleScanResults = false;
                     }
+                    updateAccessPoints();
                     break;
                 case MSG_UPDATE_NETWORK_INFO:
                     updateNetworkInfo((NetworkInfo) msg.obj);
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index 0d5ff2c..e8e0b41 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml
index 8581acb..96621eb 100644
--- a/packages/SettingsLib/tests/integ/AndroidTest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="SettingsLibTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.settingslib" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 83667ea..01df0ec 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -3,6 +3,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -12,6 +13,7 @@
 import org.junit.runner.RunWith;
 
 import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyFloat;
 import static org.mockito.Matchers.anyString;
@@ -68,4 +70,49 @@
             }
         }
     }
+
+    @Test
+    public void testPadding_returnsCorrectValues() {
+        // different pads on each side to differentiate
+        final int left = 1;
+        final int top = 2;
+        final int right = 3;
+        final int bottom = 4;
+
+        final Rect expected = new Rect(left, top, right, bottom);
+        final Rect padding = new Rect();
+
+        mBatteryDrawable.setPadding(left, top, right, bottom);
+
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(true);
+        assertThat(padding).isEqualTo(expected);
+    }
+
+    @Test
+    public void testPadding_falseIfUnsetOrZero() {
+        final Rect padding = new Rect();
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+
+        mBatteryDrawable.setPadding(0, 0, 0, 0);
+        assertThat(mBatteryDrawable.getPadding(padding)).isEqualTo(false);
+        assertThat(isRectZero(padding)).isEqualTo(true);
+    }
+
+    private boolean isRectZero(Rect r) {
+        return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0;
+    }
+
+    @Test
+    public void testPlusPaint_isEqualToBoltPaint() {
+        // Before setting color
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+
+        final int fakeFillColor = 123;
+        final int fakeBackgrundColor = 456;
+
+        // After
+        mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor);
+        assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 801844b..88d3a32 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -19,12 +19,18 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.net.NetworkKey;
+import android.net.RssiCurve;
 import android.net.ScoredNetwork;
+import android.net.WifiKey;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
@@ -40,6 +46,8 @@
 import android.text.SpannableString;
 import android.text.style.TtsSpan;
 
+import com.android.settingslib.R;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -55,7 +63,8 @@
 
     private static final String TEST_SSID = "test_ssid";
     private Context mContext;
-    @Mock private WifiNetworkScoreCache mWifiNetworkScoreCache;
+    @Mock private RssiCurve mockBadgeCurve;
+    @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
 
     @Before
     public void setUp() {
@@ -162,6 +171,21 @@
     }
 
     @Test
+    public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() {
+
+        final String firstName = "aaAaaa";
+        final String secondName = "aaaaaa";
+        final String thirdName = "BBBBBB";
+
+        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
+        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
+        AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build();
+
+        assertSortingWorks(firstAp, secondAp);
+        assertSortingWorks(secondAp, thirdAp);
+    }
+
+    @Test
     public void testCompareTo_AllSortingRulesCombined() {
 
         AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
@@ -223,7 +247,7 @@
         scanResult.BSSID = "bssid";
         scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
         scanResult.capabilities = "";
-        assertThat(ap.update(scanResult)).isTrue();
+        assertThat(ap.update(scanResult, true /* evict old scan results */)).isTrue();
 
         assertThat(ap.getRssi()).isEqualTo(expectedRssi);
     }
@@ -294,13 +318,13 @@
     public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() {
         AccessPoint ap = createAccessPointWithScanResultCache();
 
-        when(mWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
                 .thenReturn(
                         new ScoredNetwork(
                                 null /* NetworkKey */,
                                 null /* rssiCurve */,
                                 true /* metered */));
-        ap.update(mWifiNetworkScoreCache, false /* scoringUiEnabled */);
+        ap.update(mockWifiNetworkScoreCache, false /* scoringUiEnabled */);
 
         assertThat(ap.isMetered()).isTrue();
     }
@@ -321,6 +345,119 @@
         assertThat(accessPoint.isMetered()).isFalse();
     }
 
+    @Test
+    public void testSpeedLabel_returnsVeryFast() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_very_fast));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsFast() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_fast));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsOkay() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_okay));
+    }
+
+    @Test
+    public void testSpeedLabel_returnsSlow() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW);
+        assertThat(ap.getSpeedLabel())
+                .isEqualTo(mContext.getString(R.string.speed_label_slow));
+    }
+
+    @Test
+    public void testSummaryString_showsSpeedLabel() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        assertThat(ap.getSummary()).isEqualTo(mContext.getString(R.string.speed_label_very_fast));
+    }
+
+    @Test
+    public void testSummaryString_concatenatesSpeedLabel() {
+        AccessPoint ap = createAccessPointWithScanResultCache();
+        ap.update(new WifiConfiguration());
+
+        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
+                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
+        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
+
+        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
+
+        String expectedString = mContext.getString(R.string.speed_label_very_fast) + " / "
+                + mContext.getString(R.string.wifi_remembered);
+        assertThat(ap.getSummary()).isEqualTo(expectedString);
+    }
+
+    @Test
+    public void testSummaryString_showsWrongPasswordLabel() {
+        WifiConfiguration configuration = createWifiConfiguration();
+        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
+        configuration.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
+                WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+        AccessPoint ap = new AccessPoint(mContext, configuration);
+
+        assertThat(ap.getSummary()).isEqualTo(mContext.getString(
+                R.string.wifi_check_password_try_again));
+    }
+
+    private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() {
+        Bundle attr1 = new Bundle();
+        attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
+        return new ScoredNetwork(
+                new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
+                mockBadgeCurve,
+                false /* meteredHint */,
+                attr1);
+
+    }
+
     private AccessPoint createAccessPointWithScanResultCache() {
         Bundle bundle = new Bundle();
         ArrayList<ScanResult> scanResults = new ArrayList<>();
@@ -333,7 +470,7 @@
             scanResults.add(scanResult);
         }
 
-        bundle.putParcelableArrayList("key_scanresultcache", scanResults);
+        bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults);
         return new AccessPoint(mContext, bundle);
     }
 
@@ -487,4 +624,111 @@
         NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
         assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
     }
+
+    @Test
+    public void testUpdateWithDifferentRssi_returnsTrue() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        wifiInfo.setRssi(rssi + 1);
+        assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
+    }
+
+    @Test
+    public void testUpdateWithInvalidRssi_returnsFalse() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+        wifiInfo.setRssi(WifiInfo.INVALID_RSSI);
+        assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
+    }
+    @Test
+    public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        config.numNoInternetAccessReports = 1;
+
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class);
+        ap.setListener(mockListener);
+        WifiConfiguration newConfig = new WifiConfiguration(config);
+        config.validatedInternetAccess = true;
+
+        assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse();
+        verify(mockListener).onAccessPointChanged(ap);
+    }
+
+    @Test
+    public void testUpdateWithNullWifiConfiguration_doesNotThrowNPE() {
+        int networkId = 123;
+        int rssi = -55;
+        WifiConfiguration config = new WifiConfiguration();
+        config.networkId = networkId;
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.setNetworkId(networkId);
+        wifiInfo.setRssi(rssi);
+
+        NetworkInfo networkInfo =
+                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+        AccessPoint ap = new TestAccessPointBuilder(mContext)
+                .setNetworkInfo(networkInfo)
+                .setNetworkId(networkId)
+                .setRssi(rssi)
+                .setWifiInfo(wifiInfo)
+                .build();
+
+        ap.update(null, wifiInfo, networkInfo);
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
deleted file mode 100644
index 2213ae6..0000000
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
+++ /dev/null
@@ -1,174 +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.
- */
-
-package com.android.settingslib.wifi;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.os.Bundle;
-
-/**
-* Build and return a valid AccessPoint.
-*
-* Only intended for testing the AccessPoint class;
-* AccessPoints were designed to only be populated
-* by the mechanisms of scan results and wifi configurations.
-*/
-public class TestAccessPointBuilder {
-    // match the private values in WifiManager
-    private static final int MIN_RSSI = -100;
-    private static final int MAX_RSSI = -55;
-
-    // set some sensible defaults
-    private int mRssi = AccessPoint.UNREACHABLE_RSSI;
-    private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-    private String ssid = "TestSsid";
-    private NetworkInfo mNetworkInfo = null;
-    private String mFqdn = null;
-    private String mProviderFriendlyName = null;
-    private WifiConfiguration mWifiConfig;
-    private WifiInfo mWifiInfo;
-
-    Context mContext;
-
-    public TestAccessPointBuilder(Context context) {
-        mContext = context;
-    }
-
-    public AccessPoint build() {
-        Bundle bundle = new Bundle();
-
-        WifiConfiguration wifiConfig = new WifiConfiguration();
-        wifiConfig.networkId = mNetworkId;
-
-        bundle.putString(AccessPoint.KEY_SSID, ssid);
-        bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
-        bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
-        bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
-        if (mFqdn != null) {
-            bundle.putString(AccessPoint.KEY_FQDN, mFqdn);
-        }
-        if (mProviderFriendlyName != null) {
-            bundle.putString(AccessPoint.KEY_PROVIDER_FRIENDLY_NAME, mProviderFriendlyName);
-        }
-        AccessPoint ap = new AccessPoint(mContext, bundle);
-        ap.setRssi(mRssi);
-        return ap;
-    }
-
-    public TestAccessPointBuilder setActive(boolean active) {
-        if (active) {
-            mNetworkInfo = new NetworkInfo(
-                ConnectivityManager.TYPE_DUMMY,
-                ConnectivityManager.TYPE_DUMMY,
-                "TestNetwork",
-                "TestNetwork");
-        } else {
-            mNetworkInfo = null;
-        }
-        return this;
-    }
-
-    /**
-     * Set the rssi based upon the desired signal level.
-     *
-     * <p>Side effect: if this AccessPoint was previously unreachable,
-     * setting the level will also make it reachable.
-     */
-    public TestAccessPointBuilder setLevel(int level) {
-        // Reversal of WifiManager.calculateSignalLevels
-        if (level == 0) {
-            mRssi = MIN_RSSI;
-        } else if (level >= AccessPoint.SIGNAL_LEVELS) {
-            mRssi = MAX_RSSI;
-        } else {
-            float inputRange = MAX_RSSI - MIN_RSSI;
-            float outputRange = AccessPoint.SIGNAL_LEVELS - 1;
-            mRssi = (int) (level * inputRange / outputRange + MIN_RSSI);
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
-        mNetworkInfo = info;
-        return this;
-    }
-
-    public TestAccessPointBuilder setRssi(int rssi) {
-        mRssi = rssi;
-        return this;
-    }
-
-    /**
-    * Set whether the AccessPoint is reachable.
-    * Side effect: if the signal level was not previously set,
-    * making an AccessPoint reachable will set the signal to the minimum level.
-    */
-    public TestAccessPointBuilder setReachable(boolean reachable) {
-        if (reachable) {
-            // only override the mRssi if it hasn't been set yet
-            if (mRssi == AccessPoint.UNREACHABLE_RSSI) {
-                mRssi = MIN_RSSI;
-            }
-        } else {
-            mRssi = AccessPoint.UNREACHABLE_RSSI;
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setSaved(boolean saved){
-        if (saved) {
-             mNetworkId = 1;
-        } else {
-             mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-        }
-        return this;
-    }
-
-    public TestAccessPointBuilder setSsid(String newSsid) {
-        ssid = newSsid;
-        return this;
-    }
-
-    public TestAccessPointBuilder setFqdn(String fqdn) {
-        mFqdn = fqdn;
-        return this;
-    }
-
-    public TestAccessPointBuilder setProviderFriendlyName(String friendlyName) {
-        mProviderFriendlyName = friendlyName;
-        return this;
-    }
-
-    public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
-        mWifiInfo = info;
-        return this;
-    }
-
-    /**
-     * Set the networkId in the WifiConfig.
-     *
-     * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
-     * AccessPoint a saved network.
-     */
-    public TestAccessPointBuilder setNetworkId(int networkId) {
-        mNetworkId = networkId;
-        return this;
-    }
-}
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 eb9a7f6..df6587e 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
@@ -38,7 +38,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.Network;
-import android.net.NetworkBadging;
 import android.net.NetworkInfo;
 import android.net.NetworkKey;
 import android.net.NetworkScoreManager;
@@ -60,6 +59,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.FlakyTest;
 
 import org.junit.After;
 import org.junit.Before;
@@ -95,7 +95,7 @@
             new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1));
     private static final int RSSI_1 = -30;
     private static final byte SCORE_1 = 10;
-    private static final int BADGE_1 = NetworkBadging.BADGING_SD;
+    private static final int BADGE_1 = AccessPoint.Speed.MODERATE;
 
     private static final String SSID_2 = "ssid2";
     private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA";
@@ -103,7 +103,7 @@
             new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2));
     private static final int RSSI_2 = -30;
     private static final byte SCORE_2 = 15;
-    private static final int BADGE_2 = NetworkBadging.BADGING_HD;
+    private static final int BADGE_2 = AccessPoint.Speed.FAST;
 
     private static final int CONNECTED_NETWORK_ID = 123;
     private static final int CONNECTED_RSSI = -50;
@@ -135,6 +135,7 @@
     private HandlerThread mWorkerThread;
     private Looper mWorkerLooper;
     private Looper mMainLooper;
+
     private int mOriginalScoringUiSettingValue;
 
     @Before
@@ -210,6 +211,7 @@
                 InstrumentationRegistry.getTargetContext().getContentResolver(),
                 Settings.Global.NETWORK_SCORING_UI_ENABLED,
                 1 /* enabled */);
+
     }
 
     @After
@@ -257,6 +259,7 @@
         }
 
         sendScanResultsAndProcess(tracker);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         return tracker;
     }
@@ -339,7 +342,27 @@
 
         Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
-        return createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+        WifiTracker tracker =
+                createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
+        assertThat(tracker.isConnected()).isTrue();
+        return tracker;
+    }
+
+    private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
+            throws InterruptedException {
+        CountDownLatch workerLatch = new CountDownLatch(1);
+        tracker.mWorkHandler.post(() -> {
+            workerLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for WorkerHandler",
+                workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
+        CountDownLatch mainLatch = new CountDownLatch(1);
+        tracker.mMainHandler.post(() -> {
+            mainLatch.countDown();
+        });
+        assertTrue("Latch timed out while waiting for MainHandler",
+                mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
     @Test
@@ -427,7 +450,7 @@
 
     @Test
     public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException {
-        WifiTracker tracker =  createTrackerWithScanResultsAndAccessPoint1Connected();
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -455,38 +478,52 @@
     }
 
     @Test
+    public void stopTracking_shouldNotClearExistingScores()
+            throws InterruptedException {
+        // Start the tracker and inject the initial scan results and then stop tracking
+        WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        tracker.stopTracking();
+
+        assertThat(mScoreCacheCaptor.getValue().getScoredNetwork(NETWORK_KEY_1)).isNotNull();
+    }
+
+    @Test
     public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged()
             throws InterruptedException {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
         sendScanResultsAndProcess(tracker);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
     }
 
-    private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException {
+    private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
+            throws InterruptedException {
         // Updating scores can happen together or one after the other, so the latch countdown is set
         // to 2.
-        mAccessPointsChangedLatch = new CountDownLatch(2);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
         updateScores();
-        assertTrue("onAccessPointChanged was not called twice",
+        assertTrue("onAccessPointChanged was not called after updating scores",
             mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
     }
 
+    @FlakyTest
     @Test
-    public void scoreCacheUpdateScoresShouldNotChangeSortOrder() throws InterruptedException {
+    public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
         List<AccessPoint> aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
-        assertEquals(aps.get(0).getSsidStr(), SSID_1);
-        assertEquals(aps.get(1).getSsidStr(), SSID_2);
+        assertEquals(aps.get(0).getSsidStr(), SSID_2);
+        assertEquals(aps.get(1).getSsidStr(), SSID_1);
     }
 
     @Test
@@ -503,7 +540,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -511,19 +548,20 @@
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
     }
 
+    @FlakyTest
     @Test
-    public void scoreCacheUpdateScoresShouldNotInsertBadgeIntoAccessPoint()
+    public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(BADGE_1, ap.getSpeed());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(BADGE_2, ap.getSpeed());
             }
         }
     }
@@ -532,7 +570,7 @@
     public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -546,7 +584,7 @@
     }
 
     @Test
-    public void noBadgesShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
+    public void noSpeedsShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
             throws InterruptedException {
         Settings.Global.putInt(
                 InstrumentationRegistry.getTargetContext().getContentResolver(),
@@ -554,15 +592,15 @@
                 0 /* disabled */);
 
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback();
+        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
+                assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
             }
         }
     }
@@ -702,7 +740,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();
     }
@@ -755,13 +793,10 @@
             throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
-        CountDownLatch latch1 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-                latch1.countDown();
-        });
-        assertTrue("Latch 1 timed out", latch1.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        tracker.stopTracking();
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         startTracking(tracker);
 
@@ -771,14 +806,79 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
 
-        CountDownLatch latch2 = new CountDownLatch(1);
-        tracker.mMainHandler.post(() -> {
-            latch2.countDown();
-        });
-        assertTrue("Latch 2 timed out", latch2.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         verify(mockWifiListener, never()).onAccessPointsChanged();
 
         sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
     }
+
+    @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();
+
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false);
+        mAccessPointsChangedLatch = new CountDownLatch(1);
+        tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+
+        mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+
+        assertThat(tracker.getAccessPoints()).isEmpty();
+    }
+
+    @Test
+    public void onConnectedChangedCallback_shouldNotBeInvokedWhenNoStateChange() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
+
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        tracker.mReceiver.onReceive(mContext, intent);
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+    }
+
+    @Test
+    public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
+        WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
+        verify(mockWifiListener, times(1)).onConnectedChanged();
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(
+                NetworkInfo.DetailedState.DISCONNECTED, "disconnected", "test");
+
+        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        tracker.mReceiver.onReceive(mContext, intent);
+
+        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        assertThat(tracker.isConnected()).isFalse();
+        verify(mockWifiListener, times(2)).onConnectedChanged();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml b/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml
new file mode 100644
index 0000000..3fe1e9e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml b/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml
new file mode 100644
index 0000000..c47bff7
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/res/layout/preference_footer.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2016 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:background="?android:attr/selectableItemBackground"
+    android:clipToPadding="false">
+
+    <LinearLayout
+        android:id="@+id/icon_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minWidth="60dp"
+        android:gravity="start|top"
+        android:orientation="horizontal"
+        android:paddingEnd="12dp"
+        android:paddingTop="20dp"
+        android:paddingBottom="4dp">
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <com.android.settingslib.widget.LinkTextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp"
+        android:maxLines="10"
+        android:textColor="?android:attr/textColorSecondary"
+        android:ellipsize="marquee" />
+
+</LinearLayout>
diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
index 1eeafba..f02ac15 100644
--- a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
+++ b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
@@ -15,10 +15,14 @@
 -->
 
 <optional-steps>
+    <step category="com.android.settings.suggested.category.DEFERRED_SETUP"
+        exclusive="true" />
     <step category="com.android.settings.suggested.category.LOCK_SCREEN" />
+    <step category="com.android.settings.suggested.category.TRUST_AGENT" />
     <step category="com.android.settings.suggested.category.EMAIL" />
     <step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
         multiple="true" />
+    <step category="com.android.settings.suggested.category.GESTURE" />
     <step category="com.android.settings.suggested.category.HOTWORD" />
     <step category="com.android.settings.suggested.category.DEFAULT"
         multiple="true" />
diff --git a/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
new file mode 100644
index 0000000..abccd8d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/android/net/wifi/WifiNetworkScoreCache.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * 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.wifi;
+
+import android.content.Context;
+import android.os.Handler;
+
+import java.util.List;
+
+/**
+ * Will be removed once robolectric is updated to O
+ */
+public class WifiNetworkScoreCache {
+
+    public WifiNetworkScoreCache(Context context, WifiNetworkScoreCache.CacheListener listener) {
+    }
+
+    public abstract static class CacheListener {
+        public CacheListener(Handler handler) {
+        }
+
+        void post(List updatedNetworks) {
+        }
+
+        public abstract void networkCacheUpdated(List updatedNetworks);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
deleted file mode 100644
index 69efc9e..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
+++ /dev/null
@@ -1,120 +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.
- */
-
-package com.android.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.SystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BatteryInfoTest {
-    private static final String STATUS_FULL = "Full";
-    private static final String STATUS_CHARGING_NO_TIME = "Charging";
-    private static final String STATUS_CHARGING_TIME = "Charging - 2h left";
-    private static final int PLUGGED_IN = 1;
-    private static final long REMAINING_TIME_NULL = -1;
-    private static final long REMAINING_TIME = 2;
-    private Intent mDisChargingBatteryBroadcast;
-    private Intent mChargingBatteryBroadcast;
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStats mBatteryStats;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mDisChargingBatteryBroadcast = new Intent();
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED, 0);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 0);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
-        mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
-                BatteryManager.BATTERY_STATUS_FULL);
-
-        mChargingBatteryBroadcast = new Intent();
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED,
-                BatteryManager.BATTERY_PLUGGED_AC);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 50);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
-        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
-                BatteryManager.BATTERY_STATUS_UNKNOWN);
-
-        when(mContext.getResources().getString(R.string.battery_info_status_full))
-                .thenReturn(STATUS_FULL);
-        when(mContext.getResources().getString(eq(R.string.power_charging), any(),
-                any())).thenReturn(STATUS_CHARGING_NO_TIME);
-        when(mContext.getResources().getString(eq(R.string.power_charging_duration), any(),
-                any())).thenReturn(STATUS_CHARGING_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_hasStatusLabel() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeBatteryTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true);
-
-        assertThat(info.statusLabel).isEqualTo(STATUS_FULL);
-    }
-
-    @Test
-    public void testGetBatteryInfo_doNotShowChargingMethod_hasRemainingTime() {
-        doReturn(REMAINING_TIME).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
-
-        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_doNotShowChargingMethod_noRemainingTime() {
-        doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
-
-        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_NO_TIME);
-    }
-
-    @Test
-    public void testGetBatteryInfo_pluggedIn_dischargingFalse() {
-        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
-                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true);
-
-        assertThat(info.discharging).isEqualTo(false);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
deleted file mode 100644
index 7729dec..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
+++ /dev/null
@@ -1,128 +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.
- */
-
-package com.android.settingslib;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtilsTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-@RunWith(SettingLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionParserTest {
-
-    @Mock
-    private PackageManager mPackageManager;
-    private Context mContext;
-    private SuggestionParser mSuggestionParser;
-    private SuggestionParser.SuggestionCategory mSuggestioCategory;
-    private List<Tile> mSuggestionsBeforeDismiss;
-    private List<Tile> mSuggestionsAfterDismiss;
-    private SharedPreferences mPrefs;
-    private Tile mSuggestion;
-    private List<ResolveInfo> mInfo;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-        mSuggestion = new Tile();
-        mSuggestion.intent = new Intent("action");
-        mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
-        mSuggestion.metaData = new Bundle();
-        mSuggestionParser = new SuggestionParser(
-            mContext, mPrefs, R.xml.suggestion_ordering, "0,0");
-        mSuggestioCategory = new SuggestionParser.SuggestionCategory();
-        mSuggestioCategory.category = "category1";
-        mSuggestioCategory.multiple = true;
-        mInfo = new ArrayList<>();
-        ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
-        info1.activityInfo.packageName = "pkg";
-        ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
-        info2.activityInfo.packageName = "pkg2";
-        mInfo.add(info1);
-        mInfo.add(info2);
-        when(mPackageManager.queryIntentActivitiesAsUser(
-            any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo);
-    }
-
-    @Test
-    public void testDismissSuggestion_withoutSmartSuggestion() {
-        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
-    }
-
-    @Test
-    public void testDismissSuggestion_withSmartSuggestion() {
-        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
-    }
-
-    @Test
-    public void testGetSuggestions_withoutSmartSuggestions() {
-        readAndDismissSuggestion(false);
-        mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false);
-        assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1);
-        assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
-    }
-
-    @Test
-    public void testGetSuggestions_withSmartSuggestions() {
-        readAndDismissSuggestion(true);
-        assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2);
-        assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
-    }
-
-    private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
-        mSuggestionsBeforeDismiss = new ArrayList<Tile>();
-        mSuggestionsAfterDismiss = new ArrayList<Tile>();
-        mSuggestionParser.readSuggestions(
-            mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
-        if (mSuggestionParser.dismissSuggestion(
-            mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) {
-            mInfo.remove(0);
-        }
-        mSuggestionParser.readSuggestions(
-            mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 22fd83c..31abecd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -19,5 +19,5 @@
 public class TestConfig {
     public static final int SDK_VERSION = 23;
     public static final String MANIFEST_PATH =
-            "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
+            "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
new file mode 100644
index 0000000..3b1c3ac
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.settingslib;
+
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class TetherUtilTest {
+
+    @Mock
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void isEntitlementCheckRequired_noConfigManager_returnTrue() {
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)).thenReturn(null);
+
+        assertThat(TetherUtil.isEntitlementCheckRequired(mContext)).isTrue();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index e42c35b..0164f80 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -21,6 +21,12 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+
 @RunWith(SettingLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class UtilsTest {
@@ -54,4 +60,18 @@
             assertThat(percentage).isEqualTo(expectedPercentages[i]);
         }
     }
+
+    @Test
+    public void testStorageManagerDaysToRetainUsesResources() {
+        Resources resources = mock(Resources.class);
+        when(resources.getInteger(
+                        eq(
+                                com.android
+                                        .internal
+                                        .R
+                                        .integer
+                                        .config_storageManagerDaystoRetainDefault)))
+                .thenReturn(60);
+        assertThat(Utils.getDefaultStorageManagerDaysToRetain(resources)).isEqualTo(60);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
new file mode 100644
index 0000000..e2ebbeb
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.R;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, resourceDir =
+        "../../res")
+public class CachedBluetoothDeviceTest {
+    @Mock
+    private LocalBluetoothAdapter mAdapter;
+    @Mock
+    private LocalBluetoothProfileManager mProfileManager;
+    @Mock
+    private HeadsetProfile mHfpProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private HidProfile mHidProfile;
+    @Mock
+    private BluetoothDevice mDevice;
+    private CachedBluetoothDevice mCachedDevice;
+    private Context mContext;
+    private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+        when(mHfpProfile.isProfileReady()).thenReturn(true);
+        when(mA2dpProfile.isProfileReady()).thenReturn(true);
+        when(mHidProfile.isProfileReady()).thenReturn(true);
+        mCachedDevice = spy(
+                new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice));
+        doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
+    }
+
+    /**
+     * Test to verify the current test context object works so that we are not checking null
+     * against null
+     */
+    @Test
+    public void testContextMock() {
+        assertThat(mContext.getString(R.string.bluetooth_connected)).isEqualTo("Connected");
+    }
+
+    @Test
+    public void testGetConnectionSummary_testSingleProfileConnectDisconnect() {
+        // Test without battery level
+        // Set HID profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected));
+
+        // Set HID profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+
+        // Test with battery level
+        mBatteryLevel = 10;
+        // Set HID profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Set HID profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+
+        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+
+        // Set HID profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected));
+
+        // Set HID profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void testGetConnectionSummary_testMultipleProfileConnectDisconnect() {
+        mBatteryLevel = 10;
+
+        // Set HFP, A2DP and HID profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect HFP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_headset_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect A2DP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_a2dp_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect both HFP and A2DP and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(mContext.getString(
+                R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
+                com.android.settingslib.Utils.formatPercentage(mBatteryLevel)));
+
+        // Disconnect all profiles and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHidProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
new file mode 100644
index 0000000..5856332
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -0,0 +1,261 @@
+/*
+ * 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.settingslib.core.lifecycle;
+
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.events.OnAttach;
+import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ActivityController;
+import org.robolectric.util.FragmentController;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class LifecycleTest {
+
+    public static class TestDialogFragment extends ObservableDialogFragment {
+
+        final TestObserver mFragObserver;
+
+        public TestDialogFragment() {
+            mFragObserver = new TestObserver();
+            mLifecycle.addObserver(mFragObserver);
+        }
+    }
+
+    public static class TestFragment extends ObservableFragment {
+
+        final TestObserver mFragObserver;
+
+        public TestFragment() {
+            mFragObserver = new TestObserver();
+            getLifecycle().addObserver(mFragObserver);
+        }
+    }
+
+    public static class TestActivity extends ObservableActivity {
+
+        final TestObserver mActObserver;
+
+        public TestActivity() {
+            mActObserver = new TestObserver();
+            getLifecycle().addObserver(mActObserver);
+        }
+
+    }
+
+    public static class TestObserver implements LifecycleObserver, OnAttach, OnStart, OnResume,
+            OnPause, OnStop, OnDestroy, OnCreateOptionsMenu, OnPrepareOptionsMenu,
+            OnOptionsItemSelected {
+
+        boolean mOnAttachObserved;
+        boolean mOnAttachHasContext;
+        boolean mOnStartObserved;
+        boolean mOnResumeObserved;
+        boolean mOnPauseObserved;
+        boolean mOnStopObserved;
+        boolean mOnDestroyObserved;
+        boolean mOnCreateOptionsMenuObserved;
+        boolean mOnPrepareOptionsMenuObserved;
+        boolean mOnOptionsItemSelectedObserved;
+
+        @Override
+        public void onAttach(Context context) {
+            mOnAttachObserved = true;
+            mOnAttachHasContext = context != null;
+        }
+
+        @Override
+        public void onStart() {
+            mOnStartObserved = true;
+        }
+
+        @Override
+        public void onPause() {
+            mOnPauseObserved = true;
+        }
+
+        @Override
+        public void onResume() {
+            mOnResumeObserved = true;
+        }
+
+        @Override
+        public void onStop() {
+            mOnStopObserved = true;
+        }
+
+        @Override
+        public void onDestroy() {
+            mOnDestroyObserved = true;
+        }
+
+        @Override
+        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+            mOnCreateOptionsMenuObserved = true;
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem menuItem) {
+            mOnOptionsItemSelectedObserved = true;
+            return true;
+        }
+
+        @Override
+        public void onPrepareOptionsMenu(Menu menu) {
+            mOnPrepareOptionsMenuObserved = true;
+        }
+    }
+
+    @Test
+    public void runThroughActivityLifecycles_shouldObserveEverything() {
+        ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
+        TestActivity activity = ac.get();
+
+        ac.start();
+        assertThat(activity.mActObserver.mOnStartObserved).isTrue();
+        ac.resume();
+        assertThat(activity.mActObserver.mOnResumeObserved).isTrue();
+        activity.onCreateOptionsMenu(null);
+        assertThat(activity.mActObserver.mOnCreateOptionsMenuObserved).isTrue();
+        activity.onPrepareOptionsMenu(null);
+        assertThat(activity.mActObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        activity.onOptionsItemSelected(null);
+        assertThat(activity.mActObserver.mOnOptionsItemSelectedObserved).isTrue();
+        ac.pause();
+        assertThat(activity.mActObserver.mOnPauseObserved).isTrue();
+        ac.stop();
+        assertThat(activity.mActObserver.mOnStopObserved).isTrue();
+        ac.destroy();
+        assertThat(activity.mActObserver.mOnDestroyObserved).isTrue();
+    }
+
+    @Test
+    public void runThroughDialogFragmentLifecycles_shouldObserveEverything() {
+        FragmentController<TestDialogFragment> fragmentController =
+                Robolectric.buildFragment(TestDialogFragment.class);
+        TestDialogFragment fragment = fragmentController.get();
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
+        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
+    }
+
+    @Test
+    public void runThroughFragmentLifecycles_shouldObserveEverything() {
+        FragmentController<TestFragment> fragmentController =
+                Robolectric.buildFragment(TestFragment.class);
+        TestFragment fragment = fragmentController.get();
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(fragment.mFragObserver.mOnAttachObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnAttachHasContext).isTrue();
+        assertThat(fragment.mFragObserver.mOnStartObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnResumeObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPauseObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnStopObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnDestroyObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnCreateOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnPrepareOptionsMenuObserved).isTrue();
+        assertThat(fragment.mFragObserver.mOnOptionsItemSelectedObserved).isTrue();
+    }
+
+    @Test
+    public void addObserverDuringObserve_shoudNotCrash() {
+        Lifecycle lifecycle = new Lifecycle();
+        lifecycle.addObserver(new OnStartObserver(lifecycle));
+        lifecycle.onStart();
+    }
+
+    private static class OptionItemAccepter implements LifecycleObserver, OnOptionsItemSelected {
+        public boolean wasCalled = false;
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem menuItem) {
+            wasCalled = true;
+            return false;
+        }
+    }
+
+    @Test
+    public void onOptionItemSelectedShortCircuitsIfAnObserverHandlesTheMenuItem() {
+        FragmentController<TestFragment> fragmentController =
+                Robolectric.buildFragment(TestFragment.class);
+        TestFragment fragment = fragmentController.get();
+        OptionItemAccepter accepter = new OptionItemAccepter();
+        fragment.getLifecycle().addObserver(accepter);
+
+        fragmentController.attach().create().start().resume();
+        fragment.onCreateOptionsMenu(null, null);
+        fragment.onPrepareOptionsMenu(null);
+        fragment.onOptionsItemSelected(null);
+        fragmentController.pause().stop().destroy();
+
+        assertThat(accepter.wasCalled).isFalse();
+    }
+
+    private class OnStartObserver implements LifecycleObserver, OnStart {
+
+        private final Lifecycle mLifecycle;
+
+        public OnStartObserver(Lifecycle lifecycle) {
+            mLifecycle = lifecycle;
+        }
+
+        @Override
+        public void onStart() {
+            mLifecycle.addObserver(new LifecycleObserver() {
+            });
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index 40353e7..9fc8a96 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -54,13 +54,14 @@
         allKeys.add(CategoryKey.CATEGORY_SOUND);
         allKeys.add(CategoryKey.CATEGORY_STORAGE);
         allKeys.add(CategoryKey.CATEGORY_SECURITY);
+        allKeys.add(CategoryKey.CATEGORY_SECURITY_LOCKSCREEN);
         allKeys.add(CategoryKey.CATEGORY_ACCOUNT);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
         // DO NOT REMOVE ANYTHING ABOVE
 
-        assertThat(allKeys.size()).isEqualTo(13);
+        assertThat(allKeys.size()).isEqualTo(14);
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 8415dc5..0364418 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -16,11 +16,23 @@
 
 package com.android.settingslib.drawer;
 
-import android.app.ActivityManager;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import android.content.IContentProvider;
+import static org.mockito.Mockito.when;
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.IContentProvider;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -37,40 +49,34 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Pair;
+import android.widget.RemoteViews;
 
-import com.android.settingslib.SuggestionParser;
+import com.android.settingslib.R;
 import com.android.settingslib.TestConfig;
-import com.android.settingslib.drawer.TileUtilsTest;
-import static org.mockito.Mockito.atLeastOnce;
+import com.android.settingslib.suggestions.SuggestionParser;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.internal.ShadowExtractor;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-import org.mockito.ArgumentCaptor;
-
-
 @RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
 public class TileUtilsTest {
 
     @Mock
@@ -94,8 +100,11 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
-        mContentResolver = spy(RuntimeEnvironment.application.getContentResolver());
+        when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
+                .thenReturn(application.getApplicationInfo());
+        mContentResolver = spy(application.getContentResolver());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageName()).thenReturn("com.android.settings");
     }
 
     @Test
@@ -112,7 +121,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).category).isEqualTo(testCategory);
@@ -133,7 +142,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).key).isEqualTo(keyHint);
@@ -153,7 +162,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.isEmpty()).isTrue();
     }
@@ -176,10 +185,14 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
-        SuggestionParser parser = new SuggestionParser(mContext, null);
+        SuggestionParser parser = new SuggestionParser(
+                mContext,
+                null,
+                Collections.emptyList(),
+                "0,10");
         parser.filterSuggestions(outTiles, 0, false);
         assertThat(outTiles.size()).isEqualTo(0);
     }
@@ -204,8 +217,8 @@
         }), anyInt(), anyInt())).thenReturn(info);
 
         List<DashboardCategory> categoryList = TileUtils.getCategories(
-            mContext, cache, false /* categoryDefinedInManifest */, testAction,
-            TileUtils.SETTING_PKG);
+                mContext, cache, false /* categoryDefinedInManifest */, testAction,
+                TileUtils.SETTING_PKG);
         assertThat(categoryList.get(0).tiles.get(0).category).isEqualTo(testCategory);
     }
 
@@ -221,13 +234,13 @@
         when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
 
         TileUtils.getCategories(
-            mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
-            TileUtils.SETTING_PKG);
+                mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
+                TileUtils.SETTING_PKG);
         verify(mPackageManager, atLeastOnce()).queryIntentActivitiesAsUser(
-            intentCaptor.capture(), anyInt(), anyInt());
+                intentCaptor.capture(), anyInt(), anyInt());
 
         assertThat(intentCaptor.getAllValues().get(0).getPackage())
-            .isEqualTo(TileUtils.SETTING_PKG);
+                .isEqualTo(TileUtils.SETTING_PKG);
     }
 
     @Test
@@ -245,7 +258,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my title");
@@ -269,10 +282,60 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).title).isEqualTo("my localized title");
+
+        // Icon should be tintable because the tile is not from settings package, and
+        // "forceTintExternalIcon" is set
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.packageName = "com.android.settings";
+        resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isFalse();
+    }
+
+    @Test
+    public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+                URI_GET_SUMMARY, null, 123);
+        resolveInfo.activityInfo.metaData
+                .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, false /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        assertThat(outTiles.get(0).isIconTintable).isTrue();
     }
 
     @Test
@@ -291,7 +354,7 @@
         // Case 1: No provider associated with the uri specified.
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -309,7 +372,7 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -331,11 +394,115 @@
 
         TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
                 null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */);
+                false /* checkCategory */, true /* forceTintExternalIcon */);
 
         assertThat(outTiles.size()).isEqualTo(1);
     }
 
+    @Test
+    public void getTilesForIntent_shouldShowRemoteViewIfSpecified() {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+    }
+
+    @Test
+    public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
+            throws RemoteException {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
+                null, URI_GET_SUMMARY);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        // Mock the content provider interaction.
+        Bundle bundle = new Bundle();
+        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+        when(mIContentProvider.call(anyString(),
+                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
+                any())).thenReturn(bundle);
+        when(mContentResolver.acquireUnstableProvider(anyString()))
+                .thenReturn(mIContentProvider);
+        when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
+                .thenReturn(mIContentProvider);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+        // Make sure the summary TextView got a new text string.
+        TileUtilsShadowRemoteViews shadowRemoteViews =
+                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
+        assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
+    }
+
+    @Test
+    public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
+            throws RemoteException {
+        Intent intent = new Intent();
+        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+        List<Tile> outTiles = new ArrayList<>();
+        List<ResolveInfo> info = new ArrayList<>();
+        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
+                null, URI_GET_SUMMARY);
+        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
+                R.layout.user_preference);
+        info.add(resolveInfo);
+
+        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+                .thenReturn(info);
+
+        // Mock the content provider interaction.
+        Bundle bundle = new Bundle();
+        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+        when(mIContentProvider.call(anyString(),
+                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
+                any())).thenReturn(bundle);
+
+        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+                null /* defaultCategory */, outTiles, false /* usePriority */,
+                false /* checkCategory */, true /* forceTintExternalIcon */);
+
+        assertThat(outTiles.size()).isEqualTo(1);
+        Tile tile = outTiles.get(0);
+        assertThat(tile.remoteViews).isNotNull();
+        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
+        // Make sure the summary TextView didn't get any text view updates.
+        TileUtilsShadowRemoteViews shadowRemoteViews =
+                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
+        assertThat(shadowRemoteViews.overrideViewId).isNull();
+        assertThat(shadowRemoteViews.overrideText).isNull();
+    }
+
     public static ResolveInfo newInfo(boolean systemApp, String category) {
         return newInfo(systemApp, category, null);
     }
@@ -370,7 +537,9 @@
         if (summaryUri != null) {
             info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
         }
-        if (title != null) {
+        if (titleResId != 0) {
+            info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
+        } else if (title != null) {
             info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
         }
         if (titleResId != 0) {
@@ -395,4 +564,17 @@
             info.activityInfo.metaData.putString(key, value);
         }
     }
+
+    @Implements(RemoteViews.class)
+    public static class TileUtilsShadowRemoteViews {
+
+        private Integer overrideViewId;
+        private CharSequence overrideText;
+
+        @Implementation
+        public void setTextViewText(int viewId, CharSequence text) {
+            overrideViewId = viewId;
+            overrideText = text;
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
deleted file mode 100644
index ec21723..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
+++ /dev/null
@@ -1,70 +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.
- *
- *
- */
-
-package com.android.settingslib.graph;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.Space;
-
-import com.android.settingslib.R;
-import com.android.settingslib.TestConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BottomLabelLayoutTest {
-    private BottomLabelLayout mBottomLabelLayout;
-    private Context mContext;
-    private Space mSpace;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mBottomLabelLayout = new BottomLabelLayout(mContext, null);
-        mBottomLabelLayout.setOrientation(LinearLayout.HORIZONTAL);
-
-        mSpace = new Space(mContext);
-        mSpace.setId(R.id.spacer);
-        mBottomLabelLayout.addView(mSpace);
-    }
-
-    @Test
-    public void testSetStacked_stackedTrue_layoutVertical() {
-        mBottomLabelLayout.setStacked(true);
-
-        assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.VERTICAL);
-        assertThat(mSpace.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void testSetStacked_stackedFalse_layoutHorizontal() {
-        mBottomLabelLayout.setStacked(false);
-
-        assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.HORIZONTAL);
-        assertThat(mSpace.getVisibility()).isEqualTo(View.VISIBLE);
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
new file mode 100644
index 0000000..8391136
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -0,0 +1,238 @@
+/*
+ * 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.settingslib.suggestions;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtilsTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.res.ResourceLoader;
+import org.robolectric.res.builder.DefaultPackageManager;
+import org.robolectric.res.builder.RobolectricPackageManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SuggestionParserTest {
+
+    private Context mContext;
+    private RobolectricPackageManager mPackageManager;
+    private SuggestionParser mSuggestionParser;
+    private SuggestionCategory mMultipleCategory;
+    private SuggestionCategory mExclusiveCategory;
+    private SuggestionCategory mExpiredExclusiveCategory;
+    private List<Tile> mSuggestionsBeforeDismiss;
+    private List<Tile> mSuggestionsAfterDismiss;
+    private SharedPreferences mPrefs;
+    private Tile mSuggestion;
+
+    @Before
+    public void setUp() {
+        RuntimeEnvironment.setRobolectricPackageManager(
+                new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
+        mContext = RuntimeEnvironment.application;
+        mPackageManager = RuntimeEnvironment.getRobolectricPackageManager();
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+        mSuggestion = new Tile();
+        mSuggestion.intent = new Intent("action");
+        mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
+        mSuggestion.metaData = new Bundle();
+        mMultipleCategory = new SuggestionCategory();
+        mMultipleCategory.category = "category1";
+        mMultipleCategory.multiple = true;
+        mExclusiveCategory = new SuggestionCategory();
+        mExclusiveCategory.category = "category2";
+        mExclusiveCategory.exclusive = true;
+        mExpiredExclusiveCategory = new SuggestionCategory();
+        mExpiredExclusiveCategory.category = "category3";
+        mExpiredExclusiveCategory.exclusive = true;
+        mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
+
+        mSuggestionParser = new SuggestionParser(mContext, mPrefs,
+                Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
+                "0,0");
+
+        ResolveInfo info1 = TileUtilsTest.newInfo(true, null);
+        info1.activityInfo.packageName = "pkg";
+        ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, null);
+        infoDupe1.activityInfo.packageName = "pkg";
+
+        ResolveInfo info2 = TileUtilsTest.newInfo(true, null);
+        info2.activityInfo.packageName = "pkg2";
+        ResolveInfo info3 = TileUtilsTest.newInfo(true, null);
+        info3.activityInfo.packageName = "pkg3";
+        ResolveInfo info4 = TileUtilsTest.newInfo(true, null);
+        info4.activityInfo.packageName = "pkg4";
+
+        Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
+        Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
+        Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3");
+
+        mPackageManager.addResolveInfoForIntent(intent1, info1);
+        mPackageManager.addResolveInfoForIntent(intent1, info2);
+        mPackageManager.addResolveInfoForIntent(intent1, infoDupe1);
+        mPackageManager.addResolveInfoForIntent(intent2, info3);
+        mPackageManager.addResolveInfoForIntent(intent3, info4);
+    }
+
+    @Test
+    public void testDismissSuggestion_withoutSmartSuggestion() {
+        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
+    }
+
+    @Test
+    public void testDismissSuggestion_withSmartSuggestion() {
+        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
+    }
+
+    @Test
+    public void testGetSuggestions_withoutSmartSuggestions() {
+        readAndDismissSuggestion(false);
+        mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
+        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+        assertThat(mSuggestionsAfterDismiss).hasSize(1);
+        assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
+    }
+
+    @Test
+    public void testGetSuggestions_withSmartSuggestions() {
+        readAndDismissSuggestion(true);
+        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
+        assertThat(mSuggestionsAfterDismiss).hasSize(2);
+        assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
+    }
+
+    @Test
+    public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() {
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+                "pkg3");
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category3"),
+                "pkg4");
+
+        // If exclusive item is not available, the other categories should be shown
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+        assertThat(suggestions).hasSize(2);
+
+        assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg");
+        assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2");
+    }
+
+    @Test
+    public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() {
+        // First remove permanent exclusive
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+                "pkg3");
+        // Set the other exclusive to be expired.
+        mPrefs.edit()
+                .putLong(mExpiredExclusiveCategory.category + "_setup_time",
+                        System.currentTimeMillis() - 1000)
+                .commit();
+
+        // If exclusive is expired, they should be shown together with the other categories
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(true /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+
+        assertThat(suggestions).hasSize(3);
+
+        final List<Tile> category1Suggestions = sl.getSuggestionForCategory("category1");
+        final List<Tile> category3Suggestions = sl.getSuggestionForCategory("category3");
+
+        assertThat(category1Suggestions).hasSize(2);
+        assertThat(category3Suggestions).hasSize(1);
+    }
+
+    @Test
+    public void testGetSuggestions_exclusive() {
+        final SuggestionList sl =
+                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
+        final List<Tile> suggestions = sl.getSuggestions();
+
+        assertThat(suggestions).hasSize(1);
+        assertThat(sl.getSuggestionForCategory("category2")).hasSize(1);
+    }
+
+    @Test
+    public void isSuggestionDismissed_mismatchRule_shouldDismiss() {
+        final Tile suggestion = new Tile();
+        suggestion.metaData = new Bundle();
+        suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
+        suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
+
+        // Dismiss suggestion when smart suggestion is not enabled.
+        mSuggestionParser.dismissSuggestion(suggestion, false /* isSmartSuggestionEnabled */);
+        final String suggestionKey = suggestion.intent.getComponent().flattenToShortString();
+        // And point to last rule in dismiss control
+        mPrefs.edit().putInt(suggestionKey + SuggestionParser.DISMISS_INDEX, 2).apply();
+
+        // Turn on smart suggestion, and check if suggestion is enabled.
+        assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
+                .isTrue();
+    }
+
+    private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
+        mSuggestionsBeforeDismiss = new ArrayList<>();
+        mSuggestionsAfterDismiss = new ArrayList<>();
+        mSuggestionParser.readSuggestions(
+                mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
+
+        final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
+        if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
+            RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+                    new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
+                    suggestion.intent.getComponent().getPackageName());
+        }
+        mSuggestionParser.readSuggestions(
+                mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
+    }
+
+    private static class TestPackageManager extends DefaultPackageManager {
+
+        TestPackageManager(ResourceLoader appResourceLoader) {
+            super(appResourceLoader);
+        }
+
+        @Override
+        public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+            return super.queryIntentActivities(intent, flags);
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
new file mode 100644
index 0000000..425d162
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/ThreadUtilsTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.settingslib.utils;
+
+
+import com.android.settingslib.TestConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ThreadUtilsTest {
+
+    @Test
+    public void testMainThread() throws InterruptedException {
+        assertThat(ThreadUtils.isMainThread()).isTrue();
+        Thread background = new Thread(new Runnable() {
+            public void run() {
+                assertThat(ThreadUtils.isMainThread()).isFalse();
+            }
+        });
+        background.start();
+        background.join();
+    }
+
+    @Test
+    public void testEnsureMainThread() throws InterruptedException {
+        ThreadUtils.ensureMainThread();
+        Thread background = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    ThreadUtils.ensureMainThread();
+                    fail("Should not pass ensureMainThread in a background thread");
+                } catch (RuntimeException e) {
+                }
+            }
+        });
+        background.start();
+        background.join();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
new file mode 100644
index 0000000..ded1574
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.settingslib.widget;
+
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FooterPreferenceMixinTest {
+
+    @Mock
+    private PreferenceFragment mFragment;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Lifecycle mLifecycle;
+    private FooterPreferenceMixin mMixin;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLifecycle = new Lifecycle();
+        when(mFragment.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
+        when(mFragment.getPreferenceManager().getContext())
+                .thenReturn(ShadowApplication.getInstance().getApplicationContext());
+        mMixin = new FooterPreferenceMixin(mFragment, mLifecycle);
+    }
+
+    @Test
+    public void createFooter_screenNotAvailable_noCrash() {
+        assertThat(mMixin.createFooterPreference()).isNotNull();
+    }
+
+    @Test
+    public void createFooter_screenAvailable_canAttachToScreen() {
+        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+        final FooterPreference preference = mMixin.createFooterPreference();
+
+        assertThat(preference).isNotNull();
+        verify(mScreen).addPreference(preference);
+    }
+
+    @Test
+    public void createFooter_screenAvailableDelayed_canAttachToScreen() {
+        final FooterPreference preference = mMixin.createFooterPreference();
+
+        mLifecycle.setPreferenceScreen(mScreen);
+
+        assertThat(preference).isNotNull();
+        verify(mScreen).addPreference(preference);
+    }
+
+    @Test
+    public void createFooterTwice_screenAvailable_replaceOldFooter() {
+        when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
+
+        mMixin.createFooterPreference();
+        mMixin.createFooterPreference();
+
+        verify(mScreen).removePreference(any(FooterPreference.class));
+        verify(mScreen, times(2)).addPreference(any(FooterPreference.class));
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
new file mode 100644
index 0000000..17b3de0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.settingslib.widget;
+
+import android.content.Context;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.view.LayoutInflater;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FooterPreferenceTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = ShadowApplication.getInstance().getApplicationContext();
+    }
+
+    @Test
+    public void createNewPreference_shouldSetKeyAndOrder() {
+        final FooterPreference preference = new FooterPreference(mContext);
+
+        assertThat(preference.getKey()).isEqualTo(FooterPreference.KEY_FOOTER);
+        assertThat(preference.getOrder()).isEqualTo(FooterPreference.ORDER_FOOTER);
+    }
+
+    @Test
+    public void bindPreference_shouldLinkifyContent() {
+        final FooterPreference preference = new FooterPreference(mContext);
+        final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
+                LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null));
+
+        preference.onBindViewHolder(holder);
+        assertThat(((TextView) holder.findViewById(android.R.id.title)).getMovementMethod())
+                .isInstanceOf(LinkMovementMethod.class);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
new file mode 100644
index 0000000..335653b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/AccessPointPreferenceTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.settingslib.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AccessPointPreferenceTest {
+
+    private Context mContext = RuntimeEnvironment.application;
+
+    @Test
+    public void generatePreferenceKey_shouldReturnSsidPlusSecurity() {
+        String ssid = "ssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = ssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setSsid(ssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+
+    @Test
+    public void generatePreferenceKey_shouldReturnBssidPlusSecurity() {
+        String bssid = "bssid";
+        int security = AccessPoint.SECURITY_WEP;
+        String expectedKey = bssid + ',' + security;
+
+        TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext);
+        builder.setBssid(bssid).setSecurity(security);
+
+        assertThat(AccessPointPreference.generatePreferenceKey(builder.build()))
+                .isEqualTo(expectedKey);
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b777d41..06d00be 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -45,8 +45,8 @@
 
 import com.android.ims.ImsConfig;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockPatternView;
@@ -2617,9 +2617,9 @@
             loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
 
             // Set the preferred cdma subscription source to target desired value or default
-            // value defined in CdmaSubscriptionSourceManager
+            // value defined in Phone
             type = SystemProperties.getInt("ro.telephony.default_cdma_sub",
-                        CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
+                        Phone.PREFERRED_CDMA_SUBSCRIPTION);
             loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);
 
             loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 920df2e..f8701c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.settings;
 
+import android.annotation.UserIdInt;
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
@@ -133,6 +134,10 @@
     // Keys within the lock settings section
     private static final String KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED = "owner_info_enabled";
     private static final String KEY_LOCK_SETTINGS_OWNER_INFO = "owner_info";
+    private static final String KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED =
+            "visible_pattern_enabled";
+    private static final String KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS =
+            "power_button_instantly_locks";
 
     // Name of the temporary file we use during full backup/restore.  This is
     // stored in the full-backup tarfile as well, so should not be changed.
@@ -142,6 +147,10 @@
 
     private WifiManager mWifiManager;
 
+    // Version of the SDK that com.android.providers.settings package has been restored from.
+    // Populated in onRestore().
+    private int mRestoredFromSdkInt;
+
     @Override
     public void onCreate() {
         if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked");
@@ -158,7 +167,7 @@
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
         byte[] globalSettingsData = getGlobalSettings();
-        byte[] lockSettingsData   = getLockSettings();
+        byte[] lockSettingsData   = getLockSettings(UserHandle.myUserId());
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] softApConfigData = getSoftAPConfiguration();
         byte[] netPoliciesData = getNetworkPolicies();
@@ -196,6 +205,9 @@
     public void onRestore(BackupDataInput data, int appVersionCode,
             ParcelFileDescriptor newState) throws IOException {
 
+        // versionCode of com.android.providers.settings corresponds to SDK_INT
+        mRestoredFromSdkInt = appVersionCode;
+
         HashSet<String> movedToGlobal = new HashSet<String>();
         Settings.System.getMovedToGlobalSettings(movedToGlobal);
         Settings.Secure.getMovedToGlobalSettings(movedToGlobal);
@@ -236,7 +248,7 @@
                     break;
 
                 case KEY_LOCK_SETTINGS :
-                    restoreLockSettings(data);
+                    restoreLockSettings(UserHandle.myUserId(), data);
                     break;
 
                 case KEY_SOFTAP_CONFIG :
@@ -275,7 +287,7 @@
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
         byte[] globalSettingsData = getGlobalSettings();
-        byte[] lockSettingsData   = getLockSettings();
+        byte[] lockSettingsData   = getLockSettings(UserHandle.myUserId());
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] softApConfigData = getSoftAPConfiguration();
         byte[] netPoliciesData = getNetworkPolicies();
@@ -405,7 +417,7 @@
                 if (nBytes > buffer.length) buffer = new byte[nBytes];
                 if (nBytes > 0) {
                     in.readFully(buffer, 0, nBytes);
-                    restoreLockSettings(buffer, nBytes);
+                    restoreLockSettings(UserHandle.myUserId(), buffer, nBytes);
                 }
             }
             // softap config
@@ -531,12 +543,16 @@
     }
 
     /**
-     * Serialize the owner info settings
+     * Serialize the owner info and other lock settings
      */
-    private byte[] getLockSettings() {
+    private byte[] getLockSettings(@UserIdInt int userId) {
         final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
-        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(UserHandle.myUserId());
-        final String ownerInfo = lockPatternUtils.getOwnerInfo(UserHandle.myUserId());
+        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(userId);
+        final String ownerInfo = lockPatternUtils.getOwnerInfo(userId);
+        final boolean lockPatternEnabled = lockPatternUtils.isLockPatternEnabled(userId);
+        final boolean visiblePatternEnabled = lockPatternUtils.isVisiblePatternEnabled(userId);
+        final boolean powerButtonInstantlyLocks =
+                lockPatternUtils.getPowerButtonInstantlyLocks(userId);
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(baos);
@@ -547,6 +563,14 @@
                 out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO);
                 out.writeUTF(ownerInfo != null ? ownerInfo : "");
             }
+            if (lockPatternUtils.isVisiblePatternEverChosen(userId)) {
+                out.writeUTF(KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED);
+                out.writeUTF(visiblePatternEnabled ? "1" : "0");
+            }
+            if (lockPatternUtils.isPowerButtonInstantlyLocksEverChosen(userId)) {
+                out.writeUTF(KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS);
+                out.writeUTF(powerButtonInstantlyLocks ? "1" : "0");
+            }
             // End marker
             out.writeUTF("");
             out.flush();
@@ -623,7 +647,8 @@
             final Uri destination = (movedToGlobal != null && movedToGlobal.contains(key))
                     ? Settings.Global.CONTENT_URI
                     : contentUri;
-            settingsHelper.restoreValue(this, cr, contentValues, destination, key, value);
+            settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
+                    mRestoredFromSdkInt);
 
             if (DEBUG) {
                 Log.d(TAG, "Restored setting: " + destination + " : " + key + "=" + value);
@@ -632,12 +657,12 @@
     }
 
     /**
-     * Restores the owner info enabled and owner info settings in LockSettings.
+     * Restores the owner info enabled and other settings in LockSettings.
      *
      * @param buffer
      * @param nBytes
      */
-    private void restoreLockSettings(byte[] buffer, int nBytes) {
+    private void restoreLockSettings(@UserIdInt int userId, byte[] buffer, int nBytes) {
         final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
 
         ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, nBytes);
@@ -652,11 +677,17 @@
                 }
                 switch (key) {
                     case KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED:
-                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value),
-                                UserHandle.myUserId());
+                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value), userId);
                         break;
                     case KEY_LOCK_SETTINGS_OWNER_INFO:
-                        lockPatternUtils.setOwnerInfo(value, UserHandle.myUserId());
+                        lockPatternUtils.setOwnerInfo(value, userId);
+                        break;
+                    case KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED:
+                        lockPatternUtils.reportPatternWasChosen(userId);
+                        lockPatternUtils.setVisiblePatternEnabled("1".equals(value), userId);
+                        break;
+                    case KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS:
+                        lockPatternUtils.setPowerButtonInstantlyLocks("1".equals(value), userId);
                         break;
                 }
             }
@@ -665,7 +696,7 @@
         }
     }
 
-    private void restoreLockSettings(BackupDataInput data) {
+    private void restoreLockSettings(@UserIdInt int userId, BackupDataInput data) {
         final byte[] settings = new byte[data.getDataSize()];
         try {
             data.readEntityData(settings, 0, settings.length);
@@ -673,7 +704,7 @@
             Log.e(TAG, "Couldn't read entity data");
             return;
         }
-        restoreLockSettings(settings, settings.length);
+        restoreLockSettings(userId, settings, settings.length);
     }
 
     /**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 1e171d3..344cd8f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -37,10 +37,12 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Slog;
 
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String TAG = "SettingsHelper";
     private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
@@ -110,7 +112,7 @@
      * and in some cases the property value needs to be modified before setting.
      */
     public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues,
-            Uri destination, String name, String value) {
+            Uri destination, String name, String value, int restoredFromSdkInt) {
         // Will we need a post-restore broadcast for this element?
         String oldValue = null;
         boolean sendBroadcast = false;
@@ -167,7 +169,8 @@
                         .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                         .putExtra(Intent.EXTRA_SETTING_NAME, name)
                         .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value)
-                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue);
+                        .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue)
+                        .putExtra(Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, restoredFromSdkInt);
                 context.sendBroadcastAsUser(intent, UserHandle.SYSTEM, null);
             }
         }
@@ -324,11 +327,17 @@
      */
     void setLocaleData(byte[] data, int size) {
         // Check if locale was set by the user:
-        Configuration conf = mContext.getResources().getConfiguration();
-        // TODO: The following is not working as intended because the network is forcing a locale
-        // change after registering. Need to find some other way to detect if the user manually
-        // changed the locale
-        if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
+        final ContentResolver cr = mContext.getContentResolver();
+        final boolean userSetLocale = mContext.getResources().getConfiguration().userSetLocale;
+        final boolean provisioned = Settings.Global.getInt(cr,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (userSetLocale || provisioned) {
+            // Don't change if user set it in the SetupWizard, or if this is a post-setup
+            // deferred restore operation
+            Slog.i(TAG, "Not applying restored locale; "
+                    + (userSetLocale ? "user already specified" : "device already provisioned"));
+            return;
+        }
 
         final String[] availableLocales = mContext.getAssets().getLocales();
         // Replace "_" with "-" to deal with older backups.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index b328933..819ee3e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -915,9 +915,6 @@
                 Settings.Global.DEVICE_DEMO_MODE,
                 GlobalSettingsProto.DEVICE_DEMO_MODE);
         dumpSetting(s, p,
-                Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
-                GlobalSettingsProto.RETAIL_DEMO_MODE_CONSTANTS);
-        dumpSetting(s, p,
                 Settings.Global.DATABASE_DOWNGRADE_REASON,
                 GlobalSettingsProto.DATABASE_DOWNGRADE_REASON);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f5d7dd8..d22d0b36 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2597,7 +2597,7 @@
             synchronized (mLock) {
                 final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
                 File globalFile = getSettingsFile(key);
-                if (globalFile.exists()) {
+                if (SettingsState.stateFileExists(globalFile)) {
                     return;
                 }
 
@@ -2634,7 +2634,7 @@
             // Every user has secure settings and if no file we need to migrate.
             final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
             File secureFile = getSettingsFile(secureKey);
-            if (secureFile.exists()) {
+            if (SettingsState.stateFileExists(secureFile)) {
                 return;
             }
 
@@ -2895,7 +2895,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 145;
+            private static final int SETTINGS_VERSION = 146;
 
             private final int mUserId;
 
@@ -3421,22 +3421,11 @@
                 }
 
                 if (currentVersion == 141) {
-                    // Version 142: We added the notion of a default and whether the system set
-                    // the setting. This is used for resetting the internal state and we need
-                    // to make sure this value is updated for the existing settings, otherwise
-                    // we would delete system set settings while they should stay unmodified.
-                    SettingsState globalSettings = getGlobalSettingsLocked();
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings);
-                    globalSettings.persistSyncLocked();
-
-                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings);
-                    secureSettings.persistSyncLocked();
-
-                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings);
-                    systemSettings.persistSyncLocked();
-
+                    // This implementation was incorrectly setting the current value of
+                    // settings changed by non-system packages as the default which default
+                    // is set by the system. We add a new upgrade step at the end to properly
+                    // handle this case which would also fix incorrect changes made by the
+                    // old implementation of this step.
                     currentVersion = 142;
                 }
 
@@ -3496,6 +3485,31 @@
                     currentVersion = 145;
                 }
 
+                if (currentVersion == 145) {
+                    // Version 146: In step 142 we had a bug where incorrectly
+                    // some settings were considered system set and as a result
+                    // made the default and marked as the default being set by
+                    // the system. Here reevaluate the default and default system
+                    // set flags. This would both fix corruption by the old impl
+                    // of step 142 and also properly handle devices which never
+                    // run 142.
+                    if (userId == UserHandle.USER_SYSTEM) {
+                        SettingsState globalSettings = getGlobalSettingsLocked();
+                        ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
+                        globalSettings.persistSyncLocked();
+                    }
+
+                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
+                    secureSettings.persistSyncLocked();
+
+                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
+                    systemSettings.persistSyncLocked();
+
+                    currentVersion = 146;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
@@ -3514,19 +3528,46 @@
             }
         }
 
-        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings) {
+        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
+                int userId) {
             List<String> names = settings.getSettingNamesLocked();
             final int nameCount = names.size();
             for (int i = 0; i < nameCount; i++) {
                 String name = names.get(i);
                 Setting setting = settings.getSettingLocked(name);
-                if (setting.getDefaultValue() == null) {
-                    boolean systemSet = SettingsState.isSystemPackage(getContext(),
-                            setting.getPackageName());
+
+                // In the upgrade case we pretend the call is made from the app
+                // that made the last change to the setting to properly determine
+                // whether the call has been made by a system component.
+                int callingUid = -1;
+                try {
+                    callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
+                } catch (RemoteException e) {
+                    /* ignore - handled below */
+                }
+                if (callingUid < 0) {
+                    Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
+                    continue;
+                }
+                try {
+                    final boolean systemSet = SettingsState.isSystemPackage(getContext(),
+                            setting.getPackageName(), callingUid);
                     if (systemSet) {
                         settings.insertSettingLocked(name, setting.getValue(),
                                 setting.getTag(), true, setting.getPackageName());
+                    } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
+                        // We had a bug where changes by non-system packages were marked
+                        // as system made and as a result set as the default. Therefore, if
+                        // the package changed the setting last is not a system one but the
+                        // setting is marked as its default coming from the system we clear
+                        // the default and clear the system set flag.
+                        settings.resetSettingDefaultValueLocked(name);
                     }
+                } catch (IllegalStateException e) {
+                    // If the package goes over its quota during the upgrade, don't
+                    // crash but just log the error as the system does the upgrade.
+                    Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);
+
                 }
             }
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 5f4b239..4151ada 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -298,6 +298,22 @@
     }
 
     // The settings provider must hold its lock when calling here.
+    public void resetSettingDefaultValueLocked(String name) {
+        Setting oldSetting = getSettingLocked(name);
+        if (oldSetting != null && !oldSetting.isNull() && oldSetting.getDefaultValue() != null) {
+            String oldValue = oldSetting.getValue();
+            String oldDefaultValue = oldSetting.getDefaultValue();
+            Setting newSetting = new Setting(name, oldSetting.getValue(), null,
+                    oldSetting.getPackageName(), oldSetting.getTag(), false,
+                    oldSetting.getId());
+            mSettings.put(name, newSetting);
+            updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
+                    newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
+            scheduleWriteIfNeededLocked();
+        }
+    }
+
+    // The settings provider must hold its lock when calling here.
     public boolean insertSettingLocked(String name, String value, String tag,
             boolean makeDefault, String packageName) {
         if (TextUtils.isEmpty(name)) {
@@ -689,17 +705,11 @@
 
     private void readStateSyncLocked() {
         FileInputStream in;
-        if (!mStatePersistFile.exists()) {
-            Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
-            addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
-            return;
-        }
         try {
             in = new AtomicFile(mStatePersistFile).openRead();
         } catch (FileNotFoundException fnfe) {
-            String message = "No settings state " + mStatePersistFile;
-            Slog.wtf(LOG_TAG, message);
-            Slog.i(LOG_TAG, message);
+            Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
+            addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
             return;
         }
         try {
@@ -715,6 +725,16 @@
         }
     }
 
+    /**
+     * Uses AtomicFile to check if the file or its backup exists.
+     * @param file The file to check for existence
+     * @return whether the original or backup exist
+     */
+    public static boolean stateFileExists(File file) {
+        AtomicFile stateFile = new AtomicFile(file);
+        return stateFile.exists();
+    }
+
     private void parseStateLocked(XmlPullParser parser)
             throws IOException, XmlPullParserException {
         final int outerDepth = parser.getDepth();
@@ -1003,6 +1023,10 @@
     }
 
     public static boolean isSystemPackage(Context context, String packageName) {
+        return isSystemPackage(context, packageName, Binder.getCallingUid());
+    }
+
+    public static boolean isSystemPackage(Context context, String packageName, int callingUid) {
         synchronized (sLock) {
             if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
                 return true;
@@ -1015,7 +1039,7 @@
             }
 
             // Native services running as a special UID get a pass
-            final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
+            final int callingAppId = UserHandle.getAppId(callingUid);
             if (callingAppId < FIRST_APPLICATION_UID) {
                 sSystemUids.put(callingAppId, callingAppId);
                 return true;
@@ -1026,7 +1050,7 @@
             // profile for the purpose of determining whether the other end is a
             // system component we need to use the user id of the caller for
             // pulling information about the caller from the package manager.
-            final int callingUserId = UserHandle.getCallingUserId();
+            final int callingUserId = UserHandle.getUserId(callingUid);
 
             final long identity = Binder.clearCallingIdentity();
             try {
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index 2673f3d..85e611f 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -19,4 +19,6 @@
 
 LOCAL_CERTIFICATE := platform
 
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
 include $(BUILD_PACKAGE)
diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml
new file mode 100644
index 0000000..3a156895
--- /dev/null
+++ b/packages/SettingsProvider/test/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<configuration description="Run Settings Provider Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="SettingsProviderTest.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="SettingsProviderTest" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.providers.setting.test" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 5809bfc..805aed6 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -23,7 +23,9 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izveštaj o grešci će se uskoro pojaviti na telefonu"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izaberite da biste delili izveštaj o grešci"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izaberite da biste delili izveštaj o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, koji obuhvataju lične i privatne podatke (poput korišćenja aplikacija i podataka o lokaciji). Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
index f69317c..bea1c30 100644
--- a/packages/Shell/res/values-be/strings.xml
+++ b/packages/Shell/res/values-be/strings.xml
@@ -23,7 +23,9 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Дадаванне падрабязнасцей да справаздачы пра памылкі"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Калі ласка, пачакайце..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Паведамленне пра памылку хутка з\'явіцца на тэлефоне"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Выберыце, каб абагуліць справаздачу пра памылку"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Дакраніцеся, каб абагуліць сваю справаздачу пра памылку"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Выберыце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Справаздачы пра памылкі ўтрымліваюць даныя з розных файлаў журналаў сістэмы, якія могуць уключаць даныя, што вы лічыце канфідэнцыяльнымі (напрыклад, пра выкарыстанне праграм і даныя аб месцазнаходжанні). Абагульвайце справаздачы пра памылкі толькі з тымі людзьмі і праграмамі, якім вы давяраеце."</string>
diff --git a/packages/Shell/res/values-bs/strings.xml b/packages/Shell/res/values-bs/strings.xml
index 8815e94..6abcc33 100644
--- a/packages/Shell/res/values-bs/strings.xml
+++ b/packages/Shell/res/values-bs/strings.xml
@@ -23,10 +23,12 @@
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Izvještaj o greškama će se ubrzo pojaviti na ekranu"</string>
+    <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Odaberite da podijelite izvještaj o greškama"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Odaberite da podijelite izvještaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o upotrebi aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o korištenju aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj opet"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Nije moguće pročitati izvještaj o grešci"</string>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 348b02a..988b986 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -786,14 +786,6 @@
      */
     private void onBugreportFinished(int id, Intent intent) {
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
-        // Since BugreportProvider and BugreportProgressService aren't tightly coupled,
-        // we need to make sure they are explicitly tied to a single unique notification URI
-        // so that the service can alert the provider of changes it has done (ie. new bug
-        // reports)
-        // See { @link Cursor#setNotificationUri } and {@link ContentResolver#notifyChanges }
-        final Uri notificationUri = BugreportStorageProvider.getNotificationUri();
-        mContext.getContentResolver().notifyChange(notificationUri, null, false);
-
         if (bugreportFile == null) {
             // Should never happen, dumpstate always set the file.
             Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
index b9b77a4..1bb36fb 100644
--- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
+++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
@@ -26,22 +26,22 @@
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
-import android.provider.DocumentsProvider;
-import android.webkit.MimeTypeMap;
+
+import com.android.internal.content.FileSystemProvider;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 
-public class BugreportStorageProvider extends DocumentsProvider {
+public class BugreportStorageProvider extends FileSystemProvider {
     private static final String AUTHORITY = "com.android.shell.documents";
     private static final String DOC_ID_ROOT = "bugreport";
 
-    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{
             Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
             Root.COLUMN_DOCUMENT_ID,
     };
 
-    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
+    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[]{
             Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME,
             Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
     };
@@ -50,6 +50,7 @@
 
     @Override
     public boolean onCreate() {
+        super.onCreate(DEFAULT_DOCUMENT_PROJECTION);
         mRoot = new File(getContext().getFilesDir(), "bugreports");
         return true;
     }
@@ -69,35 +70,13 @@
     @Override
     public Cursor queryDocument(String documentId, String[] projection)
             throws FileNotFoundException {
-        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
         if (DOC_ID_ROOT.equals(documentId)) {
-            final RowBuilder row = result.newRow();
-            row.add(Document.COLUMN_DOCUMENT_ID, documentId);
-            row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
-            row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
-            row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
-            row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
+            final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+            includeDefaultDocument(result);
+            return result;
         } else {
-            addFileRow(result, getFileForDocId(documentId));
+            return super.queryDocument(documentId, projection);
         }
-        return result;
-    }
-
-    @Override
-    public Cursor queryChildDocuments(
-            String parentDocumentId, String[] projection, String sortOrder)
-            throws FileNotFoundException {
-        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
-        if (DOC_ID_ROOT.equals(parentDocumentId)) {
-            final File[] files = mRoot.listFiles();
-            if (files != null) {
-                for (File file : files) {
-                    addFileRow(result, file);
-                }
-                result.setNotificationUri(getContext().getContentResolver(), getNotificationUri());
-            }
-        }
-        return result;
     }
 
     @Override
@@ -112,17 +91,8 @@
     }
 
     @Override
-    public void deleteDocument(String documentId) throws FileNotFoundException {
-        if (!getFileForDocId(documentId).delete()) {
-            throw new FileNotFoundException("Failed to delete: " + documentId);
-        }
-        getContext().getContentResolver().notifyChange(getNotificationUri(), null);
-    }
-
-    // This is used by BugreportProgressService so that the notification uri shared by
-    // BugreportProgressService and BugreportStorageProvider are guaranteed the same and unique
-    protected static Uri getNotificationUri() {
-      return DocumentsContract.buildChildDocumentsUri(AUTHORITY, DOC_ID_ROOT);
+    protected Uri buildNotificationUri(String docId) {
+        return DocumentsContract.buildChildDocumentsUri(AUTHORITY, docId);
     }
 
     private static String[] resolveRootProjection(String[] projection) {
@@ -133,45 +103,45 @@
         return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
     }
 
-    private static String getTypeForName(String name) {
-        final int lastDot = name.lastIndexOf('.');
-        if (lastDot >= 0) {
-            final String extension = name.substring(lastDot + 1).toLowerCase();
-            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
-            if (mime != null) {
-                return mime;
-            }
-        }
-        return "application/octet-stream";
-    }
-
-    private String getDocIdForFile(File file) {
+    @Override
+    protected String getDocIdForFile(File file) {
         return DOC_ID_ROOT + ":" + file.getName();
     }
 
-    private File getFileForDocId(String documentId) throws FileNotFoundException {
-        final int splitIndex = documentId.indexOf(':', 1);
-        final String name = documentId.substring(splitIndex + 1);
-        if (splitIndex == -1 || !DOC_ID_ROOT.equals(documentId.substring(0, splitIndex)) ||
-                !FileUtils.isValidExtFilename(name)) {
-            throw new FileNotFoundException("Invalid document ID: " + documentId);
+    @Override
+    protected File getFileForDocId(String documentId, boolean visible)
+            throws FileNotFoundException {
+        if (DOC_ID_ROOT.equals(documentId)) {
+            return mRoot;
+        } else {
+            final int splitIndex = documentId.indexOf(':', 1);
+            final String name = documentId.substring(splitIndex + 1);
+            if (splitIndex == -1 || !DOC_ID_ROOT.equals(documentId.substring(0, splitIndex)) ||
+                    !FileUtils.isValidExtFilename(name)) {
+                throw new FileNotFoundException("Invalid document ID: " + documentId);
+            }
+            final File file = new File(mRoot, name);
+            if (!file.exists()) {
+                throw new FileNotFoundException("File not found: " + documentId);
+            }
+            return file;
         }
-        final File file = new File(mRoot, name);
-        if (!file.exists()) {
-            throw new FileNotFoundException("File not found: " + documentId);
-        }
-        return file;
     }
 
-    private void addFileRow(MatrixCursor result, File file) {
-        String mimeType = getTypeForName(file.getName());
-        int flags = Document.FLAG_SUPPORTS_DELETE;
+    @Override
+    protected RowBuilder includeFile(MatrixCursor result, String docId, File file)
+            throws FileNotFoundException {
+        RowBuilder row = super.includeFile(result, docId, file);
+        row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
+        return row;
+    }
+
+    private void includeDefaultDocument(MatrixCursor result) {
         final RowBuilder row = result.newRow();
-        row.add(Document.COLUMN_DOCUMENT_ID, getDocIdForFile(file));
-        row.add(Document.COLUMN_MIME_TYPE, mimeType);
-        row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
-        row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
-        row.add(Document.COLUMN_FLAGS, flags);
-        row.add(Document.COLUMN_SIZE, file.length());
+        row.add(Document.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
+        row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
+        row.add(Document.COLUMN_DISPLAY_NAME, mRoot.getName());
+        row.add(Document.COLUMN_LAST_MODIFIED, mRoot.lastModified());
+        row.add(Document.COLUMN_FLAGS, Document.FLAG_DIR_PREFERS_LAST_MODIFIED);
     }
 }
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index 92c5fcc..8e27edf 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -100,7 +100,7 @@
         // Rotate the screenshot to the current orientation
         if (rotation != ROTATION_FREEZE_0) {
             Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
-                    Bitmap.Config.ARGB_8888);
+                    Bitmap.Config.ARGB_8888, screenShot.hasAlpha(), screenShot.getColorSpace());
             Canvas canvas = new Canvas(unrotatedScreenShot);
             canvas.translate(unrotatedScreenShot.getWidth() / 2,
                     unrotatedScreenShot.getHeight() / 2);
diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml
index ed9cb2b..bd37712c 100644
--- a/packages/Shell/tests/AndroidTest.xml
+++ b/packages/Shell/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="ShellTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.shell.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 193c336..86ff8fe 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -22,6 +22,11 @@
         android:sharedUserId="android.uid.systemui"
         coreApp="true">
 
+    <!-- SysUI must be the one to define this permission; its name is
+         referenced by the core OS. -->
+    <permission android:name="android.permission.systemui.IDENTITY"
+        android:protectionLevel="signature" />
+
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -190,6 +195,9 @@
     <!-- to access instant apps -->
     <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
 
+    <!-- to change themes - light or dark -->
+    <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
@@ -200,7 +208,7 @@
         android:icon="@drawable/icon"
         android:process="com.android.systemui"
         android:supportsRtl="true"
-        android:theme="@style/systemui_theme"
+        android:theme="@style/Theme.SystemUI"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true">
         <!-- Keep theme in sync with SystemUIApplication.onCreate().
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index 258c76b..6cf7060 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -29,6 +29,7 @@
 ```battery```        |                            |                | Control the battery display
                      | ```level```                |                | Sets the battery level (0 - 100)
                      | ```plugged```              |                | Sets charging state (```true```, ```false```)
+                     | ```powersave```            |                | Sets power save mode (```true```, ```anything else```)
 ```network```        |                            |                | Control the RSSI display
                      | ```airplane```             |                | ```show``` to show icon, any other value to hide
                      | ```fully```                |                | Sets MCS state to fully connected (```true```, ```false```)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java
new file mode 100644
index 0000000..3ca5690
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DozeServicePlugin.java
@@ -0,0 +1,21 @@
+package com.android.systemui.plugins;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@ProvidesInterface(action = DozeServicePlugin.ACTION, version = DozeServicePlugin.VERSION)
+public interface DozeServicePlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_DOZE";
+    int VERSION = 1;
+
+    public interface RequestDoze {
+        void onRequestShowDoze();
+
+        void onRequestHideDoze();
+    }
+
+    void onDreamingStarted();
+
+    void onDreamingStopped();
+
+    void setDozeRequester(RequestDoze requester);
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
index bb21fb3..1f633da 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
@@ -26,6 +26,8 @@
     int VERSION = 1;
 
     void showGlobalActions(GlobalActionsManager manager);
+    default void showShutdownUi(boolean isReboot, String reason) {
+    }
 
     @ProvidesInterface(version = GlobalActionsManager.VERSION)
     public interface GlobalActionsManager {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java
new file mode 100644
index 0000000..fac9e98
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java
@@ -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.
+ */
+
+package com.android.systemui.plugins;
+
+import android.service.notification.NotificationListenerService.RankingMap;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@ProvidesInterface(action = NotificationListenerController.ACTION,
+        version = NotificationListenerController.VERSION)
+@DependsOn(target = NotificationProvider.class)
+public interface NotificationListenerController extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_ASSISTANT";
+    int VERSION = 1;
+
+    void onListenerConnected(NotificationProvider provider);
+
+    default boolean onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+        return false;
+    }
+    default boolean onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+        return false;
+    }
+
+    default StatusBarNotification[] getActiveNotifications(
+            StatusBarNotification[] activeNotifications) {
+        return activeNotifications;
+    }
+
+    default RankingMap getCurrentRanking(RankingMap currentRanking) {
+        return currentRanking;
+    }
+
+    @ProvidesInterface(version = NotificationProvider.VERSION)
+    interface NotificationProvider {
+        int VERSION = 1;
+
+        // Methods to get info about current notifications
+        StatusBarNotification[] getActiveNotifications();
+        RankingMap getRankingMap();
+
+        // Methods to notify sysui of changes to notification list.
+        void addNotification(StatusBarNotification sbn);
+        void removeNotification(StatusBarNotification sbn);
+        void updateRanking();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
new file mode 100644
index 0000000..925214e
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java
@@ -0,0 +1,92 @@
+/*
+ * 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.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity)
+ * at runtime within the sysui process.
+ */
+@ProvidesInterface(version = PluginActivity.VERSION)
+public abstract class PluginActivity extends Activity implements Plugin {
+
+    public static final int VERSION = 1;
+
+    public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS";
+
+    private Context mSysuiContext;
+    private boolean mSettingActionBar;
+
+    @Override
+    public final void onCreate(Context sysuiContext, Context pluginContext) {
+        mSysuiContext = sysuiContext;
+        super.attachBaseContext(pluginContext);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Theme theme = getClass().getDeclaredAnnotation(Theme.class);
+        if (theme != null && theme.value() != 0) {
+            setTheme(theme.value());
+        }
+        mSettingActionBar = true;
+        getActionBar();
+        mSettingActionBar = false;
+    }
+
+    @Override
+    public Resources getResources() {
+        return mSettingActionBar ? mSysuiContext.getResources() : super.getResources();
+    }
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        mSysuiContext = newBase;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    public Context getSysuiContext() {
+        return mSysuiContext;
+    }
+
+    public Context getPluginContext() {
+        return getBaseContext();
+    }
+
+    /**
+     * Since PluginActivities are declared as services instead of activities (since they
+     * are plugins), they can't have a theme attached to them. Instead a PluginActivity
+     * can annotate itself with @Theme to specify the resource of the style it wants
+     * to be themed with.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Theme {
+        int value();
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
index 25ce3dd..db2e376 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
@@ -21,6 +21,11 @@
     public static final int VERSION = 1;
     static DependencyProvider sProvider;
 
+    /**
+     * Allows a plugin to get a hold of static dependencies if they have declared dependence
+     * on their interface. For one-shot plugins this will only work during onCreate and will
+     * not work afterwards.
+     */
     public static <T> T get(Plugin p, Class<T> cls) {
         return sProvider.get(p, cls);
     }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index ed62b71..b4b4e19 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -112,6 +112,7 @@
         public boolean dualTarget = false;
         public boolean isTransient = false;
         public String expandedAccessibilityClassName;
+        public SlashState slash;
 
         public boolean copyTo(State other) {
             if (other == null) throw new IllegalArgumentException();
@@ -126,7 +127,8 @@
                     || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
                     || !Objects.equals(other.state, state)
                     || !Objects.equals(other.isTransient, isTransient)
-                    || !Objects.equals(other.dualTarget, dualTarget);
+                    || !Objects.equals(other.dualTarget, dualTarget)
+                    || !Objects.equals(other.slash, slash);
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
@@ -136,6 +138,7 @@
             other.state = state;
             other.dualTarget = dualTarget;
             other.isTransient = isTransient;
+            other.slash = slash != null ? slash.copy() : null;
             return changed;
         }
 
@@ -155,6 +158,7 @@
             sb.append(",dualTarget=").append(dualTarget);
             sb.append(",isTransient=").append(isTransient);
             sb.append(",state=").append(state);
+            sb.append(",slash=\"").append(slash).append("\"");
             return sb.append(']');
         }
 
@@ -252,4 +256,34 @@
         }
     }
 
+    @ProvidesInterface(version = SlashState.VERSION)
+    public static class SlashState {
+        public static final int VERSION = 2;
+
+        public boolean isSlashed;
+        public float rotation;
+
+        @Override
+        public String toString() {
+            return "isSlashed=" + isSlashed + ",rotation=" + rotation;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+            try {
+                return (((SlashState) o).rotation == rotation)
+                        && (((SlashState) o).isSlashed == isSlashed);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+
+        public SlashState copy() {
+            SlashState state = new SlashState();
+            state.rotation = rotation;
+            state.isSlashed = isSlashed;
+            return state;
+        }
+    }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index 28f78e5..ecc2ff4 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -15,6 +15,7 @@
 package com.android.systemui.plugins.statusbar;
 
 import android.content.Context;
+import android.service.notification.StatusBarNotification;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -37,7 +38,7 @@
 public interface NotificationMenuRowPlugin extends Plugin {
 
     public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
-    public static final int VERSION = 2;
+    public static final int VERSION = 3;
 
     @ProvidesInterface(version = OnMenuEventListener.VERSION)
     public interface OnMenuEventListener {
@@ -77,7 +78,7 @@
 
     public void setAppName(String appName);
 
-    public void createMenu(ViewGroup parent);
+    public void createMenu(ViewGroup parent, StatusBarNotification sbn);
 
     public View getMenuView();
 
@@ -89,10 +90,14 @@
 
     public void onHeightUpdate();
 
-    public void onNotificationUpdated();
+    public void onNotificationUpdated(StatusBarNotification sbn);
 
     public boolean onTouchEvent(View view, MotionEvent ev, float velocity);
 
+    public default boolean onInterceptTouchEvent(View view, MotionEvent ev) {
+        return false;
+    }
+
     public default boolean useDefaultMenuItems() {
         return false;
     }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
index 3cd5d89..f6cf035 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java
@@ -22,6 +22,7 @@
 import android.service.notification.StatusBarNotification;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 @ProvidesInterface(version = NotificationSwipeActionHelper.VERSION)
 @DependsOn(target = SnoozeOption.class)
@@ -56,19 +57,17 @@
     public boolean swipedFastEnough(float translation, float velocity);
 
     @ProvidesInterface(version = SnoozeOption.VERSION)
-    public static class SnoozeOption {
-        public static final int VERSION = 1;
-        public int snoozeForMinutes;
-        public SnoozeCriterion criterion;
-        public CharSequence description;
-        public CharSequence confirmation;
+    public interface SnoozeOption {
+        public static final int VERSION = 2;
 
-        public SnoozeOption(SnoozeCriterion crit, int minsToSnoozeFor, CharSequence desc,
-                CharSequence confirm) {
-            criterion = crit;
-            snoozeForMinutes = minsToSnoozeFor;
-            description = desc;
-            confirmation = confirm;
-        }
+        public SnoozeCriterion getSnoozeCriterion();
+
+        public CharSequence getDescription();
+
+        public CharSequence getConfirmation();
+
+        public int getMinutesToSnoozeFor();
+
+        public AccessibilityAction getAccessibilityAction();
     }
 }
diff --git a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
deleted file mode 100644
index 82c01ef..0000000
--- a/packages/SystemUI/res-keyguard/drawable-hdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
deleted file mode 100644
index 8c16930..0000000
--- a/packages/SystemUI/res-keyguard/drawable-mdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
deleted file mode 100644
index 6a4d8a7..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
deleted file mode 100644
index 4c04ba2..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
deleted file mode 100644
index bd6c4df..0000000
--- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/ic_done_wht.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
index 84ccb7c..fffa0bd 100644
--- a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
+++ b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -18,8 +18,7 @@
     android:height="18dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
-
     <path
-        android:fillColor="@color/clock_gray"
-        android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:fillColor="@android:color/white"
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z" />
 </vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
deleted file mode 100644
index 1e4022e..0000000
--- a/packages/SystemUI/res-keyguard/drawable/ic_backspace_24dp.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:autoMirrored="true"
-        android:height="24dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#ffffffff"
-        android:pathData="M44.0,6.0L14.0,6.0c-1.4,0.0 -2.5,0.7 -3.2,1.8L0.0,24.0l10.8,16.2c0.7,1.1 1.8,1.8 3.2,1.8l30.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L48.0,10.0C48.0,7.8 46.2,6.0 44.0,6.0zM38.0,31.2L35.2,34.0L28.0,26.8L20.8,34.0L18.0,31.2l7.2,-7.2L18.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L30.8,24.0L38.0,31.2z"/>
-</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
new file mode 100644
index 0000000..6edae4b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_backspace_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M22,3H7C6.31,3 5.77,3.35 5.41,3.88l-5.04,7.57c-0.22,0.34 -0.22,0.77 0,1.11l5.04,7.56C5.77,20.64 6.31,21 7,21h15c1.1,0 2,-0.9 2,-2V5C24,3.9 23.1,3 22,3zM18.3,16.3L18.3,16.3c-0.39,0.39 -1.02,0.39 -1.41,0L14,13.41l-2.89,2.89c-0.39,0.39 -1.02,0.39 -1.41,0h0c-0.39,-0.39 -0.39,-1.02 0,-1.41L12.59,12L9.7,9.11c-0.39,-0.39 -0.39,-1.02 0,-1.41l0,0c0.39,-0.39 1.02,-0.39 1.41,0L14,10.59l2.89,-2.89c0.39,-0.39 1.02,-0.39 1.41,0v0c0.39,0.39 0.39,1.02 0,1.41L15.41,12l2.89,2.89C18.68,15.27 18.68,15.91 18.3,16.3z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
new file mode 100644
index 0000000..5026f07
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_done_black_24dp.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ 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.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M9,16.2l-3.5,-3.5a0.984,0.984 0,0 0,-1.4 0,0.984 0.984,0 0,0 0,1.4l4.19,4.19c0.39,0.39 1.02,0.39 1.41,0L20.3,7.7a0.984,0.984 0,0 0,0 -1.4,0.984 0.984,0 0,0 -1.4,0L9,16.2z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_divider.xml b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
new file mode 100644
index 0000000..39104b5
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/pin_divider_color" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
new file mode 100644
index 0000000..8cbd94b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<!-- This contains disable esim buttonas shared by sim_pin/sim_puk screens -->
+<com.android.keyguard.KeyguardEsimArea
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:id="@+id/keyguard_disable_esim"
+    android:visibility="gone"
+    android:text="@string/disable_carrier_button_text"
+    style="?android:attr/buttonBarButtonStyle"
+    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:textSize="@dimen/kg_status_line_font_size"
+    android:textColor="?android:attr/textColorSecondary"
+    android:textAllCaps="@bool/kg_use_all_caps" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 29c93d5..9fdb00e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -43,7 +43,7 @@
          android:layout_height="wrap_content"
          android:layout_width="280dp"
          android:layout_gravity="center_horizontal"
-         android:theme="@style/PasswordTheme"
+         android:theme="?attr/passwordStyle"
          >
 
          <EditText android:id="@+id/passwordEntry"
@@ -54,6 +54,7 @@
              android:textStyle="normal"
              android:inputType="textPassword"
              android:textSize="16sp"
+             android:textColor="?attr/wallpaperTextColor"
              android:textAppearance="?android:attr/textAppearanceMedium"
              android:imeOptions="flagForceAscii|actionDone"
              android:maxLength="500"
@@ -67,6 +68,7 @@
              android:contentDescription="@string/accessibility_ime_switch_button"
              android:clickable="true"
              android:padding="8dip"
+             android:tint="@color/background_protected"
              android:layout_gravity="end|center_vertical"
              android:background="?android:attr/selectableItemBackground"
              android:visibility="gone"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index e75f3c15..631cc0d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -53,7 +53,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_pin_area"
                     />
             <ImageButton
@@ -61,23 +62,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </com.android.keyguard.AlphaOptimizedRelativeLayout>
         <LinearLayout
@@ -202,7 +205,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 920498f..6dea493 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -41,7 +41,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_horizontal|top"
-                android:textColor="@color/clock_white"
+                android:textColor="?attr/wallpaperTextColor"
                 android:singleLine="true"
                 style="@style/widget_big_thin"
                 android:format12Hour="@string/keyguard_widget_12_hours_format"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index b0a93e6..97c8965 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -42,9 +42,16 @@
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:orientation="vertical"
+            android:gravity="center"
             android:layout_weight="1"
             android:layoutDirection="ltr"
             >
+        <include layout="@layout/keyguard_esim_area"
+             android:id="@+id/keyguard_esim_area"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:layout_marginTop="@dimen/eca_overlap" />
+
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
@@ -59,7 +66,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
                     />
             <ImageButton
@@ -67,23 +75,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </RelativeLayout>
         <LinearLayout
@@ -204,7 +214,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index cf41bd3..d4c5d74 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -43,9 +43,16 @@
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:orientation="vertical"
+            android:gravity="center"
             android:layout_weight="1"
             android:layoutDirection="ltr"
             >
+        <include layout="@layout/keyguard_esim_area"
+            android:id="@+id/keyguard_esim_area"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/eca_overlap" />
+
         <RelativeLayout
                 android:id="@+id/row0"
                 android:layout_width="match_parent"
@@ -60,7 +67,8 @@
                     android:gravity="center"
                     android:layout_centerHorizontal="true"
                     android:layout_marginRight="72dp"
-                    androidprv:scaledTextSize="28"
+                    androidprv:scaledTextSize="@integer/scaled_password_text_size"
+                    android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
                     />
             <ImageButton
@@ -68,23 +76,25 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_24dp"
+                    android:src="@drawable/ic_backspace_black_24dp"
                     android:clickable="true"
                     android:paddingTop="8dip"
                     android:paddingBottom="8dip"
-                    android:paddingRight="8dp"
+                    android:paddingRight="0dp"
                     android:paddingLeft="24dp"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_delete"
                     android:layout_alignEnd="@+id/pinEntry"
                     android:layout_alignParentRight="true"
+                    android:tint="@color/pin_delete_color"
+                    android:tintMode="src_in"
                     />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
                     android:layout_height="1dp"
                     android:layout_alignParentBottom="true"
-                    android:background="#28FFFFFF"
+                    android:background="@drawable/pin_divider"
                     />
         </RelativeLayout>
         <LinearLayout
@@ -205,7 +215,8 @@
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_wht"
+                    android:src="@drawable/ic_done_black_24dp"
+                    style="@style/Keyguard.ImageButton.NumPadEnter"
                     android:background="@drawable/ripple_drawable"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index 7e664d0..56fb73f 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -29,9 +29,9 @@
         android:id="@+id/date_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textColor="@color/clock_white"
+        android:textColor="?attr/wallpaperTextColor"
         style="@style/widget_label"
-        android:letterSpacing="0.15"
+        android:letterSpacing="0.05"
         android:gravity="center"
         />
     <TextView android:id="@+id/alarm_status"
@@ -39,8 +39,10 @@
         android:layout_height="wrap_content"
         android:drawablePadding="6dp"
         android:drawableStart="@drawable/ic_access_alarms_big"
-        android:textColor="@color/clock_gray"
-        android:letterSpacing="0.15"
+        android:drawableTint="?attr/wallpaperTextColorSecondary"
+        android:drawableTintMode="src_in"
+        android:textColor="?attr/wallpaperTextColorSecondary"
+        android:letterSpacing="0.05"
         style="@style/widget_label"
         android:layout_marginStart="6dp"
         android:gravity="center"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 51adc1e..138733e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -28,41 +28,46 @@
     androidprv:layout_maxWidth="@dimen/keyguard_security_width"
     androidprv:layout_maxHeight="@dimen/keyguard_security_height"
     android:gravity="center_horizontal|top">
-    <RelativeLayout
-        android:id="@+id/keyguard_clock_container"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal|top">
-        <TextClock
-            android:id="@+id/clock_view"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_centerHorizontal="true"
-            android:layout_alignParentTop="true"
-            android:textColor="@color/clock_white"
-            android:singleLine="true"
-            style="@style/widget_big_thin"
-            android:format12Hour="@string/keyguard_widget_12_hours_format"
-            android:format24Hour="@string/keyguard_widget_24_hours_format"
-            android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
-        <com.android.systemui.ChargingView
-            android:id="@+id/battery_doze"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignTop="@id/clock_view"
-            android:layout_alignBottom="@id/clock_view"
-            android:layout_toEndOf="@id/clock_view"
-            android:visibility="invisible"
-            android:src="@drawable/ic_aod_charging_24dp"
-            android:contentDescription="@string/accessibility_ambient_display_charging"
-        />
-
-        <include layout="@layout/keyguard_status_area"
-            android:id="@+id/keyguard_status_area"
+        android:orientation="vertical">
+        <RelativeLayout
+            android:id="@+id/keyguard_clock_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/clock_view" />
+            android:layout_gravity="center_horizontal|top">
+            <TextClock
+                android:id="@+id/clock_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_centerHorizontal="true"
+                android:layout_alignParentTop="true"
+                android:textColor="?attr/wallpaperTextColor"
+                android:singleLine="true"
+                style="@style/widget_big_thin"
+                android:format12Hour="@string/keyguard_widget_12_hours_format"
+                android:format24Hour="@string/keyguard_widget_24_hours_format"
+                android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+            <com.android.systemui.ChargingView
+                android:id="@+id/battery_doze"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignTop="@id/clock_view"
+                android:layout_alignBottom="@id/clock_view"
+                android:layout_toEndOf="@id/clock_view"
+                android:visibility="invisible"
+                android:src="@drawable/ic_aod_charging_24dp"
+                android:contentDescription="@string/accessibility_ambient_display_charging"
+            />
+
+            <include layout="@layout/keyguard_status_area"
+                android:id="@+id/keyguard_status_area"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/clock_view" />
+        </RelativeLayout>
 
         <TextView
             android:id="@+id/owner_info"
@@ -71,13 +76,13 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/date_owner_info_margin"
+            android:layout_gravity="center_horizontal"
             android:layout_centerHorizontal="true"
-            android:layout_below="@id/keyguard_status_area"
-            android:textColor="@color/clock_gray"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textSize="@dimen/widget_label_font_size"
             android:letterSpacing="0.05"
             android:ellipsize="marquee"
             android:singleLine="true" />
 
-    </RelativeLayout>
+    </LinearLayout>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index ac4dfc8..5af5f9b 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-PUK-area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Volgende wekker gestel vir <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Vee uit"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiveer e-SIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Het jy die patroon vergeet?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Verkeerde patroon"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Verkeerde PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probeer weer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teken jou patroon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Voer SIM se PIN in"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Voer SIM se PIN vir \"<xliff:g id="CARRIER">%1$s</xliff:g>\" in"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Voer SIM se PIN in."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Voer SIM se PIN vir \"<xliff:g id="CARRIER">%1$s</xliff:g>\" in."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiveer e-SIM om toestel sonder mobiele diens te gebruik."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Voer PIN in"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Voer wagwoord in"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Kontak diensverskaffer vir besonderhede."</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index aa33845..7a937de 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"የሲም ፒዩኬ አካባቢ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ቀጣዩ ማንቂያ ለ<xliff:g id="ALARM">%1$s</xliff:g> ተዘጋጅቷል"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ሰርዝ"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMን አሰናክል"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"አስገባ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ስርዓተ ጥለቱን እርሳ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"የተሳሳተ ስርዓተ ጥለት"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"የተሳሳተ ፒን"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"በ<xliff:g id="NUMBER">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ስርዓተ ጥለትዎን ይሳሉ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"የሲም ፒን ያስገቡ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"የ«<xliff:g id="CARRIER">%1$s</xliff:g>» ሲም ፒን ያስገቡ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"የሲም ፒን ያስገቡ።"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"የ«<xliff:g id="CARRIER">%1$s</xliff:g>» ሲም ፒን ያስገቡ።"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"መሣሪያን ያለተንቀሳቃሽ ስልክ አገልግሎት ለመጠቀም eSIMን ያሰናክሉ።"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ፒን ያስገቡ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"የይለፍ ቃል ያስገቡ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ሲም አሁን ተሰናክሏል። ለመቀጠል የፒዩኬ ኮድ ያስገቡ። ለዝርዝር አገልግሎት አቅራቢን ያግኙ።"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 129b4cc..7aab70f 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏منطقة PUK لشريحة SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"تم ضبط التنبيه التالي على <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏تعطيل شريحة eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"نسيت النقش"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"نقش خاطئ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"رقم تعريف شخصي خاطئ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ارسم نقشك"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏أدخل رمز رقم التعريف الشخصي لشريحة SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏أدخل رقم التعريف الشخصي لشريحة SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏يجب تعطيل شريحة eSIM لاستخدام الجهاز دون خدمة جوال."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"أدخل رقم التعريف الشخصي"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"أدخل كلمة المرور"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏شريحة SIM معطّلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوّال للاطلاع على التفاصيل."</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index 08ad2b7..73887ed 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK sahəsi"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Növbəti zəng vaxtı: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Silin"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSİM\'i deaktiv edin"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Daxil edin"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Modeli unutmuşam"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Yanlış Model"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Yanlış PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Modeli çəkin"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN kodu daxil edin"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" üçün SIM PIN daxil edin"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN\'ni daxil edin."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" üçün SIM PIN\'ni daxil edin."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Mobil xidmət olmadan cihazı istifadə etmək üçün eSIM\'i deaktiv edin."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN daxil edin"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Parol daxil edin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM indi deaktivdir. Davam etmək üçün PUK kod daxil edin. Ətraflı məlumat üçün operatorla əlaqə saxlayın."</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index c7cfe88..7952b7a 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblast za PUK za SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sledeći alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravio/la sam šablon"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan šablon"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte šablon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN za SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
@@ -116,7 +118,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Treba da unesete šablon kada prelazite sa jednog profila na drugi"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Treba da unesete PIN kada prelazite sa jednog profila na drugi"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Treba da unesete lozinku kada prelazite sa jednog profila na drugi"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Administrator uređaja je zaključao uređaj"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Administrator je zaključao uređaj"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Uređaj je ručno zaključan"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Niste otključali uređaj <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite šablon.</item>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index e1dfc04..3b9a9bb 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Поле для PUK-кода SIM-карты"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Наступны будзільнік пастаўлены на <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Выдаліць"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Адключыць eSIM-карту"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Увесці"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забыў(-ла) узор"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Няправільны ўзор"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Няправільны PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Паўтарыце спробу праз <xliff:g id="NUMBER">%d</xliff:g> с."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Намалюйце ўзор"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Увядзіце PIN-код SIM-карты"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Увядзіце PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Увядзіце PIN-код SIM-карты."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Увядзіце PIN-код SIM-карты для \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Адключыце eSIM-карту, каб выкарыстоўваць прыладу без сэрвісу мабільнай перадачы даных."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Увядзіце PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Увядзіце пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта зараз адключана. Увядзіце PUK-код, каб працягнуць. Звяжыцеся са сваім аператарам, каб атрымаць дадатковую інфармацыю."</string>
@@ -108,7 +110,7 @@
     <string name="kg_pin_accepted" msgid="7637293533973802143">"Код прыняты!"</string>
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"Не абслугоўваецца."</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Пераключэнне рэжыму ўводу"</string>
-    <string name="airplane_mode" msgid="3807209033737676010">"Рэжым самалёта"</string>
+    <string name="airplane_mode" msgid="3807209033737676010">"Рэжым палёту"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Пасля перазапуску прылады патрабуецца ўзор"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Пасля перазапуску прылады патрабуецца PIN-код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Пасля перазапуску прылады патрабуецца пароль"</string>
@@ -118,7 +120,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Пры пераключэнні профіляў патрабуецца ўзор"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Пры пераключэнні профіляў патрабуецца PIN-код"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Пры пераключэнні профіляў патрабуецца пароль"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Адміністратар прылады заблакіраваў яе"</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Прылада заблакіравана адміністратарам"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Прылада была заблакіравана ўручную"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Прылада не была разблакіравана на працягу <xliff:g id="NUMBER_1">%d</xliff:g> гадзіны. Увядзіце ўзор.</item>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 73373d5..6dd7ab9 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Област за PUK кода на SIM картата"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Следващият будилник е зададен за <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Изтриване"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Деактивиране на ел. SIM карта"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"„Enter“"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забравена фигура"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Грешна фигура"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Грешен ПИН код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Опитайте отново след <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Начертайте фигурата си"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Въведете ПИН кода за SIM картата"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Въведете ПИН кода на SIM картата за „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Въведете ПИН кода за SIM картата."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Въведете ПИН кода на SIM картата за „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Деактивирайте електронната SIM карта, за да използвате устройството без мобилна услуга."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Въведете ПИН кода"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Въведете паролата"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Свържете се с оператора за подробности."</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 26ba5e9..25e7443 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"সিম PUK অঞ্চল"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"পরবর্তী অ্যালার্ম <xliff:g id="ALARM">%1$s</xliff:g> এ সেট করা হয়েছে"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"মুছুন"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"ই-সিমটি অক্ষম করুন"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"এন্টার"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"প্যাটার্ন ভুলে গেছি"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ভুল প্যাটার্ন"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ভুল পিন"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"আপনার প্যাটার্ন আঁকুন"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"সিমের পিন লিখুন"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিমের পিন লিখুন"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"সিমের পিন লিখুন।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিমের পিন লিখুন।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"মোবাইল পরিষেবা ছাড়াই ডিভাইস ব্যবহার করতে ই-সিম অক্ষম করুন।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"পিন লিখুন"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"পাসওয়ার্ড লিখুন"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"সিমটি এখন অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোডটি লিখুন। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 04256f1..0ec4ad5 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -30,7 +30,7 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Upišite PIN kôd za otključavanje"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Pogrešan PIN kôd."</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
-    <string name="keyguard_plugged_in" msgid="89308975354638682">"Puni se"</string>
+    <string name="keyguard_plugged_in" msgid="89308975354638682">"Punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Brzo punjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"Sporo punjenje"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"Priključite punjač."</string>
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Prostor za PUK kôd za SIM karticu"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naredni alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM karticu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -58,12 +59,13 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN kôd"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte uzorak"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN kôd za SIM karticu"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN kôd za SIM karticu operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN kôd SIM kartice."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN kôd SIM kartice operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM karticu za korištenje uređaja bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN kôd"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da nastavite. Obratite se operateru za detalje."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"Operater SIM kartice \"<xliff:g id="CARRIER">%1$s</xliff:g>\" sada je onemogućen. Unesite PUK kôd da nastavite. Za više detalja obratite se operateru."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da nastavite. Za više informacija obratite se operateru."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"Operater SIM kartice \"<xliff:g id="CARRIER">%1$s</xliff:g>\" sada je onemogućen. Unesite PUK kôd da nastavite. Za više informacija obratite se operateru."</string>
     <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"Unesite željeni PIN kôd"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"Potvrdite željeni PIN kôd"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"Otključavanje SIM kartice…"</string>
@@ -116,7 +118,7 @@
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Potreban je uzorak nakon prelaska na drugi profil"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Potreban je PIN kôd nakon prelaska na drugi profil"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Potrebna je lozinka nakon prelaska na drugi profil"</string>
-    <string name="kg_prompt_reason_device_admin" msgid="2438626748767361010">"Administrator je zaključao uređaj."</string>
+    <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Uređaj je zaključao administrator"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Uređaj je ručno zaključan"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
       <item quantity="one">Uređaj nije otključavan <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite uzorak.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 723d502..e5c8d71 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona del PUK de la SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"S\'ha definit la pròxima alarma per a l\'hora següent: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Suprimeix"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactiva l\'eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retorn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"He oblidat el patró"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"El patró no és correcte"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"El PIN no és correcte"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuixa el patró"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introdueix el PIN de la SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introdueix el PIN de la SIM següent: <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introdueix el PIN de la SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introdueix el PIN de la SIM de: <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desactiva l\'eSIM per utilitzar el dispositiu sense servei mòbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introdueix el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introdueix la contrasenya"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La SIM està desactivada. Introdueix el codi PUK per continuar. Contacta amb l\'operador de telefonia mòbil per obtenir més informació."</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 52b12bf..0a23d90 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblast kódu PUK SIM karty"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Další budík je nastaven na <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Smazat"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktivovat eSIM kartu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zapomenuté gesto"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nesprávné gesto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nesprávný kód PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Zkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Zadejte gesto"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Zadejte kód PIN SIM karty"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Zadejte kód PIN SIM karty <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Zadejte kód PIN SIM karty."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Zadejte kód PIN SIM karty <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"eSIM kartu deaktivujte, chcete-li telefon používat bez mobilních služeb."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Zadejte kód PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Zadejte heslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta byla zablokována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 486b46c..e55d996 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Område for PUK-koden til SIM-kortet"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næste alarm er indstillet til <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slet"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Forkert mønster"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Forkert pinkode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn dit mønster"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Indtast pinkoden til SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Indtast pinkoden til SIM-kortet for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Angiv pinkoden til SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Angiv pinkoden til SIM-kortet fra \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiver eSIM for at bruge enheden uden mobiltjeneste."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Indtast pinkode"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Angiv adgangskode"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobilselskabet for at få flere oplysninger."</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 190f203..41bc9a9 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-PUK-Bereich"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nächster Wecker gestellt für <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Löschen"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM deaktivieren"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Eingabe"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Falsches Muster"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Falsche PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Versuche es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden noch einmal."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Muster zeichnen"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-PIN eingeben"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" eingeben"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Gib die SIM-PIN ein"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Gib die SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ein."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiviere eSIM, um das Gerät ohne Mobilfunkdienst zu verwenden."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN eingeben"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Passwort eingeben"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 9707c90..d195c87 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Περιοχή κωδικού PUK κάρτας SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Το επόμενο ξυπνητήρι ορίστηκε στις <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Διαγραφή"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Απενεργοποίηση eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ξεχάσατε το μοτίβο"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Λάθος μοτίβο"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Λανθασμένος αριθμός PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Δοκιμάστε ξανά σε <xliff:g id="NUMBER">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Σχεδιάστε το μοτίβο σας"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Εισαγωγή αριθμού PIN της κάρτας SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Εισάγετε τον αριθμό PIN της SIM της εταιρείας κινητής τηλεφωνίας \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Εισαγωγή αριθμού PIN κάρτας SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Εισαγάγετε τον αριθμό PIN της κάρτας SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Απενεργοποιήστε την eSIM, για να χρησιμοποιήσετε τη συσκευή χωρίς υπηρεσία για κινητά."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Εισαγάγετε τον αριθμό PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Εισαγάγετε κωδικό πρόσβασης"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Η κάρτα SIM είναι απενεργοποιημένη αυτή τη στιγμή. Εισαγάγετε τον κωδικό PUK για να συνεχίσετε. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας για λεπτομέρειες."</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 6b02d6d..35bae2e 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 6b02d6d..35bae2e 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 6b02d6d..35bae2e 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK area"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Next alarm set for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disable eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Forgotten Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Wrong Pattern"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Wrong PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Draw your pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Enter SIM PIN"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Enter SIM PIN for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Enter SIM PIN."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Enter SIM PIN for \'<xliff:g id="CARRIER">%1$s</xliff:g>\'."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disable eSIM to use device without mobile service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Enter PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Enter Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 761e3a1..219c813 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área de PUK de la tarjeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma establecida: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Borrar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inhabilitar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"¿Olvidaste el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Patrón incorrecto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuja tu patrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ingresa el PIN de la tarjeta SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ingresa el PIN de la tarjeta SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ingresa el PIN de la tarjeta SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ingresa el PIN de la tarjeta SIM de \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inhabilita la eSIM para usar el dispositivo sin servicio de datos móviles."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ingresa el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Escribe la contraseña"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La tarjeta SIM está inhabilitada. Para continuar, ingresa el código PUK. Si quieres obtener más información, comunícate con el proveedor."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 9811023..14df1e5 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área de PUK de la tarjeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inhabilita la tarjeta eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"¿Has olvidado el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Patrón incorrecto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuja tu patrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduce el PIN de la tarjeta SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduce el PIN de la tarjeta SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduce el PIN de la tarjeta SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduce el PIN de la tarjeta SIM de <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inhabilita la tarjeta eSIM para utilizar el dispositivo sin servicio móvil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduce el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduce tu contraseña"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La tarjeta SIM está inhabilitada. Para continuar, introduce el código PUK. Si quieres obtener más información, ponte en contacto con el operador."</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 1892ef6..a6d8e20 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-kaardi PUK-koodi ala"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Järgmine alarm on määratud ajaks <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Kustuta"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Keela eSIM-kaart"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sisesta"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Unustasin mustri"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Vale muster"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Vale PIN-kood"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Proovige <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast uuesti."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Joonistage oma muster"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Sisestage SIM-kaardi PIN-kood"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Sisestage operaatori „<xliff:g id="CARRIER">%1$s</xliff:g>” puhul SIM-kaardi PIN-kood"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sisestage SIM-kaardi PIN-kood."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sisestage operaatori „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kaardi PIN-kood."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Keelake eSIM-kaart, et seadet ilma mobiilsideteenuseta kasutada."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sisestage PIN-kood"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sisestage parool"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Lisateabe saamiseks võtke ühendust operaatoriga."</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 38ff52e..4b66213c 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM txartelaren PUK kodearen eremua"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Hurrengo alarmak ordu honetan joko du: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ezabatu"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desgaitu eSIM txartela"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sartu"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Eredua ahaztu zaizu"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Eredu hori ez da zuzena"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN kode hori ez da zuzena"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Saiatu berriro <xliff:g id="NUMBER">%d</xliff:g> segundo barru."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Marraztu eredua"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Idatzi SIM txartelaren PIN kodea"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PIN kodea"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Idatzi SIM txartelaren PIN kodea."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PIN kodea."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desgaitu eSIM txartela gailua zerbitzu mugikorrik gabe erabiltzeko."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Idatzi PIN kodea"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Idatzi pasahitza"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. Xehetasunak lortzeko, jarri operadorearekin harremanetan."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 3dc59ca..2fe7bfb 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏قسمت PUK سیم‌کارت"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"زنگ ساعت بعدی برای <xliff:g id="ALARM">%1$s</xliff:g> تنظیم شد"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"حذف"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏غیرفعال کردن eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"الگو را فراموش کرده‌اید"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"الگوی اشتباه"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"پین اشتباه"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"پس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"الگوی خود را رسم کنید"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"پین سیم‌کارت را وارد کنید"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"پین سیم‌کارت را وارد کنید."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏برای استفاده از دستگاه بدون سرویس همراه، eSIM را غیرفعال کنید."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"کد پین را وارد کنید"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"گذرواژه را وارد کنید"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"اکنون سیم‌کارت غیرفعال است. کد پین را برای ادامه وارد کنید. برای جزئیات با شرکت مخابراتی خود تماس بگیرید."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 91d8d82..23139e3 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-kortin PUK-koodin alue"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Seuraava hälytys asetettu: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Poista"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Poista eSIM käytöstä"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Unohtunut kuvio"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Väärä kuvio"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Väärä PIN-koodi"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Yritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Piirrä kuvio"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Anna SIM-kortin PIN-koodi"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Anna operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Anna SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Anna operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortin PIN-koodi."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Poista eSIM käytöstä, jos haluat käyttää laitetta ilman mobiilipalvelua."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Anna PIN-koodi."</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Anna salasana"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 5f2462c..1c15724 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zone du code PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Heure de la prochaine alarme : <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Supprimer"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Désactiver la carte eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Entrée"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Schéma incorrect"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"NIP incorrect"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Veuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dessinez votre schéma"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Entrez le NIP de la carte SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Entrez le NIP de la carte SIM pour « <xliff:g id="CARRIER">%1$s</xliff:g> »"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Entrez le NIP de la carte SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Entrez le NIP de la carte SIM pour « <xliff:g id="CARRIER">%1$s</xliff:g> »."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Désactivez la carte eSIM pour utiliser l\'appareil sans service cellulaire."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Entrez le NIP"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Entrez votre mot de passe."</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Pour obtenir plus de détails, communiquez avec votre fournisseur de services."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index ed38ae0..00ee573 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Champ de la clé PUK de la carte SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Date et heure de la prochaine alarme : <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Supprimer"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Désactiver la carte eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Entrée"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Schéma incorrect"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Code incorrect"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dessinez votre schéma"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Saisissez le code PIN de la carte SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Saisissez le code PIN de la carte SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Saisissez le code PIN de la carte SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Saisissez le code PIN de la carte SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Désactivez la carte eSIM pour utiliser l\'appareil sans service mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Saisissez le code"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Saisissez le mot de passe"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La carte SIM est maintenant désactivée. Pour continuer, saisissez la clé PUK. Contactez votre opérateur pour en savoir plus."</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index a615f7f..348af67 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK da tarxeta SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma definida para: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactivar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueciches o padrón"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrón incorrecto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorrecto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Téntao de novo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Debuxa o teu padrón"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduce o PIN da SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduce o PIN da SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduce o PIN da SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduce o PIN da SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desactiva a eSIM para usar o dispositivo sen servizo móbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduce o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Insire o teu contrasinal"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Agora a tarxeta SIM está desactivada. Introduce o código PUK para continuar. Ponte en contacto co operador para obter máis información."</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index d036ef4..c795024 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK ક્ષેત્ર"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g> માટે આગલું એલાર્મ સેટ કર્યું"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"કાઢી નાખો"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMને અક્ષમ કરો"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"દાખલ કરો"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"પેટર્ન ભૂલી ગયાં"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ખોટી પેટર્ન"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ખોટો PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"તમારી પેટર્ન દોરો"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN દાખલ કરો"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" માટે SIM PIN દાખલ કરો"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN દાખલ કરો"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" માટે SIM PIN દાખલ કરો."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"મોબાઇલ સેવા વગર ઉપકરણનો ઉપયોગ કરવા eSIMને અક્ષમ કરો."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN દાખલ કરો"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"પાસવર્ડ દાખલ કરો"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM હમણાં અક્ષમ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કૅરિઅરનો સંપર્ક કરો."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 023e433..c17218b 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK क्षेत्र"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"अगला अलार्म <xliff:g id="ALARM">%1$s</xliff:g> बजे के लिए सेट किया गया है"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"हटाएं"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM अक्षम करें"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"पैटर्न भूल गए हैं"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत पैटर्न"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"गलत पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"अपना पैटर्न बनाएं"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM पिन डालें"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" का SIM पिन डालें"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन डालें."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" के लिए सिम पिन डालें"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवा के बिना डिवाइस का उपयोग करने के लिए eSIM अक्षम करें."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"पिन डालें"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड डालें"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM अब अक्षम हो गया है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 0cc452a..0fb5ba0 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Područje PUK-a za SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sljedeći alarm postavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Unos"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Pogrešan PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iscrtajte svoj uzorak"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Unesite PIN za SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Unesite PIN za SIM mobilnog operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM mobilnog operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM kako biste uređaj upotrebljavali bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite zaporku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM je sad onemogućen. Unesite PUK kôd da biste nastavili. Obratite se mobilnom operateru za više pojedinosti."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 32f2f47..3a2013d 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"A SIM-kártyához tartozó PUK-kód mezője"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"A következő ébresztés beállított ideje: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Törlés"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Az e-SIM-kártya letiltása"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Elfelejtettem a mintát"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Helytelen minta"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Helytelen PIN-kód"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Próbálja újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rajzolja le a mintát"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Adja meg a SIM-kártya PIN-kódját"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Adja meg a(z) „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kártya PIN-kódját"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Adja meg a SIM-kártya PIN-kódját."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Adja meg a(z) „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kártya PIN-kódját."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Tiltsa le az e-SIM-kártyát az eszköz mobilszolgáltatás nélküli használatához."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Adja meg a PIN-kódot"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Írja be a jelszót"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. A részletekért vegye fel a kapcsolatot szolgáltatójával."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 9433ae3..3fdffbb 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM քարտի PUK կոդի տարածք"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Հաջորդ զարթուցիչը դրված է <xliff:g id="ALARM">%1$s</xliff:g>-ի վրա"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ջնջել"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Անջատել էլեկտրոնային SIM քարտը"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Մուտքի ստեղն"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Մոռացել եմ նախշը"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Նախշը սխալ է"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN կոդը սխալ է"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Փորձեք կրկին <xliff:g id="NUMBER">%d</xliff:g> վայրկյանից:"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Մուտքագրեք նախշը"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Մուտքագրեք SIM քարտի PIN կոդը"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Մուտքագրեք SIM քարտի PIN կոդը «<xliff:g id="CARRIER">%1$s</xliff:g>»-ի համար"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Մուտքագրեք SIM քարտի PIN կոդը։"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Մուտքագրեք SIM քարտի PIN կոդը «<xliff:g id="CARRIER">%1$s</xliff:g>»-ի համար:"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Անջատել էլեկտրոնային SIM քարտը՝ սարքն առանց բջջային ծառայությունների օգտագործելու համար:"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Մուտքագրեք PIN-ը"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Մուտքագրեք գաղտնաբառը"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM քարտն այժմ անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մանրամասն տեղեկություններ ստանալու համար դիմեք օպերատորին:"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index fba6df2..0c615a4 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Bidang PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarm berikutnya disetel untuk <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Hapus"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Nonaktifkan eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Masukkan"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Lupa Pola?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pola Salah"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN Salah"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Gambar pola Anda"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Masukkan PIN SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Nonaktifkan eSIM untuk menggunakan perangkat tanpa layanan seluler."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Sandi"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM telah dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Hubungi operator untuk keterangan selengkapnya."</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index 90e378c..3340093 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-svæði SIM-korts"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næsti vekjari stilltur á <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eyða"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Aftengja eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Færa inn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Man ekki mynstrið"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Rangt mynstur"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Rangt PIN-númer"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Reyndu aftur eftir <xliff:g id="NUMBER">%d</xliff:g> sekúndur."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teiknaðu mynstrið þitt"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Sláðu inn PIN-númer SIM-kortsins"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Sláðu inn PIN-númer SIM-korts fyrir „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sláðu inn PIN-númer SIM-kortsins."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sláðu inn PIN-númer SIM-korts fyrir „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Aftengdu eSIM til að nota tækið án farsímakerfisþjónustu."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sláðu inn PIN-númer"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sláðu inn aðgangsorð"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortið hefur verið gert óvirkt. Sláðu inn PUK-númerið til að halda áfram. Hafðu samband við símafyrirtækið til að fá frekari upplýsingar."</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 47181ca..70fae42 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Area PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Prossima sveglia impostata a: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Elimina"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Disattiva eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Invio"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Sequenza dimenticata"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Sequenza sbagliata"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN errato"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Inserisci la sequenza"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Inserisci il PIN della SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Inserisci il PIN della scheda SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Inserisci il PIN della SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Inserisci il PIN della SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Disattiva l\'eSIM per usare il dispositivo senza servizio dati mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Inserisci PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Inserisci la password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La scheda SIM è disattivata. Inserisci il codice PUK per continuare. Contatta l\'operatore per avere informazioni dettagliate."</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 2efa1a8..6b06966 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏אזור לקוד הגישה של כרטיס ה-SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ההתראה הבאה נקבעה ל-<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏השבתת ה-eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"שכחתי את קו ביטול הנעילה"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"קו ביטול הנעילה שגוי"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"קוד הגישה שגוי"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"נסה שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"שרטט את קו ביטול הנעילה"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏הזן את קוד הגישה של כרטיס ה-SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏הזן את קוד הגישה של כרטיס ה-SIM של \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏הזן את קוד הגישה של כרטיס ה-SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏הזן את קוד הגישה של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏השבת את ה-eSIM כדי להשתמש במכשיר ללא שירות סלולרי."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"הזן קוד גישה"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"הזן את הסיסמה"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 9a96f7e..c108d1e 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK エリア"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"次のアラームを <xliff:g id="ALARM">%1$s</xliff:g> に設定しました"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"削除"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM を無効にする"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"入力"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"パターンを忘れた場合"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"パターンが正しくありません"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN が正しくありません"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> 秒後にもう一度お試しください。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"パターンを入力してください"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN を入力してください"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"「<xliff:g id="CARRIER">%1$s</xliff:g>」の SIM PIN を入力してください"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN を入力してください。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"「<xliff:g id="CARRIER">%1$s</xliff:g>」の SIM PIN を入力してください。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"モバイル サービスなしで端末を使用するには eSIM を無効にしてください。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN を入力してください"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"パスワードを入力してください"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM が無効になりました。続行するには PUK コードを入力してください。詳しくは携帯通信会社にお問い合わせください。"</string>
@@ -108,9 +110,9 @@
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"端末の再起動後はパターンの入力が必要となります"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"端末の再起動後は PIN の入力が必要となります"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"端末の再起動後はパスワードの入力が必要となります"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"追加の確認のためパターンが必要です"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"追加の確認のため PIN が必要です"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"追加の確認のためパスワードが必要です"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"セキュリティを強化するにはパターンが必要です"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"セキュリティを強化するには PIN が必要です"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"セキュリティを強化するにはパスワードが必要です"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"プロファイルを切り替えるにはパターンが必要です"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"プロファイルを切り替えるには PIN が必要です"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"プロファイルを切り替えるにはパスワードが必要です"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 74ae02a..38eed79 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM ბარათის PUK-კოდის არე"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"შემდეგი მაღვიძარა დაყენებულია <xliff:g id="ALARM">%1$s</xliff:g>-ზე"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"წაშლა"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-ის გათიშვა"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"შეყვანა"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"დაგავიწყდათ ნიმუში"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ნიმუში არასწორია"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN-კოდი არასწორია"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ცადეთ ხელახლა <xliff:g id="NUMBER">%d</xliff:g> წამში."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"დახატეთ თქვენი ნიმუში"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"შეიყვანეთ SIM ბარათის PIN-კოდი"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"შეიყვანეთ SIM ბარათის PIN-კოდი „<xliff:g id="CARRIER">%1$s</xliff:g>“-სთვის"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"შეიყვანეთ SIM ბარათის PIN-კოდი."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"შეიყვანეთ SIM ბარათის PIN-კოდი „<xliff:g id="CARRIER">%1$s</xliff:g>“-ისთვის."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"გათიშეთ eSIM, მოწყობილობის მობილური სერვისების გარეშე გამოსაყენებლად."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"შეიყვანეთ PIN-კოდი"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"შეიყვანეთ პაროლი"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს."</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 8a088f3..137926e 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK аумағы"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Келесі дабыл уақыты: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Жою"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM картасын өшіру"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Енгізу"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Өрнекті ұмытып қалдыңыз ба?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Өрнек қате"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN коды қате"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Өрнекті енгізіңіз"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN кодын енгізіңіз"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN кодын енгізіңіз."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Құрылғыны мобильдік қызметсіз пайдалану үшін eSIM картасын өшіріңіз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN кодын енгізіңіз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Кілтсөзді енгізіңіз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. Толығырақ ақпаратты оператордан алыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index b4be59e..21d1d2b 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ប្រអប់​បំពេញ​កូដ PUK របស់​ស៊ីម"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"បាន​កំណត់ម៉ោង​រោទិ៍​បន្ទាប់​នៅថ្ងៃ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"លុប"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"បិទ eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ភ្លេច​​លំនាំ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"លំនាំ​មិន​ត្រឹមត្រូវ​ទេ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"កូដ PIN មិន​ត្រឹមត្រូវ​ទេ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER">%d</xliff:g> វិនាទី​ទៀត។"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"គូរ​លំនាំ​របស់​អ្នក"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"បញ្ចូល​កូដ PIN របស់​ស៊ីម"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"បញ្ចូល​កូដ PIN របស់​ស៊ីម​សម្រាប់ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"បញ្ចូល​កូដ PIN របស់​ស៊ីម។"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"បញ្ចូល​កូដ PIN របស់​ស៊ីម​សម្រាប់ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"។"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"បិទ eSIM ដើម្បីប្រើប្រាស់ឧបករណ៍​ដោយ​មិនចាំបាច់ប្រើសេវាកម្មទិន្នន័យចល័ត។"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"បញ្ចូល​កូដ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ឥឡូវ​នេះ​ ស៊ីម​ត្រូវ​បាន​បិទ​ដំណើរការ​ហើយ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ សូម​ទាក់ទង​ទៅក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់​អ្នក ដើម្បី​ទទួល​បាន​ព័ត៌មាន​លម្អិត។"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index b2dd79e..c16dcb9 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ಸಿಮ್ PUK ಪ್ರದೇಶ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g> ಗಂಟೆಗೆ ಮುಂದಿನ ಅಲಾರಮ್ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ಅಳಿಸಿ"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ನಮೂದಿಸಿ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ಪ್ಯಾಟರ್ನ್ ಮರೆತಿದ್ದೀರಿ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ಪ್ಯಾಟರ್ನ್ ತಪ್ಪಾಗಿದೆ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ಪಿನ್‌ ತಪ್ಪಾಗಿದೆ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ನಿಮ್ಮ ಪ್ಯಾಟರ್ನ್ ಚಿತ್ರಿಸಿ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗೆ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗಾಗಿ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ಮೊಬೈಲ್ ಸೇವೆ ಇಲ್ಲದೆಯೇ ಸಾಧನವನ್ನು ಬಳಸಲು eSIM ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ಈಗ ಸಿಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 70588d3..a402a97 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK 영역"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g>에 다음 알람이 설정됨"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"삭제"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM 사용 중지"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 키"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"패턴을 잊음"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"잘못된 패턴"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"잘못된 PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"패턴 그리기"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN 입력"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\'<xliff:g id="CARRIER">%1$s</xliff:g>\'의 SIM PIN 입력"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN을 입력하세요."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\'<xliff:g id="CARRIER">%1$s</xliff:g>\'의 SIM PIN을 입력하세요."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"모바일 서비스 없이 기기를 사용하려면 eSIM을 사용 중지하세요."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN 입력"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"비밀번호 입력"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. 자세한 내용은 이동통신사에 문의하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 8cbd4f5..d9e033c 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-картанын PUK-кодунун аймагы"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Кийинки ойготкуч саат <xliff:g id="ALARM">%1$s</xliff:g> коюлган"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Жок кылуу"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-картаны өчүрүү"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Киргизүү"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Графикалык ачкычты унутуп калдым"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Графикалык ачкыч туура эмес"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN-код туура эмес"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секунддан кийин кайталаңыз."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Графикалык ачкычты тартыңыз"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-картанын PIN-кодун киргизиңиз"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" байланыш операторунун SIM-картасынын PIN-кодун киргизиңиз"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-картанын PIN-кодун киргизиңиз."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" SIM-картасынын PIN-кодун киргизиңиз."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Түзмөктү мобилдик кызматсыз колдонуу үчүн eSIM-картаны өчүрүңүз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN-кодду киргизиңиз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Сырсөздү киргизиңиз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. Анын чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index d063827..f253386 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ພື້ນທີ່ PUK ຂອງ SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ໂມງປຸກຕໍ່ໄປຖືກຕັ້ງໄວ້ເວລາ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ລຶບ"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"ປິດການໃຊ້ eSIM ແລ້ວ"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ປ້ອນເຂົ້າ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ລືມຮູບແບບປົດລັອກ?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ຮູບແບບຜິດ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER">%d</xliff:g> ວິນາທີ."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ໃສ່ລະຫັດ PIN ຂອງຊິມ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"ປ້ອນ SIM PIN ສຳລັບ \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ເຂົ້າໄປ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ໃສ່ລະຫັດ PIN ຂອງຊິມ."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ໃສ່ລະຫັດ PIN ຂອງຊິມສຳລັບ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ປິດການໃຊ້ eSIM ເພື່ອໃຊ້ອຸປະກອນໂດຍບໍ່ມີບໍລິການມືຖື."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ໃສ່ລະຫັດ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ໃສ່ລະຫັດຜ່ານ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 2dd3ed7..11de6e2 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM kortelės PUK kodo sritis"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Kitas nustatytas signalas: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ištrinti"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Išjungti eSIM kortelę"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pamiršau atrakinimo piešinį"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Netinkamas atrakinimo piešinys"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Netinkamas PIN kodas"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Bandykite dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nupieškite atrakinimo piešinį"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Įveskite SIM kortelės PIN kodą"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Įveskite „<xliff:g id="CARRIER">%1$s</xliff:g>“ SIM kortelės PIN kodą"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Įveskite SIM kortelės PIN kodą."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Įveskite „<xliff:g id="CARRIER">%1$s</xliff:g>“ SIM kortelės PIN kodą"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Išjungti eSIM kortelę ir naudoti įrenginį be mobiliojo ryšio paslaugos."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Įveskite PIN kodą"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Įveskite slaptažodį"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Dabar SIM neleidžiama. Jei norite tęsti, įveskite PUK kodą. Jei reikia išsamios informacijos, susisiekite su operatoriumi."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 26ed490..51df25f9 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM kartes PUK apgabals"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nākamā signāla atskaņošanas laiks: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Dzēšanas taustiņš"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Atspējot eSIM karti"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Ievadīšanas taustiņš"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Aizmirsu kombināciju"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nepareiza kombinācija."</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nepareizs PIN kods."</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundes(-ēm)."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Zīmējiet savu kombināciju."</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ievadiet SIM kartes PIN kodu"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ievadiet SIM kartes “<xliff:g id="CARRIER">%1$s</xliff:g>” PIN kodu"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ievadiet SIM kartes PIN kodu."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ievadiet SIM kartes “<xliff:g id="CARRIER">%1$s</xliff:g>” PIN kodu."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Atspējojiet eSIM karti, lai ierīci varētu izmantot bez mobilā pakalpojuma."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ievadiet PIN."</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ievadiet paroli"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karte ir atspējota. Lai turpinātu, ievadiet PUK kodu. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index e757c51..eb1eaa5 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Поле за PUK на SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Следниот аларм е поставен во <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Избриши"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Оневозможи ја eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Внеси"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ја заборавивте шемата?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Погрешна шема"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Погрешен PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Обидете се повторно за <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Нацртајте ја шемата"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Внесете PIN на SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Внесете PIN на SIM за „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Внесете PIN на SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Внесете PIN на SIM за „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Оневозможете ја eSIM за да го користите уредот без мобилна услуга."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Внесете PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Внесете лозинка"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Контактирајте со операторот за детали."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 5abf129..043e7c2 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"സിം PUK ഏരിയ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"അടുത്ത അലാറം <xliff:g id="ALARM">%1$s</xliff:g>-ന് സജ്ജീകരിച്ചു"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ഇല്ലാതാക്കുക"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"എന്റർ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"പാറ്റേൺ മറന്നു"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"പാറ്റേൺ തെറ്റാണ്"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"പിൻ തെറ്റാണ്"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> സെക്കന്റിനു‌ശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"നിങ്ങളുടെ പാറ്റേൺ വരയ്‌ക്കുക"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"സിം പിൻ നൽകുക"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" എന്നതിനുള്ള സിം പിൻ നൽകുക"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"സിം പിൻ നൽകുക."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" എന്ന കാരിയർക്കുള്ള സിം പിൻ നൽകുക."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"മൊ‌ബൈൽ സേവനമില്ലാതെ ഉപകരണം ഉപയോഗിക്കാൻ eSIM പ്രവർത്തനരഹിതമാക്കുക."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"പിൻ നൽകുക"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"പാസ്‌വേഡ് നൽകുക"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. വിശദാംശങ്ങൾക്ക് കാരിയറെ ബന്ധപ്പെടുക."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index eb045bb..360b09e 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-н PUK кодын хэсэг"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Дараагийн сэрүүлгийг <xliff:g id="ALARM">%1$s</xliff:g>-д тавьсан"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Устгах"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-г идэвхгүй болгох"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Оруулах"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Загварыг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Загвар буруу байна"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ПИН код буруу байна"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Загварыг оруулна уу"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM-н ПИН-г оруулна уу"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"-н SIM-н ПИН-г оруулна уу"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-н ПИН-г оруулна уу."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"-н SIM-н ПИН-г оруулна уу."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Төхөөрөмжийг мобайл үйлчилгээгүй ашиглахын тулд eSIM-г идэвхгүй болгоно уу."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ПИН оруулна уу"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Нууц үг оруулна уу"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM идэвхгүй байна. Үргэлжлүүлэх бол PUK кодыг оруулна уу. Дэлгэрэнгүй мэдээлэл авах бол оператор компанитайгаа холбогдоно уу."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 946a2dd..7bb8ae5 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"सिम PUK क्षेत्र"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"पुढील अलार्म <xliff:g id="ALARM">%1$s</xliff:g> साठी सेट केला"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"हटवा"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM बंद करा"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"प्रविष्ट करा"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"नमुना विसरलात"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"चुकीचा नमुना"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"चुकीचा पिन"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"आपला नमुना काढा"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"सिम पिन प्रविष्ट करा"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" साठी सिम पिन प्रविष्ट करा"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन एंटर करा"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" साठी सिम पिन एंटर करा"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवांशिवाय डिव्हाइस वापरण्यासाठी eSIM बंद करा."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"पिन प्रविष्ट करा"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"संकेतशब्द प्रविष्ट करा"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"सिम आता अक्षम केले आहे. सुरू ठेवण्यासाठी PUK कोड प्रविष्ट करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 197965f..144e507 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Bahagian PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Penggera seterusnya ditetapkan pada <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Padam"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Lumpuhkan eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Kekunci Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Terlupa Corak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Corak salah"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN salah"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Lukis corak anda"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Masukkan PIN SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Masukkan PIN SIM untuk \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM untuk \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Lumpuhkan eSIM untuk menggunakan peranti tanpa perkhidmatan mudah alih."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Kata Laluan"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kini dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk mendapatkan butiran."</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index b052b21..d3e22b4 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ဆင်းမ် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ် နေရာ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"နောက်နှိုးစက်အချိန်ကို <xliff:g id="ALARM">%1$s</xliff:g> တွင် သတ်မှတ်ထားပါသည်"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ဖျက်ရန်"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM ကို ပိတ်ရန်"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter ခလုတ်"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ပုံစံအား မေ့သွားပါသည်"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ပုံစံ မမှန်ကန်ပါ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ပင်နံပါတ် မမှန်ကန်ပါ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ပုံစံကို ဆွဲပါ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ဆင်းမ်ကဒ် ပင်နံပါတ်ကို ထည့်ပါ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" အတွက် ဆင်းမ်ပင်နံပါတ်ကို ထည့်ပါ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ဆင်းမ်ကဒ် ပင်နံပါတ်ကို ထည့်ပါ။"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" အတွက် ဆင်းမ်ကဒ်ပင်နံပါတ်ကို ထည့်ပါ။"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"စက်ပစ္စည်းကို မိုဘိုင်းဝန်ဆောင်မှုမပါဘဲ အသုံးပြုရန် eSIM ကို ပိတ်ပါ။"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ပင်နံပါတ်ကို ထည့်ပါ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"စကားဝှက်ကို ထည့်ပါ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ဆင်းမ်ကဒ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် ပင်နံပါတ် ပြန်ဖွင့်သည့် ကုဒ်ကို ထည့်ပါ။ ပိုမိုလေ့လာရန် မိုဘိုင်းဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်နိုင်ပါသည်။"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 2ba38ec..7e61e6f 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-området for SIM-kortet"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Neste alarm er stilt inn for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slett"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver e-SIM-kortet"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Feil mønster"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Feil PIN-kode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn mønsteret ditt"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Skriv inn PIN-koden for SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Skriv inn PIN-koden for SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiver e-SIM-kortet for å bruke enheten uten mobiltjeneste."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Skriv inn PIN-koden"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Skriv inn passordet"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index fa5f284..4750163 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM को PUK क्षेत्र"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"अर्को अलार्म <xliff:g id="ALARM">%1$s</xliff:g> का लागि सेट गरियो"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"मेट्नुहोस्"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM लाई असक्षम पार्नुहोस्"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ढाँचा बिर्सनुभयो"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत ढाँचा"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"गलत PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"आफ्नो ढाँचा कोर्नुहोस्"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM को PIN प्रविष्टि गर्नुहोस्"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"<xliff:g id="CARRIER">%1$s</xliff:g> को SIM PIN प्रविष्ट गर्नुहोस्"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM को PIN प्रविष्टि गर्नुहोस्।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्ट गर्नुहोस्।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"मोबाइल सेवा बिना यन्त्रको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड प्रविष्ट गर्नुहोस्"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्ट गर्नुहोस्।  विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 4da7398..eb27c2b 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Gebied voor pukcode van simkaart"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Volgende alarm ingesteld voor <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Simkaart uitschakelen"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Patroon vergeten"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Onjuist patroon"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Onjuiste pincode"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teken je patroon"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Geef de pincode van de simkaart op"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Geef de pincode op voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\'"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Geef de pincode van de simkaart op."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Geef de pincode voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' op."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Schakel de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Geef je pincode op"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Geef je wachtwoord op"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Neem contact op met de provider voor informatie."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 82bd400..be98391 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK ਖੇਤਰ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ਅਗਲਾ ਅਲਾਰਮ <xliff:g id="ALARM">%1$s</xliff:g> \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ਮਿਟਾਓ"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ਗਲਤ ਪੈਟਰਨ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"ਗਲਤ PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ਆਪਣਾ ਪੈਟਰਨ ਉਲੀਕੋ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN ਦਾਖਲ ਕਰੋ"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਲਈ SIM PIN ਦਾਖਲ ਕਰੋ"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN ਦਾਖਲ ਕਰੋ।"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਲਈ SIM PIN ਦਾਖਲ ਕਰੋ।"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ਮੋਬਾਈਲ ਸੇਵਾ ਤੋਂ ਬਿਨਾਂ ਡੀਵਾਈਸ ਨੂੰ ਵਰਤਣ ਲਈ eSIM ਅਯੋਗ ਬਣਾਓ।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM ਹੁਣ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index a71cd8b..71a2ce6 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Miejsce na kod PUK karty SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Następny alarm ustawiony na: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Usuwanie"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Wyłącz eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nie pamiętam wzoru"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nieprawidłowy wzór"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nieprawidłowy kod PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narysuj wzór"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Wpisz kod PIN karty SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Wpisz kod PIN karty SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Wyłącz eSIM, by używać urządzenia bez usługi sieci komórkowej."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Wpisz kod PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Wpisz hasło"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Skontaktuj się z operatorem, by uzyskać więcej informacji."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 8206b4f..0d1f9d0 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Excluir"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Inserir"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Digite o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Informe o PIN do SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Informe o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Informe o PIN do cartão SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desative o eSIM para usar o dispositivo sem serviço móvel."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Digite o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Digite a senha"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para mais detalhes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 871d2cf..f3fa491 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK do cartão SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Tecla Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueceu-se do padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe o seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduza o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduza o PIN do cartão SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduza o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduza o PIN do cartão SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desativar eSIM para utilizar sem serviço móvel"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduza o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduza a palavra-passe"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O cartão SIM está agora desativado. Introduza o código PUK para continuar. Contacte o operador para obter mais detalhes."</string>
@@ -91,12 +93,12 @@
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"Código PIN do cartão SIM incorreto. Tem de contactar o seu operador para desbloquear o dispositivo."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
-      <item quantity="one">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de precisar de contactar o seu operador para desbloquear o dispositivo.</item>
+      <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
       <item quantity="other">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas.</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"Cartão SIM inutilizável. Contacte o seu operador."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
-      <item quantity="one">Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável.</item>
+      <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
       <item quantity="other">Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável.</item>
     </plurals>
     <string name="kg_password_pin_failed" msgid="8769990811451236223">"Falha ao introduzir o PIN do cartão SIM!"</string>
@@ -117,15 +119,15 @@
     <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Dispositivo bloqueado pelo administrador"</string>
     <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"O dispositivo foi bloqueado manualmente"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
-      <item quantity="one">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirme o padrão.</item>
+      <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm pattern.</item>
       <item quantity="other">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
-      <item quantity="one">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirme o PIN.</item>
+      <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm PIN.</item>
       <item quantity="other">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o PIN.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
-      <item quantity="one">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirme a palavra-passe.</item>
+      <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm password.</item>
       <item quantity="other">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme a palavra-passe.</item>
     </plurals>
     <string name="fingerprint_not_recognized" msgid="348813995267914625">"Não reconhecido"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 8206b4f..0d1f9d0 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Área do PUK SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Excluir"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desativar eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Inserir"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrão incorreto"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN incorreto"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenhe seu padrão"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Digite o PIN do cartão SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Informe o PIN do SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Informe o PIN do cartão SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Informe o PIN do cartão SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desative o eSIM para usar o dispositivo sem serviço móvel."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Digite o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Digite a senha"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para mais detalhes."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 5e75e5b..3e57bec 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona codului PUK pentru cardul SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Următoarea alarmă este setată pentru <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ștergeți"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Dezactivați cardul eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Introduceți"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ați uitat modelul"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Model greșit"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Cod PIN greșit"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g> secunde."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Desenați modelul"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Introduceți codul PIN al cardului SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduceți codul PIN al cardului SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Dezactivați cardul eSIM pentru a folosi dispozitivul fără serviciu mobil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduceți codul PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introduceți parola"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Cardul SIM este acum dezactivat. Pentru a continua, introduceți codul PUK. Pentru detalii, contactați operatorul."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 1bdaaf4..ef637b4 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-код SIM-карты"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Время следующего сигнала будильника: <xliff:g id="ALARM">%1$s</xliff:g>."</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Удалить"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Отключить eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Клавиша ввода"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забыли графический ключ?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Неверный графический ключ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Неверный PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Повторите попытку через <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Введите графический ключ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Введите PIN-код SIM-карты"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Введите PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Введите PIN-код SIM-карты."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Введите PIN-код SIM-карты \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Чтобы пользоваться устройством без мобильной связи, отключите eSIM."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Введите PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Введите пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта отключена. Чтобы продолжить, введите PUK-код. За подробной информацией обратитесь к оператору связи."</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 2854853..d60b50e 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK කොටස"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g>ට ඊළඟ එලාමය සකසා ඇත"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"මකන්න"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM අබල කරන්න"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ඇතුල් කරන්න"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"රටාව අමතකයි"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"වැරදි රටාවකි"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN එක වැරදියි"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"තත්පර <xliff:g id="NUMBER">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ඔබගේ රටාව අඳින්න"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN ඇතුලු කරන්න"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" සඳහා SIM PIN ඇතුළත් කරන්න"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN ඇතුළු කරන්න"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" සඳහා SIM PIN ඇතුළු කරන්න"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ජංගම සේවාවෙන් තොරව උපාංගය භාවිත කිරීමට eSIM අබල කරන්න."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN එක ඇතුළු කරන්න"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"මුරපදය ඇතුළු කරන්න"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"දැන් SIM එක අබල කර ඇත. ඉදිරියට යාමට PUK කේතය යොදන්න. විස්තර සඳහා වාහකයා අමතන්න."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index f88055d..4b3a7f7 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Oblasť kódu PUK SIM karty"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nasledujúci budík je nastavený na <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Odstrániť"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Zakázať eSIM kartu"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nepamätám si vzor"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nesprávny vzor"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nesprávny kód PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Skúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nakreslite svoj vzor"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Zadajte PIN SIM karty"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Zadajte kód PIN pre SIM kartu operátora <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Zadajte PIN pre SIM kartu"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Zadajte kód PIN pre SIM kartu operátora <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Zakážte eSIM kartu a používajte zariadenie bez mobilnej služby."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Zadajte kód PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Zadajte heslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 882ba22..a523625 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Območje za kodo PUK kartice SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naslednji alarm je nastavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbris"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogoči kartico e-SIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Tipka Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pozabljen vzorec"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Napačen vzorec"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Napačna koda PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Poskusite znova čez <xliff:g id="NUMBER">%d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narišite vzorec"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Vnesite kodo PIN kartice SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Vnesite kodo PIN kartice SIM operaterja »<xliff:g id="CARRIER">%1$s</xliff:g>«"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Vnesite kodo PIN kartice SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Vnesite kodo PIN kartice SIM operaterja »<xliff:g id="CARRIER">%1$s</xliff:g>«."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogočite kartico e-SIM, če želite napravo uporabljati brez mobilne storitve."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Vnesite kodo PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Vnesite geslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Kartica SIM je onemogočena. Če želite nadaljevati, vnesite kodo PUK. Za dodatne informacije se obrnite na operaterja."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index d3f1f3a..d65a800 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Zona e kodit PUK të kartës SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarmi tjetër i caktuar: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Fshi"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Çaktivizo kartën eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Dërgo"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Harrova motivin"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Motivi është i gabuar"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Kod PIN i gabuar"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Provo përsëri për <xliff:g id="NUMBER">%d</xliff:g> sekonda."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vizato motivin tënd"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Fut kodin PIN të kartës SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Fut kodin PIN të kartës SIM të \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Fut kodin PIN të kartës SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Fut kodin PIN të kartës SIM për \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Çaktivizo kartën eSIM për ta përdorur pajisjen pa shërbimin celular."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Fut kodin PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Fut fjalëkalimin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM tani është e çaktivizuar. Fut kodin PUK për të vazhduar. Kontakto me operatorin për detaje."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 683eef6..bd610c5 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Област за PUK за SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Следећи аларм је подешен за <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Избриши"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Онемогући eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Заборавио/ла сам шаблон"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Погрешан шаблон"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Погрешан PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Нацртајте шаблон"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Унесите PIN за SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Унесите PIN за SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Унесите PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Унесите лозинку"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 47334f8..f7eec5c 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-kodsområde för SIM-kort"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nästa alarm är inställt på <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Radera"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inaktivera eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retur"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glömt ditt grafiska lösenord?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Fel grafiskt lösenord"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Fel pinkod"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rita ditt grafiska lösenord"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ange pinkod för SIM-kortet"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ange pinkod för SIM-kortet för <xliff:g id="CARRIER">%1$s</xliff:g>"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ange pinkod för SIM-kortet."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ange pinkod för SIM-kortet för <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inaktivera eSIM om du vill använda enheten utan mobiltjänst."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ange pinkod"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ange lösenord"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet har inaktiverats. Du måste ange en PUK-kod innan du kan fortsätta. Kontakta operatören för mer information."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index b2991d2..9a10266 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Eneo la PUK ya SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Kengele inayofuata italia saa <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Futa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Zima eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Weka"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Umesahau Mchoro"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Mchoro si Sahihi"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Nambari ya PIN si sahihi"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Chora mchoro wako"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Weka PIN ya SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Weka PIN ya SIM ya \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Weka PIN ya SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Weka PIN ya SIM ya \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Zima eSIM ili utumie kifaa bila huduma ya vifaa vya mkononi."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Weka PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Weka Nenosiri"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM sasa imefungwa. Weka nambari ya PUK ili uendelee. Wasiliana na mtoa huduma za mtandao kwa maelezo."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 436d000..5f2db2c 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"சிம் PUKக்கான பகுதி"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"அடுத்த அலாரம் <xliff:g id="ALARM">%1$s</xliff:g>க்கு அமைக்கப்பட்டுள்ளது"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"நீக்கும் பொத்தான்"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"இ-சிம்மை முடக்கும்"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"என்டர் பொத்தான்"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"பேட்டர்ன் நினைவில்லையா"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"தவறான பேட்டர்ன்"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"தவறான பின்"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"பேட்டர்னை வரையவும்"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"சிம் பின்னை உள்ளிடவும்"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"க்கான சிம் பின்னை உள்ளிடவும்"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"சிம் பின்னை உள்ளிடவும்."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"க்கான சிம் பின்னை உள்ளிடவும்."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"மொபைல் சேவை இல்லாமல் சாதனத்தைப் பயன்படுத்த, இ-சிம்மை முடக்கவும்."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"பின்னை உள்ளிடவும்"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"கடவுச்சொல்லை உள்ளிடவும்"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர, PUK குறியீட்டை உள்ளிடவும். விவரங்களுக்கு, தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 1b635659..3973bce 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK ప్రాంతం"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"తదుపరి అలారం <xliff:g id="ALARM">%1$s</xliff:g>కి సెట్ చేయబడింది"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"తొలగించు"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMని నిలిపివేయండి"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"నమూనాను మర్చిపోయాను"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"నమూనా తప్పు"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"పిన్ తప్పు"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"మీ నమూనాను గీయండి"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM పిన్‌ను నమోదు చేయండి"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" కోసం SIM పిన్ నమోదు చేయండి"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM పిన్‌ని నమోదు చేయండి."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" కోసం SIM పిన్‌ని నమోదు చేయండి."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"మొబైల్ సేవ లేకుండా డివైజ్‌ని ఉపయోగించడం కోసం eSIMని నిలిపివేయండి."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"పిన్‌ను నమోదు చేయండి"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"పాస్‌వర్డ్‌ని నమోదు చేయండి"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ఇప్పుడు SIM నిలిపివేయబడింది. కొనసాగించాలంటే, PUK కోడ్‌ను నమోదు చేయండి. వివరాల కోసం క్యారియర్‌ను సంప్రదించండి."</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 0472c16..8d69e61 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"พื้นที่ PUK ของซิม"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ตั้งเวลาปลุกครั้งถัดไปไว้ที่ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ลบ"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"ปิดใช้ซิมอิเล็กทรอนิกส์"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ลืมรูปแบบ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"รูปแบบไม่ถูกต้อง"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN ไม่ถูกต้อง"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"ลองอีกครั้งในอีก <xliff:g id="NUMBER">%d</xliff:g> วินาที"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"วาดรูปแบบของคุณ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"ป้อน PIN ของซิม"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"ป้อน PIN ของซิมสำหรับ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ป้อน PIN ของซิม"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ป้อน PIN ของซิมสำหรับ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ปิดใช้ซิมอิเล็กทรอนิกส์เพื่อใช้อุปกรณ์โดยไม่มีบริการมือถือ"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ป้อน PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ป้อนรหัสผ่าน"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ซิมการ์ดถูกปิดใช้แล้ว ป้อนรหัส PUK เพื่อดำเนินการต่อ โปรดสอบถามรายละเอียดจากผู้ให้บริการ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 0b7aa13..f34718e 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Lugar ng PUK ng SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nakatakda ang susunod na alarm sa <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"I-delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"I-disable ang eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nakalimutan ang Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Mali ang Pattern"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Mali ang PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Subukang muli sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iguhit ang iyong pattern"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Ilagay ang PIN ng SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Ilagay ang PIN ng SIM para sa \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ilagay ang PIN ng SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ilagay ang PIN ng SIM para sa \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"I-disable ang eSIM upang magamit ang device nang walang serbisyo sa mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ilagay ang PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ilagay ang Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Naka-disable na ngayon ang SIM. Ilagay ang PUK code upang magpatuloy. Makipag-ugnayan sa carrier para sa mga detalye."</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index f108095..183af79 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM PUK alanı"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sonraki alarm <xliff:g id="ALARM">%1$s</xliff:g> olarak ayarlandı"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM\'i devre dışı bırak"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Deseni unuttunuz mu?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Yanlış Desen"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Yanlış PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Deseninizi çizin"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM PIN kodunu girin"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" için SIM PIN\'ini kodunu girin"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN kodunu girin."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" için SIM PIN kodunu girin."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Cihazı mobil hizmet olmadan kullanmak için eSIM\'i devre dışı bırakın."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN\'i girin"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Şifreyi Girin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kart artık devre dışı bırakıldı. Devam etmek için PUK kodunu girin. Ayrıntılı bilgi için operatörle bağlantı kurun."</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index fc52ce3..a2f6743 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"PUK-код SIM-карти"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Наступний сигнал: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Видалити"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Вимкнути eSIM-карту"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Ввести"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Не пам’ятаю ключ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Неправильний ключ"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Неправильний PIN-код"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Повторіть спробу через <xliff:g id="NUMBER">%d</xliff:g> с."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Намалюйте ключ"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Введіть PIN-код SIM-карти"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Введіть PIN-код SIM-карти для оператора \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Введіть PIN-код SIM-карти."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Введіть PIN-код SIM-карти для оператора \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Вимкнути eSIM-карту, щоб використовувати пристрій без мобільного зв’язку."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Введіть PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Введіть пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Зараз SIM-карту вимкнено. Введіть PUK-код, щоб продовжити. Зв’яжіться з оператором, щоб дізнатися більше."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 1258547..1b20118 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"‏SIM PUK کا علاقہ"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"اگلا الارم <xliff:g id="ALARM">%1$s</xliff:g> کیلئے سیٹ ہے"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"حذف کریں"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏eSIM غیر فعال کریں"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"درج کریں"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"پیٹرن بھول گئے"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"غلط پیٹرن"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"‏غلط PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"اپنا پیٹرن ڈرا کریں"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"‏SIM PIN درج کریں"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏SIM PIN درج کریں۔"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں۔"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏موبائل سروس کے بغیر آلہ کا استعمال کرنے کیلئے eSIM غیر فعال کریں۔"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"‏PIN درج کریں"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"پاسورڈ درج کریں"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏SIM اب غیر فعال ہوگیا ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index e822382..0011c26 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM karta PUK kodi maydoni"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Signal <xliff:g id="ALARM">%1$s</xliff:g> da chalinadi."</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"O‘chirib tashlash"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMni faolsizlantirish"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter tugmasi"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Grafik kalit esimdan chiqdi"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Grafik kalit xato"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN kod xato"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"<xliff:g id="NUMBER">%d</xliff:g> soniyadan keyin qaytadan urining."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Grafik kalit chizing"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"SIM kartaning PIN kodini kiriting"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi uchun PIN kodni kiriting"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM karta PIN kodini kiriting."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi PIN kodini kiriting."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Qurilmadan mobil xizmatlarsiz foydalanish uchun eSIMni faolsizlantiring."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN kodni kiriting"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Parol kiriting"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. Batafsil axborot olish uchun tarmoq operatori bilan bog‘laning."</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 59e5c9c..4fdddb2 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Khu vực mã PUK của SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Báo thức tiếp theo được đặt cho <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Xóa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Vô hiệu hóa eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Nhập"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Đã quên hình mở khóa"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Hình mở khóa sai"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Mã PIN sai"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vẽ hình mở khóa của bạn"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Nhập mã PIN của SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Nhập mã PIN của SIM dành cho \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Nhập mã PIN của SIM."</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Nhập mã PIN của SIM dành cho \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Vô hiệu hóa eSIM để sử dụng thiết bị khi không có dịch vụ di động."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Nhập mã PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Nhập mật khẩu"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM hiện bị vô hiệu hóa. Hãy nhập mã PUK để tiếp tục. Liên hệ với nhà cung cấp dịch vụ để biết chi tiết."</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index a5eca34..ad92979 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 PUK 码区域"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"下一个闹钟时间已设置为<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"删除"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM 卡"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"输入"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘记了图案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"图案错误"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 码错误"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"绘制您的图案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"请输入 SIM 卡 PIN 码"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"请输入“<xliff:g id="CARRIER">%1$s</xliff:g>”的 SIM 卡 PIN 码"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"请输入 SIM 卡 PIN 码。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"请输入“<xliff:g id="CARRIER">%1$s</xliff:g>”的 SIM 卡 PIN 码。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM 卡即可在没有移动服务的情况下使用设备。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"请输入 PIN 码"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"请输入密码"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡现已停用,需要输入 PUK 码才能继续使用。要了解详情,请联系您的运营商。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 8059a04..5cf4ac5 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 PUK 區域"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"已經將下一個鬧鐘時間設做<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete 鍵 (刪除)"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵 (輸入)"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記上鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"上鎖圖案錯誤"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 碼錯誤"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出上鎖圖案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"輸入 SIM 卡 PIN 碼"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」的 SIM 卡 PIN 碼"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM,即可在沒有流動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡現已停用,請輸入 PUK 碼以繼續。詳情請與流動網絡供應商聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index a03635b..6b7435a 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM 卡 PUK 區"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"已設定下一個鬧鐘時間:<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"刪除"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM 卡"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記解鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"解鎖圖案錯誤"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"PIN 碼錯誤"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出解鎖圖案"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"輸入 SIM 卡 PIN 碼"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」的 SIM 卡 PIN 碼"</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM 卡即可在沒有行動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡已遭停用,輸入 PUK 碼即可繼續使用。如需瞭解詳情,請與電信業者聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index eaa5ecb..8008ce4 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -51,6 +51,7 @@
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Indawo ye-SIM PUK"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"I-alamu elandelayo esethelwe i-<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Susa"</string>
+    <string name="disable_carrier_button_text" msgid="6914341927421916114">"Khubaza i-eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Faka"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ukhohlwe iphethini?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Iphatheni engalungile"</string>
@@ -58,8 +59,9 @@
     <string name="kg_wrong_pin" msgid="4785660766909463466">"Iphinikhodi engalungile"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="527455490371878356">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dweba iphethini yakho"</string>
-    <string name="kg_sim_pin_instructions" msgid="1795013002231184046">"Faka i-PIN ye-SIM"</string>
-    <string name="kg_sim_pin_instructions_multi" msgid="1586316574649150223">"Faka i-PIN ye-SIM ye-\"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Faka i-PIN ye-SIM"</string>
+    <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Faka i-PIN ye-SIM ye-\"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Khubaza i-eSIM ukusebenzisa idivayisi ngaphandle kwesevisi yeselula."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Faka iphinikhodi"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Faka iphasiwedi"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Xhumana nenkampani yenethiwekhi ngemininingwane."</string>
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index 7cfe631..e2ce210 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -35,9 +35,12 @@
         <attr name="android:gravity" />
         <attr name="dotSize" format="dimension" />
         <attr name="charPadding" format="dimension" />
+        <attr name="android:textColor" format="color" />
     </declare-styleable>
 
     <declare-styleable name="CarrierText">
         <attr name="allCaps" format="boolean" />
     </declare-styleable>
+
+    <attr name="passwordStyle" format="reference" />
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/colors.xml b/packages/SystemUI/res-keyguard/values/colors.xml
deleted file mode 100644
index 3998c5b..0000000
--- a/packages/SystemUI/res-keyguard/values/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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>
-
-    <!-- Clock -->
-    <color name="clock_white">#ffffffff</color>
-    <color name="clock_gray">@*android:color/secondary_text_default_material_dark</color>
-</resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 41c723e..a721dd0 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -48,6 +48,8 @@
 
     <!-- The size of the dots in the PIN unlock method. -->
     <dimen name="password_dot_size">9dp</dimen>
+    <!-- The size of PIN text in the PIN unlock method. -->
+    <integer name="scaled_password_text_size">40</integer>
 
     <!-- The padding between chars of the password view. -->
     <dimen name="password_char_padding">8dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 1efa3a8..589f1c1 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -99,12 +99,12 @@
     <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
 
     <!-- Time format strings for fall-back clock widget -->
-    <string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string>
+    <string name="keyguard_widget_12_hours_format" translatable="false">h:mm</string>
     <!-- Time format strings for fall-back clock widget -->
-    <string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
+    <string name="keyguard_widget_24_hours_format" translatable="false">kk:mm</string>
     <!-- The character used in keyguard_widget_12_hours_format and keyguard_widget_24_hours_format
          to represent a ":". -->
-    <string name="keyguard_fancy_colon" translatable="false">\uee01</string>
+    <string name="keyguard_fancy_colon" translatable="false"></string>
 
     <!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_pin_area">PIN area</string>
@@ -119,6 +119,8 @@
     <!-- KeyguardPinView - accessibility support --><skip />
     <!-- Description of the Delete button in a KeyboardView. [CHAR LIMIT=NONE] -->
     <string name="keyboardview_keycode_delete">Delete</string>
+    <!-- Description of the button used to disable current carrier when the device supported embedded SIM. [CHAR LIMIT=30] -->
+    <string name="disable_carrier_button_text">Disable eSIM</string>
     <!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
     <string name="keyboardview_keycode_enter">Enter</string>
 
@@ -135,9 +137,11 @@
     <!-- Instructions for using the pattern unlock screen -->
     <string name="kg_pattern_instructions">Draw your pattern</string>
     <!-- Instructions for using the SIM PIN unlock screen -->
-    <string name="kg_sim_pin_instructions">Enter SIM PIN</string>
+    <string name="kg_sim_pin_instructions">Enter SIM PIN.</string>
     <!-- Instructions for using the SIM PIN unlock screen when there's more than one SIM -->
-    <string name="kg_sim_pin_instructions_multi">Enter SIM PIN for \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\"</string>
+    <string name="kg_sim_pin_instructions_multi">Enter SIM PIN for \"<xliff:g id="carrier" example="CARD 1">%1$s</xliff:g>\".</string>
+    <!-- Instructions for disabling eSIM carrier to unlock the phone with embedded SIM -->
+    <string name="kg_sim_lock_instructions_esim">Disable eSIM to use device without mobile service.</string>
     <!-- Instructions for using the PIN unlock screen -->
     <string name="kg_pin_instructions">Enter PIN</string>
     <!-- Instructions for using the password unlock screen -->
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 53a559f..826e3ea 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -20,11 +20,11 @@
 <resources>
     <!-- Keyguard PIN pad styles -->
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
-        <item name="android:textColor">@*android:color/primary_device_default_light</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="@android:style/DeviceDefault.ButtonBar">
-        <item name="android:textColor">@*android:color/primary_device_default_light</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
         <item name="android:background">@null</item>
     </style>
@@ -32,15 +32,18 @@
         <item name="android:singleLine">true</item>
         <item name="android:gravity">center_horizontal|center_vertical</item>
         <item name="android:background">@null</item>
-        <item name="android:textSize">36sp</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:textColor">#ffffffff</item>
+        <item name="android:textSize">32sp</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
         <item name="android:paddingBottom">-16dp</item>
     </style>
+    <style name="Keyguard.ImageButton.NumPadEnter" parent="@android:style/Widget.ImageButton">
+        <item name="android:tint">@color/background_protected</item>
+    </style>
     <style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
         <item name="android:textSize">12sp</item>
         <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textColor">#80ffffff</item>
+        <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
         <item name="android:paddingBottom">0dp</item>
     </style>
 
@@ -50,19 +53,29 @@
     </style>
     <style name="widget_big_thin">
         <item name="android:textSize">@dimen/widget_big_font_size</item>
-        <item name="android:fontFamily">sans-serif-light</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
+        <item name="android:fontFeatureSettings">@*android:string/config_headlineFontFeatureSettings</item>
     </style>
 
     <style name="BouncerSecurityContainer">
         <item name="android:layout_gravity">center_horizontal|bottom</item>
     </style>
 
-    <style name="PasswordTheme" parent="@android:style/Theme.DeviceDefault">
-        <item name="android:colorControlNormal">#80ffffff</item>
-        <item name="android:colorControlActivated">#80ffffff</item>
+    <style name="PasswordTheme" parent="Theme.SystemUI">
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
+    </style>
+
+    <style name="PasswordTheme.Light" parent="Theme.SystemUI.Light">
+        <item name="android:textColor">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
+        <item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
     </style>
 
     <style name="keyguard_presentation_theme" parent="@android:style/Theme.Material.NoActionBar.Fullscreen">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml
new file mode 100644
index 0000000..073bf6d
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_bottompath_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+        android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+        android:valueType="pathType"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml
new file mode 100644
index 0000000..990392d
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_circlepath_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="383"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
old mode 100755
new mode 100644
index 1c50165..a00d937
--- a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
@@ -1,46 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathStart"
-        android:valueFrom="0.5001"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="1.5"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_6" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
deleted file mode 100755
index 598255c..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
+++ /dev/null
@@ -1,49 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-            android:valueTo="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
-    </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.xml
new file mode 100644
index 0000000..59d6232
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_errorcircle_animation.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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="5.0"
+            android:valueTo="5.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="366"
+            android:propertyName="rotation"
+            android:valueFrom="5.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml
new file mode 100644
index 0000000..55bfa58
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_errorexclamationdot_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.0,12.0 c 0.0,-0.66667 0.0,-3.33333 0.0,-4.0"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_5" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
deleted file mode 100755
index 7e0fa43..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
+++ /dev/null
@@ -1,59 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="133"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M -0.00391,5.333 c 0.00065,-0.22217 0.00326,-1.11083 0.00391,-1.333"
-        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml
new file mode 100644
index 0000000..4c44c6b
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_exclamationtop_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="283"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,-2.0 c 0.0,0.5 0.0,2.5 0.0,3.0"
+        android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_2" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
deleted file mode 100755
index f413cbf..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
+++ /dev/null
@@ -1,53 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
deleted file mode 100755
index f413cbf..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
+++ /dev/null
@@ -1,53 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleX"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="scaleY"
-            android:valueFrom="1.33333"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
old mode 100755
new mode 100644
index 2518041..6f7d692
--- a/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
@@ -1,32 +1,31 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="333"
+            android:duration="266"
             android:propertyName="scaleX"
             android:valueFrom="0.0"
             android:valueTo="0.0"
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="16"
+            android:duration="66"
             android:propertyName="scaleX"
             android:valueFrom="0.0"
             android:valueTo="1.0"
@@ -36,14 +35,14 @@
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="333"
+            android:duration="266"
             android:propertyName="scaleY"
             android:valueFrom="0.0"
             android:valueTo="0.0"
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="16"
+            android:duration="66"
             android:propertyName="scaleY"
             android:valueFrom="0.0"
             android:valueTo="1.0"
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
old mode 100755
new mode 100644
index 15f8d2e..6821e62
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
+            android:duration="283"
             android:propertyName="pathData"
-            android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-            android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+            android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+            android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="183"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-            android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="316"
+            android:duration="266"
             android:propertyName="pathData"
             android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
old mode 100755
new mode 100644
index aa81fcf..a8251dc
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
+            android:duration="283"
             android:propertyName="pathData"
-            android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-            android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+            android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+            android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="183"
-            android:propertyName="pathData"
-            android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-            android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="316"
+            android:duration="266"
             android:propertyName="pathData"
             android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
             android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
old mode 100755
new mode 100644
index f94fe0a..c1ece08
--- a/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
@@ -1,49 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="233"
+            android:duration="250"
             android:propertyName="pathData"
             android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueType="pathType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="366"
+            android:duration="216"
             android:propertyName="pathData"
             android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueTo="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_2" />
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
deleted file mode 100755
index bcc8c41..0000000
--- a/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
+++ /dev/null
@@ -1,32 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFF3511E"
-        android:valueTo="#FFFFFFFF"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.5"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml
new file mode 100644
index 0000000..d9781df
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_toppath_animation.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-6.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,5.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-5.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="283"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml
new file mode 100644
index 0000000..b5dd5c3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_left_animation.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml
new file mode 100644
index 0000000..14704bf
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_dot_right_animation.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
deleted file mode 100644
index 26c6aa7..0000000
--- a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
deleted file mode 100644
index e1f8989..0000000
--- a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml b/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml
new file mode 100644
index 0000000..d465f19
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_down_left_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.699,8.701 c 0.0,1.09767 0.0,5.48833 0.0,6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="-45.0"
+        android:valueTo="45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_down_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml b/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml
new file mode 100644
index 0000000..7a38ac3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_down_right_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 11.287,8.701 c 0.0,1.09767 0.0,5.48833 0.0,6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="-45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_down_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml b/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml
new file mode 100644
index 0000000..125a616
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_up_left_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.699,15.287 c -0.04833,0.452 -0.04833,-7.03583 0.0,-6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="-45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_up_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml b/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml
new file mode 100644
index 0000000..3fd4df5
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_caret_up_right_animation.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 11.287,15.287 c 0.04883,0.452 0.04883,-7.03583 0.0,-6.586"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <objectAnimator
+        android:duration="200"
+        android:propertyName="rotation"
+        android:valueFrom="-45.0"
+        android:valueTo="45.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_caret_up_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
deleted file mode 100644
index a914687c..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.680404663086,3.53039550781 c 0.0,0.0 -0.01416015625,0.00492858886719 -0.01416015625,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151519775391,-0.00492858886719 0.0151519775391,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
-        android:valueTo="M 0.680404663086,3.53039550781 c 0.0,0.0 20.0110015869,20.0110015869 20.0110015869,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0100097656,-20.0110015869 -20.0100097656,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
deleted file mode 100644
index 3c60c01..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
-        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 20.4531555176,20.4530792236 20.4531555176,20.4530792236 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -20.4531402588,-20.4530487061 -20.4531402588,-20.4530487061 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
deleted file mode 100644
index 8d3296e..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
-        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 19.8804626465,19.8695220947 19.8804626465,19.8695220947 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -19.8804473877,-19.8694915771 -19.8804473877,-19.8694915771 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
deleted file mode 100644
index 2626499..0000000
--- a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 -0.0141754150391,0.00492858886719 -0.014175415039,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151672363281,-0.00492858886719 0.0151672363281,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 3.0,1.0 c 0.0,0.0 -6.0,0.0 -6.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 6.0,0.0 6.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-6.0 c -3.30000305176,0.0 -6.0,2.69999694824 -6.0,6.0 c 0.0,3.30000305176 2.69999694824,6.0 6.0,6.0 c 3.30000305176,0.0 6.0,-2.69999694824 6.0,-6.0 c 0.0,-3.30000305176 -2.60000610352,-6.0 -6.0,-6.0 Z"
-        android:valueTo="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 20.0109863281,20.0110015869 20.0109863281,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0099945068,-20.0110015869 -20.0099945068,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 5.0,1.0 c 0.0,0.0 -10.0,0.0 -10.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 10.0,0.0 10.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-10.0 c -5.52000427246,0.0 -10.0,4.47999572754 -10.0,10.0 c 0.0,5.52000427246 4.47999572754,10.0 10.0,10.0 c 5.52000427246,0.0 10.0,-4.47999572754 10.0,-10.0 c 0.0,-5.52000427246 -4.47999572754,-10.0 -10.0,-10.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.xml
new file mode 100644
index 0000000..91829c0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_bottompath_animation.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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_5" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.xml
new file mode 100644
index 0000000..9b08fa2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_circlepath_animation.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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="533"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.xml
new file mode 100644
index 0000000..1ea2100
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorcircle_animation.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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="rotation"
+            android:valueFrom="190.0"
+            android:valueTo="190.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="549"
+            android:propertyName="rotation"
+            android:valueFrom="190.0"
+            android:valueTo="-6.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.xml
new file mode 100644
index 0000000..0b9cb95
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_errorexclamation_animation.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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="180.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_6" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml
new file mode 100644
index 0000000..c597b82
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationbottom_animation.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml
new file mode 100644
index 0000000..bde83de
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_exclamationtop_animation.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="700"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,0.0 c 0.0,-0.33333 0.0,-1.66667 0.0,-2.0"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml
new file mode 100644
index 0000000..a3afaef
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprinterror_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml
new file mode 100644
index 0000000..a3afaef
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_fingerprintwhite_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml
new file mode 100644
index 0000000..1c3a766
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="133"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml
new file mode 100644
index 0000000..5a9258a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml
new file mode 100644
index 0000000..04b8b80
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+    </set>
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathStart"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_2" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml
new file mode 100644
index 0000000..c69001c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml
new file mode 100644
index 0000000..6fb22cd
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml
new file mode 100644
index 0000000..8e9a0510
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_5_path_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="150"
+        android:propertyName="trimPathStart"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml
new file mode 100644
index 0000000..3ffb8f8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="199"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml
new file mode 100644
index 0000000..3584f91
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml
new file mode 100644
index 0000000..0d44810
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="199"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml
new file mode 100644
index 0000000..52a5b3e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml
new file mode 100644
index 0000000..ff7420b
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_toerror_toppath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="pathData"
+            android:valueFrom="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_toerror_animation_interpolator_4" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml
new file mode 100644
index 0000000..4bc18f2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_bottompath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml
new file mode 100644
index 0000000..9273b9a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_circlepath_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="383"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml
new file mode 100644
index 0000000..062c6a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorcircle_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="10.0"
+            android:valueTo="10.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="366"
+            android:propertyName="rotation"
+            android:valueFrom="10.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml
new file mode 100644
index 0000000..5d4b268
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_errorexclamation_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="416"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-180.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_5" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml
new file mode 100644
index 0000000..d3d7d1c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationbottom_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="450"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,4.0 c 0.0,-0.66667 0.0,-3.33333 0.0,-4.0"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml
new file mode 100644
index 0000000..04b6868
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_exclamationtop_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="450"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,-2.0 c 0.0,0.33333 0.0,1.66667 0.0,2.0"
+        android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml
new file mode 100644
index 0000000..25f2c43
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_fingerprintwhite_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="180.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="499"
+            android:propertyName="rotation"
+            android:valueFrom="180.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml
new file mode 100644
index 0000000..4a6f39a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="416"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml
new file mode 100644
index 0000000..c9a9f64
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml
new file mode 100644
index 0000000..43e44cf
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_5_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml
new file mode 100644
index 0000000..04a6036
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml
new file mode 100644
index 0000000..031c5e6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="433"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml b/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml
new file mode 100644
index 0000000..9b3498f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_fingerprint_tofp_toppath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="250"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueTo="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/ic_fingerprint_tofp_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml
deleted file mode 100644
index ad06d8e..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-        android:valueTo="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml
deleted file mode 100644
index 4cd8ce9..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_disable_animation_mask.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1" />
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml
deleted file mode 100644
index 523e53a..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-        android:valueTo="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml
deleted file mode 100644
index 7562c9b..0000000
--- a/packages/SystemUI/res/anim/ic_hotspot_enable_animation_mask.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1" />
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="pathData"
-            android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 29.8566131592,30.1964874268 29.8566131592,30.1964874268 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -29.6566467285,-29.6924133301 -29.6566467285,-29.6924133301 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.905746459961,0.856552124023 0.905746459961,0.856552124023 c 0.0,0.0 -3.13299560547,2.82975769043 -3.13299560547,2.82975769043 c 0.0,0.0 28.7644195557,34.2162475586 28.7644195557,34.2162475586 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
index 3444747..5e71847 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_1_animation.xml
@@ -1,16 +1,24 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="266"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
             android:duration="16"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
@@ -18,7 +26,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
index 06e08cd9..9081e6f 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_2_animation.xml
@@ -1,10 +1,25 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="133"
+            android:duration="200"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
             android:valueTo="1.0"
@@ -18,7 +33,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
index 6b01687..eaf5f05 100644
--- a/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
+++ b/packages/SystemUI/res/anim/ic_hotspot_transient_circle_3_animation.xml
@@ -1,9 +1,31 @@
 <?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.
+-->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
+            android:duration="400"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
             android:duration="16"
             android:propertyName="fillAlpha"
             android:valueFrom="1.0"
@@ -11,7 +33,7 @@
             android:valueType="floatType"
             android:interpolator="@android:interpolator/linear" />
         <objectAnimator
-            android:duration="433"
+            android:duration="633"
             android:propertyName="fillAlpha"
             android:valueFrom="0.5"
             android:valueTo="0.5"
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
deleted file mode 100644
index 5e78f4c..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
deleted file mode 100644
index 7f77372..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
deleted file mode 100644
index eacd248..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
deleted file mode 100644
index 50a1af6..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.54"
-            android:valueTo="0.54"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.54"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
deleted file mode 100644
index a2126a0..0000000
--- a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_invert_colors_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index b003e92..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="367"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 5c37479..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
deleted file mode 100644
index aa086c9..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
deleted file mode 100644
index 27fd653..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-45"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index fa10b119..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
deleted file mode 100644
index caae73a..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleX"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="scaleY"
-        android:valueFrom="0.9"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-    <objectAnimator
-        android:duration="450"
-        android:propertyName="rotation"
-        android:valueFrom="-135"
-        android:valueTo="0"
-        android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
deleted file mode 100644
index aa22c3b..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
deleted file mode 100644
index 2530f08..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="-45"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
new file mode 100644
index 0000000..8fdad80
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="-90.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
new file mode 100644
index 0000000..3c3c131
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
new file mode 100644
index 0000000..57132e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="1.0"
+        android:valueTo="0.909"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="45.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index 4e20d81..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 4e20d81..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 61bdfea..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="117"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-221"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
deleted file mode 100644
index 6a0a20b..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,24 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0"
-        android:valueTo="-135"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
deleted file mode 100644
index 92b19ad..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="167"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
deleted file mode 100644
index 682dcf3..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
deleted file mode 100644
index 682dcf3..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
deleted file mode 100644
index 9fa8ec0..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="0.9"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="0.9"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="0.9"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <objectAnimator
-        android:duration="617"
-        android:propertyName="rotation"
-        android:valueFrom="-221"
-        android:valueTo="0"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
deleted file mode 100644
index 3208eee..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="-135"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="-135"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
deleted file mode 100644
index c1124af..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
new file mode 100644
index 0000000..ad2a5fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
new file mode 100644
index 0000000..cdb7890
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-221.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
new file mode 100644
index 0000000..46100b4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
new file mode 100644
index 0000000..8f6d24d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="400"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-135.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
new file mode 100644
index 0000000..300ed53
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
new file mode 100644
index 0000000..ad2a5fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleX"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="scaleY"
+            android:valueFrom="1.0"
+            android:valueTo="0.9"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
new file mode 100644
index 0000000..c152152
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="0.0"
+        android:valueTo="-180.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
new file mode 100644
index 0000000..b2c1eb8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
new file mode 100644
index 0000000..2a9bbe3
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
@@ -0,0 +1,60 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleX"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="0.909"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="scaleY"
+            android:valueFrom="0.909"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
+    </set>
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="45.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
new file mode 100644
index 0000000..ce26770
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleX"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+    <objectAnimator
+        android:duration="466"
+        android:propertyName="scaleY"
+        android:valueFrom="0.9"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
new file mode 100644
index 0000000..6e8941d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="616"
+        android:propertyName="rotation"
+        android:valueFrom="-221.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
new file mode 100644
index 0000000..3c3c131
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="83"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
new file mode 100644
index 0000000..fd8e4f8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="-135.0"
+            android:valueTo="-135.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="400"
+            android:propertyName="rotation"
+            android:valueFrom="-135.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
new file mode 100644
index 0000000..a77a536
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="500"
+            android:propertyName="pathData"
+            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
deleted file mode 100644
index 39e4aec..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
deleted file mode 100644
index 7f77372..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
deleted file mode 100644
index 1b73cc0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
deleted file mode 100644
index c45426c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
deleted file mode 100644
index b9b19f5..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-        android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
deleted file mode 100644
index 321a965..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
deleted file mode 100644
index 011a96f..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-        android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
deleted file mode 100644
index 14bab3a..0000000
--- a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
deleted file mode 100644
index 0c57530..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-        android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
deleted file mode 100644
index 9cc3b8e..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="1"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
deleted file mode 100644
index 501d68b..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
deleted file mode 100644
index 1b5445d..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-        android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
deleted file mode 100644
index 5fdb2a0..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
deleted file mode 100644
index 9ca12da..0000000
--- a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_location_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
deleted file mode 100644
index 661ab08..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
+++ /dev/null
@@ -1,31 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator" />
-    <objectAnimator
-        android:duration="17"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
deleted file mode 100644
index 1199442..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
deleted file mode 100644
index 6c7e751..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
deleted file mode 100644
index c699fe2..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
deleted file mode 100644
index 5595e5c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml
deleted file mode 100644
index 443f2a6..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_chevron_02_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="250"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:pathData="M 12.0,9.0 c 0.0,0.66667 0.0,5.0 0.0,6.0"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml
deleted file mode 100644
index d82f670..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_1_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_collapse_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="-45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml b/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml
deleted file mode 100644
index 0bc66bd..0000000
--- a/packages/SystemUI/res/anim/ic_volume_collapse_rectangle_2_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_collapse_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="-45.0"
-        android:valueTo="45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml
deleted file mode 100644
index e43e645..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_chevron_01_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="250"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:pathData="M 12.0,15.0 c 0.0,-1.0 0.0,-5.33333 0.0,-6.0"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml
deleted file mode 100644
index 9b575d8..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_3_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_expand_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="-45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml b/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml
deleted file mode 100644
index 6ae0fef..0000000
--- a/packages/SystemUI/res/anim/ic_volume_expand_rectangle_4_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <objectAnimator
-        android:duration="200"
-        android:interpolator="@interpolator/ic_volume_expand_animation_interpolator_0"
-        android:propertyName="rotation"
-        android:valueFrom="-45.0"
-        android:valueTo="45.0"
-        android:valueType="floatType" />
-
-</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml
deleted file mode 100644
index 0c87c4b..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation.xml
+++ /dev/null
@@ -1,27 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="416"
-        android:propertyName="rotation"
-        android:valueFrom="430.0"
-        android:valueTo="206.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_linear_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml
deleted file mode 100644
index 0ff1c8c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation.xml
+++ /dev/null
@@ -1,27 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="233"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-289.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml
deleted file mode 100644
index a1cadf8..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation.xml
+++ /dev/null
@@ -1,37 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,0.0250244140625 -0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0213623046875,-0.0250244140625 0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml
deleted file mode 100644
index 1ca49ba..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation.xml
+++ /dev/null
@@ -1,37 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0340270996094,0.050048828125 0.0340270996094,0.050048828125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0340270996094,-0.050048828125 -0.0340270996094,-0.050048828125 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml
deleted file mode 100644
index 8491747..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="383"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_linear_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml
deleted file mode 100644
index b9636ae..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="199"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml
deleted file mode 100644
index c1a3ecf..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml
deleted file mode 100644
index e285edc..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml
deleted file mode 100644
index 2ea1021..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml
deleted file mode 100644
index 1481cfa..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="233"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml
deleted file mode 100644
index 9dc587c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="rotation"
-            android:valueFrom="200.66753"
-            android:valueTo="200.66753"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="rotation"
-            android:valueFrom="200.66753"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml
deleted file mode 100644
index ada4213..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="516"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-        <objectAnimator
-            android:duration="1116"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="800"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-720.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml
deleted file mode 100644
index 2cdd02c..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="rotation"
-            android:valueFrom="231.0"
-            android:valueTo="231.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="231.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml
deleted file mode 100644
index 7b62f20..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="scaleX"
-            android:valueFrom="0.63838"
-            android:valueTo="0.63838"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="scaleX"
-            android:valueFrom="0.63838"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="scaleY"
-            android:valueFrom="0.63838"
-            android:valueTo="0.63838"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="scaleY"
-            android:valueFrom="0.63838"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="266"
-            android:propertyName="rotation"
-            android:valueFrom="184.0"
-            android:valueTo="184.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="rotation"
-            android:valueFrom="184.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.xml
deleted file mode 100644
index bdd24b7..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation.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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M 1.33227539062,-6.75866699219 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.33227539062,-6.75866699219 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-            android:valueTo="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml
deleted file mode 100644
index 8ec7c30..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="316"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueTo="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="pathData"
-            android:valueFrom="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-            android:valueTo="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.72023010254,-0.00544738769531 2.72023010254,-0.00544738769531 c 0.0,0.0 -0.013427734375,0.00141906738281 -0.013427734375,0.00141906738281 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.72023010254,-0.00544738769531 2.72023010254,-0.00544738769531 c 0.0,0.0 -0.013427734375,0.00141906738281 -0.013427734375,0.00141906738281 Z"
-            android:valueTo="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.00682067871094,-0.0040283203125 0.00682067871094,-0.0040283203125 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="99"
-            android:propertyName="pathData"
-            android:valueFrom="M 1.36582946777,4.05706787109 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.00682067871094,-0.0040283203125 0.00682067871094,-0.0040283203125 Z"
-            android:valueTo="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml
deleted file mode 100644
index ec65805..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation.xml
+++ /dev/null
@@ -1,37 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml
deleted file mode 100644
index 26622dd..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="133"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml
deleted file mode 100644
index 443e6fb..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation.xml
+++ /dev/null
@@ -1,37 +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
-  -->
-
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml
deleted file mode 100644
index f383c0a..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-    </set>
-    <objectAnimator
-        android:duration="166"
-        android:propertyName="trimPathStart"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml
deleted file mode 100644
index f8140d5..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml
deleted file mode 100644
index 870c44d..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="166"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml
deleted file mode 100644
index eef1efd..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="150"
-        android:propertyName="trimPathStart"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml
deleted file mode 100644
index 1b8a77f..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="trimPathEnd"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml
deleted file mode 100644
index ad37bc1..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml
deleted file mode 100644
index cd04aba..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="trimPathEnd"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="199"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml
deleted file mode 100644
index a09bdea..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="trimPathStart"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml
deleted file mode 100644
index ada4213..0000000
--- a/packages/SystemUI/res/anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="516"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3" />
-        <objectAnimator
-            android:duration="1116"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-305.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-        <objectAnimator
-            android:duration="800"
-            android:propertyName="rotation"
-            android:valueFrom="-305.0"
-            android:valueTo="-720.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml
new file mode 100644
index 0000000..7a01896
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_bottompath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="149"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+            android:valueTo="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml
new file mode 100644
index 0000000..ac5e448
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_circlepath_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
old mode 100755
new mode 100644
index 5cf4809..6697316
--- a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
@@ -1,66 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="strokeAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathOffset"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="433"
-            android:propertyName="trimPathOffset"
-            android:valueFrom="1.0"
-            android:valueTo="0.5"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_2" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="433"
-            android:propertyName="trimPathStart"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
-    </set>
+        android:duration="200"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+        android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+        android:valueType="pathType"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
deleted file mode 100755
index a387f97..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
+++ /dev/null
@@ -1,39 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="200"
-        android:propertyName="pathData"
-        android:valueFrom="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
-        android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml
new file mode 100644
index 0000000..903d97e
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_errorcircle_animation.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="184.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="450"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml
new file mode 100644
index 0000000..c5339a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_errorexclamationdot_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="550"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.0,8.0 c 0.0,0.66667 0.0,3.33333 0.0,4.0"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
deleted file mode 100755
index 7a9fb3b..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
+++ /dev/null
@@ -1,59 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="566"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,4.0 c -0.00065,0.22217 -0.00326,1.11083 -0.00391,1.333"
-        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_1" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="300"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="300"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="16"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml
new file mode 100644
index 0000000..c5b2c12
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_exclamationtop_animation.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="500"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 0.0,2.5 c 0.0,-0.75 0.0,-3.75 0.0,-4.5"
+        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_4" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
deleted file mode 100755
index 2a4753a..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
+++ /dev/null
@@ -1,53 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
deleted file mode 100755
index 2a4753a..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
+++ /dev/null
@@ -1,53 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.33333"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
old mode 100755
new mode 100644
index 1f601d3..63a25d9
--- a/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
@@ -1,25 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="116"
+            android:duration="150"
             android:propertyName="scaleX"
             android:valueFrom="1.0"
             android:valueTo="1.0"
@@ -36,7 +35,7 @@
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="116"
+            android:duration="150"
             android:propertyName="scaleY"
             android:valueFrom="1.0"
             android:valueTo="1.0"
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
old mode 100755
new mode 100644
index 7b9be5c..547f42e
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
-            android:propertyName="pathData"
-            android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
+            android:duration="200"
             android:propertyName="pathData"
             android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
         <objectAnimator
-            android:duration="200"
+            android:duration="149"
             android:propertyName="pathData"
             android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
             android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_5" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
old mode 100755
new mode 100644
index 8eb0c62..e5fe4d1
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
@@ -1,56 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
     <set
         android:ordering="sequentially" >
         <objectAnimator
-            android:duration="33"
-            android:propertyName="pathData"
-            android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-            android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
+            android:duration="200"
             android:propertyName="pathData"
             android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
             android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
         <objectAnimator
-            android:duration="200"
+            android:duration="149"
             android:propertyName="pathData"
             android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
             android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
             android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_5" />
     </set>
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
old mode 100755
new mode 100644
index 2e86744..455d0b8
--- a/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
@@ -1,39 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
-    You may obtain a copy of the License at
+     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
+          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.
+     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.
 -->
 <set
     xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="200"
-        android:propertyName="pathData"
-        android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-        android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_3" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueTo="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="pathData"
+            android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
+    </set>
 </set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
deleted file mode 100755
index 46d571c..0000000
--- a/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
+++ /dev/null
@@ -1,32 +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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillColor"
-        android:valueFrom="#FFFFFFFF"
-        android:valueTo="#FFF3511E"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-    <objectAnimator
-        android:duration="600"
-        android:propertyName="fillAlpha"
-        android:valueFrom="0.5"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml
new file mode 100644
index 0000000..b2944e5
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_toppath_animation.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="300"
+            android:propertyName="pathData"
+            android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
+            android:valueTo="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z"
+            android:valueType="pathType"
+            android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_2" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="fillAlpha"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/color/background_protect_secondary.xml b/packages/SystemUI/res/color/background_protect_secondary.xml
new file mode 100644
index 0000000..97744db
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protect_secondary.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/wallpaperTextColorSecondary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/background_protected.xml b/packages/SystemUI/res/color/background_protected.xml
new file mode 100644
index 0000000..ff2009d
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protected.xml
@@ -0,0 +1,20 @@
+<?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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="?attr/wallpaperTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_delete_color.xml b/packages/SystemUI/res/color/pin_delete_color.xml
new file mode 100644
index 0000000..7d4f132
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_delete_color.xml
@@ -0,0 +1,19 @@
+<?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
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.61" android:color="?attr/wallpaperTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_divider_color.xml b/packages/SystemUI/res/color/pin_divider_color.xml
new file mode 100644
index 0000000..aff2317
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_divider_color.xml
@@ -0,0 +1,19 @@
+<?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
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.45" android:color="?attr/wallpaperTextColorSecondary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_background_dark.xml b/packages/SystemUI/res/color/qs_background_dark.xml
new file mode 100644
index 0000000..62e4959
--- /dev/null
+++ b/packages/SystemUI/res/color/qs_background_dark.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:alpha="0.93"
+          android:color="?android:attr/colorBackgroundFloating"/>
+</selector>
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index 0c69d89..b3a0484 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="?android:attr/colorPrimary" />
+    <solid android:color="@color/qs_background_dark" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/car_progress_bar.xml b/packages/SystemUI/res/drawable/car_progress_bar.xml
new file mode 100644
index 0000000..742fca7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_progress_bar.xml
@@ -0,0 +1,30 @@
+<!--
+  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
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background">
+        <shape>
+            <solid android:color="@color/car_user_switcher_progress_bgcolor" />
+        </shape>
+    </item>
+
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <solid android:color="@color/car_user_switcher_progress_fgcolor" />
+            </shape>
+        </clip>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/car_round_button.xml b/packages/SystemUI/res/drawable/car_round_button.xml
new file mode 100644
index 0000000..5f4deb3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_round_button.xml
@@ -0,0 +1,21 @@
+<!--
+  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
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="@color/car_start_driving_background" />
+    <corners android:radius="@dimen/car_start_driving_corner_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
index b131c38..99ee3b1 100644
--- a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
+++ b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.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="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate.xml b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
index 6211edf..bc196c9 100755
--- a/packages/SystemUI/res/drawable/error_to_trustedstate.xml
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -17,50 +17,38 @@
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="error_to_trustedstate"
-    android:width="32dp"
-    android:viewportWidth="32"
-    android:height="32dp"
-    android:viewportHeight="32" >
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
     <group
-        android:name="error_to_trusted_state"
-        android:translateX="16"
-        android:translateY="16" >
-        <group
-            android:name="error_circle" >
-            <path
-                android:name="ellipse_path_1"
-                android:trimPathStart="0"
-                android:trimPathEnd="1"
-                android:trimPathOffset="0.0"
-                android:strokeColor="#FFF3511E"
-                android:strokeWidth="2"
-                android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
-        </group>
+        android:name="lock"
+        android:translateX="12"
+        android:translateY="12" >
         <group
             android:name="middle_ellipse"
             android:translateY="2.9375" >
             <path
-                android:name="ellipse_path_2"
-                android:fillColor="#FFF3511E"
+                android:name="ellipse_path_1"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5"
                 android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
         </group>
         <group
-            android:name="lock_right_side"
-            android:scaleX="1.33333"
-            android:scaleY="1.33333" >
+            android:name="lock_right_side" >
             <path
                 android:name="path_1"
-                android:pathData="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
-                android:fillColor="#FFF3511E" />
+                android:pathData="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
         <group
-            android:name="lock_left_side"
-            android:scaleX="1.33333"
-            android:scaleY="1.33333" >
+            android:name="lock_left_side" >
             <path
                 android:name="path_2"
-                android:pathData="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
-                android:fillColor="#FFF3511E" />
+                android:pathData="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
         <group
             android:name="lock_top"
@@ -69,16 +57,49 @@
             <path
                 android:name="path_3"
                 android:pathData="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-                android:fillColor="#FFF3511E" />
+                android:fillColor="?attr/wallpaperTextColor"
+                android:fillAlpha="0.5" />
         </group>
+    </group>
+    <group
+        android:name="errorexclamationdot"
+        android:translateX="12"
+        android:translateY="12" >
         <group
-            android:name="exclamation_dot"
-            android:translateX="-0.00391"
-            android:translateY="5.333" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="rectangle_path_1"
-                android:fillColor="#FFF3511E"
-                android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
+        <group
+            android:name="exclamationtop"
+            android:translateY="-2" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="5" >
+        <group
+            android:name="circle" >
+            <path
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
index 6befe13..a494f1d 100755
--- a/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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.
@@ -21,18 +21,9 @@
         android:name="ellipse_path_1"
         android:animation="@anim/error_to_trustedstate_ellipse_path_1_animation" />
     <target
-        android:name="ellipse_path_2"
-        android:animation="@anim/error_to_trustedstate_ellipse_path_2_animation" />
-    <target
-        android:name="lock_right_side"
-        android:animation="@anim/error_to_trustedstate_lock_right_side_animation" />
-    <target
         android:name="path_1"
         android:animation="@anim/error_to_trustedstate_path_1_animation" />
     <target
-        android:name="lock_left_side"
-        android:animation="@anim/error_to_trustedstate_lock_left_side_animation" />
-    <target
         android:name="path_2"
         android:animation="@anim/error_to_trustedstate_path_2_animation" />
     <target
@@ -42,9 +33,21 @@
         android:name="path_3"
         android:animation="@anim/error_to_trustedstate_path_3_animation" />
     <target
-        android:name="exclamation_dot"
-        android:animation="@anim/error_to_trustedstate_exclamation_dot_animation" />
+        android:name="errorexclamationdot"
+        android:animation="@anim/error_to_trustedstate_errorexclamationdot_animation" />
     <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/error_to_trustedstate_rectangle_path_1_animation" />
+        android:name="bottompath"
+        android:animation="@anim/error_to_trustedstate_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/error_to_trustedstate_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/error_to_trustedstate_toppath_animation" />
+    <target
+        android:name="errorcircle"
+        android:animation="@anim/error_to_trustedstate_errorcircle_animation" />
+    <target
+        android:name="circlepath"
+        android:animation="@anim/error_to_trustedstate_circlepath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
index b94cc8e..f6e5ceb 100644
--- a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
+++ b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@
     android:width="16dp"
     android:height="16dp"
     android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/textColorTertiary">
-
+    android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
index 76026af..33d1fb3 100644
--- a/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
@@ -1,4 +1,18 @@
 <?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:name="ic_bluetooth_transient"
@@ -7,89 +21,54 @@
     android:height="48dp"
     android:viewportHeight="48" >
     <group
-        android:name="ic_signal_wifi_4_bar_48px_outlines_"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
+        android:name="ic_bluetooth_transient_0"
+        android:translateX="23.99883"
+        android:translateY="23.99839" >
         <group
-            android:name="ic_signal_wifi_4_bar_48px_outlines__pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
+            android:name="ic_bluetooth_transient_pivot"
+            android:translateX="-23.99883"
+            android:translateY="-23.99839" >
             <group
-                android:name="bluetooth"
-                android:translateX="22.08789"
-                android:translateY="18.72031" >
+                android:name="ic_bluetooth_white_outlines"
+                android:translateX="22.73986"
+                android:translateY="23.99839" >
                 <group
-                    android:name="bluetooth_pivot"
-                    android:translateX="-22.08789"
-                    android:translateY="-18.72031" >
-                    <group
-                        android:name="cross"
-                        android:rotation="-1.88453" >
-                        <path
-                            android:name="extented_cross"
-                            android:pathData="M 10.6188659668,6.56344604492 c 0.0,0.0 21.7386016846,23.1297454834 21.7386016846,23.1297454834"
-                            android:strokeColor="#FFFFFFFF"
-                            android:strokeWidth="4" />
-                    </group>
-                    <group
-                        android:name="bluetooth_0"
-                        android:translateX="23.38789"
-                        android:translateY="18.72031" >
-                        <path
-                            android:name="b_shape_merged"
-                            android:pathData="M 11.3999938965,-8.60000610352 c 0.0,0.0 -11.3999938965,-11.3999938965 -11.3999938965,-11.3999938965 c 0.0,0.0 -2.0,0.0 -2.0,0.0 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 -9.19999694824,-9.19999694824 -9.19999694824,-9.19999694824 c 0.0,0.0 -2.80000305176,2.80000305176 -2.80000305176,2.80000305176 c 0.0,0.0 11.1999969482,11.1999969482 11.1999969482,11.1999969482 c 0.0,0.0 -11.1999969482,11.1999969482 -11.1999969482,11.1999969482 c 0.0,0.0 2.80000305176,2.80000305176 2.80000305176,2.80000305176 c 0.0,0.0 9.19999694824,-9.19999694824 9.19999694824,-9.19999694824 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 2.0,0.0 2.0,0.0 c 0.0,0.0 11.3999938965,-11.3999938965 11.3999938965,-11.3999938965 c 0.0,0.0 -8.59999084473,-8.60000610352 -8.59999084473,-8.60000610352 c 0.0,0.0 8.59999084473,-8.60000610352 8.59999084473,-8.60000610352 Z M 2.0,-12.3000030518 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 Z M 5.80000305176,8.60000610352 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
+                    android:name="ic_bluetooth_white_outlines_pivot"
+                    android:translateX="-12.84937"
+                    android:translateY="-20.4772" >
+                    <path
+                        android:name="b_shape_merged"
+                        android:pathData="M 17.1289978027,20.4790039062 c 0.0,0.0 7.5,-7.48100280762 7.5,-7.48100280762 c 0.81999206543,-0.819000244141 0.81999206543,-2.13899230957 0.0,-2.95999145508 c 0.0,0.0 -8.93899536133,-8.93899536133 -8.93899536133,-8.93899536133 c 0.0,0.0 -0.0610046386719,-0.0610046386719 -0.0610046386718,-0.0610046386719 c -0.844009399414,-0.788009643555 -2.16799926758,-0.74299621582 -2.95600891113,0.102005004883 c -0.359985351562,0.384994506836 -0.561996459961,0.891998291016 -0.56298828125,1.41899108887 c 0.0,0.0 0.0,12.8800048828 0.0,12.8800048828 c 0.0,0.0 -8.10000610352,-8.10000610352 -8.10000610352,-8.10000610352 c -0.81999206543,-0.81999206543 -2.12100219727,-0.81999206543 -2.9409942627,0.0 c -0.819000244141,0.819000244141 -0.819000244141,2.12001037598 0.0,2.94000244141 c 0.0,0.0 10.1799926758,10.1999969482 10.1799926758,10.1999969482 c 0.0,0.0 -10.1799926758,10.1790008545 -10.1799926758,10.1790008545 c -0.819000244141,0.820999145508 -0.819000244141,2.12100219727 0.0,2.94100952148 c 0.81999206543,0.81999206543 2.12100219727,0.81999206543 2.9409942627,0.0 c 0.0,0.0 8.10000610352,-8.1009979248 8.10000610352,-8.1009979248 c 0.0,0.0 0.0,12.9009857178 0.0,12.9009857178 c 0.0,1.14801025391 0.929992675781,2.08000183105 2.08000183105,2.08000183105 c 0.526992797852,0.0 1.03399658203,-0.199996948242 1.41999816895,-0.559997558594 c 0.0,0.0 0.0989990234375,-0.100006103516 0.0989990234375,-0.100006103516 c 0.0,0.0 8.91999816895,-8.91999816895 8.91999816895,-8.91999816895 c 0.81999206543,-0.820999145508 0.81999206543,-2.13999938965 0.0,-2.95999145508 c 0.0,0.0 -7.5,-7.46000671387 -7.5,-7.46000671387 Z M 16.0899963379,15.8190002441 c 0.0,0.0 0.0,-8.59999084473 0.0,-8.59999084473 c 0.0,0.0 4.30000305176,4.30000305176 4.30000305176,4.30000305176 c 0.0,0.0 -4.30000305176,4.29998779297 -4.30000305176,4.29998779297 Z M 16.0899963379,33.7190093994 c 0.0,0.0 0.0,-8.6009979248 0.0,-8.6009979248 c 0.0,0.0 4.30000305176,4.30099487305 4.30000305176,4.30099487305 c 0.0,0.0 -4.30000305176,4.30000305176 -4.30000305176,4.30000305176 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
             <group
-                android:name="dot_left"
-                android:translateX="20.16992"
-                android:translateY="18.64258" >
+                android:name="dot_left_outlines"
+                android:translateX="20.6501"
+                android:translateY="24.00011" >
                 <group
-                    android:name="dot_left_pivot"
-                    android:translateX="-20.16992"
-                    android:translateY="-18.64258" >
-                    <group
-                        android:name="group_1"
-                        android:translateX="9.38789"
-                        android:translateY="18.72031" >
-                        <group
-                            android:name="group_1_pivot"
-                            android:translateX="-9.38789"
-                            android:translateY="-18.72031" >
-                            <path
-                                android:name="dot_left_0"
-                                android:pathData="M 13.3878936768,18.7203063965 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 Z"
-                                android:fillColor="#FFFFFFFF" />
-                        </group>
-                    </group>
+                    android:name="dot_left_outlines_pivot"
+                    android:translateX="-14.2"
+                    android:translateY="-3.55" >
+                    <path
+                        android:name="dot_left"
+                        android:pathData="M 5.66999816895,5.66999816895 c -1.18000793457,1.17999267578 -3.08000183105,1.17999267578 -4.24000549316,0.0 c -1.17999267578,-1.16000366211 -1.17999267578,-3.03999328613 -0.0199890136719,-4.2200012207 c 0.0,0.0 0.0199890136719,-0.0200042724609 0.0199890136719,-0.0200042724609 c 1.16000366211,-1.17999267578 3.04000854492,-1.17999267578 4.2200012207,-0.0199890136719 c 0.0,0.0 0.0200042724609,0.0199890136719 0.0200042724609,0.0199890136719 c 1.17999267578,1.17900085449 1.17999267578,3.06001281738 0.0,4.24000549316 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="0.5" />
                 </group>
             </group>
             <group
-                android:name="dot_right"
-                android:translateX="26.16094"
-                android:translateY="18.60898" >
+                android:name="dot_right_outlines"
+                android:translateX="27.3501"
+                android:translateY="23.99741" >
                 <group
-                    android:name="dot_right_pivot"
-                    android:translateX="-26.16094"
-                    android:translateY="-18.60898" >
-                    <group
-                        android:name="group_2"
-                        android:translateX="37.38789"
-                        android:translateY="18.72031"
-                        android:scaleX="0"
-                        android:scaleY="0" >
-                        <group
-                            android:name="group_1_pivot_0"
-                            android:translateX="-37.38789"
-                            android:translateY="-18.72031" >
-                            <path
-                                android:name="dot_right_0"
-                                android:pathData="M 37.3878936768,14.7203063965 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 Z"
-                                android:fillColor="#FFFFFFFF" />
-                        </group>
-                    </group>
+                    android:name="dot_right_outlines_pivot"
+                    android:translateX="7.1"
+                    android:translateY="-3.5525" >
+                    <path
+                        android:name="dot_right"
+                        android:pathData="M 5.66999816895,1.43499755859 c 1.17999267578,1.18000793457 1.17999267578,3.08000183105 0.0,4.24000549316 c -1.18000793457,1.17999267578 -3.08000183105,1.17999267578 -4.24000549316,0.0 c -1.17999267578,-1.16000366211 -1.17999267578,-3.04000854492 -0.0200042724609,-4.21899414062 c 0.0,0.0 0.0200042724609,-0.0210113525391 0.0200042724609,-0.0210113525391 c 1.15299987793,-1.17098999023 3.03799438477,-1.18499755859 4.20899963379,-0.0309906005859 c 0.0,0.0 0.031005859375,0.0309906005859 0.031005859375,0.0309906005859 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
         </group>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
index f7eb23c..dc3c3e2 100644
--- a/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
@@ -1,11 +1,25 @@
 <?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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_bluetooth_transient" >
     <target
-        android:name="group_1"
-        android:animation="@anim/ic_bluetooth_transient_group_1_animation" />
+        android:name="dot_left"
+        android:animation="@anim/ic_bluetooth_transient_dot_left_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/ic_bluetooth_transient_group_2_animation" />
+        android:name="dot_right"
+        android:animation="@anim/ic_bluetooth_transient_dot_right_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index 604e918..beedcbb 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
         android:pathData="m18.250000,12.000000a6.250000,6.250000 0.000000,1.000000 1.000000,-12.500000 0.000000,6.250000 6.250000,0.000000 1.000000,1.000000 12.500000,0.000000z"
         android:fillColor="?android:attr/colorPrimary" />
     <path
-        android:fillColor="?android:attr/colorControlNormal"
-        android:pathData="M20.000000,8.700000L20.000000,4.000000L15.300000,4.000000L12.000000,0.700000 8.700000,4.000000L4.000000,4.000000L4.000000,8.700000L0.700000,12.000000 4.000000,15.300000L4.000000,20.000000L8.700000,20.000000L12.000000,23.299999 15.300000,20.000000L20.000000,20.000000L20.000000,15.300000L23.299999,12.000000 20.000000,8.700000zM12.000000,18.000000C8.700000,18.000000 6.000000,15.300000 6.000000,12.000000 6.000000,8.700000 8.700000,6.000000 12.000000,6.000000c3.300000,0.000000 6.000000,2.700000 6.000000,6.000000 0.000000,3.300000 -2.700000,6.000000 -6.000000,6.000000zM12.000000,8.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000 0.000000,2.200000 1.800000,4.000000 4.000000,4.000000 2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000 0.000000,-2.200000 -1.800000,-4.000000 -4.000000,-4.000000z"/>
+        android:pathData="M20,8.69L20,5c0,-0.55 -0.45,-1 -1,-1h-3.69l-2.6,-2.6a0.996,0.996 0,0 0,-1.41 0L8.69,4L5,4c-0.55,0 -1,0.45 -1,1v3.69l-2.6,2.6a0.996,0.996 0,0 0,0 1.41L4,15.3L4,19c0,0.55 0.45,1 1,1h3.69l2.6,2.6c0.39,0.39 1.02,0.39 1.41,0l2.6,-2.6L19,20c0.55,0 1,-0.45 1,-1v-3.69l2.6,-2.6a0.996,0.996 0,0 0,0 -1.41L20,8.69zM12,18.08c-3.36,0 -6.08,-2.73 -6.08,-6.08S8.64,5.92 12,5.92s6.08,2.73 6.08,6.08 -2.72,6.08 -6.08,6.08zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"
+        android:fillColor="?android:attr/colorControlNormal" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_close_white_rounded.xml b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
new file mode 100644
index 0000000..ca37698
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_close_white_rounded.xml
@@ -0,0 +1,26 @@
+<?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.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18.3,5.71a0.996,0.996 0,0 0,-1.41 0L12,10.59 7.11,5.7A0.996,0.996 0,1 0,5.7 7.11L10.59,12 5.7,16.89a0.996,0.996 0,1 0,1.41 1.41L12,13.41l4.89,4.89a0.996,0.996 0,1 0,1.41 -1.41L13.41,12l4.89,-4.89c0.38,-0.38 0.38,-1.02 0,-1.4z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
index 64bbff0..0f027ee 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver.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.
@@ -14,18 +14,15 @@
     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:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+        android:pathData="M16,12c0,0.55 -0.45,1 -1,1h-2v2c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1v-2L9,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2L11,9c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v2h2c0.55,0 1,0.45 1,1zM17.69,16.87a7.437,7.437 0,0 1,-5.93 2.63c-3.82,-0.12 -7.03,-3.25 -7.25,-7.07 -0.21,-3.84 2.48,-7.1 6.07,-7.79 0.24,-0.04 0.42,-0.24 0.42,-0.48L11,2.62c0,-0.3 -0.27,-0.55 -0.57,-0.5A10.02,10.02 0,0 0,2.09 13.4c0.59,4.4 4.16,7.94 8.56,8.52a9.99,9.99 0,0 0,9.14 -3.65,0.5 0.5,0 0,0 -0.15,-0.74l-1.32,-0.76a0.469,0.469 0,0 0,-0.63 0.1z"
+        android:fillColor="#FFFFFFFF"/>
     <path
-        android:fillColor="#54FFFFFF"
-        android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+        android:pathData="M13.41,4.64a0.493,0.493 0,0 1,-0.41 -0.48L13,2.62c0,-0.3 0.27,-0.55 0.57,-0.5C18.35,2.88 22,7.01 22,12c0,1.23 -0.23,2.41 -0.64,3.5 -0.11,0.28 -0.45,0.4 -0.72,0.24l-1.33,-0.77a0.484,0.484 0,0 1,-0.21 -0.59c0.25,-0.75 0.39,-1.55 0.39,-2.38 0.01,-3.65 -2.62,-6.69 -6.08,-7.36z"
+        android:fillColor="#54FFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
index 3001ad9..29e6c91 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver_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.
@@ -21,8 +21,5 @@
         android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
+        android:pathData="M18.32,16.75l1.32,0.76c0.26,0.15 0.34,0.51 0.15,0.74 -2.09,2.6 -5.44,4.14 -9.14,3.65 -4.4,-0.58 -7.96,-4.12 -8.56,-8.52C1.34,7.8 5.21,2.95 10.43,2.12c0.3,-0.05 0.57,0.2 0.57,0.5v1.53c0,0.24 -0.18,0.44 -0.41,0.49 -3.6,0.69 -6.29,3.95 -6.07,7.79 0.21,3.82 3.43,6.95 7.25,7.07 2.37,0.08 4.51,-0.96 5.93,-2.63a0.48,0.48 0,0 1,0.62 -0.12zM19.5,12c0,0.83 -0.14,1.63 -0.39,2.38 -0.08,0.23 0.01,0.47 0.21,0.59l1.33,0.77c0.26,0.15 0.61,0.04 0.72,-0.24 0.4,-1.09 0.63,-2.27 0.63,-3.5 0,-4.99 -3.65,-9.12 -8.43,-9.88 -0.3,-0.04 -0.57,0.2 -0.57,0.5v1.53c0,0.24 0.18,0.44 0.41,0.48 3.46,0.68 6.09,3.72 6.09,7.37z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml
index e658e68..9a1d502 100644
--- a/packages/SystemUI/res/drawable/ic_dnd.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z" />
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
deleted file mode 100644
index d755481..0000000
--- a/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<animated-vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_dnd_disable" >
-    <target
-        android:name="mask_1"
-        android:animation="@anim/ic_dnd_disable_mask_1_animation" />
-    <target
-        android:name="bar01_0"
-        android:animation="@anim/ic_dnd_disable_bar01_0_animation" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
index 0515b35..e7b9fa7 100644
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+        android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
deleted file mode 100644
index f796d62..0000000
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<animated-vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_dnd_total_silence_disable" >
-    <target
-        android:name="mask_1"
-        android:animation="@anim/ic_dnd_total_silence_disable_mask_1_animation" />
-    <target
-        android:name="outer_ring_merged"
-        android:animation="@anim/ic_dnd_total_silence_disable_outer_ring_merged_animation" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_fingerprint.xml b/packages/SystemUI/res/drawable/ic_fingerprint.xml
index ee2cf03..7bbd39d 100644
--- a/packages/SystemUI/res/drawable/ic_fingerprint.xml
+++ b/packages/SystemUI/res/drawable/ic_fingerprint.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright (C) 2015 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.
@@ -13,24 +13,55 @@
   ~ 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="32.0dp"
-        android:height="32.0dp"
-        android:viewportWidth="32.0"
-        android:viewportHeight="32.0">
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M23.7,5.9c-0.1,0.0 -0.2,0.0 -0.3,-0.1C21.0,4.5 18.6,3.9 16.0,3.9c-2.5,0.0 -4.6,0.6 -6.9,1.9C8.8,6.0 8.3,5.9 8.1,5.5C7.9,5.2 8.0,4.7 8.4,4.5c2.5,-1.4 4.9,-2.1 7.7,-2.1c2.8,0.0 5.4,0.7 8.0,2.1c0.4,0.2 0.5,0.6 0.3,1.0C24.2,5.7 24.0,5.9 23.7,5.9z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M5.3,13.2c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,-0.2 -0.4,-0.7 -0.2,-1.0c1.3,-1.9 2.9,-3.4 4.9,-4.5c4.1,-2.2 9.3,-2.2 13.4,0.0c1.9,1.1 3.6,2.5 4.9,4.4c0.2,0.3 0.1,0.8 -0.2,1.0c-0.3,0.2 -0.8,0.1 -1.0,-0.2c-1.2,-1.7 -2.6,-3.0 -4.3,-4.0c-3.7,-2.0 -8.3,-2.0 -12.0,0.0c-1.7,0.9 -3.2,2.3 -4.3,4.0C5.7,13.1 5.5,13.2 5.3,13.2z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M13.3,29.6c-0.2,0.0 -0.4,-0.1 -0.5,-0.2c-1.1,-1.2 -1.7,-2.0 -2.6,-3.6c-0.9,-1.7 -1.4,-3.7 -1.4,-5.9c0.0,-4.1 3.3,-7.4 7.4,-7.4c4.1,0.0 7.4,3.3 7.4,7.4c0.0,0.4 -0.3,0.7 -0.7,0.7s-0.7,-0.3 -0.7,-0.7c0.0,-3.3 -2.7,-5.9 -5.9,-5.9c-3.3,0.0 -5.9,2.7 -5.9,5.9c0.0,2.0 0.4,3.8 1.2,5.2c0.8,1.6 1.4,2.2 2.4,3.3c0.3,0.3 0.3,0.8 0.0,1.0C13.7,29.5 13.5,29.6 13.3,29.6z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M22.6,27.1c-1.6,0.0 -2.9,-0.4 -4.1,-1.2c-1.9,-1.4 -3.1,-3.6 -3.1,-6.0c0.0,-0.4 0.3,-0.7 0.7,-0.7s0.7,0.3 0.7,0.7c0.0,1.9 0.9,3.7 2.5,4.8c0.9,0.6 1.9,1.0 3.2,1.0c0.3,0.0 0.8,0.0 1.3,-0.1c0.4,-0.1 0.8,0.2 0.8,0.6c0.1,0.4 -0.2,0.8 -0.6,0.8C23.4,27.1 22.8,27.1 22.6,27.1z"/>
-    <path
-        android:fillColor="#80ffffff"
-        android:pathData="M20.0,29.9c-0.1,0.0 -0.1,0.0 -0.2,0.0c-2.1,-0.6 -3.4,-1.4 -4.8,-2.9c-1.8,-1.9 -2.8,-4.4 -2.8,-7.1c0.0,-2.2 1.8,-4.1 4.1,-4.1c2.2,0.0 4.1,1.8 4.1,4.1c0.0,1.4 1.2,2.6 2.6,2.6c1.4,0.0 2.6,-1.2 2.6,-2.6c0.0,-5.1 -4.2,-9.3 -9.3,-9.3c-3.6,0.0 -6.9,2.1 -8.4,5.4C7.3,17.1 7.0,18.4 7.0,19.8c0.0,1.1 0.1,2.7 0.9,4.9c0.1,0.4 -0.1,0.8 -0.4,0.9c-0.4,0.1 -0.8,-0.1 -0.9,-0.4c-0.6,-1.8 -0.9,-3.6 -0.9,-5.4c0.0,-1.6 0.3,-3.1 0.9,-4.4c1.7,-3.8 5.6,-6.3 9.8,-6.3c5.9,0.0 10.7,4.8 10.7,10.7c0.0,2.2 -1.8,4.1 -4.1,4.1s-4.0,-1.8 -4.0,-4.1c0.0,-1.4 -1.2,-2.6 -2.6,-2.6c-1.4,0.0 -2.6,1.2 -2.6,2.6c0.0,2.3 0.9,4.5 2.4,6.1c1.2,1.3 2.4,2.0 4.2,2.5c0.4,0.1 0.6,0.5 0.5,0.9C20.6,29.7 20.3,29.9 20.0,29.9z"/>
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:viewportWidth="24"
+    android:height="32dp"
+    android:viewportHeight="24" >
+    <group
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
+        <group
+            android:translateX="33"
+            android:translateY="34" >
+            <path
+                android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:name="ridge_7_path"
+                android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <path
+                android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+                android:strokeColor="?attr/wallpaperTextColor"
+                android:strokeAlpha="0.5"
+                android:strokeWidth="1.45"
+                android:strokeLineCap="round" />
+            <group
+                android:translateX="-97.5"
+                android:translateY="-142.5" >
+                <path
+                    android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+                    android:strokeColor="?attr/wallpaperTextColor"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+        </group>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot.xml b/packages/SystemUI/res/drawable/ic_hotspot.xml
new file mode 100644
index 0000000..8450bf6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_hotspot.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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateY="-0.32">
+        <path
+            android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13a6,6 0,0 0,-6.75 -5.95c-2.62,0.32 -4.78,2.41 -5.18,5.02 -0.32,2.14 0.49,4.11 1.92,5.39 0.48,0.43 1.24,0.33 1.56,-0.23 0.24,-0.42 0.14,-0.94 -0.22,-1.26a3.99,3.99 0,0 1,-1.22 -3.94,3.954 3.954,0 0,1 2.9,-2.91A4.007,4.007 0,0 1,16 13c0,1.18 -0.51,2.23 -1.33,2.96 -0.36,0.33 -0.47,0.85 -0.23,1.27 0.31,0.54 1.04,0.69 1.5,0.28A5.97,5.97 0,0 0,18 13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96a9.966,9.966 0,0 0,4.02 9.01c0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31A9.96,9.96 0,0 0,22 13c0,-5.91 -5.13,-10.62 -11.17,-9.93z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml b/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
deleted file mode 100644
index 2570483..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
+++ /dev/null
@@ -1,63 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="ic_hotspot"
-        android:translateX="23.9778"
-        android:translateY="24.26443" >
-        <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <path
-                        android:name="path_3"
-                        android:pathData="M -0.0042724609375,-2.64895629883 c -2.20922851562,0.0 -4.0,1.791015625 -4.0,4.0 c 0.0,2.20922851562 1.79077148438,4.0 4.0,4.0 c 2.208984375,0.0 4.0,-1.79077148438 4.0,-4.0 c 0.0,-2.208984375 -1.791015625,-4.0 -4.0,-4.0 Z M 11.9957275391,1.35104370117 c 0.0,-6.626953125 -5.373046875,-12.0 -12.0,-12.0 c -6.62719726562,0.0 -12.0,5.373046875 -12.0,12.0 c 0.0,4.43603515625 2.41381835938,8.30004882812 5.99194335938,10.3771972656 c 0.0,0.0 2.01586914062,-3.48217773438 2.01586914062,-3.48217773438 c -2.38500976562,-1.38500976562 -4.0078125,-3.93798828125 -4.0078125,-6.89501953125 c 0.0,-4.41796875 3.58178710938,-8.0 8.0,-8.0 c 4.41796875,0.0 8.0,3.58203125 8.0,8.0 c 0.0,2.95703125 -1.623046875,5.51000976562 -4.00805664062,6.89501953125 c 0.0,0.0 2.01586914062,3.48217773438 2.01586914062,3.48217773438 c 3.578125,-2.0771484375 5.9921875,-5.94116210938 5.9921875,-10.3771972656 Z M -0.0042724609375,-18.6489562988 c -11.0451660156,0.0 -20.0,8.9541015625 -20.0,20.0 c 0.0,7.39306640625 4.02099609375,13.8330078125 9.98779296875,17.2951660156 c 0.0,0.0 2.00219726562,-3.458984375 2.00219726562,-3.458984375 c -4.77319335938,-2.77001953125 -7.98999023438,-7.92211914062 -7.98999023438,-13.8361816406 c 0.0,-8.8369140625 7.16381835938,-16.0 16.0,-16.0 c 8.83595275879,0.0 16.0000152588,7.1630859375 16.0000152588,16.0 c 0.0,5.9140625 -3.21704101562,11.0661621094 -7.990234375,13.8361816406 c 0.0,0.0 2.00219726562,3.458984375 2.00219726563,3.458984375 c 5.966796875,-3.46215820312 9.98803710937,-9.90209960938 9.98803710938,-17.2951660156 c 0.0,-11.0458984375 -8.955078125,-20.0 -20.0000152588,-20.0 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.xml
deleted file mode 100644
index e446a32..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_disable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_hotspot_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_hotspot_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_hotspot_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml b/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
deleted file mode 100644
index 7a99630..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
+++ /dev/null
@@ -1,61 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_hotspot"
-        android:translateX="23.97354"
-        android:translateY="24.26306" >
-        <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <path
-                        android:name="circle_3"
-                        android:pathData="M 0.0843505859375,-2.93901062012 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z M 11.1185302734,5.83390808105 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695313,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808593,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007812 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820313 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007812 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015624,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265626,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z M 19.9300231934,2.95698547363 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0,0.0 0,-0.00997924804688 0,-0.00997924804687 c 0,0.0 0,-0.00100708007812 0,-0.00100708007813 c 0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0,0.0 0,0.00100708007812 0,0.00100708007813 c 0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632812 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976562,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585938,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.xml
deleted file mode 100644
index 945e42f..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_enable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_hotspot_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_hotspot_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_hotspot_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_transient.xml b/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
index 8c1f7ea..22f7267 100644
--- a/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
+++ b/packages/SystemUI/res/drawable/ic_hotspot_transient.xml
@@ -1,4 +1,19 @@
 <?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:name="ic_hotspot_transient"
@@ -7,42 +22,53 @@
     android:height="48dp"
     android:viewportHeight="48" >
     <group
-        android:name="ic_hotspot"
-        android:translateX="23.97354"
-        android:translateY="24.26306" >
+        android:name="ic_hotspot_transient_0"
+        android:translateX="24.00209"
+        android:translateY="24.2354" >
         <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
+            android:name="ic_hotspot_transient_pivot"
+            android:translateX="-24.00209"
+            android:translateY="-24.2354" >
             <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
+                android:name="circle01"
+                android:translateX="24.0002"
+                android:translateY="25.9996" >
                 <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <group
-                        android:name="group_3" >
-                        <path
-                            android:name="circle_3"
-                            android:pathData="M -0.154739379883,-3.04708862305 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
-                    <group
-                        android:name="group_1" >
-                        <path
-                            android:name="circle_2"
-                            android:pathData="M 10.8794403076,5.72583007812 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695312,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808594,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007813 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820312 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007813 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015625,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265625,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
-                    <group
-                        android:name="group_2" >
-                        <path
-                            android:name="circle_1"
-                            android:pathData="M 19.6909332275,2.8489074707 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0.0,0.0 0.0,-0.00997924804688 0.0,-0.00997924804687 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007813 c 0.0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0.0,0.0 0.0,0.00100708007812 0.0,0.00100708007813 c 0.0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632813 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976563,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0.0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0.0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585937,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
-                            android:fillColor="#FFFFFFFF" />
-                    </group>
+                    android:name="circle01_pivot"
+                    android:translateX="-24.0002"
+                    android:translateY="-25.9996" >
+                    <path
+                        android:name="circle01_0"
+                        android:pathData="M 24.0001983643,21.9996032715 c -2.19999694824,0.0 -4.0,1.80000305176 -4.0,4.0 c 0.0,2.20100402832 1.80000305176,4.0 4.0,4.0 c 2.19999694824,0.0 4.0,-1.79899597168 4.0,-4.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 Z"
+                        android:fillColor="#FFFFFFFF" />
+                </group>
+            </group>
+            <group
+                android:name="circle02"
+                android:translateX="24.00071"
+                android:translateY="24.74686" >
+                <group
+                    android:name="circle02_pivot"
+                    android:translateX="-24.00071"
+                    android:translateY="-24.74686" >
+                    <path
+                        android:name="circle02_0"
+                        android:pathData="M 36.0001983643,25.9996032715 c -0.00299072265625,-6.62699890137 -5.37899780273,-11.9969940186 -12.0059967041,-11.9940032959 c -0.5,0.0 -0.999008178711,0.031005859375 -1.4940032959,0.0940093994141 c -5.24000549316,0.640991210938 -9.55999755859,4.81999206543 -10.3600006104,10.0399932861 c -0.639999389648,4.2799987793 0.979995727539,8.22099304199 3.83999633789,10.7799987793 c 0.960006713867,0.86100769043 2.48001098633,0.660003662109 3.1190032959,-0.460006713867 c 0.481002807617,-0.839996337891 0.281005859375,-1.87998962402 -0.438995361328,-2.51899719238 c -2.21299743652,-1.97099304199 -3.15200805664,-5.00500488281 -2.44000244141,-7.8809967041 c 0.695007324219,-2.86999511719 2.93099975586,-5.11500549316 5.79899597168,-5.81900024414 c 4.29100036621,-1.08599853516 8.65000915527,1.51100158691 9.73600769043,5.80200195312 c 0.162002563477,0.639999389648 0.244003295898,1.29699707031 0.244995117188,1.95700073242 c 0.0,2.36099243164 -1.02000427246,4.45999145508 -2.66000366211,5.91999816895 c -0.720001220703,0.660003662109 -0.939987182617,1.69999694824 -0.459991455078,2.53999328613 c 0.619995117188,1.08000183105 2.08000183105,1.38000488281 3.0,0.560012817383 c 2.61599731445,-2.26699829102 4.1190032959,-5.55801391602 4.11999511719,-9.02000427246 Z"
+                        android:fillColor="#FFFFFFFF" />
+                </group>
+            </group>
+            <group
+                android:name="circle03"
+                android:translateX="24.00209"
+                android:translateY="24.23539" >
+                <group
+                    android:name="circle03_pivot"
+                    android:translateX="-24.00209"
+                    android:translateY="-24.23539" >
+                    <path
+                        android:name="circle03_0"
+                        android:pathData="M 21.6602020264,6.13960266113 c -9.24000549316,1.03999328613 -16.6999969482,8.66000366211 -17.5599975586,17.9199981689 c -0.690002441406,7.00500488281 2.36599731445,13.8540039062 8.03999328613,18.0200042725 c 0.958999633789,0.700988769531 2.32000732422,0.401000976562 2.91900634766,-0.620010375977 c 0.5,-0.860000610352 0.280990600586,-1.97898864746 -0.518997192383,-2.57998657227 c -4.56001281738,-3.38000488281 -7.30000305176,-9.09901428223 -6.32000732422,-15.3990020752 c 1.08000183105,-7.0 6.91900634766,-12.5800018311 13.9600067139,-13.3610076904 c 9.63999938965,-1.09999084473 17.8199920654,6.44000244141 17.8199920654,15.8800048828 c 0.0,5.30000305176 -2.57998657227,9.95999145508 -6.53999328613,12.8800048828 c -0.800003051758,0.600997924805 -1.02000427246,1.69999694824 -0.520004272461,2.57998657227 c 0.600006103516,1.04000854492 1.96000671387,1.32099914551 2.91999816895,0.620010375977 c 5.12100219727,-3.75500488281 8.14500427246,-9.72799682617 8.13999938965,-16.0800018311 c 0.0,-11.8200073242 -10.2599945068,-21.2400054932 -22.3399963379,-19.8600006104 Z"
+                        android:fillColor="#FFFFFFFF" />
                 </group>
             </group>
         </group>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml b/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
index b2945f1..929a941 100644
--- a/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_hotspot_transient_animation.xml
@@ -1,14 +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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_hotspot_transient" >
     <target
-        android:name="circle_3"
-        android:animation="@anim/ic_hotspot_transient_circle_3_animation" />
+        android:name="circle01_0"
+        android:animation="@anim/ic_hotspot_transient_circle_1_animation" />
     <target
-        android:name="circle_2"
+        android:name="circle02_0"
         android:animation="@anim/ic_hotspot_transient_circle_2_animation" />
     <target
-        android:name="circle_1"
-        android:animation="@anim/ic_hotspot_transient_circle_1_animation" />
+        android:name="circle03_0"
+        android:animation="@anim/ic_hotspot_transient_circle_3_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors.xml b/packages/SystemUI/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..f7a86a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors.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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="-0.61">
+        <path
+            android:pathData="M17.44,7.71L12.7,2.97a0.996,0.996 0,0 0,-1.41 0L6.56,7.71c-3,3 -3.4,7.89 -0.62,11.1 1.6,1.85 3.83,2.77 6.06,2.77s4.46,-0.92 6.06,-2.77c2.78,-3.21 2.38,-8.1 -0.62,-11.1zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
deleted file mode 100644
index 49ee48b..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
+++ /dev/null
@@ -1,57 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="icon"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="icon_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="ink_drop"
-                android:translateY="-6.8" >
-                <path
-                    android:name="outer_drop"
-                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
deleted file mode 100644
index aeda0a5..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_invert_colors_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_invert_colors_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_invert_colors_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
deleted file mode 100644
index 169cc71..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="icon"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="icon_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="ink_drop"
-                android:translateY="-6.8" >
-                <path
-                    android:name="outer_drop"
-                    android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
deleted file mode 100644
index 85928ac..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_invert_colors_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_invert_colors_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_invert_colors_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
deleted file mode 100644
index 8b2585b..0000000
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
+++ /dev/null
@@ -1,63 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
-    android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="ic_screen_rotation_48px_outlines"
-        android:translateX="24"
-        android:translateY="24" >
-        <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
-            android:translateX="-24.15"
-            android:translateY="-24.25" >
-            <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25" >
-                <path
-                    android:name="body"
-                    android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
index 400a28b..00bcaf6 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_from_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_rotate_to_landscape_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_landscape_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_landscape_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_landscape_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
index 603d0bf..cde6797 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_landscape_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="ic_screen_rotation_48px_outlines"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="ic_screen_rotation_48px_outlines_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-135" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
-                android:translateX="24.14999"
-                android:translateY="24.25"
-                android:rotation="-45" >
+                android:name="landscape"
+                android:translateX="24"
+                android:translateY="24" >
                 <path
-                    android:name="body"
-                    android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:name="device_merged"
+                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-90" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
index 5263eb4..86dc6ce 100644
--- a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_landscape_to_auto_rotate" >
     <target
+        android:name="landscape"
+        android:animation="@anim/ic_landscape_to_rotate_landscape_animation" />
+    <target
         android:name="arrows"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_landscape_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" />
-    <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" />
-    <target
-        android:name="body"
-        android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_landscape_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
index 204af7e..bf0dc95 100644
--- a/packages/SystemUI/res/drawable/ic_lock_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -20,6 +20,6 @@
         android:viewportHeight="24.0">
 
     <path
-        android:fillColor="@color/keyguard_affordance"
+        android:fillColor="?attr/wallpaperTextColor"
         android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
index c877f06..232cf70 100644
--- a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -20,6 +20,6 @@
         android:viewportHeight="24.0">
 
     <path
-        android:fillColor="@color/keyguard_affordance"
+        android:fillColor="?attr/wallpaperTextColor"
         android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_mic_26dp.xml b/packages/SystemUI/res/drawable/ic_mic_26dp.xml
index 83e4ba8..15c97b3 100644
--- a/packages/SystemUI/res/drawable/ic_mic_26dp.xml
+++ b/packages/SystemUI/res/drawable/ic_mic_26dp.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2015 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.
@@ -19,6 +19,6 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:pathData="M12.000000,14.000000c1.700000,0.000000 3.000000,-1.300000 3.000000,-3.000000l0.000000,-6.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,6.000000C9.000000,12.700000 10.300000,14.000000 12.000000,14.000000zM17.299999,11.000000c0.000000,3.000000 -2.500000,5.100000 -5.300000,5.100000c-2.800000,0.000000 -5.300000,-2.100000 -5.300000,-5.100000L5.000000,11.000000c0.000000,3.400000 2.700000,6.200000 6.000000,6.700000L11.000000,21.000000l2.000000,0.000000l0.000000,-3.300000c3.300000,-0.500000 6.000000,-3.300000 6.000000,-6.700000L17.299999,11.000001z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM18.08,11c-0.42,0 -0.77,0.3 -0.83,0.71 -0.37,2.61 -2.72,4.39 -5.25,4.39s-4.88,-1.77 -5.25,-4.39a0.839,0.839 0,0 0,-0.83 -0.71c-0.52,0 -0.92,0.46 -0.85,0.97 0.46,2.96 2.96,5.3 5.93,5.75v2.43c0,0.47 0.38,0.85 0.85,0.85h0.31c0.47,0 0.85,-0.38 0.85,-0.85v-2.43c2.96,-0.43 5.47,-2.78 5.93,-5.75a0.87,0.87 0,0 0,-0.86 -0.97z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_mode_edit.xml b/packages/SystemUI/res/drawable/ic_mode_edit.xml
deleted file mode 100644
index f32da59..0000000
--- a/packages/SystemUI/res/drawable/ic_mode_edit.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="20.0dp"
-        android:height="20.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.81,9.94l-3.75,-3.75L3.0,17.25zM20.71,7.04c0.39,-0.3 0.39,-1.02 0.0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
index 17185a7c..bce494c 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,50 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_portrait_to_rotate"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
+                    android:fillColor="#FFFFFFFF" />
             </group>
         </group>
     </group>
 </vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
index 565ef26..b8465f4 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_portrait_to_rotate_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_portrait_to_rotate_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_portrait_to_rotate_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_portrait_to_rotate_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_portrait_to_rotate_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
index 88bf486..0ef15f0 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,53 +14,54 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_rotate_to_portrait"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
     android:viewportWidth="48"
     android:tint="?android:attr/colorControlNormal" >
     <group
-        android:name="icon"
+        android:name="device"
         android:translateX="24"
         android:translateY="24" >
         <group
-            android:name="icon_pivot"
+            android:name="device_pivot"
             android:translateX="-24.15"
             android:translateY="-24.25" >
             <group
-                android:name="arrows"
-                android:translateX="24.1"
-                android:translateY="24.1"
-                android:scaleX="0.9"
-                android:scaleY="0.9"
-                android:rotation="-221" >
-                <group
-                    android:name="arrows_pivot"
-                    android:translateX="-24.1"
-                    android:translateY="-24.1" >
-                    <path
-                        android:name="arrow_top"
-                        android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                    <path
-                        android:name="arrow_bottom"
-                        android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="0" />
-                </group>
-            </group>
-            <group
-                android:name="device"
+                android:name="device_0"
                 android:translateX="24.14999"
                 android:translateY="24.25"
                 android:rotation="-135" >
                 <path
-                    android:name="device_1"
+                    android:name="device_merged"
                     android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                    android:fillColor="#FFFFFFFF" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="arrows"
+        android:translateX="24"
+        android:translateY="24"
+        android:rotation="-221" >
+        <group
+            android:name="arrows_pivot"
+            android:translateX="-24.0798"
+            android:translateY="-24.23" >
+            <group
+                android:name="arrows_0"
+                android:translateX="12.2505"
+                android:translateY="37.2145"
+                android:scaleX="0.9"
+                android:scaleY="0.9" >
+                <path
+                    android:name="bottom_merged"
+                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
                     android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
+                    android:fillAlpha="0" />
             </group>
         </group>
     </group>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
index f75617f..6d3fd37 100644
--- a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
@@ -14,21 +14,22 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+    <target
+        android:name="device_0"
+        android:animation="@anim/ic_rotate_to_portrait_device_0_animation" />
+    <target
+        android:name="device_merged"
+        android:animation="@anim/ic_rotate_to_portrait_device_merged_animation" />
     <target
         android:name="arrows"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" />
+        android:animation="@anim/ic_rotate_to_portrait_arrows_animation" />
     <target
-        android:name="arrow_top"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" />
+        android:name="arrows_0"
+        android:animation="@anim/ic_rotate_to_portrait_arrows_0_animation" />
     <target
-        android:name="arrow_bottom"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" />
-    <target
-        android:name="device"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" />
-    <target
-        android:name="device_1"
-        android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" />
+        android:name="bottom_merged"
+        android:animation="@anim/ic_rotate_to_portrait_bottom_merged_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
index 8a3e975..3eb81f8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal" >
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:pathData="M13.51,12l3.75,-3.74c0.41,-0.41 0.41,-1.07 0,-1.48l-4.47,-4.47 -0.03,-0.03a1.046,1.046 0,0 0,-1.76 0.76v6.44L6.95,5.43c-0.41,-0.41 -1.06,-0.41 -1.47,0s-0.41,1.06 0,1.47l5.09,5.1 -5.09,5.09c-0.41,0.41 -0.41,1.06 0,1.47s1.06,0.41 1.47,0L11,14.51v6.45a1.04,1.04 0,0 0,1.75 0.76l0.05,-0.05 4.46,-4.46c0.41,-0.41 0.41,-1.07 0,-1.48L13.51,12zM12.99,9.67v-4.3l2.15,2.15 -2.15,2.15zM12.99,18.62v-4.3l2.15,2.15 -2.15,2.15zM6.06,13.06c-0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0c0.59,0.59 0.59,1.53 0,2.12zM20.06,10.94c0.59,0.59 0.59,1.54 0,2.12 -0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
index 1dadc05..fbd92de 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal" >
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M28.5,24.0l4.6,4.6c0.6,-1.4 0.9,-3.0 0.9,-4.7c0.0,-1.6 -0.3,-3.2 -0.9,-4.6L28.5,24.0zM39.1,13.4L36.5,16.0c1.3,2.4 2.0,5.1 2.0,8.0s-0.7,5.6 -2.0,8.0l2.4,2.4c1.9,-3.1 3.1,-6.7 3.1,-10.6C42.0,20.0 40.9,16.5 39.1,13.4zM31.4,15.4L20.0,4.0l-2.0,0.0l0.0,15.2L8.8,10.0L6.0,12.8L17.2,24.0L6.0,35.2L8.8,38.0l9.2,-9.2L18.0,44.0l2.0,0.0l11.4,-11.4L22.8,24.0L31.4,15.4zM22.0,11.7l3.8,3.8L22.0,19.2L22.0,11.7zM25.8,32.6L22.0,36.3l0.0,-7.5L25.8,32.6z"/>
+        android:pathData="M14.95,11.3l1.62,-1.61C16.84,10.41 17,11.18 17,12s-0.16,1.61 -0.44,2.33l-1.61,-1.61C14.56,12.33 14.56,11.69 14.95,11.3zM18.69,7.54c-0.26,0.26 -0.32,0.65 -0.17,0.98c0.47,1.07 0.72,2.24 0.72,3.47c0,1.24 -0.26,2.43 -0.73,3.49c-0.14,0.32 -0.09,0.69 0.16,0.94c0.4,0.4 1.09,0.29 1.34,-0.23c0.63,-1.3 0.98,-2.76 0.98,-4.3c-0.01,-1.46 -0.33,-2.86 -0.91,-4.12C19.84,7.23 19.12,7.11 18.69,7.54zM15.26,15.74c0.41,0.41 0.41,1.07 0,1.48l-4.51,4.51C10.57,21.89 10.32,22 10.04,22C9.47,22 9,21.53 9,20.96v-6.45l-4.05,4.05c-0.41,0.41 -1.06,0.41 -1.47,0s-0.41,-1.06 0,-1.47L8.57,12L3.48,6.9c-0.41,-0.41 -0.41,-1.06 0,-1.47s1.06,-0.41 1.47,0L9,9.49V3.04C9,2.47 9.47,2 10.04,2c0.28,0 0.53,0.11 0.72,0.29l4.5,4.5c0.41,0.41 0.41,1.07 0,1.48L11.51,12L15.26,15.74zM13.14,7.53l-2.15,-2.15v4.3C10.99,9.68 13.14,7.53 13.14,7.53zM13.14,16.47l-2.15,-2.15v4.3C10.99,18.62 13.14,16.47 13.14,16.47z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
index 33a4047..e6d6f2c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -16,12 +16,12 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="56dp"
         android:height="56dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
         android:alpha="0.14"
         android:tint="?android:attr/colorForeground">
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
deleted file mode 100644
index 3148a2c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
index 2e9e741..8cc6caa 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,13 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
index b7fe5ab..aaebc77 100644
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     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");
      you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
index fc831f4..ffde286 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -23,5 +23,5 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
index 06a0886..9e57577 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,12 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z"
+        android:fillColor="#FFFFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
index 794eb9e..3dda87c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="64dp"
         android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
+        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
 </vector>
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_dnd_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
new file mode 100644
index 0000000..d71018b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="56dp"
+    android:height="56dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:alpha="0.14"
+    android:tint="?android:attr/colorForeground">
+    <path
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
deleted file mode 100644
index 9168dbc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="64dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:width="64dp" >
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.8,11.1L17.0,11.1l0.0,2.0l-1.2,0.0l4.5,4.5c1.1,-1.6 1.7,-3.5 1.7,-5.5c0.0,-5.5 -4.5,-10.0 -10.0,-10.0c-2.0,0.0 -3.9,0.6 -5.5,1.7L13.8,11.1z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.0,13.1L7.0,13.1l0.0,-2.0l4.0,0.0L4.9,5.0C3.1,6.8 2.0,9.3 2.0,12.1c0.0,5.5 4.5,10.0 10.0,10.0c2.8,0.0 5.3,-1.1 7.1,-2.9L13.0,13.1z" />
-
-    <group
-        android:pivotX="12.0"
-        android:pivotY="12.0"
-        android:rotation="45.0"
-        android:translateX="0.5"
-        android:translateY="0.5" >
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M-2.8,11.8l28.3,0.0l0.0,2.0l-28.3,0.0z" />
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
index f4c20a9..233b9b9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 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,9 +16,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="64dp"
         android:height="64dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
index fb26c09..5012aa4 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2015 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.
@@ -18,12 +18,7 @@
         android:height="64dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
-
+        android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_minus.xml b/packages/SystemUI/res/drawable/ic_qs_minus.xml
index 6a3410a..ead6b03 100644
--- a/packages/SystemUI/res/drawable/ic_qs_minus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_minus.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,12 +15,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp" >
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M38.0,26.0L10.0,26.0l0.0,-4.0l28.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+        android:pathData="M18,13H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h12c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
deleted file mode 100644
index aaca663..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
deleted file mode 100644
index aaca663..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_plus.xml b/packages/SystemUI/res/drawable/ic_qs_plus.xml
index 393f51c..f1b19e1e 100644
--- a/packages/SystemUI/res/drawable/ic_qs_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_plus.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,12 +15,10 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp" >
-
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z" />
-
-</vector>
\ No newline at end of file
+        android:pathData="M18,13h-5v5c0,0.55 -0.45,1 -1,1h0c-0.55,0 -1,-0.45 -1,-1v-5H6c-0.55,0 -1,-0.45 -1,-1v0c0,-0.55 0.45,-1 1,-1h5V6c0,-0.55 0.45,-1 1,-1h0c0.55,0 1,0.45 1,1v5h5c0.55,0 1,0.45 1,1v0C19,12.55 18.55,13 18,13z"/>
+</vector>
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/ic_qs_wifi_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
index e6f9292..7cbc26f 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_0.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.
@@ -14,15 +14,19 @@
     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:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
index d423ccb..675dfc9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_1.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.
@@ -14,18 +14,19 @@
     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:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,13.2c-0.1,0.0 -0.3,-0.1 -0.4,-0.1c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,0.0 -0.6,-0.1 -0.9,-0.1c0.0,0.0 0.0,0.0 -0.1,0.0c0.0,0.0 0.0,0.0 0.0,0.0s0.0,0.0 0.0,0.0c0.0,0.0 0.0,0.0 -0.1,0.0c-0.3,0.0 -0.6,0.0 -0.9,0.1c-0.1,0.0 -0.3,0.0 -0.4,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.1,0.0 -0.1,0.0 -0.2,0.1c-1.6,0.5 -2.7,1.3 -2.8,1.5l5.3,6.6l0.0,0.0l0.0,0.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.700002,13.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-5.1,-6.35C7.65,13.85 9.72,13 12,13c0.69,0 1.36,0.08 2,0.23V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
index 1982130..c9a7eb8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_2.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.
@@ -14,18 +14,19 @@
     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:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l4.9,0.0c-1.0,-0.7 -3.4,-2.2 -6.7,-2.2c-4.1,0.0 -6.9,2.2 -7.2,2.5l7.2,9.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.800001,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.800001,1.9 -1.800001,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-6.98,-8.7C6.28,11.1 9.01,10 12,10c2.45,0 4.72,0.74 6.62,2H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
index b350111..a6facae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_3.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.
@@ -14,18 +14,19 @@
     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:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0l1.0,-1.2C20.0,10.6 16.8,8.0 12.0,8.0s-8.0,2.6 -8.5,3.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillAlpha="0.3"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFF"/>
+        <path
+            android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0L2.93,11.35C5.37,9.26 8.54,8 12,8c3.46,0 6.62,1.26 9.07,3.34L20.54,12H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
index 136a004..2eae8f5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_4.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.
@@ -14,14 +14,15 @@
     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:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="#FFFFFF"/>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="25.50"
+    android:viewportHeight="25.50">
+    <group
+        android:translateX="0.77"
+        android:translateY="0.23" >
+        <path
+            android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67zM14,12h6.54l3.12,-3.89c0.39,-0.48 0.28,-1.19 -0.23,-1.54C21.66,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
index 7993c80..95345b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,17 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="56dp"
-        android:height="56dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0"
-        android:alpha="0.14"
-        android:tint="?android:attr/colorForeground">
-
-    <path
-        android:pathData="M24.0,4.0C15.0,4.0 6.7,7.0 0.0,12.0l24.0,32.0l24.0,-32.0C41.3,7.0 33.0,4.0 24.0,4.0z"
-        android:fillColor="#FFFFFF" />
+    android:width="56dp"
+    android:height="56dp"
+    android:viewportWidth="25.0"
+    android:viewportHeight="23.5"
+    android:alpha="0.14"
+    android:tint="?android:attr/colorForeground" >
+    <group
+        android:translateX="0.51"
+        android:translateY="-1.1">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
index 70e4780..ea02ba7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,16 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"
-        android:fillAlpha=".3"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"
-        android:fillAlpha=".3"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="1.1">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
index 2dcdb71..cb87cae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.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.
@@ -14,29 +14,19 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="26.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.0,8.5
-        c0.85,0.0 1.6,0.23 2.3,0.62l2.24,-2.79
-        C25.1,5.96 20.26,2.0 13.0,2.0
-        S0.9,5.9 0.42,6.32
-        l12.57,15.6 4.21,-5.17
-        c-0.76,-0.87 -1.22,-2.0 -1.22,-3.25
-        c0.0,-2.76 2.24,-5.0 5.0,-5.0z"
-        android:fillAlpha=".3"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.0,10.0
-        c-1.93,0.0 -3.5,1.57 -3.5,3.5l1.75,0.0
-        c0.0,-0.9 0.78,-1.75 1.75,-1.75s1.7,0.78 1.75,1.75
-        c0.0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1
-        c-0.6,0.63 -1.02,1.51 -1.02,2.47l0.0,0.44l1.75,0.0
-        c0.0,-1.3 0.39,-1.84 1.03,-2.47l0.78,-0.8
-        c0.5,-0.5 0.82,-1.2 0.82,-1.97
-        C24.5,11.57 22.93,10.0 21.0,10.0z
-        m-0.95,11.95l1.9,0.0l0.0,-1.9l-1.9,0.0l0.0,1.9z"/>
+    android:width="26dp"
+    android:height="24dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.7">
+    <group
+        android:translateX="0.82"
+        android:translateY="-1">
+        <path
+            android:pathData="M18.9,20.85c0,-0.61 0.49,-1.1 1.1,-1.1 0.61,0 1.1,0.49 1.1,1.1 0,0.61 -0.49,1.1 -1.1,1.1 -0.61,0 -1.1,-0.49 -1.1,-1.1zM20,10c-1.53,0 -2.84,0.99 -3.31,2.36 -0.19,0.56 0.23,1.14 0.81,1.14 0.36,0 0.72,-0.21 0.84,-0.55 0.23,-0.7 0.89,-1.2 1.66,-1.2 0.97,0 1.75,0.78 1.75,1.75 0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1c-0.69,0.69 -0.92,1.38 -0.99,2.2 -0.04,0.51 0.36,0.96 0.88,0.96 0.44,0 0.83,-0.33 0.87,-0.77 0.07,-0.79 0.31,-1.27 1,-1.95l0.78,-0.8c0.5,-0.5 0.82,-1.2 0.82,-1.97C23.5,11.57 21.93,10 20,10z"
+            android:fillColor="#FFFFFFFF"/>
+        <path
+            android:pathData="M14.73,12.88c0,-2.7 2.19,-4.88 4.88,-4.88 1.22,0 2.32,0.46 3.18,1.2l0.88,-1.09c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0l3.88,-4.82a4.862,4.862 0,0 1,-1.97 -3.9z"
+            android:fillAlpha="0.3"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
index 1bc7438..53e4efc 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32.0dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
index 5856115..8294183 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.100000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.500000,6.500000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.100000,22.000000l5.500000,-6.800000c-0.200000,-0.200000 -2.300000,-1.900000 -5.500000,-1.900000s-5.300000,1.800000 -5.500000,1.900000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l5.11,-6.36A8.942,8.942 0,0 0,12 13c-2.28,0 -4.35,0.85 -5.94,2.25l5.1,6.35c0.43,0.53 1.23,0.53 1.66,0z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
index 4a5e1f8..3d59cf2 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000l7.600000,-9.400000C20.299999,12.400000 17.400000,10.000000 13.000000,10.000000s-7.300000,2.400000 -7.600000,2.700000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l6.99,-8.7C17.71,11.1 14.99,10 12,10c-2.99,0 -5.72,1.1 -7.82,2.91l6.98,8.7c0.43,0.52 1.23,0.52 1.66,-0.01z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
index 965442d..21313b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000l9.200000,-11.400000c-0.400000,-0.300000 -3.900000,-3.200000 -9.200000,-3.200000s-8.900000,3.000000 -9.200000,3.200000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#4DFFFFFF"/>
+        <path
+            android:pathData="M12.82,21.6l8.25,-10.26A13.961,13.961 0,0 0,12 8c-3.46,0 -6.63,1.26 -9.07,3.35l8.23,10.26c0.43,0.52 1.23,0.52 1.66,-0.01z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
index b29d3f9..fd763ff 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6">
+    <group
+        android:translateX="0.8"
+        android:translateY="-0.9">
+        <path
+            android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings.xml b/packages/SystemUI/res/drawable/ic_settings.xml
index 9c78742..6d24c7e 100644
--- a/packages/SystemUI/res/drawable/ic_settings.xml
+++ b/packages/SystemUI/res/drawable/ic_settings.xml
@@ -1,4 +1,4 @@
-<!-- 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");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at"+
@@ -13,14 +13,11 @@
 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:viewportHeight="24.0">
-
-
-<path
-     android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
-     android:fillColor="#ffffffff"
-     />
-
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_16dp.xml b/packages/SystemUI/res/drawable/ic_settings_16dp.xml
index c21b60c..e3ed229 100644
--- a/packages/SystemUI/res/drawable/ic_settings_16dp.xml
+++ b/packages/SystemUI/res/drawable/ic_settings_16dp.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.
@@ -19,6 +19,6 @@
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
     <path
-        android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
-        android:fillColor="#ffffffff" />
+        android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane.xml b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
new file mode 100644
index 0000000..50dd436
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
@@ -0,0 +1,30 @@
+<?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="48dp"
+    android:height="48dp"
+    android:viewportWidth="20.5"
+    android:viewportHeight="20.5">
+    <group
+        android:translateX="0.985"
+        android:translateY="1.10">
+        <path
+            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+            android:fillColor="#FF0"/>
+    </group>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
deleted file mode 100644
index 09a67e1..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
+++ /dev/null
@@ -1,57 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_airplane"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_airplane_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="plane"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="plane_1"
-                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
deleted file mode 100644
index 56ae4aa..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_airplane_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_airplane_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_airplane_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
deleted file mode 100644
index b7ac0134..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_airplane"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_airplane_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="plane"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="plane_1"
-                    android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
deleted file mode 100644
index 87dfba9..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_airplane_enable" >
-    <target
-        android:name="ic_signal_airplane"
-        android:animation="@anim/ic_signal_airplane_enable_animation_ic_signal_airplane" />
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_airplane_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_airplane_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml
new file mode 100644
index 0000000..38979a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight.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="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateX="-0.05"
+        android:translateY="0.85" >
+        <path
+            android:pathData="M8.28,2h7.43c0.55,0 1,0.45 1,1v0.96L7.28,3.96L7.28,3c0,-0.55 0.45,-1 1,-1zM14.8,9.76L14.8,21c0,0.55 -0.45,1 -1,1h-3.61c-0.55,0 -1,-0.45 -1,-1L9.19,9.78c-2.2,-1.17 -1.91,-3.76 -1.91,-3.76L7.28,5.7h9.44v0.32s0.26,2.57 -1.92,3.74zM13.38,12.47c0,-0.76 -0.62,-1.38 -1.38,-1.38s-1.38,0.62 -1.38,1.38 0.62,1.38 1.38,1.38 1.38,-0.62 1.38,-1.38z"
+            android:fillColor="#FFFFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
deleted file mode 100644
index 35844b7..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
+++ /dev/null
@@ -1,57 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_flashlight"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_flashlight_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="flashlight"
-                android:translateX="25.06235"
-                android:translateY="22.48294" >
-                <path
-                    android:name="light"
-                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
deleted file mode 100644
index e228b7c..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_flashlight_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_flashlight_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_flashlight_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
deleted file mode 100644
index c2215f1..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_flashlight"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_flashlight_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="flashlight"
-                android:translateX="25.06235"
-                android:translateY="22.48294" >
-                <path
-                    android:name="light"
-                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
deleted file mode 100644
index 220c65e..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_flashlight_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_flashlight_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_flashlight_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
deleted file mode 100644
index 439851d..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
+++ /dev/null
@@ -1,57 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:alpha="1.0"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_location"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_location_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="0"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="location"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="pin"
-                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
deleted file mode 100644
index 0e9d1cb..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_location_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_location_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_location_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
deleted file mode 100644
index d4b8673..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_signal_location"
-        android:translateX="21.9995"
-        android:translateY="25.73401" >
-        <group
-            android:name="ic_signal_location_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="location"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <path
-                    android:name="pin"
-                    android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
-                    android:fillColor="#FFFFFFFF"
-                    android:fillAlpha="1" />
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
deleted file mode 100644
index 9f1d917..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_location_enable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_location_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_location_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
deleted file mode 100644
index 9c23126..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
+++ /dev/null
@@ -1,25 +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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_workmode_disable" >
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_workmode_disable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_workmode_disable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
deleted file mode 100644
index 04ddfad..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/ic_signal_workmode_enable" >
-    <target
-        android:name="ic_signal_briefcase"
-        android:animation="@anim/ic_signal_workmode_enable_animation_ic_signal_briefcase" />
-    <target
-        android:name="mask"
-        android:animation="@anim/ic_signal_workmode_enable_animation_mask" />
-    <target
-        android:name="cross_1"
-        android:animation="@anim/ic_signal_workmode_enable_animation_cross_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
index e64f445..996e488 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z" />
+        android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
index 37d7690..02fb1e7 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,13 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal" >
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z" />
+        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
index 5c3c650..b0b9404 100644
--- a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,16 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24.0dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:width="24.0dp"
     android:tint="?android:attr/colorControlNormal" >
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M29.41,19.0L34.0,14.41L34.0,22.0l1.0,0.0l5.71,-5.71 -4.3,-4.29 4.29,-4.29L35.0,2.0l-1.0,0.0l0.0,7.59L29.41,5.0 28.0,6.41 33.59,12.0 28.0,17.59 29.41,19.0zM36.0,5.83l1.88,1.88L36.0,9.59L36.0,5.83zm0.0,8.58l1.88,1.88L36.0,18.17l0.0,-3.76zM40.0,31.0c-2.49,0.0 -4.89,-0.4 -7.14,-1.14 -0.69,-0.22 -1.48,-0.06 -2.0,0.49l-4.4,4.41c-5.67,-2.88 -10.29,-7.51 -13.18,-13.17l4.4,-4.41c0.55,-0.5 0.71,-1.3 0.49,-2.03C17.4,12.9 17.0,10.49 17.0,8.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0L8.0,6.0c-1.11,0.0 -2.0,0.89 -2.0,2.0 0.0,18.78 15.22,34.0 34.0,34.0 1.11,0.0 2.0,-0.89 2.0,-2.0l0.0,-7.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0z" />
+        android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57c-0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1H4C3.45,3 3,3.45 3,4c0,9.39 7.61,17 17,17c0.55,0 1,-0.45 1,-1v-3.5C21,15.95 20.55,15.5 20,15.5z"/>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.97,6l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L17.6,1.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L16.49,6l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L17.97,6zM17.75,2.78l0.99,0.99l-0.99,0.99V2.78zM17.75,9.23V7.27l0.99,0.99L17.75,9.23z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_collapse.xml b/packages/SystemUI/res/drawable/ic_volume_collapse.xml
index 0f488a4..3853d12 100644
--- a/packages/SystemUI/res/drawable/ic_volume_collapse.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_collapse.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -13,51 +13,43 @@
      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:name="ic_volume_collapse"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_caret_down"
+    android:width="24dp"
+    android:viewportWidth="24"
     android:height="24dp"
     android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
-
     <group
-        android:name="chevron_02"
-        android:rotation="90"
-        android:translateX="12"
-        android:translateY="9" >
+        android:name="caret___4" >
         <group
-            android:name="rectangle_2"
-            android:rotation="-45" >
+            android:name="right"
+            android:translateX="11.287"
+            android:translateY="8.701"
+            android:rotation="45" >
             <group
-                android:name="rectangle_2_pivot"
-                android:translateY="4" >
-                <group
-                    android:name="rectangle_path_2_position"
-                    android:translateY="-1" >
-                    <path
-                        android:name="rectangle_path_2"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="right_pivot"
+                android:translateX="4.242" >
+                <path
+                    android:name="rectangle_path_1"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
         <group
-            android:name="rectangle_1"
-            android:rotation="45" >
+            android:name="left"
+            android:translateX="12.699"
+            android:translateY="8.701"
+            android:rotation="-45" >
             <group
-                android:name="rectangle_1_pivot"
-                android:translateY="-4" >
-                <group
-                    android:name="rectangle_path_1_position"
-                    android:translateY="1" >
-                    <path
-                        android:name="rectangle_path_1"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="left_pivot"
+                android:translateX="-4.242" >
+                <path
+                    android:name="rectangle_path_2"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
     </group>
-
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml b/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
index 5c482bc..18c6307 100644
--- a/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_collapse_animation.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -13,17 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_volume_collapse" >
-
     <target
-        android:name="chevron_02"
-        android:animation="@anim/ic_volume_collapse_chevron_02_animation" />
+        android:name="right"
+        android:animation="@anim/ic_caret_down_right_animation" />
     <target
-        android:name="rectangle_2"
-        android:animation="@anim/ic_volume_collapse_rectangle_2_animation" />
-    <target
-        android:name="rectangle_1"
-        android:animation="@anim/ic_volume_collapse_rectangle_1_animation" />
-
-</animated-vector>
\ No newline at end of file
+        android:name="left"
+        android:animation="@anim/ic_caret_down_left_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_expand.xml b/packages/SystemUI/res/drawable/ic_volume_expand.xml
index 70ff1f3..79ff808 100644
--- a/packages/SystemUI/res/drawable/ic_volume_expand.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_expand.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -13,51 +13,43 @@
      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:name="ic_volume_expand"
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_caret_up"
+    android:width="24dp"
+    android:viewportWidth="24"
     android:height="24dp"
     android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
-
     <group
-        android:name="chevron_01"
-        android:rotation="90"
-        android:translateX="12"
-        android:translateY="15" >
+        android:name="caret___4" >
         <group
-            android:name="rectangle_3"
-            android:rotation="45" >
+            android:name="right"
+            android:translateX="11.287"
+            android:translateY="15.287"
+            android:rotation="-45" >
             <group
-                android:name="rectangle_2_pivot_0"
-                android:translateY="4" >
-                <group
-                    android:name="rectangle_path_3_position"
-                    android:translateY="-1" >
-                    <path
-                        android:name="rectangle_path_3"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="right_pivot"
+                android:translateX="4.242" >
+                <path
+                    android:name="rectangle_path_1"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
         <group
-            android:name="rectangle_4"
-            android:rotation="-45" >
+            android:name="left"
+            android:translateX="12.699"
+            android:translateY="15.287"
+            android:rotation="45" >
             <group
-                android:name="rectangle_1_pivot_0"
-                android:translateY="-4" >
-                <group
-                    android:name="rectangle_path_4_position"
-                    android:translateY="1" >
-                    <path
-                        android:name="rectangle_path_4"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -1.0,-4.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-8.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
+                android:name="left_pivot"
+                android:translateX="-4.242" >
+                <path
+                    android:name="rectangle_path_2"
+                    android:fillColor="#FFFFFFFF"
+                    android:pathData="M -3.242,-1.0 l 6.484,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l -6.484,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
             </group>
         </group>
     </group>
-
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml b/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
index ae2d7e4..abd6678 100644
--- a/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_expand_animation.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -13,17 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/ic_volume_expand" >
-
     <target
-        android:name="chevron_01"
-        android:animation="@anim/ic_volume_expand_chevron_01_animation" />
+        android:name="right"
+        android:animation="@anim/ic_caret_up_right_animation" />
     <target
-        android:name="rectangle_3"
-        android:animation="@anim/ic_volume_expand_rectangle_3_animation" />
-    <target
-        android:name="rectangle_4"
-        android:animation="@anim/ic_volume_expand_rectangle_4_animation" />
-
-</animated-vector>
\ No newline at end of file
+        android:name="left"
+        android:animation="@anim/ic_caret_up_left_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml
index d689207..53c0740 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M12.0,3.0l0.0,9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12.0 6.0,14.01 6.0,16.5S8.01,21.0 10.5,21.0c2.31,0.0 4.2,-1.75 4.45,-4.0L15.0,17.0L15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0z" />
+        android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
index 9b7b2da..60d0184 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M17.0,3.0l-7.0,0.0l0.0,9.3C9.5,12.1 9.0,12.0 8.5,12.0C6.0,12.0 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0s4.5,-2.3 4.5,-4.5C13.0,14.7 13.0,6.0 13.0,6.0l4.0,0.0L17.0,3.0z"/>
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+        android:pathData="M16,3h-5c-0.55,0 -1,0.45 -1,1v8.3c-0.93,-0.39 -1.96,-0.4 -2.9,-0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26C4,19 6.01,21 8.49,21c0,0 0.01,0 0.01,0c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4C17,3.45 16.55,3 16,3zM20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l0.02,-0.02l2.23,-2.23c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,10.75V8.78l0.99,0.99L20.75,10.75zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
index 17ac01d..49fcfc4 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,12 +22,12 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M13.0,6.0l4.0,0.0L17.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C13.0,8.8 13.0,6.0 13.0,6.0z"/>
+        android:pathData="M13,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6z"/>
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M2.1,5.7L8.4,12.0C6.0,12.1 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3l0.0,-0.1l3.9,3.9l1.3,-1.3L3.4,4.5L2.1,5.7z"/>
+        android:pathData="M4,5.1C3.67,4.76 3.12,4.75 2.78,5.08C2.41,5.42 2.4,6 2.75,6.35L8.4,12C6,12.1 4,14 4,16.5c0,2.51 2.33,4.67 4.84,4.48C11.35,20.81 13,18.62 13,16.7v-0.1l3.27,3.27c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L4,5.1z"/>
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+        android:pathData="M20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,8.78l0.99,0.99l-0.99,0.98V8.78zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
index 267d09d..ebb86e8 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C15.0,8.8 15.0,6.0 15.0,6.0z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4.8,3.9L3.5,5.1l6.9,6.9C8.0,12.1 6.0,14.0 6.0,16.5C6.0,19.0 8.0,21.0 10.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3c0.0,0.0 0.0,-0.1 0.0,-0.1l4.0,4.0l1.3,-1.3L4.8,3.9z" />
+        android:pathData="M15,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6zM4.18,4.48c-0.37,0.34 -0.38,0.92 -0.03,1.27L10.4,12C8,12.1 6,14 6,16.5c0,2.51 2.33,4.67 4.84,4.48 2.51,-0.17 4.16,-2.36 4.16,-4.28v-0.1l3.37,3.37c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L5.4,4.5a0.866,0.866 0,0 0,-1.22 -0.02z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
index 18af711..f258856 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,17 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
+    android:viewportHeight="23.4"
+    android:viewportWidth="23.4"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
 
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z" />
+    <group
+        android:translateX="-0.78"
+        android:translateY="-0.5" >
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/>
+    </group>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
index bc926c3..106d899 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -15,13 +15,23 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="24dp"
-    android:viewportHeight="48.0"
-    android:viewportWidth="48.0"
+    android:viewportHeight="23.4"
+    android:viewportWidth="23.3"
     android:width="24dp"
     android:tint="?android:attr/colorControlNormal" >
 
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z" />
+    <group
+        android:translateX="-0.85"
+        android:translateY="-0.5" >
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M20.73,19.46l-0.6,-0.6c0,0 0,0 0,0L5.54,4.26c-0.35,-0.35 -0.92,-0.35 -1.27,0c-0.35,0.35 -0.35,0.92 0,1.27l2.4,2.4C6.25,8.85 6,9.88 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h13.53l1.73,1.73c0.35,0.35 0.92,0.35 1.27,0C21.09,20.38 21.09,19.81 20.73,19.46z"/>
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.87,4.83 9.31,5.08 8.8,5.4l9.2,9.2V11z"/>
+        <path
+            android:fillColor="#FF0"
+            android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+    </group>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
index ffbffad..9db8511 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
@@ -1,5 +1,5 @@
 <!--
-     Copyright (C) 2015 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.
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z" />
+        android:pathData="M1,15c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM4,17c0.55,0 1,-0.45 1,-1L5,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM22,10v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1zM20,17c0.55,0 1,-0.45 1,-1L21,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM16.5,3h-9C6.67,3 6,3.67 6,4.5v15c0,0.83 0.67,1.5 1.5,1.5h9c0.83,0 1.5,-0.67 1.5,-1.5v-15c0,-0.83 -0.67,-1.5 -1.5,-1.5zM16,19L8,19L8,5h8v14z"/>
 
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
index 81da26d..8d382a3 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_off.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 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.
@@ -34,7 +34,7 @@
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -44,7 +44,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -54,7 +54,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -64,7 +64,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -76,7 +76,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
index 8b517b6..4fe160d 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_draw_on.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 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.
@@ -34,7 +34,7 @@
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -45,7 +45,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -56,7 +56,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -67,7 +67,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -80,7 +80,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
index 3af2f7f..832716a 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 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,26 +16,28 @@
   -->
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="lockscreen_fingerprint_error_state_to_fp"
+    android:name="ic_fingerprint_tofp"
     android:width="32dp"
-    android:viewportWidth="32"
+    android:viewportWidth="24"
     android:height="32dp"
-    android:viewportHeight="32" >
+    android:viewportHeight="24" >
     <group
-        android:name="white_fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75"
-        android:rotation="200.66753" >
+        android:name="fingerprintwhite"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738"
+        android:rotation="180" >
         <group
-            android:name="white_fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprintwhite_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_5" >
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -46,18 +48,18 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
-                    android:trimPathStart="1" />
+                    android:trimPathEnd="0" />
             </group>
             <group
                 android:name="ridge_3" >
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -68,7 +70,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -81,7 +83,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round"
@@ -90,37 +92,39 @@
         </group>
     </group>
     <group
-        android:name="exclamation"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="10" >
         <group
-            android:name="group_2" >
+            android:name="circle" >
             <path
-                android:name="path_2"
-                android:pathData="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z"
-                android:fillColor="?android:attr/colorError" />
-            <path
-                android:name="path_1"
-                android:pathData="M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
-                android:fillColor="?android:attr/colorError" />
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
     <group
-        android:name="circle_outline"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
         <group
-            android:name="group_1"
-            android:scaleX="1.12734"
-            android:scaleY="1.12734"
-            android:rotation="430" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="path_3"
-                android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
-                android:strokeColor="?android:attr/colorError"
-                android:strokeWidth="2"
-                android:trimPathStart="0"
-                android:trimPathEnd="1" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-1.1 l 0.0,0.0 c 0.60751322478,0.0 1.1,0.49248677522 1.1,1.1 l 0.0,0.0 c 0.0,0.60751322478 -0.49248677522,1.1 -1.1,1.1 l 0.0,0.0 c -0.60751322478,0.0 -1.1,-0.49248677522 -1.1,-1.1 l 0.0,0.0 c 0.0,-0.60751322478 0.49248677522,-1.1 1.1,-1.1 Z" />
+        </group>
+        <group
+            android:name="exclamationtop"
+            android:translateY="-2" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-3.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,4.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,-4.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
index 0351524..2f33306 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_to_fp_animation.xml
@@ -1,53 +1,59 @@
 <?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
-  -->
+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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/lockscreen_fingerprint_error_state_to_fp" >
     <target
-        android:name="white_fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_white_fingerprint_ridges_animation" />
+        android:name="fingerprintwhite"
+        android:animation="@anim/ic_fingerprint_tofp_fingerprintwhite_animation" />
     <target
         android:name="ridge_5_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_5_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_5_path_animation" />
     <target
         android:name="ridge_7_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_7_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_7_path_animation" />
     <target
         android:name="ridge_6_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_6_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_6_path_animation" />
     <target
         android:name="ridge_2_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_2_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_2_path_animation" />
     <target
         android:name="ridge_1_path"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_ridge_1_path_animation" />
+        android:animation="@anim/ic_fingerprint_tofp_ridge_1_path_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_group_2_animation" />
+        android:name="errorcircle"
+        android:animation="@anim/ic_fingerprint_tofp_errorcircle_animation" />
     <target
-        android:name="path_2"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_2_animation" />
+        android:name="circlepath"
+        android:animation="@anim/ic_fingerprint_tofp_circlepath_animation" />
     <target
-        android:name="path_1"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_1_animation" />
+        android:name="errorexclamation"
+        android:animation="@anim/ic_fingerprint_tofp_errorexclamation_animation" />
     <target
-        android:name="group_1"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_group_1_animation" />
+        android:name="exclamationbottom"
+        android:animation="@anim/ic_fingerprint_tofp_exclamationbottom_animation" />
     <target
-        android:name="path_3"
-        android:animation="@anim/lockscreen_fingerprint_error_state_to_fp_path_3_animation" />
+        android:name="bottompath"
+        android:animation="@anim/ic_fingerprint_tofp_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/ic_fingerprint_tofp_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/ic_fingerprint_tofp_toppath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
index a577afc..7cc2e5c 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state.xml
@@ -1,40 +1,42 @@
 <?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
-  -->
+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:name="lockscreen_fingerprint_fp_to_error_state"
+    android:name="ic_fingerprint_toerror"
     android:width="32dp"
-    android:viewportWidth="32"
+    android:viewportWidth="24"
     android:height="32dp"
-    android:viewportHeight="32" >
+    android:viewportHeight="24" >
     <group
-        android:name="white_fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75" >
+        android:name="fingerprintwhite"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
         <group
-            android:name="white_fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprintwhite_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_5" >
                 <path
                     android:name="ridge_5_path"
                     android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -44,7 +46,7 @@
                 <path
                     android:name="ridge_7_path"
                     android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -54,7 +56,7 @@
                 <path
                     android:name="ridge_6_path"
                     android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -64,7 +66,7 @@
                 <path
                     android:name="ridge_2_path"
                     android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -76,7 +78,7 @@
                 <path
                     android:name="ridge_1_path"
                     android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
-                    android:strokeColor="#FFFFFFFF"
+                    android:strokeColor="?attr/wallpaperTextColor"
                     android:strokeAlpha="0.5"
                     android:strokeWidth="1.45"
                     android:strokeLineCap="round" />
@@ -84,13 +86,15 @@
         </group>
     </group>
     <group
-        android:name="fingerprint_ridges"
-        android:translateX="16.125"
-        android:translateY="19.75" >
+        android:name="fingerprinterror"
+        android:translateX="12"
+        android:translateY="12.4"
+        android:scaleX="0.738"
+        android:scaleY="0.738" >
         <group
-            android:name="fingerprint_ridges_pivot"
-            android:translateX="33.2085"
-            android:translateY="30.91685" >
+            android:name="fingerprinterror_pivot"
+            android:translateX="33"
+            android:translateY="34" >
             <group
                 android:name="ridge_6" >
                 <path
@@ -146,39 +150,40 @@
         </group>
     </group>
     <group
-        android:name="exclamation"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="190" >
         <group
-            android:name="group_2"
-            android:scaleX="0.63838"
-            android:scaleY="0.63838"
-            android:rotation="184" >
+            android:name="circle" >
             <path
-                android:name="path_2"
-                android:pathData="M -1.3705291748,4.06730651855 c 0.0,0.0 0.036376953125,-0.0102386474609 0.036376953125,-0.0102386474609 c 0.0,0.0 -0.00682067871094,0.0040283203125 -0.00682067871093,0.0040283203125 c 0.0,0.0 -0.0161437988281,0.00479125976562 -0.0161437988281,0.00479125976563 c 0.0,0.0 -0.0134124755859,0.00141906738281 -0.0134124755859,0.00141906738281 Z"
-                android:fillColor="?android:attr/colorError" />
-            <path
-                android:name="path_1"
-                android:pathData="M -1.3737487793,-6.77532958984 c 0.0,0.0 0.00604248046875,0.0166625976562 0.00604248046876,0.0166625976562 c 0.0,0.0 0.0213623046875,0.0250244140625 0.0213623046875,0.0250244140625 c 0.0,0.0 -0.00604248046875,-0.0166625976562 -0.00604248046876,-0.0166625976562 c 0.0,0.0 -0.0213623046875,-0.0250244140625 -0.0213623046875,-0.0250244140625 Z"
-                android:fillColor="?android:attr/colorError" />
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:trimPathStart="1"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
     <group
-        android:name="circle_outline"
-        android:translateX="16"
-        android:translateY="16" >
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="180" >
         <group
-            android:name="group_1"
-            android:scaleX="1.12734"
-            android:scaleY="1.12734"
-            android:rotation="231" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="path_3"
-                android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
-                android:strokeColor="?android:attr/colorError"
-                android:strokeWidth="2"
-                android:trimPathStart="1" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+        </group>
+        <group
+            android:name="exclamationtop" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M -1.0,0.0 l 2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
index f7b710f..38096a9 100644
--- a/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_fp_to_error_state_animation.xml
@@ -1,71 +1,77 @@
 <?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
-  -->
+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.
+-->
 <animated-vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:drawable="@drawable/lockscreen_fingerprint_fp_to_error_state" >
     <target
-        android:name="white_fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_white_fingerprint_ridges_animation" />
+        android:name="fingerprintwhite"
+        android:animation="@anim/ic_fingerprint_toerror_fingerprintwhite_animation" />
     <target
         android:name="ridge_5_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_5_path_animation" />
     <target
         android:name="ridge_7_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_7_path_animation" />
     <target
         android:name="ridge_6_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_6_path_animation" />
     <target
         android:name="ridge_2_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_2_path_animation" />
     <target
         android:name="ridge_1_path"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_1_path_animation" />
     <target
-        android:name="fingerprint_ridges"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_fingerprint_ridges_animation" />
+        android:name="fingerprinterror"
+        android:animation="@anim/ic_fingerprint_toerror_fingerprinterror_animation" />
     <target
         android:name="ridge_5_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_5_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_5_path_0_animation" />
     <target
         android:name="ridge_7_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_7_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_7_path_0_animation" />
     <target
         android:name="ridge_6_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_6_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_6_path_0_animation" />
     <target
         android:name="ridge_2_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_2_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_2_path_0_animation" />
     <target
         android:name="ridge_1_path_0"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_ridge_1_path_0_animation" />
+        android:animation="@anim/ic_fingerprint_toerror_ridge_1_path_0_animation" />
     <target
-        android:name="group_2"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_group_2_animation" />
+        android:name="errorcircle"
+        android:animation="@anim/ic_fingerprint_toerror_errorcircle_animation" />
     <target
-        android:name="path_2"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_2_animation" />
+        android:name="circlepath"
+        android:animation="@anim/ic_fingerprint_toerror_circlepath_animation" />
     <target
-        android:name="path_1"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_1_animation" />
+        android:name="errorexclamation"
+        android:animation="@anim/ic_fingerprint_toerror_errorexclamation_animation" />
     <target
-        android:name="group_1"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_group_1_animation" />
+        android:name="exclamationbottom"
+        android:animation="@anim/ic_fingerprint_toerror_exclamationbottom_animation" />
     <target
-        android:name="path_3"
-        android:animation="@anim/lockscreen_fingerprint_fp_to_error_state_path_3_animation" />
+        android:name="bottompath"
+        android:animation="@anim/ic_fingerprint_toerror_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/ic_fingerprint_toerror_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/ic_fingerprint_toerror_toppath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 8ea9e06..03bba53 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -15,6 +15,6 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android">
     <shape>
-        <solid android:color="?android:attr/colorPrimary"/>
+        <solid android:color="@color/qs_background_dark"/>
     </shape>
 </inset>
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
index 951269b..b837ebe 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_dark.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_dark_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_dark_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_dismiss_light.xml b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
index 1f44c1c..2b20814 100644
--- a/packages/SystemUI/res/drawable/recents_dismiss_light.xml
+++ b/packages/SystemUI/res/drawable/recents_dismiss_light.xml
@@ -14,11 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48.0dp"
-        android:height="48.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:fillColor="@color/recents_task_bar_light_icon_color"
-        android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/>
+android:width="24dp"
+android:height="24dp"
+android:viewportWidth="24"
+android:viewportHeight="24">
+
+<path
+    android:fillColor="@color/recents_task_bar_light_icon_color"
+    android:pathData="M18.3 5.71a.996 .996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996 .996 0 1 0 5.7
+7.11L10.59 12 5.7 16.89a.996 .996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996 .996 0
+1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38 .38 -1.02 0-1.4z" />
+<path
+    android:pathData="M0 0h24v24H0z" />
 </vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/rounded.xml b/packages/SystemUI/res/drawable/rounded.xml
new file mode 100644
index 0000000..ef7aea7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    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="8dp"
+    android:height="8dp"
+    android:viewportWidth="8"
+    android:viewportHeight="8">
+
+    <path
+        android:fillColor="#000000"
+        android:pathData="M8,0H0v8C0,3.6,3.6,0,8,0z" />
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/rounded_bg.xml b/packages/SystemUI/res/drawable/rounded_bg.xml
new file mode 100644
index 0000000..c23a87f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimary" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
new file mode 100644
index 0000000..b3bea63
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimaryDark" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full.xml b/packages/SystemUI/res/drawable/rounded_bg_full.xml
new file mode 100644
index 0000000..a6f40fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_full.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimary" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="@dimen/corner_size"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
new file mode 100644
index 0000000..c3e36f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimaryDark" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
index 433da5f..2655bcd 100644
--- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
@@ -1,28 +1,31 @@
+<?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
-  -->
+**
+** Copyright 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="17.25dp"
-        android:height="18dp"
-        android:viewportWidth="46.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M20.4,18.0"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,32.0l0.0,-4.0L26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,11.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0L26.0,27.0L42.0,32.0z"/>
+    android:width="17.25dp"
+    android:height="18dp"
+    android:viewportWidth="19.65"
+    android:viewportHeight="20.5">
+    <group
+        android:translateX="1.3"
+        android:translateY="1.7">
+        <path
+            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
index 48c2222..0e9319c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
@@ -1,29 +1,35 @@
+<?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
-  -->
+**
+** Copyright 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.
+*/
+-->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
     android:insetRight="2.5dp">
-    <vector xmlns:android="http://schemas.android.com/apk/res/android"
+    <vector
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#ffffffff"
-            android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:viewportWidth="19.3"
+        android:viewportHeight="19.3">
+        <group
+            android:translateX="1.2"
+            android:translateY="1.2">
+            <path
+                android:pathData="M0.97,3.97c-0.32,-0.33 -0.24,-0.81 0.08,-1.13L3.47,0.74C3.79,0.42 4.28,0.5 4.6,0.82s0.24,0.89 -0.08,1.13L2.1,4.05c-0.4,0.32 -0.89,0.24 -1.13,-0.08zM15.97,2.84l-2.5,-2.1c-0.32,-0.32 -0.8,-0.25 -1.13,0.08 -0.32,0.32 -0.24,0.81 0.08,1.13l2.5,2.1c0.33,0.3 0.81,0.24 1.13,-0.08 0.27,-0.31 0.25,-0.89 -0.08,-1.13zM15.73,9.21c0,4.03 -3.23,7.26 -7.26,7.26s-7.26,-3.23 -7.26,-7.26 3.23,-7.26 7.26,-7.26 7.26,3.23 7.26,7.26zM14.2,9.21c0,-3.15 -2.58,-5.73 -5.73,-5.73S2.74,6.06 2.74,9.21s2.58,5.73 5.73,5.73 5.73,-2.59 5.73,-5.73zM8.27,5.18c-0.33,0 -0.6,0.27 -0.6,0.6v4.23l3.34,2c0.27,0.17 0.62,0.08 0.79,-0.19s0.07,-0.64 -0.2,-0.8L8.87,9.41L8.87,5.78c0,-0.33 -0.27,-0.6 -0.6,-0.6z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml
index 4a7cbb3..5228085 100644
--- a/packages/SystemUI/res/drawable/stat_sys_cast.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_cast.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -18,11 +18,11 @@
     android:insetRight="2.5dp">
     <vector android:width="17dp"
             android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
+            android:viewportWidth="17.0"
+            android:viewportHeight="17.0">
 
         <path
             android:fillColor="#FFFFFFFF"
-            android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
+            android:pathData="M0.71,12.75v1.42c0,0.39 0.32,0.71 0.71,0.71h1.42C2.83,13.7 1.88,12.75 0.71,12.75zM0.69,10.67c-0.01,0.36 0.25,0.66 0.6,0.72c1.47,0.26 2.65,1.42 2.9,2.89c0.06,0.34 0.35,0.6 0.7,0.6c0.43,0 0.77,-0.38 0.71,-0.81c-0.34,-2.11 -2,-3.76 -4.11,-4.09C1.08,9.91 0.7,10.24 0.69,10.67zM13.46,4.96H3.54v1.15c2.81,0.91 5.02,3.12 5.93,5.93h3.99V4.96zM0.69,7.81C0.68,8.18 0.95,8.49 1.31,8.53c3.02,0.3 5.44,2.71 5.74,5.72c0.04,0.35 0.34,0.62 0.7,0.62c0.42,0 0.75,-0.36 0.71,-0.78c-0.37,-3.69 -3.3,-6.62 -6.99,-6.98C1.06,7.08 0.7,7.4 0.69,7.81zM14.88,2.12H2.12c-0.78,0 -1.42,0.64 -1.42,1.42v2.12h1.42V3.54h12.75v9.92H9.92v1.42h4.96c0.78,0 1.42,-0.64 1.42,-1.42V3.54C16.29,2.76 15.65,2.12 14.88,2.12z" />
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
index e2d3539..4dc0e4b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
@@ -1,25 +1,31 @@
+<?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.
+**
+** Copyright 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="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:viewportWidth="17.0"
+        android:viewportHeight="17.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M8.84,8l2.62,-2.62c0.29,-0.29 0.29,-0.75 0,-1.04L8.33,1.22L8.31,1.2c-0.3,-0.28 -0.76,-0.26 -1.03,0.04c-0.13,0.13 -0.2,0.31 -0.2,0.5v4.51L4.24,3.4c-0.29,-0.29 -0.74,-0.29 -1.03,0s-0.29,0.74 0,1.03L6.78,8l-3.56,3.56c-0.29,0.29 -0.29,0.74 0,1.03s0.74,0.29 1.03,0l2.83,-2.83v4.51c0,0.4 0.33,0.73 0.73,0.73c0.18,0 0.36,-0.07 0.5,-0.2l0.03,-0.03l3.12,-3.12c0.29,-0.29 0.29,-0.75 0,-1.04L8.84,8zM8.47,6.37V3.36l1.5,1.5L8.47,6.37zM8.47,12.63V9.62l1.5,1.5L8.47,12.63z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
index 94c40ba..c8a4440 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
@@ -1,25 +1,31 @@
+<?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.
+**
+** Copyright 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="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
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/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
index c36678d..fed7cae 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
@@ -1,34 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2016 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 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.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
-        <path
-            android:fillColor="#4DFFFFFF"
-            android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+        android:width="18dp"
+        android:height="18dp"
+        android:viewportWidth="19.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M11.5,8.5c0,0.41 -0.34,0.74 -0.74,0.74L9.24,9.24v1.5c0,0.41 -0.34,0.74 -0.74,0.74s-0.74,-0.34 -0.74,-0.74v-1.5h-1.5c-0.41,0 -0.74,-0.34 -0.74,-0.74s0.34,-0.74 0.74,-0.74h1.5v-1.5c0,-0.41 0.34,-0.74 0.74,-0.74s0.74,0.34 0.74,0.74v1.5h1.5c0.42,-0.01 0.76,0.33 0.76,0.74z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M13.23,12.05l0.99,0.57c0.19,0.12 0.25,0.38 0.12,0.55A7.452,7.452 0,0 1,7.5 15.9c-3.29,-0.44 -5.96,-3.08 -6.41,-6.38 -0.57,-4.17 2.33,-7.8 6.23,-8.42 0.23,-0.04 0.44,0.15 0.44,0.37v1.15c0,0.18 -0.14,0.33 -0.31,0.37 -2.7,0.52 -4.71,2.96 -4.55,5.83 0.16,2.86 2.57,5.21 5.43,5.29 1.77,0.06 3.38,-0.72 4.44,-1.97 0.11,-0.14 0.31,-0.18 0.46,-0.09z"
+                android:fillColor="#FFF" />
+            <path
+                android:pathData="M14.11,8.5c0,0.62 -0.11,1.22 -0.29,1.78 -0.06,0.17 0.01,0.35 0.16,0.45l1,0.57c0.19,0.12 0.46,0.03 0.54,-0.18 0.3,-0.82 0.47,-1.7 0.47,-2.62 0,-3.73 -2.73,-6.82 -6.31,-7.39a0.377,0.377 0,0 0,-0.44 0.37v1.15c0,0.18 0.14,0.33 0.31,0.36 2.59,0.51 4.56,2.78 4.56,5.51z"
+                android:fillAlpha="0.3"
+                android:fillColor="#FFF" />
+
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
index 3bf5e98..bd4cb0a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -1,28 +1,35 @@
+<?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.
+**
+** Copyright 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.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,1.59c-3.81,0 -6.91,3.09 -6.91,6.91s3.09,6.91 6.91,6.91 6.91,-3.09 6.91,-6.91 -3.1,-6.91 -6.91,-6.91zM11.16,9.56L5.84,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h5.31a1.06,1.06 0,0 1,0.01 2.12z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
index 82e25ca..11a3bdd 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
@@ -1,31 +1,38 @@
+<?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.
+**
+** Copyright 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.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+        android:width="16dp"
+        android:height="16dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,3.72c-2.62,0 -4.78,2.16 -4.78,4.78s2.16,4.78 4.78,4.78 4.78,-2.16 4.78,-4.78 -2.07,-4.78 -4.78,-4.78zM10.09,9.56L6.91,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h3.19c0.59,0 1.06,0.48 1.06,1.06s-0.48,1.06 -1.07,1.06z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M8.5,0.53C4.11,0.53 0.53,4.11 0.53,8.5s3.58,7.97 7.97,7.97 7.97,-3.58 7.97,-7.97S12.89,0.53 8.5,0.53zM8.5,15.28c-3.75,0 -6.78,-3.03 -6.78,-6.78S4.75,1.72 8.5,1.72s6.78,3.03 6.78,6.78 -3.03,6.78 -6.78,6.78z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
index 01e8888..4f52777 100644
--- a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -17,13 +17,16 @@
     android:insetLeft="2.5dp"
     android:insetRight="2.5dp">
     <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.000000,22.000000c-2.200000,0.000000 -4.000000,1.800000 -4.000000,4.000000c0.000000,2.200000 1.800000,4.000000 4.000000,4.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000C28.000000,23.799999 26.200001,22.000000 24.000000,22.000000zM36.000000,26.000000c0.000000,-6.600000 -5.400000,-12.000000 -12.000000,-12.000000c-6.600000,0.000000 -12.000000,5.400000 -12.000000,12.000000c0.000000,4.400000 2.400000,8.300000 6.000000,10.400000l2.000000,-3.500000c-2.400000,-1.400000 -4.000000,-3.900000 -4.000000,-6.900000c0.000000,-4.400000 3.600000,-8.000000 8.000000,-8.000000s8.000000,3.600000 8.000000,8.000000c0.000000,3.000000 -1.600000,5.500000 -4.000000,6.900000l2.000000,3.500000C33.599998,34.299999 36.000000,30.400000 36.000000,26.000000zM24.000000,6.000000C13.000000,6.000000 4.000000,15.000000 4.000000,26.000000c0.000000,7.400000 4.000000,13.800000 10.000000,17.299999l2.000000,-3.500000c-4.800000,-2.800000 -8.000000,-7.900000 -8.000000,-13.800000c0.000000,-8.800000 7.200000,-16.000000 16.000000,-16.000000s16.000000,7.200000 16.000000,16.000000c0.000000,5.900000 -3.200000,11.100000 -8.000000,13.800000l2.000000,3.500000c6.000000,-3.500000 10.000000,-9.900000 10.000000,-17.299999C44.000000,15.000000 35.000000,6.000000 24.000000,6.000000z"/>
+        android:width="18.0dp"
+        android:height="18.0dp"
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+      <group
+          android:translateX="0.5"
+          android:translateY="0.5" >
+          <path
+              android:pathData="M8.5,7.79c-0.78,0 -1.42,0.64 -1.42,1.42c0,0.78 0.64,1.42 1.42,1.42s1.42,-0.64 1.42,-1.42C9.92,8.43 9.28,7.79 8.5,7.79zM12.75,9.21c0,-2.35 -1.9,-4.25 -4.25,-4.25c-0.18,0 -0.35,0.01 -0.53,0.03C6.11,5.22 4.58,6.7 4.3,8.55c-0.23,1.52 0.35,2.91 1.36,3.82C6,12.67 6.54,12.6 6.76,12.2c0.17,-0.3 0.1,-0.67 -0.16,-0.89c-0.78,-0.7 -1.12,-1.77 -0.86,-2.79C5.99,7.5 6.78,6.71 7.8,6.46C9.32,6.08 10.86,7 11.25,8.52c0.06,0.23 0.09,0.46 0.09,0.69c0,0.84 -0.36,1.58 -0.94,2.1c-0.25,0.23 -0.33,0.6 -0.16,0.9c0.22,0.38 0.74,0.49 1.06,0.2C12.22,11.6 12.75,10.43 12.75,9.21zM7.63,1.85C4.19,2.24 1.42,5.07 1.1,8.52c-0.26,2.61 0.88,5.15 2.99,6.7c0.36,0.26 0.86,0.15 1.09,-0.23c0.19,-0.32 0.1,-0.74 -0.19,-0.96c-1.7,-1.26 -2.71,-3.38 -2.35,-5.73c0.4,-2.6 2.57,-4.68 5.19,-4.97c3.59,-0.41 6.63,2.4 6.63,5.91c0,1.97 -0.96,3.7 -2.43,4.79c-0.3,0.22 -0.38,0.63 -0.19,0.96c0.22,0.39 0.73,0.49 1.09,0.23c1.9,-1.4 3.03,-3.62 3.03,-5.98C15.94,4.84 12.12,1.34 7.63,1.85z"
+              android:fillColor="#FFFFFFFF"/>
+      </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
index 370f89c..d73e2a4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -22,19 +22,19 @@
     The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
 -->
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M15.0815,4.5903 L15.0815,3.43636 L13.9276,2.2 L9.14696,2.2 L7.99302,3.43636
 L7.99302,4.5903 L9.14696,4.5903 L9.14696,3.43636 L13.9276,3.43636
 L13.9276,4.5903 Z" />
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M18.0488,4.5903 L5.02575,4.5903 C4.36635,4.5903,3.87181,5.08485,3.87181,5.74424
 L3.87181,9.28848 C3.87181,9.94788,4.36635,10.4424,5.02575,10.4424
 L9.72393,10.4424 L9.72393,9.28848 L13.2682,9.28848 L13.2682,10.4424
 L17.9664,10.4424 C18.6257,10.4424,19.1203,9.94788,19.1203,9.28848
 L19.1203,5.74424 C19.2027,5.08485,18.6257,4.5903,18.0488,4.5903 Z" />
     <path
-        android:fillColor="@android:color/white"
+        android:fillColor="#ff000000"
         android:pathData="M9.80635,12.8327 L9.80635,11.6788 L4.44878,11.6788 L4.44878,14.6461
 C4.44878,15.3055,4.94332,15.8,5.60272,15.8 L17.3894,15.8
 C18.0488,15.8,18.5433,15.3055,18.5433,14.6461 L18.5433,11.6788 L13.2682,11.6788
diff --git a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
index 2229c99..faea7d1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
@@ -1,25 +1,31 @@
+<?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.
+**
+** Copyright 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="17dp"
-        android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="18.4"
+    android:viewportHeight="18.4">
+    <group
+        android:translateX="0.7"
+        android:translateY="1.0">
+        <path
+            android:pathData="M13.91,11.84L5.14,3.08l1.81,-1.81h5.41c0.85,0 1.54,0.69 1.54,1.54l0.01,9.03zM15.06,14.95L2.54,2.44c-0.28,-0.28 -0.71,-0.28 -0.99,0s-0.28,0.71 0,0.98l1.53,1.53v8.67c0,0.85 0.69,1.54 1.54,1.54h7.74c0.27,0 0.52,-0.07 0.74,-0.2l0.96,0.96c0.28,0.28 0.71,0.28 0.99,0 0.28,-0.26 0.28,-0.69 0.01,-0.97z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index eb7b4fc..e525fec 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -1,28 +1,35 @@
+<?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.
+**
+** Copyright 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.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="3dp"
-    android:insetRight="3dp">
-    <vector android:width="18dp"
-            android:height="18dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:width="19dp"
+        android:height="17dp"
+        android:viewportWidth="21.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M13.28,0.53L5.84,0.53c-0.88,0 -1.59,0.71 -1.59,1.59v12.75c0,0.88 0.71,1.59 1.59,1.59h7.44c0.88,0 1.59,-0.71 1.59,-1.59L14.87,2.12c0.01,-0.88 -0.71,-1.59 -1.59,-1.59zM13.28,14.88L5.84,14.88L5.84,2.12h7.44v12.76zM2.66,13.81a0.52,0.52 0,0 1,-0.53 -0.53L2.13,3.72c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v9.56c0,0.3 -0.24,0.53 -0.53,0.53zM0.53,11.69a0.52,0.52 0,0 1,-0.53 -0.53L0,5.84c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v5.31c0,0.3 -0.23,0.54 -0.53,0.54zM16.47,13.81c0.3,0 0.53,-0.23 0.53,-0.53L17,3.72c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v9.56c0,0.3 0.23,0.53 0.53,0.53zM18.59,11.69c0.3,0 0.53,-0.23 0.53,-0.53L19.12,5.84c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v5.31c0,0.3 0.24,0.54 0.53,0.54z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
index 7ca8c40..66f4fbb 100644
--- a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
@@ -1,24 +1,31 @@
+<?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.
+**
+** Copyright 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="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.700000,10.000000c-0.800000,-2.300000 -3.000000,-4.000000 -5.700000,-4.000000c-3.300000,0.000000 -6.000000,2.700000 -6.000000,6.000000s2.700000,6.000000 6.000000,6.000000c2.600000,0.000000 4.800000,-1.700000 5.700000,-4.000000L17.000000,14.000000l0.000000,4.000000l4.000000,0.000000l0.000000,-4.000000l2.000000,0.000000l0.000000,-4.000000L12.700000,10.000000zM7.000000,14.000000c-1.100000,0.000000 -2.000000,-0.900000 -2.000000,-2.000000c0.000000,-1.100000 0.900000,-2.000000 2.000000,-2.000000s2.000000,0.900000 2.000000,2.000000C9.000000,13.100000 8.100000,14.000000 7.000000,14.000000z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="19.0"
+    android:viewportHeight="19.0">
+    <group
+        android:translateX="1.0"
+        android:translateY="1.0">
+        <path
+            android:pathData="M15.46,6.96H9a4.637,4.637 0,0 0,-4.37 -3.09C2.07,3.87 0,5.94 0,8.5s2.07,4.63 4.63,4.63c2.02,0 3.73,-1.29 4.37,-3.09h2.2v1.54a1.54,1.54 0,0 0,3.08 0v-1.54h1.16c0.87,0 1.56,-0.69 1.56,-1.54s-0.69,-1.54 -1.54,-1.54zM4.63,10.04a1.54,1.54 0,1 1,0.001 -3.081,1.54 1.54,0 0,1 -0.001,3.081z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml
index 2de2e36..b3cd455 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.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,12 +16,16 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="18.41dp"
         android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+        android:viewportWidth="21.2"
+        android:viewportHeight="21.2">
+      <group
+          android:translateX="0.5"
+          android:translateY="2.0">
+        <path
+            android:pathData="M18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
index 60f7eb6..6c0fad8 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.66"
+    android:viewportHeight="20">
+    <group
+        android:translateX="0.74"
+        android:translateY="1.2">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml
index 144a7c1..2ebbaf2 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.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.
@@ -14,17 +14,21 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,13.2c-0.1,0.0 -0.3,-0.1 -0.4,-0.1c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,0.0 -0.6,-0.1 -0.9,-0.1c0.0,0.0 0.0,0.0 -0.1,0.0c0.0,0.0 0.0,0.0 0.0,0.0s0.0,0.0 0.0,0.0c0.0,0.0 0.0,0.0 -0.1,0.0c-0.3,0.0 -0.6,0.0 -0.9,0.1c-0.1,0.0 -0.3,0.0 -0.4,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.1,0.0 -0.1,0.0 -0.2,0.1c-1.6,0.5 -2.7,1.3 -2.8,1.5l5.3,6.6l0.0,0.0l0.0,0.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.700002,13.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.7"
+    android:viewportHeight="21.7">
+    <group
+        android:translateY="2.2"
+        android:translateX="0.75">
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor" />
+        <path
+            android:pathData="M5.02,10.86l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V9.14c-0.51,-0.11 -1.05,-0.17 -1.59,-0.17C8.15,8.97 6.37,9.69 5.02,10.86z"
+            android:fillColor="?attr/fillColor" />
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor" />
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
index 554350d..eaead9b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.100000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.500000,6.500000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.100000,22.000000l5.500000,-6.800000c-0.200000,-0.200000 -2.300000,-1.900000 -5.500000,-1.900000s-5.300000,1.800000 -5.500000,1.900000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.66"
+    android:viewportHeight="20.0">
+    <group
+        android:translateX="0.79"
+        android:translateY="1.2">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.1,8.97c-1.95,0 -3.72,0.72 -5.08,1.9l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l4.26,-5.22a7.702,7.702 0,0 0,-5.07 -1.89z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml
index 6b7f712..809147c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.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.
@@ -14,17 +14,21 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l4.9,0.0c-1.0,-0.7 -3.4,-2.2 -6.7,-2.2c-4.1,0.0 -6.9,2.2 -7.2,2.5l7.2,9.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.800001,12.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.800001,1.9 -1.800001,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.7"
+    android:viewportHeight="21.7">
+    <group
+        android:translateX="0.75"
+        android:translateY="2.2" >
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44h2.84C13.18,6.8 11.68,6.44 10.09,6.44z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
index 2c2465a..6d4fb77 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.000000,22.000000l7.600000,-9.400000C20.299999,12.400000 17.400000,10.000000 13.000000,10.000000s-7.300000,2.400000 -7.600000,2.700000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+android:width="18.41dp"
+android:height="17dp"
+android:viewportWidth="21.86"
+android:viewportHeight="20.19">
+    <group
+        android:translateX="0.85"
+        android:translateY="1.4" >
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor" />
+        <path
+            android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l5.86,-7.19a10.284,10.284 0,0 0,-6.67 -2.44z"
+            android:fillColor="?attr/fillColor" />
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml
index d34b4de..4c479c0 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.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,15 +16,19 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="18.41dp"
         android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0l1.0,-1.2C20.0,10.6 16.8,8.0 12.0,8.0s-8.0,2.6 -8.5,3.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/fillColor"/>
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/backgroundColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/fillColor"/>
+        android:viewportWidth="21.7"
+        android:viewportHeight="21.7">
+    <group
+            android:translateX="0.75"
+            android:translateY="2.3" >
+        <path
+            android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39c0.22,0 0.44,-0.07 0.63,-0.2c0.07,-0.05 0.14,-0.11 0.2,-0.19l0.78,-0.96V7.44h5.98C15.6,5.77 12.96,4.75 10.08,4.75z"
+            android:fillColor="?attr/fillColor"/>
+        <path
+            android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
index 7d0f756..6c96300 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-    <path
-        android:fillColor="?attr/fillColor"
-        android:pathData="M13.000000,22.000000l9.200000,-11.400000c-0.400000,-0.300000 -3.900000,-3.200000 -9.200000,-3.200000s-8.900000,3.000000 -9.200000,3.200000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.80"
+    android:viewportHeight="20.1">
+    <group
+        android:translateX="0.81"
+        android:translateY="1.29" >
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/backgroundColor"/>
+        <path
+            android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39 0.23,0 0.46,-0.07 0.65,-0.22 -0.02,0.02 -0.04,0.03 -0.07,0.05 0.09,-0.06 0.17,-0.13 0.24,-0.22l6.93,-8.5c-2.09,-1.74 -4.8,-2.82 -7.76,-2.82z"
+            android:fillColor="?attr/fillColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml
index 7d1bfe1..8fb7a7b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.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.
@@ -14,14 +14,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="18.41dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
-        android:fillColor="?attr/singleToneColor"/>
-    <path
-        android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
-        android:fillColor="?attr/singleToneColor"/>
+    android:width="18.41dp"
+    android:height="18.41dp"
+    android:viewportWidth="21.95"
+    android:viewportHeight="21.65">
+    <group
+        android:translateX="0.90"
+        android:translateY="2.25"
+        >
+        <path
+            android:pathData="M11.69,15.12l-0.78,0.96c-0.43,0.52 -1.22,0.52 -1.64,0L0.24,5c-0.4,-0.49 -0.29,-1.22 0.23,-1.56c1.59,-1.05 5.03,-2.9 9.62,-2.9c4.59,0 8.02,1.85 9.62,2.9c0.53,0.35 0.63,1.08 0.23,1.56l-1.99,2.44h-6.27V15.12zM18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z"
+            android:fillColor="?attr/singleToneColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
index a7e213f..bc3fdb5 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml
@@ -1,5 +1,5 @@
 <!--
-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");
     you may not use this file except in compliance with the License.
@@ -14,11 +14,15 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="18.41dp"
-        android:height="17dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="?attr/singleToneColor"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    android:width="18.41dp"
+    android:height="17dp"
+    android:viewportWidth="21.75"
+    android:viewportHeight="20.0">
+    <group
+        android:translateX="0.80"
+        android:translateY="1.25">
+        <path
+            android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z"
+            android:fillColor="?attr/singleToneColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error.xml b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
index 534a9a5..4a8e452 100755
--- a/packages/SystemUI/res/drawable/trusted_state_to_error.xml
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -17,31 +17,20 @@
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="trusted_state_to_error"
-    android:width="32dp"
-    android:viewportWidth="32"
-    android:height="32dp"
-    android:viewportHeight="32" >
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
     <group
-        android:name="trusted_state_to_error_0"
-        android:translateX="16"
-        android:translateY="16" >
-        <group
-            android:name="error_circle" >
-            <path
-                android:name="ellipse_path_1"
-                android:trimPathStart="1"
-                android:trimPathOffset="1"
-                android:strokeColor="#FFFFFFFF"
-                android:strokeAlpha="0.5"
-                android:strokeWidth="2"
-                android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
-        </group>
+        android:name="lock"
+        android:translateX="12"
+        android:translateY="12" >
         <group
             android:name="middle_ellipse"
             android:translateY="2.9375" >
             <path
-                android:name="ellipse_path_2"
-                android:fillColor="#FFFFFFFF"
+                android:name="ellipse_path_1"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5"
                 android:pathData="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z" />
         </group>
@@ -50,7 +39,7 @@
             <path
                 android:name="path_1"
                 android:pathData="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
         <group
@@ -58,7 +47,7 @@
             <path
                 android:name="path_2"
                 android:pathData="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
         <group
@@ -66,19 +55,50 @@
             <path
                 android:name="path_3"
                 android:pathData="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
-                android:fillColor="#FFFFFFFF"
+                android:fillColor="?attr/wallpaperTextColor"
                 android:fillAlpha="0.5" />
         </group>
+    </group>
+    <group
+        android:name="errorexclamationdot"
+        android:translateX="12"
+        android:translateY="8" >
         <group
-            android:name="exclamation_dot"
-            android:translateY="4"
-            android:scaleX="0"
-            android:scaleY="0" >
+            android:name="exclamationbottom"
+            android:translateY="4" >
             <path
-                android:name="rectangle_path_1"
-                android:fillColor="#FFFFFFFF"
-                android:fillAlpha="0.5"
-                android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+                android:name="bottompath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorexclamation"
+        android:translateX="12"
+        android:translateY="12" >
+        <group
+            android:name="exclamationtop"
+            android:translateY="2.5" >
+            <path
+                android:name="toppath"
+                android:fillColor="?android:attr/colorError"
+                android:pathData="M 0.0,-7.0 l 0.0,0.0 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 l 0.0,7.0 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 l 0.0,0.0 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 l 0.0,-7.0 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z" />
+        </group>
+    </group>
+    <group
+        android:name="errorcircle"
+        android:translateX="12"
+        android:translateY="12"
+        android:rotation="184" >
+        <group
+            android:name="circle" >
+            <path
+                android:name="circlepath"
+                android:strokeColor="?android:attr/colorError"
+                android:strokeWidth="2"
+                android:strokeLineCap="round"
+                android:trimPathStart="1"
+                android:pathData="M 0.0,-9.0 c 4.9705627482,0.0 9.0,4.0294372518 9.0,9.0 c 0.0,4.9705627482 -4.0294372518,9.0 -9.0,9.0 c -4.9705627482,0.0 -9.0,-4.0294372518 -9.0,-9.0 c 0.0,-4.9705627482 4.0294372518,-9.0 9.0,-9.0 Z" />
         </group>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
index 5686d54..3457be5 100755
--- a/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -21,18 +21,9 @@
         android:name="ellipse_path_1"
         android:animation="@anim/trusted_state_to_error_ellipse_path_1_animation" />
     <target
-        android:name="ellipse_path_2"
-        android:animation="@anim/trusted_state_to_error_ellipse_path_2_animation" />
-    <target
-        android:name="lock_right_side"
-        android:animation="@anim/trusted_state_to_error_lock_right_side_animation" />
-    <target
         android:name="path_1"
         android:animation="@anim/trusted_state_to_error_path_1_animation" />
     <target
-        android:name="lock_left_side"
-        android:animation="@anim/trusted_state_to_error_lock_left_side_animation" />
-    <target
         android:name="path_2"
         android:animation="@anim/trusted_state_to_error_path_2_animation" />
     <target
@@ -42,9 +33,21 @@
         android:name="path_3"
         android:animation="@anim/trusted_state_to_error_path_3_animation" />
     <target
-        android:name="exclamation_dot"
-        android:animation="@anim/trusted_state_to_error_exclamation_dot_animation" />
+        android:name="errorexclamationdot"
+        android:animation="@anim/trusted_state_to_error_errorexclamationdot_animation" />
     <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/trusted_state_to_error_rectangle_path_1_animation" />
+        android:name="bottompath"
+        android:animation="@anim/trusted_state_to_error_bottompath_animation" />
+    <target
+        android:name="exclamationtop"
+        android:animation="@anim/trusted_state_to_error_exclamationtop_animation" />
+    <target
+        android:name="toppath"
+        android:animation="@anim/trusted_state_to_error_toppath_animation" />
+    <target
+        android:name="errorcircle"
+        android:animation="@anim/trusted_state_to_error_errorcircle_animation" />
+    <target
+        android:name="circlepath"
+        android:animation="@anim/trusted_state_to_error_circlepath_animation" />
 </animated-vector>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml
index d6adea9..996ac5e 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
-    <solid android:color="?android:attr/colorPrimary" />
+    <solid android:color="?android:attr/colorBackgroundFloating" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
old mode 100755
new mode 100644
index 262cb88..7f4fdbf
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.254777070064,0.0 c 0.00007,0.0 0.447133757962,1.0 0.745222929936,1.0 L 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
old mode 100755
new mode 100644
index 9ecee94..1695962
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
old mode 100755
new mode 100644
index ae0b2d7..91c08f8
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.000100000000009,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 l 0.236439499305,0.0 c 0.763560500695,0.0 0.458136300417,1.0 0.763560500695,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
old mode 100755
new mode 100644
index be7cc69..f5cbc31
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.00100000000001,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
old mode 100755
new mode 100644
index f8f978d..cf21d81
--- a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.00100000000002,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml
new file mode 100644
index 0000000..0bf41e5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_6.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
deleted file mode 100644
index c421f9e..0000000
--- a/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml
new file mode 100644
index 0000000..ed90d64
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_caret_down_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml
new file mode 100644
index 0000000..ed90d64
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_caret_up_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml
new file mode 100644
index 0000000..fcd751d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml
new file mode 100644
index 0000000..38dbdb7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml
new file mode 100644
index 0000000..1695962
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml
new file mode 100644
index 0000000..8538f98
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.286298568507,0.0 c 0.142740286299,0.0 0.0,1.0 0.713701431493,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml
new file mode 100644
index 0000000..0bf41e5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.2,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml
new file mode 100644
index 0000000..2202094
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_toerror_animation_interpolator_6.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml
new file mode 100644
index 0000000..ac1b566
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.555555555556,0.0 c 0.177777777778,0.0 0.0888888888889,1.0 0.444444444444,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml
new file mode 100644
index 0000000..7f4fdbf
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml
new file mode 100644
index 0000000..1695962
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml
new file mode 100644
index 0000000..02c6cd5
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.445544554455,0.0 c 0.554455445545,0.0 0.332673267327,1.0 0.554455445545,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml
new file mode 100644
index 0000000..7ae249e
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml
new file mode 100644
index 0000000..0c18d92
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_fingerprint_tofp_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_ic_hotspot_alpha_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml
deleted file mode 100644
index 0cc9c02..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_1.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.833333333,0.833333333 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml
deleted file mode 100644
index 44c755e..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_disable_mask_pathdata_interpolator_2.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0.166666667 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml
deleted file mode 100644
index e361d9c..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_1.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,0.833333333 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml
deleted file mode 100644
index 25ba970..0000000
--- a/packages/SystemUI/res/interpolator/ic_hotspot_enable_mask_pathdata_interpolator_2.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0.166666667 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
deleted file mode 100644
index 76f5667..0000000
--- a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
deleted file mode 100644
index ac27e4d..0000000
--- a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_rotate_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_landscape_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
new file mode 100644
index 0000000..793e7ff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_rotate_to_portrait_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc0442f..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index bc90d28..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index f7072f2..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index 66cfaff..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index a0118d70..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index 1820bab..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml
deleted file mode 100644
index c3930e4..0000000
--- a/packages/SystemUI/res/interpolator/ic_volume_collapse_animation_interpolator_0.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0001,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml
deleted file mode 100644
index c3930e4..0000000
--- a/packages/SystemUI/res/interpolator/ic_volume_expand_animation_interpolator_0.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0001,0.0 0.0,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml
deleted file mode 100644
index 708de2a..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_0.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.29,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml
deleted file mode 100644
index 07cae89..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_1.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml
deleted file mode 100644
index a5ffc40..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_2.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml
deleted file mode 100644
index 34156c3..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_3.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.9999,0.999933333333 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml
deleted file mode 100644
index 24a3d43..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_4.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.612659627466,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml
deleted file mode 100644
index c0a68e2..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_to_fp_animation_interpolator_5.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.9999,0.999883333333 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml
deleted file mode 100644
index 39c5211..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_0.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml
deleted file mode 100644
index 9769a83..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_1.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.312548622571,1.03663900165 0.662518487347,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml
deleted file mode 100644
index e10db01..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_2.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml
deleted file mode 100644
index 736eac6..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_3.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml
deleted file mode 100644
index d3ae9d7..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_4.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml
deleted file mode 100644
index a5ffc40..0000000
--- a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_fp_to_error_state_animation_interpolator_5.xml
+++ /dev/null
@@ -1,19 +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
-  -->
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.0,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
old mode 100755
new mode 100644
index 9ecee94..7f4fdbf
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 1.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
old mode 100755
new mode 100644
index 87ef1d4..1695962
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.412907702984,0.0 c 0.00006,0.0 0.35225537821,1.0 0.587092297016,1.0 L 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
old mode 100755
new mode 100644
index be7cc69..138851e
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 c 0.001,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
old mode 100755
new mode 100644
index 83af65a..7657cb6
--- a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2015 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
 
@@ -16,4 +16,4 @@
 -->
 <pathInterpolator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.9999,1.0 1.0,1.0" />
+    android:pathData="M 0.0,0.0 l 0.364238410596,0.0 c 0.127152317881,0.0 0.0,1.0 0.635761589404,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml
new file mode 100644
index 0000000..3e5efd7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.4,0.0 c 0.0006,0.0 0.12,1.0 0.6,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml
new file mode 100644
index 0000000..2202094
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_5.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/ambient_indication.xml b/packages/SystemUI/res/layout/ambient_indication.xml
new file mode 100644
index 0000000..37ba35f
--- /dev/null
+++ b/packages/SystemUI/res/layout/ambient_indication.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 4e8726b..43bec91 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -22,8 +22,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="4"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_back"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
deleted file mode 100644
index 6162d65..0000000
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/charge_and_estimation"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="16dp"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/colorAccent" />
-
-    <com.android.systemui.ResizingSpace
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/battery_detail_graph_space_top" />
-
-    <com.android.settingslib.graph.UsageView
-        android:id="@+id/battery_usage"
-        android:layout_width="match_parent"
-        android:layout_height="141dp"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="24dp"
-        systemui:sideLabels="@array/battery_labels"
-        android:colorAccent="?android:attr/colorAccent"
-        systemui:textColor="?android:attr/textColorSecondary" />
-
-    <com.android.systemui.ResizingSpace
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/battery_detail_graph_space_bottom" />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:background="?android:attr/listDivider"
-        android:layout_marginBottom="8dp" />
-
-    <RelativeLayout
-        android:id="@+id/switch_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:clickable="true">
-
-        <ImageView
-            android:id="@android:id/icon"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:scaleType="fitCenter"
-            android:adjustViewBounds="true"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:layout_marginStart="16dp"
-            android:layout_marginEnd="32dp" />
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toStartOf="@android:id/toggle"
-            android:layout_toEndOf="@android:id/icon"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
-            android:text="@string/battery_detail_switch_title" />
-
-        <TextView
-            android:id="@android:id/summary"
-            android:visibility="gone"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/title"
-            android:layout_toStartOf="@android:id/toggle"
-            android:layout_toEndOf="@android:id/icon"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary"
-            android:text="@string/battery_detail_switch_summary" />
-
-        <Switch
-            android:id="@android:id/toggle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_alignParentTop="true"
-            android:layout_marginEnd="16dp"
-            android:clickable="false"
-            android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
-
-    </RelativeLayout>
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index bbaff6a..d6e7507 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -16,7 +16,7 @@
   -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/brightness_mirror"
-    android:layout_width="@dimen/notification_panel_width"
+    android:layout_width="@dimen/qs_panel_width"
     android:layout_height="wrap_content"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:visibility="invisible">
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index b7e666f..bc29012 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -15,24 +15,26 @@
      limitations under the License.
 -->
 
-<!--  LinearLayout -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
-    android:gravity="top|center_horizontal"
-    android:layout_width="180dp"
-    android:layout_height="wrap_content">
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginLeft="@dimen/car_fullscreen_user_pod_margin_side"
+    android:layout_marginRight="@dimen/car_fullscreen_user_pod_margin_side"
+    android:gravity="center"
+    android:layout_weight="1" >
 
     <ImageView android:id="@+id/user_avatar"
-               android:padding="10dp"
-               android:layout_gravity="center"
-               android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
-               android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height" />
+        android:layout_gravity="center"
+        android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
+        android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height" />
 
     <TextView android:id="@+id/user_name"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:textSize="@dimen/car_fullscreen_user_pod_text_size"
-              android:textColor="@color/qs_user_detail_name"
-              android:gravity="center_horizontal" />
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_above_text"
+        android:textSize="@dimen/car_fullscreen_user_pod_text_size"
+        android:textColor="@color/qs_user_detail_name"
+        android:layout_gravity="center_horizontal" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml
new file mode 100644
index 0000000..8c55680
--- /dev/null
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod_container.xml
@@ -0,0 +1,24 @@
+<?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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center">
+
+    <!-- car_fullscreen_user_pods will be dynamically added here. -->
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index 6e4b213..c82eddc 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -14,38 +14,58 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:fitsSystemWindows="true"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             android:visibility="gone">
-    <LinearLayout
+        android:fitsSystemWindows="true"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical">
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/car_lockscreen_disclaimer_title"
-            android:textSize="@dimen/car_lockscreen_disclaimer_title_size"
-            android:paddingStart="@dimen/car_lockscreen_disclaimer_title_padding_start"
-            android:paddingTop="@dimen/car_lockscreen_disclaimer_title_padding_top" />
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:text="@string/car_lockscreen_disclaimer_text"
-            android:textSize="@dimen/car_lockscreen_disclaimer_text_size"
-            android:paddingStart="@dimen/car_lockscreen_disclaimer_text_padding_start"
-            android:paddingEnd="@dimen/car_lockscreen_disclaimer_text_padding_end"
-            android:paddingTop="@dimen/car_lockscreen_disclaimer_text_padding_top" />
+        android:background="@android:color/black"
+        android:visibility="gone">
+
+    <!-- This progressbar is activated while we're switching users. -->
+    <ProgressBar
+        android:id="@+id/switching_users"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:indeterminate="true"
+        android:visibility="gone"
+        android:layout_gravity="center" />
+
+    <RelativeLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <!-- This progress bar is the countdown timer. -->
+        <ProgressBar
+            android:id="@+id/countdown_progress"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/car_user_switcher_progress_bar_height"
+            style="@style/CarUserSwitcher.ProgressBar"
+            android:layout_marginTop="@dimen/car_user_switcher_progress_bar_margin_top"
+            android:layout_alignParentTop="true"/>
+
         <com.android.systemui.statusbar.car.UserGridView
             android:id="@+id/user_grid"
-            android:layout_gravity="center"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:stretchMode="columnWidth">
-        </com.android.systemui.statusbar.car.UserGridView>
-    </LinearLayout>
+            android:layout_marginLeft="@dimen/car_margin"
+            android:layout_marginRight="@dimen/car_margin"
+            android:layout_centerInParent="true" />
+
+        <com.android.systemui.statusbar.car.PageIndicator
+            android:id="@+id/user_switcher_page_indicator"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/car_page_indicator_dot_diameter"
+            android:layout_marginTop="@dimen/car_page_indicator_margin_top"
+            android:layout_below="@+id/user_grid" />
+
+        <Button
+            android:id="@+id/start_driving"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/car_start_driving_height"
+            android:text="@string/start_driving"
+            style="@style/CarUserSwitcher.StartDrivingButton"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true" />
+    </RelativeLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
new file mode 100644
index 0000000..e3a488c
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- RelativeLayouts have an issue enforcing minimum heights, so just
+     work around this for now with LinearLayouts. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:minWidth="92dp"
+    android:minHeight="92dp"
+    android:gravity="center"
+    android:orientation="vertical"
+    android:paddingEnd="8dip"
+    android:paddingStart="8dip">
+
+    <ImageView
+        android:id="@*android:id/icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_gravity="center"
+        android:scaleType="center"/>
+
+    <TextView
+        android:id="@*android:id/message"
+        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"
+        />
+
+    <TextView
+        android:id="@*android:id/status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="center"
+        android:textColor="?android:attr/textColorTertiary"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
new file mode 100644
index 0000000..ec357d2
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginBottom="0dp"
+    android:paddingTop="@dimen/global_actions_top_padding"
+    android:clipToPadding="false"
+    android:theme="@style/qs_theme"
+    android:clipChildren="false">
+
+    <LinearLayout
+        android:id="@android:id/list"
+        android:layout_width="@dimen/global_actions_panel_width"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|end"
+        android:gravity="center"
+        android:orientation="vertical"
+        android:padding="12dp"
+        android:translationZ="8dp" />
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 9586327..53ef2ab 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -21,8 +21,10 @@
     android:layout_height="match_parent"
     android:layout_weight="0"
     systemui:keyCode="3"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_home"
+    android:paddingTop="13dp"
+    android:paddingBottom="13dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index e3063c5..2fd4df4 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -39,7 +39,7 @@
             android:layout_height="wrap_content"
             android:gravity="center_horizontal"
             android:textStyle="italic"
-            android:textColor="#ffffff"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:visibility="gone" />
 
@@ -49,7 +49,7 @@
             android:layout_height="wrap_content"
             android:gravity="center_horizontal"
             android:textStyle="italic"
-            android:textColor="#ffffff"
+            android:textColor="?attr/wallpaperTextColorSecondary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:accessibilityLiveRegion="polite" />
 
@@ -68,7 +68,8 @@
         android:layout_gravity="bottom|end"
         android:src="@drawable/ic_camera_alt_24dp"
         android:scaleType="center"
-        android:contentDescription="@string/accessibility_camera_button" />
+        android:contentDescription="@string/accessibility_camera_button"
+        android:tint="?attr/wallpaperTextColor" />
 
     <com.android.systemui.statusbar.KeyguardAffordanceView
         android:id="@+id/left_button"
@@ -77,7 +78,8 @@
         android:layout_gravity="bottom|start"
         android:src="@drawable/ic_phone_24dp"
         android:scaleType="center"
-        android:contentDescription="@string/accessibility_phone_button" />
+        android:contentDescription="@string/accessibility_phone_button"
+        android:tint="?attr/wallpaperTextColor" />
 
     <com.android.systemui.statusbar.phone.LockIcon
         android:id="@+id/lock_icon"
@@ -88,4 +90,13 @@
         android:contentDescription="@string/accessibility_unlock_button"
         android:scaleType="center" />
 
+    <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/keyguard_bottom_area_overlay.xml b/packages/SystemUI/res/layout/keyguard_bottom_area_overlay.xml
new file mode 100644
index 0000000..37ba35f
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area_overlay.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+
+<!-- empty stub -->
+<merge />
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index c5f2f4a..7b30d6a 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -63,7 +63,7 @@
         android:gravity="center_vertical"
         android:ellipsize="marquee"
         android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="#ffffff"
+        android:textColor="?attr/wallpaperTextColorSecondary"
         android:singleLine="true" />
 
 </com.android.systemui.statusbar.phone.KeyguardStatusBarView>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 2bf4d9c..53f5dfe 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,9 +18,13 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginStart="@dimen/rounded_corner_content_padding"
+    android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp">
 
-    <FrameLayout
+    <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
@@ -40,7 +44,7 @@
             android:orientation="horizontal"
             android:clipChildren="false" />
 
-    </FrameLayout>
+    </com.android.systemui.statusbar.phone.NearestTouchFrame>
 
     <com.android.systemui.statusbar.policy.DeadZone
         android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 7601efc..39cdff4 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,9 +18,13 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/rounded_corner_content_padding"
+    android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
 
-    <FrameLayout
+    <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
@@ -40,7 +44,7 @@
             android:orientation="vertical"
             android:clipChildren="false" />
 
-    </FrameLayout>
+    </com.android.systemui.statusbar.phone.NearestTouchFrame>
 
     <com.android.systemui.statusbar.policy.DeadZone
         android:id="@+id/deadzone"
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 76315b8..eb74306 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -20,4 +20,4 @@
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
     android:layout_height="@dimen/notification_divider_height"
-    android:background="#FF616161" />
+    android:background="@color/notification_divider_color" />
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml
index b70f24b..3209f27 100644
--- a/packages/SystemUI/res/layout/notification_snooze.xml
+++ b/packages/SystemUI/res/layout/notification_snooze.xml
@@ -20,12 +20,13 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
+    android:clickable="true"
     android:background="@color/notification_guts_bg_color"
     android:theme="@*android:style/Theme.DeviceDefault.Light">
 
     <RelativeLayout
-        android:layout_width="match_parent"
         android:id="@+id/notification_snooze"
+        android:layout_width="match_parent"
         android:layout_height="@dimen/snooze_snackbar_min_height">
 
         <TextView
diff --git a/packages/SystemUI/res/layout/qs_customize_panel.xml b/packages/SystemUI/res/layout/qs_customize_panel.xml
index cbc2575..9ab8ac6 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel.xml
@@ -21,7 +21,6 @@
     android:layout_width="match_parent"
     android:layout_height="0dp"
     android:orientation="vertical"
-    android:elevation="4dp"
     android:background="@drawable/qs_customizer_background"
     android:gravity="center_horizontal">
 
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 34e43ce..1fd239b 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/qs_detail_background"
-    android:elevation="4dp"
     android:clickable="true"
     android:orientation="vertical"
     android:paddingBottom="8dp"
@@ -41,7 +40,6 @@
         android:background="@color/qs_detail_progress_track"
         android:src="@drawable/indeterminate_anim"
         android:scaleType="fitXY"
-        android:translationY="16dp"
         />
 
     <com.android.systemui.qs.NonInterceptingScrollView
diff --git a/packages/SystemUI/res/layout/qs_footer.xml b/packages/SystemUI/res/layout/qs_footer.xml
index 871d1f3..db39905 100644
--- a/packages/SystemUI/res/layout/qs_footer.xml
+++ b/packages/SystemUI/res/layout/qs_footer.xml
@@ -21,13 +21,11 @@
     android:id="@+id/header"
     android:layout_width="match_parent"
     android:layout_height="48dp"
-    android:elevation="4dp"
     android:baselineAligned="false"
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:paddingTop="0dp"
-    android:background="#00000000"
     android:gravity="center_vertical"
     android:orientation="horizontal">
 
@@ -116,9 +114,4 @@
             android:padding="14dp" />
     </LinearLayout>
 
-    <include layout="@layout/qs_divider"
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:layout_gravity="bottom" />
-
 </com.android.systemui.qs.QSFooter>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index fb4ac04..87101e4 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -18,24 +18,16 @@
     android:id="@+id/quick_settings_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="?android:attr/colorPrimaryDark"
+    android:background="@drawable/qs_background_primary"
+    android:elevation="4dp"
     android:clipToPadding="false"
     android:clipChildren="false">
 
-    <View
-        android:id="@+id/qs_background"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@drawable/qs_background_primary"
-        android:elevation="4dp" />
-
     <com.android.systemui.qs.QSPanel
         android:id="@+id/quick_settings_panel"
         android:layout_marginTop="28dp"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:elevation="4dp"
-        android:background="#00000000"
         android:layout_marginBottom="48dp" />
 
     <include layout="@layout/quick_status_bar_expanded_header" />
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 1fb254c..f8b7b8a 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -24,8 +24,6 @@
     android:layout_height="@dimen/status_bar_header_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:baselineAligned="false"
-    android:background="#00000000"
-    android:elevation="4dp"
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
@@ -35,13 +33,13 @@
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="32dp"
+        android:layout_height="40dp"
         android:layout_alignParentEnd="true"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:gravity="center"
-        android:paddingStart="16dp"
-        android:paddingEnd="16dp"
+        android:paddingStart="8dp"
+        android:paddingEnd="8dp"
         android:orientation="horizontal">
 
 
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 870bcf7..c84d280 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -21,8 +21,10 @@
     android:layout_width="@dimen/navigation_key_width"
     android:layout_height="match_parent"
     android:layout_weight="0"
-    android:scaleType="center"
+    android:scaleType="fitCenter"
     android:contentDescription="@string/accessibility_recent"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp"
     android:paddingStart="@dimen/navigation_key_padding"
     android:paddingEnd="@dimen/navigation_key_padding"
     />
diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml
index 53d9cc5..d7f058c 100644
--- a/packages/SystemUI/res/layout/recents_empty.xml
+++ b/packages/SystemUI/res/layout/recents_empty.xml
@@ -23,7 +23,8 @@
     android:drawableTop="@drawable/recents_empty"
     android:drawablePadding="25dp"
     android:textSize="16sp"
-    android:textColor="#ffffffff"
+    android:drawableTint="?attr/wallpaperTextColor"
+    android:textColor="?attr/wallpaperTextColor"
     android:text="@string/recents_empty_message"
     android:fontFamily="sans-serif"
     android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_stack_action_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
index 34b4e17..4707a8c 100644
--- a/packages/SystemUI/res/layout/recents_stack_action_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -24,7 +24,7 @@
     android:paddingBottom="12dp"
     android:text="@string/recents_stack_action_button_label"
     android:textSize="14sp"
-    android:textColor="#FFFFFF"
+    android:textColor="?attr/wallpaperTextColor"
     android:textAllCaps="true"
     android:shadowColor="#99000000"
     android:shadowDx="0"
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
new file mode 100644
index 0000000..d1ef5d6
--- /dev/null
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2012, 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"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ImageView
+        android:id="@+id/left"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:layout_gravity="left"
+        android:tint="#ff000000"
+        android:src="@drawable/rounded" />
+    <ImageView
+        android:id="@+id/right"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:tint="#ff000000"
+        android:layout_gravity="right"
+        android:src="@drawable/rounded" />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 2e22943..25c87d3 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -32,6 +32,7 @@
         android:layout_width="wrap_content"
         android:paddingEnd="6dp"
         android:src="@drawable/stat_sys_vpn_ic"
+        android:tint="@color/background_protect_secondary"
         android:contentDescription="@string/accessibility_vpn_on"
         />
     <FrameLayout
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 0852020..bef0830 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -27,7 +27,6 @@
 
     <include
         layout="@layout/keyguard_status_view"
-        android:layout_height="wrap_content"
         android:visibility="gone" />
 
     <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
@@ -41,7 +40,7 @@
         <FrameLayout
             android:id="@+id/qs_frame"
             android:layout="@layout/qs_panel"
-            android:layout_width="@dimen/notification_panel_width"
+            android:layout_width="@dimen/qs_panel_width"
             android:layout_height="match_parent"
             android:layout_gravity="@integer/notification_panel_layout_gravity"
             android:clipToPadding="false"
@@ -50,11 +49,15 @@
 
         <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
             android:id="@+id/notification_stack_scroller"
+            android:layout_marginTop="@dimen/notification_panel_margin_top"
             android:layout_width="@dimen/notification_panel_width"
             android:layout_height="match_parent"
             android:layout_gravity="@integer/notification_panel_layout_gravity"
             android:layout_marginBottom="@dimen/close_handle_underlap" />
 
+        <include layout="@layout/ambient_indication"
+            android:id="@+id/ambient_indication_container" />
+
         <ViewStub
             android:id="@+id/keyguard_user_switcher"
             android:layout="@layout/keyguard_user_switcher"
diff --git a/packages/SystemUI/res/layout/status_bar_no_notifications.xml b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
index 6f87184..0a25b69 100644
--- a/packages/SystemUI/res/layout/status_bar_no_notifications.xml
+++ b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
@@ -27,7 +27,7 @@
             android:layout_height="64dp"
             android:paddingTop="28dp"
             android:gravity="top|center_horizontal"
-            android:textColor="#e6ffffff"
+            android:textColor="?attr/wallpaperTextColor"
             android:textSize="16sp"
             android:text="@string/empty_shade_text"/>
 </com.android.systemui.statusbar.EmptyShadeView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
index efb273f..8dc4cb4 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -30,5 +30,6 @@
             android:focusable="true"
             android:contentDescription="@string/accessibility_clear_all"
             android:text="@string/clear_all_notifications_text"
+            android:textColor="?attr/wallpaperTextColor"
             android:textAllCaps="true"/>
 </com.android.systemui.statusbar.DismissView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 51eefb6..029d16e 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,7 +48,6 @@
         android:layout_height="match_parent"
         android:importantForAccessibility="no"
         sysui:ignoreRightInset="true"
-        sysui:scrimColor="@color/scrim_behind_color"
         />
 
     <com.android.systemui.statusbar.AlphaOptimizedView
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 18ffd0f..4487abc 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -21,6 +21,7 @@
     android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
     android:background="@drawable/volume_dialog_background"
     android:paddingTop="@dimen/volume_dialog_padding_top"
+    android:theme="@style/qs_theme"
     android:translationZ="4dp" >
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index 91dc617..7ffcb1e 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -51,8 +51,7 @@
             android:clickable="true"
             android:contentDescription="@string/accessibility_desc_close"
             android:scaleType="center"
-            android:src="@drawable/ic_close"
-            android:tint="@android:color/white" />
+            android:src="@drawable/ic_close_white_rounded" />
 
         <TextView
             android:id="@+id/zen_introduction_message"
@@ -128,4 +127,4 @@
         android:textColor="?android:attr/colorAccent"
         android:textAppearance="@style/TextAppearance.QS.DetailButton" />
 
-</com.android.systemui.volume.ZenFooter>
\ No newline at end of file
+</com.android.systemui.volume.ZenFooter>
diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index 2b4a0f5..ab52465 100644
--- a/packages/SystemUI/res/layout/zen_mode_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -27,6 +27,8 @@
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="48dp"
+        android:gravity="center_vertical"
         android:layout_centerVertical="true"
         android:orientation="vertical"
         android:layout_toEndOf="@android:id/checkbox"
@@ -79,4 +81,4 @@
         android:tint="?android:attr/textColorPrimary"
         android:src="@drawable/ic_qs_plus" />
 
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 200eabf..3826bdd 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -59,8 +59,7 @@
                 android:clickable="true"
                 android:contentDescription="@string/accessibility_desc_close"
                 android:scaleType="center"
-                android:src="@drawable/ic_close"
-                android:tint="@android:color/white" />
+                android:src="@drawable/ic_close_white_rounded" />
 
             <TextView
                 android:id="@+id/zen_introduction_message"
@@ -94,7 +93,7 @@
 
         </RelativeLayout>
 
-        <LinearLayout
+        <com.android.systemui.volume.ZenRadioLayout
             android:id="@+id/zen_conditions"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -112,7 +111,7 @@
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
                 android:orientation="vertical"/>
-        </LinearLayout>
+        </com.android.systemui.volume.ZenRadioLayout>
 
         <TextView
             android:id="@+id/zen_alarm_warning"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 32f3ca5..db8edff 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Jy sal nie deur geluide en vibrasies gepla word nie, behalwe deur wekkers, herinneringe, geleenthede en bellers wat jy spesifiseer. Jy sal steeds enigiets hoor wat jy kies om te speel, insluitend musiek, video\'s en speletjies."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Jy sal nie deur geluide en vibrasies gepla word nie, behalwe deur wekkers. Jy sal steeds enigiets hoor wat jy kies om te speel, insluitend musiek, video\'s en speletjies."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Jy sal nie deur klanke en vibrasies gesteur word nie, afgesien van wekkers, onthounotas, gebeurtenisse en bellers wat jy spesifiseer."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Pasmaak"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af. Jy sal steeds foonoproepe kan maak."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Jy is gekoppel aan <xliff:g id="APPLICATION">%1$s</xliff:g>, wat jou persoonlike netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> bestuur jou werkprofiel. Die profiel is gekoppel aan <xliff:g id="APPLICATION">%2$s</xliff:g>, wat jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor.\n\nKontak jou administrateur vir meer inligting."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> bestuur jou werkprofiel. Die profiel is gekoppel aan <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, wat jou netwerkaktiwiteit, insluitend e-posse, programme en webwerwe, kan monitor.\n\nJy is ook gekoppel aan <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, wat jou persoonlike netwerkaktiwiteit kan monitor."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ontsluit vir <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> loop tans"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Toestel sal gesluit bly totdat jy dit handmatig ontsluit"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Kry kennisgewings vinniger"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Sien hulle voordat jy ontsluit"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nee dankie"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Stel op"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Skakel nou af"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Beëindig nou"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Vou uit"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Vou in"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skerm is vasgespeld"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Af"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met kragkennisgewingkontroles kan jy \'n belangrikheidvlak van 0 tot 5 vir \'n program se kennisgewings stel. \n\n"<b>"Vlak 5"</b>" \n- Wys aan die bokant van die kennisgewinglys \n- Laat volskermonderbreking toe \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 4"</b>" \n- Verhoed volskermonderbreking \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 3"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n\n"<b>"Vlak 2"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n\n"<b>"Vlak 1"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n- Versteek van sluitskerm en statusbalk \n- Wys aan die onderkant van die kennisgewinglys \n\n"<b>"Vlak 0"</b>" \n- Blokkeer alle kennisgewings van die program af"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Kennisgewings"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jy sal nie meer hierdie kennisgewings kry nie."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jy sal nie meer hierdie kennisgewings kry nie"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kennisgewingkategorieë"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Hierdie program het nie kennisgewingkategorieë nie"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 uit <xliff:g id="NUMBER_1">%d</xliff:g> kennisgewingkategorieë van hierdie program</item>
       <item quantity="one">1 uit <xliff:g id="NUMBER_0">%d</xliff:g> kennisgewingkategorie van hierdie program</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kennisgewingkontroles"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"kennisgewing-sluimeropsies"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minute"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uur"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ONTDOEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Sluimer vir <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batterygebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
diff --git a/packages/SystemUI/res/values-af/strings_car.xml b/packages/SystemUI/res/values-af/strings_car.xml
index 7c6f609..87462fc 100644
--- a/packages/SystemUI/res/values-af/strings_car.xml
+++ b/packages/SystemUI/res/values-af/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Ry veilig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bly heeltemal bewus van bestuurtoestande en gehoorsaam toepaslike wette altyd. Rigtingaanwysings sal dalk onakkuraat, onvolledig, gevaarlik, ontoepaslik of verbode wees of behels dat administratiewe gebiede oorgesteek word. Besigheidsinligting sal dalk ook onakkuraat of onvolledig wees. Data is nie intyds nie en liggingakkuraatheid kan nie gewaarborg word nie. Moenie jou mobiele toestel hanteer of programme wat nie vir Android Auto bedoel is, gebruik terwyl jy bestuur nie."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Onbekend"</string>
+    <string name="start_driving" msgid="864023351402918991">"Begin ry"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 197239f..b641a49 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"እርስዎ ከወሰንዋቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር፣ በድምጾች እና ንዝረቶች አይረበሹም። ሙዚቃ፣ ቪዲዮዎች እና ጨዋታዎች ጨምሮ ለመጫወት የሚመርጡትን ማንኛውም ነገር አሁንም ይሰማሉ።"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"ከማንቂያዎች በስተቀር፣ በድምጾች እና ንዝረቶች አይረበሹም። ሙዚቃ፣ ቪዲዮዎች እና ጨዋታዎች ጨምሮ ለመጫወት የሚመርጡትን ማንኛውም ነገር አሁንም ይሰማሉ።"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"እርስዎ ከገለጿቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር በድምጾች እና ንዝረቶች አይረበሹም።"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"አብጅ"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል። አሁንም የድምጽ ጥሪዎችን ማድረግ ይችላሉ።"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል።"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"እርስዎ ኢሜይሎችን፣ መተግበሪያዎችን እና ድር ጣቢያዎችንም ጨምሮ የግል የአውታረ መረብ እንቅስቃሴዎን ከሚከታተለው ከ<xliff:g id="APPLICATION">%1$s</xliff:g> ጋር ተገናኝተዋል።"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"የእርስዎ የሥራ መገለጫ በ<xliff:g id="ORGANIZATION">%1$s</xliff:g> የሚተዳደር ነው። መገለጫው ኢሜይሎችን፣ መተግበሪያዎችን፣ እና የድር ጣቢያዎችን ጨምሮ የአውታረ መረብ እንቅስቃሴን መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION">%2$s</xliff:g> ጋር ተገናኝቷል።\n\nለተጨማሪ መረጃ የእርስዎን አስተዳዳሪ ያነጋግሩ።"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"የእርስዎ የሥራ መገለጫ በ<xliff:g id="ORGANIZATION">%1$s</xliff:g> የሚተዳደር ነው። መገለጫው ኢሜይሎችን፣ መተግበሪያዎችን፣ እና የድር ጣቢያዎችን ጨምሮ የአውታረ መረብ እንቅስቃሴን መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ጋር ተገናኝቷል።\n\nበተጨማሪ የእርስዎን የግል የአውታረ መረብ እንቅስቃሴ መቆጣጠር ከሚችለው ከ<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ጋር ተገናኝተዋል።"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ለ<xliff:g id="USER_NAME">%1$s</xliff:g> ተከፍቷል"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> እያሄደ ነው"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"እራስዎ እስኪከፍቱት ድረስ መሣሪያ እንደተቆለፈ ይቆያል"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ማሳወቂያዎችን ፈጥነው ያግኙ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ከመክፈትዎ በፊት ይመልከቷቸው"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"አይ፣ አመሰግናለሁ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"አዋቅር"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"አሁን አጥፋ"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"አሁን ጨርስ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"አስፋ"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ሰብስብ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ማያ ገጽ ተሰክቷል"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ጠፍቷል"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"በኃይል ማሳወቂያ መቆጣጠሪያዎች አማካኝነት የአንድ መተግበሪያ ማሳወቂያዎች የአስፈላጊነት ደረጃ ከ0 እስከ 5 ድረስ ማዘጋጀት ይችላሉ። \n\n"<b>"ደረጃ 5"</b>" \n- በማሳወቂያ ዝርዝሩ አናት ላይ አሳይ \n- የሙሉ ማያ ገጽ ማቋረጥን ፍቀድ \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 4"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 3"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- በፍጹም አጮልቀው አይምልከቱ \n\n"<b>"ደረጃ 2"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ እና ንዝረትን በፍጹም አይኑር \n\n"<b>"ደረጃ 1"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ ወይም ንዝረትን በፍጹም አያደርጉ \n- ከመቆለፊያ ገጽ እና የሁኔታ አሞሌ ይደብቁ \n- በማሳወቂያ ዝርዝር ግርጌ ላይ አሳይ \n\n"<b>"ደረጃ 0"</b>" \n- ሁሉንም የመተግበሪያው ማሳወቂያዎች ያግዱ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ማሳወቂያዎች"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያግኙዋቸውም።"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያገኟቸውም"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> የማሳወቂያ ምድቦች"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ይህ መተግበሪያ የማሳወቂያ ምድቦች የሉትም"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 ከ<xliff:g id="NUMBER_1">%d</xliff:g> የማሳወቂያ ምድቦች ከዚህ መተግበሪያ</item>
       <item quantity="other">1 <xliff:g id="NUMBER_1">%d</xliff:g> የማሳወቂያ ምድቦች ከዚህ መተግበሪያ</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"የማሳወቂያ መቆጣጠሪያዎች"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"የማሳወቂያ ማሸለቢያ አማራጮች"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ደቂቃዎች"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ደቂቃዎች"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ሰዓት"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ሰዓቶች"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ቀልብስ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ለ<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> አሸልቧል"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"የባትሪ አጠቃቀም"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
diff --git a/packages/SystemUI/res/values-am/strings_car.xml b/packages/SystemUI/res/values-am/strings_car.xml
index 8550c42..5ebb05a 100644
--- a/packages/SystemUI/res/values-am/strings_car.xml
+++ b/packages/SystemUI/res/values-am/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ደህንነትዎን ጠብቀው ያሽከርክሩ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"የመኪና አነዳድ ሁኔታዎችን በተመለከተ ሙሉ በሙሉ ግንዛቤ ይኑርዎት፣ እንዲሁም የሚመለከታቸውን ሕጎች ሁልጊዜ ያክብሩ። የሚሰጡ አቅጣጫዎች ምናልባት ትክክል ያልሆኑ፣ ያልተሟሉ፣ አደገኛ፣ አግባብ ያልሆኑ፣ የተከለከሉ ወይም አስተዳደራዊ አካባቢዎችን ማቋረጥን የሚያካትቱ ሊሆኑ ይችላሉ። በተጨማሪም የንግድ ሥራ መረጃ ትክክል ያልሆነ ወይም ያልተሟላ ሊሆን ይችላል። ውሂብ ቅጽበታዊ አይደለም፣ እና የአካባቢ ትክክለኛነት ዋስትና ሊሰጥበት አይችልም። መኪና በሚነዱበት ጊዜ የእርስዎን ተንቀሳቃሽ መሣሪያ አይነካኩ ወይም ለAndroid Auto የታለሙ መተግበሪያዎችን አይጠቀሙ።"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ያልታወቀ"</string>
+    <string name="start_driving" msgid="864023351402918991">"መንዳት ይጀምሩ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index 7a375a9..89fd692 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/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-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5775436..e37152f 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -74,8 +74,8 @@
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"جارٍ حفظ لقطة الشاشة..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"جارٍ حفظ لقطة الشاشة..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"يتم حفظ لقطة."</string>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"تم التقاط لقطة الشاشة"</string>
-    <string name="screenshot_saved_text" msgid="2685605830386712477">"انقر لعرض لقطة الشاشة"</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"تم التقاط لقطة الشاشة."</string>
+    <string name="screenshot_saved_text" msgid="2685605830386712477">"انقر لعرض لقطة الشاشة."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"تعذر التقاط لقطة الشاشة."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"حدثت مشكلة أثناء حفظ لقطة الشاشة."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"يتعذر حفظ لقطة الشاشة نظرًا لأن مساحة التخزين المتاحة محدودة."</string>
@@ -161,7 +161,7 @@
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"إيقاف بيانات الجوال"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ربط البلوتوث."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"وضع الطائرة."</string>
-    <string name="accessibility_vpn_on" msgid="5993385083262856059">"‏الشبكة الافتراضية الخاصة (VPN) قيد التشغيل."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"‏الشبكة الظاهرية الخاصة (VPN) قيد التشغيل."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"‏ليس هناك شريحة SIM."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"فتح تفاصيل البطارية"</string>
@@ -254,7 +254,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏تم تعيين الموقع بواسطة GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
-    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"و<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
       <item quantity="zero"><xliff:g id="NUMBER_1">%s</xliff:g> إشعار آخر بداخل المجموعة.</item>
       <item quantity="two">إشعاران (<xliff:g id="NUMBER_1">%s</xliff:g>) آخران بداخل المجموعة.</item>
@@ -360,8 +360,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"لن يتم إزعاجك بالأصوات والاهتزاز، عدا من التنبيهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى ومقاطع الفيديو والألعاب."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"لن يتم إزعاجك بالأصوات والاهتزاز، عدا من التنبيهات. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى ومقاطع الفيديو والألعاب."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"لن يتم إزعاجك بأصوات أو اهتزاز، عدا من التنبيهات والتذكيرات والأحداث والمتصلين الذين تحددهم."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"تخصيص"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب. إلا أنه سيظل بإمكانك إجراء مكالمات هاتفية."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب."</string>
@@ -428,22 +427,22 @@
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"يخضع الجهاز لإدارة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بـ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"يخضع الجهاز لإدارة مؤسستك"</string>
     <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"يخضع الجهاز لإدارة مؤسستك وتم ربطه بالشبكات الافتراضية الخاصة"</string>
-    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"يخضع الجهاز لإدارة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بالشبكات الافتراضية الخاصة"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"يخضع الجهاز لإدارة مؤسستك وتم ربطه بالشبكات الظاهرية الخاصة"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"يخضع الجهاز لإدارة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> وتم ربطه بالشبكات الظاهرية الخاصة"</string>
     <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"يمكن لمؤسستك مراقبة حركة بيانات الشبكة في الملف الشخصي للعمل"</string>
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"يمكن لـ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مراقبة حركة بيانات الشبكة في ملفك الشخصي للعمل"</string>
     <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"قد تكون الشبكة خاضعة للمراقبة"</string>
-    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"تم ربط الجهاز بالشبكات الافتراضية الخاصة"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"تم ربط الجهاز بالشبكات الظاهرية الخاصة"</string>
     <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"تم ربط الملف الشخصي للعمل بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"تم ربط الملف الشخصي بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"تم ربط الجهاز بـ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="1652495295941959815">"إدارة الأجهزة"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"مراقبة الملف الشخصي"</string>
     <string name="monitoring_title" msgid="169206259253048106">"مراقبة الشبكات"</string>
-    <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"‏شبكة افتراضية خاصة (VPN)"</string>
+    <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"‏شبكة ظاهرية خاصة (VPN)"</string>
     <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"تسجيل بيانات الشبكة"</string>
     <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"‏شهادات CA"</string>
-    <string name="disable_vpn" msgid="4435534311510272506">"تعطيل الشبكة الافتراضية الخاصة"</string>
+    <string name="disable_vpn" msgid="4435534311510272506">"تعطيل الشبكة الظاهرية الخاصة"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"‏قطع الاتصال بشبكة VPN"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"عرض السياسات"</string>
     <string name="monitoring_description_named_management" msgid="5281789135578986303">"تتم إدارة جهازك بواسطة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nيمكن للمشرف مراقبة وإدارة الإعدادات والدخول إلى المؤسسة والتطبيقات والبيانات المرتبطة بجهازك ومعلومات الموقع الجغرافي للجهاز.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف."</string>
@@ -463,25 +462,27 @@
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"مزيد من المعلومات"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"لقد اتصلت بتطبيق <xliff:g id="VPN_APP">%1$s</xliff:g>، الذي يمكن أن يراقب نشاط الشبكة، بما في ذلك رسائل البريد الإلكتروني والتطبيقات والمواقع الإلكترونية."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
-    <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"‏فتح إعدادات الشبكة الافتراضية الخاصة (VPN)"</string>
+    <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"‏فتح إعدادات الشبكة الظاهرية الخاصة (VPN)"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"فتح بيانات الاعتماد الموثوق بها"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات على جهازك.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"‏لقد منحت تطبيقًا الإذن لإعداد اتصال شبكة افتراضية خاصة (VPN).\n\nيمكن لهذا التطبيق مراقبة أنشطتك على الجهاز والشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"تتم إدارة ملفك الشخصي للعمل بواسطة <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nويمكن للمشرف مراقبة نشاط الشبكة، بما في ذلك رسائل البريد الإلكتروني والتطبيقات والمواقع الإلكترونية.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف.\n\nوتجدر الإشارة إلى أنك متصل أيضًا بشبكة افتراضية خاصة يمكن أن تراقب نشاط الشبكة."</string>
-    <string name="legacy_vpn_name" msgid="6604123105765737830">"شبكة افتراضية خاصة"</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"‏لقد منحت تطبيقًا الإذن لإعداد اتصال شبكة ظاهرية خاصة (VPN).\n\nيمكن لهذا التطبيق مراقبة أنشطتك على الجهاز والشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"تتم إدارة ملفك الشخصي للعمل بواسطة <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nويمكن للمشرف مراقبة نشاط الشبكة، بما في ذلك رسائل البريد الإلكتروني والتطبيقات والمواقع الإلكترونية.\n\nللحصول على المزيد من المعلومات، اتصل بالمشرف.\n\nوتجدر الإشارة إلى أنك متصل أيضًا بشبكة ظاهرية خاصة يمكن أن تراقب نشاط الشبكة."</string>
+    <string name="legacy_vpn_name" msgid="6604123105765737830">"شبكة ظاهرية خاصة"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"تم ربطك بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"أنت متصل بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"أنت متصل بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط الملف الشخصي بـ <xliff:g id="APPLICATION">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nيمكنك الاتصال بالمشرف للحصول على مزيد من المعلومات."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط هذا الملف الشخصي بـ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nتم ربطك بـ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك الشخصية."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"تم إلغاء القفل لـ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> قيد التشغيل"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"سيظل الجهاز مقفلاً إلى أن يتم إلغاء قفله يدويًا"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"الحصول على الإشعارات بشكل أسرع"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"الاطلاع عليها قبل إلغاء القفل"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"لا، شكرًا"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"إعداد"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"إيقاف التشغيل الآن"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"إنهاء الآن"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"توسيع"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"تصغير"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"تم تثبيت الشاشة"</string>
@@ -556,9 +557,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"إيقاف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك تعيين مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة التأمين وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"الإشعارات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"لن تتلقى هذه الإشعارات بعد الآن."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"لن تتلقى هذه الإشعارات بعد الآن."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> فئة إشعار"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"لا يحتوي هذا التطبيق على فئات إشعار"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="zero">1 من إجمالي <xliff:g id="NUMBER_1">%d</xliff:g> فئة إشعار من هذا التطبيق</item>
       <item quantity="two">1 من إجمالي فئتي إشعار (<xliff:g id="NUMBER_1">%d</xliff:g>) من هذا التطبيق</item>
@@ -586,12 +589,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"عناصر التحكم في الإشعارات"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"خيارات تأجيل الإشعارات"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"١٥ دقيقة"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"٣۰ دقيقة"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"ساعة واحدة"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"ساعتان"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"تراجع"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"تم تأجيل الإشعار لمدة <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"استخدام البطارية"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
diff --git a/packages/SystemUI/res/values-ar/strings_car.xml b/packages/SystemUI/res/values-ar/strings_car.xml
index 0f315a4..7fec955 100644
--- a/packages/SystemUI/res/values-ar/strings_car.xml
+++ b/packages/SystemUI/res/values-ar/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"القيادة بأمان"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏عليك التعرف بشكل تام على ظروف القيادة والالتزام بالقوانين السارية. ويمكن أن تكون الاتجاهات غير دقيقة أو غير مكتملة أو خطيرة أو غير مناسبة أو محظورة أو تتضمن عبور مناطق إدارية. ويمكن أن تكون معلومات الأنشطة التجارية أيضًا غير دقيقة أو غير مكتملة. ولا يتم نشر البيانات في الوقت الفعلي، كما لا يمكن ضمان دقة المواقع. ولا تتعامل مع جهازك الجوّال أو تستخدم تطبيقات ليست متوافقة مع Android Auto أثناء القيادة."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"غير معروف"</string>
+    <string name="start_driving" msgid="864023351402918991">"بدء القيادة"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 40bd32a..ddb1848 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Seçdiyiniz siqnal, xatırladıcı, tədbir və zənglər istisna olmaqla səslər və vibrasiyalar Sizi narahat etməyəcək. Musiqi, video və oyunlar da daxil olmaqla oxutmaq istədiyiniz hər şeyi eşidəcəksiniz."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Siqnallar istisna olmaqla səslər və vibrasiyalar Sizi narahat etməyəcək. Musiqi, video və oyunlar da daxil olmaqla oxutmaq istədiyiniz hər şeyi eşidəcəksiniz."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Zəng, xatırlatma, hadisə və seçdiyiniz zəng edənlər istisna olmaqla səs və vibrasiya Sizi narahat etməyəcək."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Fərdiləşdirin"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır. Yenə də telefon zəngi edə bilərsiniz."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə qoşulmusunuz və o, e-məktublar, tətbiq və veb saytlar daxil olmaqla şəxsi şəbəkə fəaliyyətinizə nəzarət edə bilər."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"İş profili <xliff:g id="ORGANIZATION">%1$s</xliff:g> tərəfindən idarə olunur. Profil e-poçt, tətbiq və veb saytlar da daxil olmaqla şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION">%2$s</xliff:g> tətbiqinə qoşuludur.\n\nƏtraflı məlumat üçün admin ilə əlaqə saxlayın."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"İş profili <xliff:g id="ORGANIZATION">%1$s</xliff:g> tərəfindən idarə edilir. Profil e-poçt, tətbiq və veb saytlar da daxil olmaqla şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> tətbiqinə qoşuludur.\n\nEyni zamanda şəxsi şəbəkə fəaliyyətinə nəzarət edən <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> tətbiqinə qoşulusunuz."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> üçün kiliddən çıxarıldı"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> işləyir"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirişləri daha sürətlə əldə edin"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Kiliddən çıxarmadan öncə onları görün"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Yox, çox sağ olun"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Quraşdırın"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"İndi deaktiv edin"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"İndi qurtarın"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Genişləndirin"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Yığcamlaşdırın"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrana sancaq taxıldı"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Deaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Enerji bildiriş nəzarəti ilə, tətbiq bildirişləri üçün əhəmiyyət səviyyəsini 0-dan 5-ə kimi ayarlaya bilərsiniz. \n\n"<b>"Səviyyə 5"</b>" \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n- Tam ekran kəsintisinə icazə verin \n- Hər zaman izləyin \n\n"<b>"Səviyyə 4"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Hər zaman izləyin \n\n"<b>"Level 3"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n\n"<b>"Level 2"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n\n"<b>"Səviyyə 1"</b>" \n- Prevent full screen interruption \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n- Ekran kilidi və ya status panelindən gizlədin \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n\n"<b>"Səviyyə 0"</b>" \n- Bütün bildirişləri tətbiqdən blok edin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirişlər"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirişlər daha sizə göndərilməyəcək."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirişlər daha sizə göndərilməyəcək"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildiriş kateqoriyaları"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu tətbiqin bildiriş kateqoriyası yoxdur"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu tətbiqin <xliff:g id="NUMBER_1">%d</xliff:g> bildiriş kateqoriyasından 1 kanal</item>
       <item quantity="one">Bu tətbiqin <xliff:g id="NUMBER_0">%d</xliff:g> bildiriş kateqoriyasından 1 kanal</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"bildiriş nəzarəti"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildiriş təxirə salma seçimləri"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dəqiqə"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 dəqiqə"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 saat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ QAYTARIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> üçün təxirə salınıb"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya istifadəsi"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
diff --git a/packages/SystemUI/res/values-az/strings_car.xml b/packages/SystemUI/res/values-az/strings_car.xml
index 9ac7ce0..0b49eda 100644
--- a/packages/SystemUI/res/values-az/strings_car.xml
+++ b/packages/SystemUI/res/values-az/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Təhlükəsiz sürün"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Yol şəraitindən tam xəbərdar olun və hər zaman tətbiq olunan qaydalara riayət edin. İstiqamətlər qeyri-dəqiq, natamam, təhlükəli, uyğun olmayan, qadağan edilmiş və ya inzibati sahələrə keçid ilə nəticələnə bilər. Biznes məlumatı da qeyri-dəqiq və ya natamam ola bilər. Data real vaxtda deyil və məkan dəqiqliyinə zəmanət verilmir. Avtomobil idarə edərkən mobil cihazınızı elinizə almayın və ya Android Avto üçün nəzərdə tutulmamış tətbiqlərdən istifadə etməyin."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Naməlum"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sürməyə başlayın"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 0b44eb5..42a3aec 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -76,7 +76,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nije moguće napraviti snimak ekrana."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Došlo je do problema pri čuvanju snimka ekrana."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prenosa datoteka"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Priključi kao medija plejer (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Priključi kao kameru (PTP)"</string>
@@ -91,7 +91,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključajte"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Dugme za otključavanje, čeka se na otisak prsta"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Čeka se otisak prsta"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključaj bez korišćenja otiska prsta"</string>
     <string name="unlock_label" msgid="8779712358041029439">"otključaj"</string>
     <string name="phone_label" msgid="2320074140205331708">"otvori telefon"</string>
@@ -153,11 +153,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Nema SIM kartice."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Podaci za mobilne uređaje"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Podaci za mobilne uređaje su uključeni"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Podaci za mobilne uređaje su isključeni"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilni podaci"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilni podaci su uključeni"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobilni podaci su isključeni"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth privezivanje."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim rada u avionu."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN je uključen."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Nema SIM kartice."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Promena mreže mobilnog operatera."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o bateriji"</string>
@@ -165,7 +166,7 @@
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemska podešavanja."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obaveštenja."</string>
-    <string name="notification_shelf_content_description" msgid="5511922384591583913">"Kontejner preklopnog menija za obaveštenja"</string>
+    <string name="accessibility_overflow_action" msgid="5681882033274783311">"Pogledajte sva obaveštenja"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Obriši obaveštenje."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS je omogućen."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Učitavanje GPS-a."</string>
@@ -237,13 +238,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Osvetljenost ekrana"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Puni se"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci su pauzirani"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilni podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Podaci su pauzirani"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Ograničenje potrošnje podataka koje ste podesili je dostignuto. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će biti naplaćeni troškovi za potrošnju podataka."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli se ograničenje za podatke koje ste podesili. Više ne koristite mobilne podatke.\n\nAko nastavite, možda će važiti tarife za potrošnju podataka."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internet veze"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi je povezan"</string>
@@ -279,7 +279,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Osvetljenost"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatska rotacija"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Automatsko rotiranje ekrana"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Podesi na <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Režim <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotacija je zaključana"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertikalni prikaz"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horizontalni prikaz"</string>
@@ -317,7 +317,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obaveštenja"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampa"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Podaci za mobilne uređaje"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Potrošnja podataka"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Preko ograničenja"</string>
@@ -337,7 +337,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g> nije uspelo."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je onemogućena u bezbednom režimu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Aplikacija ne podržava podeljeni ekran"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Prevucite ovde da biste koristili razdeljeni ekran"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podeli vertikalno"</string>
@@ -363,7 +362,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitna obaveštenja su u nastavku"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da biste otvorili"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite nagore da biste otključali"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Ovim uređajem se upravlja"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite od ikone za telefon"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Prevucite od ikone za glasovnu pomoć"</string>
@@ -401,7 +400,7 @@
     <string name="user_logout_notification_text" msgid="3350262809611876284">"Odjavite aktuelnog korisnika"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVI KORISNIKA"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"Dodajete novog korisnika?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
     <string name="user_remove_user_title" msgid="4681256956076895559">"Želite li da uklonite korisnika?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Ukloni"</string>
@@ -416,13 +415,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profil se možda nadgleda"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"Mreža se možda nadgleda"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"Mreža se možda nadgleda"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Nadgledanje uređaja"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može da nadgleda mrežni saobraćaj"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Uređajem upravlja organizacija i povezan je sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Uređajem upravlja organizacija"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Uređajem upravlja organizacija i povezan je sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Organizacija može da prati mrežni saobraćaj na profilu za Work"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na profilu za Work"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Mreža se možda nadgleda"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Uređaj je povezan sa VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Profil za Work je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Uređaj je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Upravljanje uređajima"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Nadgledanje profila"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Nadgledanje mreže"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Evidentiranje mreže"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Evidentiranje mreže"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA sertifikati"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Onemogući VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Prekini vezu sa VPN-om"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Prikaži smernice"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Uređajem upravlja organizacija.\n\nAdministrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Organizacija je na ovom uređaju instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Organizacija je na profilu za Work instalirala autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Povezani ste sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Povezani ste sa aplikacijama <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>, koje mogu da nadgledaju aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Profil za Work je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Lični profil je povezan sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Uređajem upravlja <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> koristi <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> za upravljanje uređajem."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Administrator može da nadgleda podešavanja, korporativni pristup, aplikacije, podatke povezane sa uređajem i informacije o lokaciji uređaja, kao i da upravlja njima."</string>
@@ -431,20 +457,24 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Povezani ste sa aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Otvorite podešavanja VPN-a"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Otvorite pouzdane akreditive"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju.\n\nKontaktirajte administratora za više informacija."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Dali ste dozvolu aplikaciji da podešava VPN vezu.\n\nTa aplikacija može da nadgleda aktivnosti na uređaju i mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> upravlja profilom za Work.\n\nAdministrator može da prati aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nKontaktirajte administratora za više informacija.\n\nPovezani ste i sa VPN-om, koji može da prati aktivnosti na mreži."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži, uključujući imejlove, aplikacije i veb-sajtove."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> upravlja profilom za Work. On je povezan sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može da prati aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nKontaktirajte administratora za više informacija."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nViše informacija potražite od administratora."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profilom za Work upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može da nadgleda aktivnosti na poslovnoj mreži, uključujući imejlove, aplikacije i veb-sajtove.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može da nadgleda aktivnosti na ličnoj mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Funkcija <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je pokrenuta"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ne otključate ručno"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže dobijajte obaveštenja"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Pregledajte ih pre otključavanja"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
-    <string name="hidden_notifications_setup" msgid="41079514801976810">"Podesi"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Aktiviraj"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Prekini odmah"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
@@ -470,10 +500,8 @@
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Dodirnite da biste uključili zvuk."</string>
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da biste isključili zvuk."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Kontrole za jačinu zvuka (%s) su prikazane. Prevucite nagore da biste ih odbacili."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole za jačinu zvuka su sakrivene"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tjuner za korisnički interfejs sistema"</string>
@@ -523,24 +551,36 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obaveštenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete da dobijate ova obaveštenja."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija iz ove aplikacije</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete dobijati ova obaveštenja"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Kategorija obaveštenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obaveštenja"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obaveštenja za ovu aplikaciju</item>
+      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obaveštenja za ovu aplikaciju</item>
+      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija obaveštenja za ovu aplikaciju</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Kontrole obaveštenja za otvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Kontrole obaveštenja za zatvaranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Dozvoli obaveštenja sa ovog kanala"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Sve kategorije"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Još podešavanja"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Prilagodite: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obaveštenja"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije za odlaganje obaveštenja"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Ne odlaži"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
@@ -553,8 +593,8 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Taster sa strelicom nalevo"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Taster sa strelicom nadesno"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Taster sa centralnom strelicom"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
-    <string name="keyboard_key_space" msgid="2499861316311153293">"Taster za razmak"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Razmak"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Taster za brisanje unazad"</string>
     <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Taster za reprodukciju/pauziranje"</string>
@@ -620,7 +660,7 @@
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"Prebacivač za tastaturu"</string>
     <string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+    <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"Prilagodi širinu dugmeta"</string>
     <string name="clipboard" msgid="1313879395099896312">"Privremena memorija"</string>
     <string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -666,6 +706,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava podeljeni ekran."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Otvori Podešavanja."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Otvori Brza podešavanja."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Zatvori Brza podešavanja."</string>
@@ -680,6 +722,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Proširi"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Umanji"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zatvori"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Prevucite nadole da biste odbili"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Meni Slika u slici"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je slika u slici"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da biste otvorili podešavanja i isključili je."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Pusti"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Pauziraj"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Pređi na sledeće"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Pređi na prethodno"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telefon se isključio zbog toplote"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Telefon sada normalno radi"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Telefon je bio prevruć, pa se isključio da se ohladi. Sada radi normalno.\n\nTelefon može previše da se ugreje ako:\n	• Koristite aplikacije koje zahtevaju puno resursa (npr. video igre, video ili aplikacije za navigaciju)\n	• Preuzimate/otpremate velike datoteke\n	• Koristite telefon na visokoj temperaturi"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Telefon se zagrejao"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Neke funkcije su ograničene dok se telefon ne ohladi"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Telefon će automatski pokušati da se ohladi. I dalje ćete moći da koristite telefon, ali će sporije reagovati.\n\nKada se telefon ohladi, normalno će raditi."</string>
@@ -688,7 +741,7 @@
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"I leva prečica otključava"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"I desna prečica otključava"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"Ništa"</string>
-    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokretanje <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokreni <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Druge aplikacije"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Krug"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"Plus"</string>
@@ -702,9 +755,19 @@
     <string name="notification_channel_general" msgid="4525309436693914482">"Opšte poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memorijski prostor"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije ne zahtevaju instalaciju."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idi na veb"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Režim Ne uznemiravaj je isključen"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>) je uključilo režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Aplikacija (<xliff:g id="ID_1">%s</xliff:g>) je uključila režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Automatsko pravilo ili aplikacija su uključili režim Ne uznemiravaj."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije pokrenute u pozadini"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
index f45af7c..ac65171 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite bezbedno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvek vodite računa o uslovima vožnje i uvek poštujte primenjive zakone. Uputstva mogu da budu netačna, nepotpuna, opasna, neprikladna ili zabranjena, odnosno da podrazumevaju prelazak između administrativnih oblasti. I podaci o preduzeću mogu da budu netačni ili nepotpuni. Podaci ne nastaju u realnom vremenu i ne možemo da garantujemo preciznost lokacije. Nemojte da upotrebljavate mobilni uređaj niti da koristite aplikacije koje nisu namenjene za Android Auto tokom vožnje."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Počnite da vozite"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index 8b01a83..6be4046 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <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">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ceo ekran"</string>
-    <string name="pip_play" msgid="674145557658227044">"Pusti"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
-    <string name="pip_hold_home" msgid="340086535668778109"><b>"POČETNI EKRAN"</b>" kont. PIP"</string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Slika u slici"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Na ovaj način će video biti prikazan dok ne pustite neki drugi. Pritisnite i zadržite "<b>"POČETNA"</b>" da biste ga kontrolisali."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Važi"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0796cff..d48ee4f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -77,7 +77,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Не атрымалася зрабiць скрыншот."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Падчас захавання скрыншота адбылася памылка."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Немагчыма захаваць здымак экрана, бо мала месца ў памяці."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Парам. перадачы файлаў па USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Падлучыць як медыяпрайгравальнік (ССП)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Падлучыць як камеру (PTP)"</string>
@@ -92,7 +92,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Тэлефон"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Галасавая дапамога"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Разблакiраваць"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка разблакіроўкі, чаканне адбітка пальца"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Чаканне ўводу даных адбітка пальца"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Разблакіроўка без выкарыстання адбітка пальца"</string>
     <string name="unlock_label" msgid="8779712358041029439">"разблакiраваць"</string>
     <string name="phone_label" msgid="2320074140205331708">"адкрыць тэлефон"</string>
@@ -154,11 +154,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Няма SIM-карты."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Сотавая перадача даных"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Сотавая перадача даных уключана"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Мабільная перадача даных адключана"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Мабільная перадача даных"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Мабільная перадача даных уключана"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Мабільная перадача даных выключана"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Сувязь па Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Рэжым палёту."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN уключана."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Няма SIM-карты."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Змяненне аператара сеткі."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Паказаць падрабязную інфармацыю пра акумулятар"</string>
@@ -168,7 +169,7 @@
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарадка акумулятара, працэнтаў: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Сістэмныя налады."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Апавяшчэнні."</string>
-    <string name="notification_shelf_content_description" msgid="5511922384591583913">"Кантэйнер для апавяшчэнняў пры перапаўненні"</string>
+    <string name="accessibility_overflow_action" msgid="5681882033274783311">"Паказаць усе апавяшчэнні"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Выдаліць апавяшчэнне."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS уключаны."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Атрыманне GPS."</string>
@@ -231,7 +232,7 @@
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Інверсія колеру адключаецца."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Інверсія колеру ўключаецца."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мабільны хот-спот выключаецца."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільны хот-спот ўключаецца."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільная кропка доступу ўключаная."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Трансляцыя экрана спынена."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Рэжым працы выкл."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Рэжым працы ўкл."</string>
@@ -240,13 +241,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Эканомія трафіку адключана."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Эканомія трафіку ўключана."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Яркасць дысплэя"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Ідзе зарадка"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Перадача даных 2G-3G прыпынена"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Перадача даных 4G прыпынена"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Мабільная перадача даных прыпынена"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Мабільная перадача даных прыпынена"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Перадача даных прыпынена"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Ліміт даных, які вы задалі, быў дасягнуты. Вы больш не выкарыстоўваеце сотавую перадачу даных.\n\nКалі вы ўзновіце карыстанне, можа спаганяцца плата за выкарыстанне трафіка."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Ліміт даных, які вы задалі, быў дасягнуты. Вы больш не выкарыстоўваеце мабільную перадачу даных.\n\nКалі вы ўзновіце карыстанне, можа спаганяцца плата за выкарыстанне трафіка."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Узнавіць"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Няма падключэння да Iнтэрнэту"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi падключаны"</string>
@@ -283,7 +283,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Яркасць"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Аўтапаварот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Аўтаматычны паварот экрана"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Усталявана на <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Рэжым <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Паварот заблакіраваны"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Кніжная арыентацыя"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Альбомная арыентацыя"</string>
@@ -318,10 +318,10 @@
     <string name="quick_settings_connected" msgid="1722253542984847487">"Падлучана"</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>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Кропка доступу"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Апавяшчэнні"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ліхтарык"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Мабільная перадача даных"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мабільная перадача даных"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Выкарыстанне трафіку"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Засталося трафіку"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Ліміт перавышаны"</string>
@@ -341,7 +341,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не атрымалася запусціць <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> адключана ў бяспечным рэжыме."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ачысціць усё"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Праграма не падтрымлівае функцыю дзялення экрана"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Перацягніце сюды, каб перайсці ў рэжым падзеленага экрана"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Падзяліць гарызантальна"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Падзяліць вертыкальна"</string>
@@ -367,7 +366,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менш тэрміновыя апавяшчэнні ніжэй"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Правядзіце пальцам уверх, каб разблакіраваць"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Гэта прылада знаходзіцца пад кіраваннем"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Тэлефон: правядзіце пальцам ад значка"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Галасавая дапамога: правядзіце пальцам ад значка"</string>
@@ -420,13 +419,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"За профілем могуць назіраць"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"За сеткай могуць назіраць"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"За сеткай могуць назіраць"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Маніторынг прылад"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> кіруе гэтай прыладай і можа сачыць за сеткавым трафікам"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да праграмы <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Прылада знаходзіцца пад кіраваннем вашай арганізацыі і падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> і падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Ваша арганізацыя можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"За сеткай могуць сачыць"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Прылада падключана да сетак VPN"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Працоўны профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Асабісты профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Прылада падключана да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Кіраванне прыладай"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Маніторынг профіляў"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Маніторынг сеткі"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Журнал сеткі"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Журнал сеткі"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"Сертыфікаты ЦС"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Адключыць VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Адлучыць VPN"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Праглядзець палітыку"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Ваша прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць і кіраваць наладамі, карпаратыўным доступам, праграмамі, данымі, звязанымі з вашай прыладай, і звесткамі пра месцазнаходжанне вашай прылады.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Ваша прылада знаходзіцца пад кіраваннем вашай арганізацыі.\n\nУ вашага адміністратара ёсць магчымасць маніторынгу і адміністравання налад, карпаратыўнага доступу, праграм, даных, звязаных з гэтай прыладай, і адпаведных геаданых.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Ваша арганізацыя ўсталявала на гэтай прыладзе цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Ваша арганізацыя ўсталявала ў вашым працоўным профілі цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"На гэтай прыладзе ўсталяваны цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Вы падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Вы падключаны да праграм <xliff:g id="VPN_APP_0">%1$s</xliff:g> і <xliff:g id="VPN_APP_1">%2$s</xliff:g>, якія могуць сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Ваш працоўны профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Ваш асабісты профіль падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Ваша прылада знаходзіцца пад кіраваннем <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> выкарыстоўвае <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> для кіравання вашай прыладай."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Адміністратар кантралюе налады, праграмы, карпаратыўны доступ, звязаныя з прыладай даныя і перадачу геаданых."</string>
@@ -435,15 +461,19 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Вы падключаны да праграмы <xliff:g id="VPN_APP">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" ,"</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Адкрыйце налады VPN"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Адкрыць давераныя ўліковыя даныя"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Вы далі праграме дазвол на наладжванне злучэння VPN.\n\nГэта праграма можа сачыць за актыўнасцю вашай прылады і вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nВаш адміністратар можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара.\n\nВы таксама падключаны да сеткі VPN, якая можа сачыць за вашай сеткавай дзейнасцю."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Вы падлучаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Вы падключаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Вы падлучаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая сачыць за вашай асабістай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Вы падключаны да праграмы <xliff:g id="APPLICATION">%1$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION">%2$s</xliff:g>, якая можа сачыць за вашай сеткавай дзейнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падлучаны да праграмы <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, якая можа сачыць за вашай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nВы таксама падлучаны да праграмы <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай актыўнасцю."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION">%2$s</xliff:g>, якая можа сачыць за вашай працоўнай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nДля атрымання дадатковай інфармацыі звярніцеся да адміністратара."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ваш працоўны профіль знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ён падключаны да праграмы <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, якая можа сачыць за вашай працоўнай сеткавай актыўнасцю, уключаючы электронную пошту, праграмы і вэб-сайты.\n\nВы таксама падключаны да праграмы <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, якая можа сачыць за вашай асабістай сеткавай актыўнасцю."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Разблакіравана для карыстальніка <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> працуе"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Прылада будзе заставацца заблакіраванай, пакуль вы не разблакіруеце яе ўручную"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Атрымлівайце апавяшчэнні хутчэй"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Праглядайце іх перад разблакіроўкай"</string>
@@ -474,10 +504,8 @@
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Дакраніцеся, каб уключыць гук."</string>
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Дакраніцеся, каб уключыць вібрацыю. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дакраніцеся, каб адключыць гук. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Дакраніцеся, каб уключыць вібрацыю."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Дакраніцеся, каб адключыць гук"</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Паказваецца наступная колькасць рэгулятараў гучнасці: %s. Правядзіце пальцам уверх, каб закрыць іх."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Рэгулятары гучнасці схаваны"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Наладка сістэмнага інтэрфейсу карыстальніка"</string>
@@ -500,7 +528,7 @@
     <string name="alarm_template" msgid="3980063409350522735">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Хуткія налады, <xliff:g id="TITLE">%s</xliff:g>."</string>
-    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Хот-спот"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Кропка доступу"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Працоўны профіль"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Цікава для некаторых, але не для ўсіх"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string>
@@ -527,25 +555,38 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Выключана"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"З дапамогай пашыранага кіравання апавяшчэннямі вы можаце задаваць узровень важнасці апавяшчэнняў праграмы ад 0 да 5. \n\n"<b>"Узровень 5"</b>" \n- Паказваць уверсе спіса апавяшчэнняў \n- Дазваляць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 4"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 3"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n\n"<b>"Узровень 2"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n\n"<b>"Узровень 1"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n- Хаваць з экрана блакіроўкі і панэлі стану \n- Паказваць унізе спіса апавяшчэнняў \n\n"<b>"Узровень 0"</b>" \n- Блакіраваць усе апавяшчэнні ад праграмы"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Апавяшчэнні"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі ў гэтай праграме</item>
-      <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый у гэтай праграме</item>
-      <item quantity="many">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый у гэтай праграме</item>
-      <item quantity="other">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі ў гэтай праграме</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Катэгорый апавяшчэнняў: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"У гэтай праграме няма катэгорый апавяшчэнняў"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі апавяшчэнняў у гэтай праграме</item>
+      <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый апавяшчэнняў у гэтай праграме</item>
+      <item quantity="many">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорый апавяшчэнняў у гэтай праграме</item>
+      <item quantity="other">1 з <xliff:g id="NUMBER_1">%d</xliff:g> катэгорыі апавяшчэнняў у гэтай праграме</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="many"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> і яшчэ <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Кіраванне апавяшчэннямі для <xliff:g id="APP_NAME">%1$s</xliff:g> адкрыта"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Кіраванне апавяшчэннямі для <xliff:g id="APP_NAME">%1$s</xliff:g> закрыта"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Дазволіць апавяшчэнні з гэтага канала"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Усе катэгорыі"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Дадатковыя налады"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Персаналізаваць: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Гатова"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"кіраванне апавяшчэннямі"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметры адкладвання апавяшчэнняў"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвілін"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвілін"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 гадзіна"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Не адкладваць"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"АДРАБІЦЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Адкладзена на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Выкарыстанне зараду"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Эканомія зараду акумулятара недаступная падчас зарадкі"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Эканомія зараду"</string>
@@ -671,6 +712,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Праграма можа не працаваць на дадатковых экранах."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Адкрыць налады."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Адкрыць хуткія налады."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Закрыць хуткія налады."</string>
@@ -685,6 +728,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Разгарнуць"</string>
     <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_notification_message" msgid="4171698133469539591">"Калі вы не хочаце, каб праграма <xliff:g id="NAME">%s</xliff:g> выкарыстоўвала гэту функцыю, дакраніцеся, каб адкрыць налады і адключыць яе."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Прайграць"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Прыпыніць"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Перайсці да наступнага"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Перайсці да папярэдняга"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"З-за перагрэву тэл. выключыўся"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Тэлефон працуе нармальна"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Ваш тэлефон пераграваўся, таму ён выключыўся, каб астыць. Зараз тэлефон працуе нармальна.\n\nТэлефон можа перагравацца пры:\n	• Выкарыстанні рэсурсаёмістых праграм (напрыклад, гульняў, відэа або праграм навігацыі)\n	• Спампоўцы або запампоўцы вялікіх файлаў\n	• Выкарыстанні тэлефона пры высокіх тэмпературах"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Тэлефон награваецца"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Некаторыя функцыі абмежаваны, пакуль тэлефон астывае"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Ваш тэлефон аўтаматычна паспрабуе астыць. Вы можаце па-ранейшаму карыстацца сваім тэлефонам, але ён можа працаваць больш павольна.\n\nПасля таго як ваш тэлефон астыне, ён будзе працаваць у звычайным рэжыме."</string>
@@ -707,9 +761,19 @@
     <string name="notification_channel_general" msgid="4525309436693914482">"Агульныя паведамленні"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Захоўванне"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Імгненныя праграмы"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Імгненныя праграмы не патрабуюць усталёўкі."</string>
     <string name="app_info" msgid="6856026610594615344">"Інфармацыя пра праграму"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Перайсці ў інтэрнэт"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Маб. перадача даных"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi выключаны"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth выключаны"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Рэжым \"Не турбаваць\" выключаны"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Рэжым \"Не турбаваць\" быў уключаны праграмай (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Рэжым \"Не турбаваць\" быў уключаны аўтаматычным правілам ці праграмай."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Да <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Пакінуць"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Замяніць"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings_car.xml b/packages/SystemUI/res/values-be/strings_car.xml
index e3ef7c6..7d53c97 100644
--- a/packages/SystemUI/res/values-be/strings_car.xml
+++ b/packages/SystemUI/res/values-be/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Кіруйце аўтамабілем бяспечна"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Будзьце заўсёды ў курсе дарожных умоў і заўсёды прытрымлівайцеся дзеючага заканадаўства. Указанні могуць быць недакладнымі, няпоўнымі, небяспечнымі, непадыходзячымі, забароненымі ці прадугледжваць уезд на адміністрацыйныя тэрыторыі. Інфармацыя пра кампаніі таксама можа быць недакладнай ці няпоўнай. Даныя не прадстаўляюцца ў рэжыме рэальнага часу, і дакладнасць вызначэння месцазнаходжання не можа быць гарантавана. Не выкарыстоўвайце сваю мабільную прыладу або праграмы, не прызначаныя для Android Auto, падчас кіравання."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Невядомы"</string>
+    <string name="start_driving" msgid="864023351402918991">"Пачаць паездку"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index 4b871a6..b9761b7 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <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="pip_notification_unknown_title" msgid="6289156118095849438">"(Праграма без назвы)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Закрыць PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ва ўвесь экран"</string>
-    <string name="pip_play" msgid="674145557658227044">"Прайграць"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Прыпыніць"</string>
-    <string name="pip_hold_home" msgid="340086535668778109">"Утрым. "<b>"HOME"</b>" для кір. PIP"</string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Відарыс у відарысе"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Гэта дазваляе захоўваць ваша відэа ў полі зроку, пакуль вы не пачняце прайграванне іншага. Націсніце і ўтрымлівайце "<b>"HOME"</b>" для кіравання."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Зразумела"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Адхіліць"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ac11dc7..1095134 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Няма да бъдете обезпокоявани от звуци и вибрирания освен от будилници, напомняния, събития и обаждания от посочени от вас контакти. Пак ще чувате всичко, което изберете да се пусне, включително музика, видеоклипове и игри."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Няма да бъдете обезпокоявани от звуци и вибрирания освен от будилници. Пак ще чувате всичко, което изберете да се пусне, включително музика, видеоклипове и игри."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Няма да бъдете обезпокоявани от звуци и вибрирания, различни от будилници, напомняния, събития и обаждания от посочени от вас контакти."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Персонализиране"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри. Пак ще можете да извършвате телефонни обаждания."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Установена е връзка с приложението <xliff:g id="APPLICATION">%1$s</xliff:g>, което може да наблюдава личната ви активност в мрежата, включително имейли, приложения и уебсайтове."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Служебният ви потребителски профил се управлява от <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Той е свързан с приложението <xliff:g id="APPLICATION">%2$s</xliff:g>, което може да наблюдава служебната ви активност в мрежата, включително имейли, приложения и уебсайтове.\n\nЗа още информация се свържете с администратора си."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Служебният ви потребителски профил се управлява от <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Той е свързан с приложението <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, което може да наблюдава служебната ви активност в мрежата, включително имейли, приложения и уебсайтове.\n\nУстановена е връзка и с приложението <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, което може да наблюдава личната ви активност в мрежата."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Отключено за <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> се изпълнява"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Устройството ще остане заключено, докато не го отключите ръчно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Получавайте известия по-бързо"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Вижте известията, преди да отключите"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Няма нужда"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Настройване"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Изключване сега"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Прекратяване сега"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Разгъване"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Свиване"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екранът е фиксиран"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Изкл."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощта на контролите за известията можете да зададете ниво на важност от 0 до 5 за известията от дадено приложение. \n\n"<b>"Ниво 5"</b>" \n– Показване най-горе в списъка с известия. \n– Разрешаване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 4"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 3"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n\n"<b>"Ниво 2"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n\n"<b>"Ниво 1"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n– Скриване от заключения екран и лентата на състоянието. \n– Показване най-долу в списъка с известия. \n\n"<b>"Ниво 0"</b>" \n– Блокиране на всички известия от приложението."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известия"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вече няма да получавате тези известия."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вече няма да получавате тези известия"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известия"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"За това приложение няма категории на известията"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 от <xliff:g id="NUMBER_1">%d</xliff:g> категории известия от това приложение</item>
       <item quantity="one">1 от <xliff:g id="NUMBER_0">%d</xliff:g> категория известия от това приложение</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроли за известията"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опции за отлагане на известията"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЯНА"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Ползв. на батерията"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
@@ -718,8 +719,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="4171698133469539591">"Ако не искате <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-bg/strings_car.xml b/packages/SystemUI/res/values-bg/strings_car.xml
index bd9fe79..c7f6974 100644
--- a/packages/SystemUI/res/values-bg/strings_car.xml
+++ b/packages/SystemUI/res/values-bg/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Карайте внимателно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Бъдете осведомени за условията при шофиране и винаги спазвайте приложимите закони. Упътванията може да са неточни, непълни, опасни, неподходящи, забранени или да включват преминаване през административни райони. Бизнес информацията може също да е неточна или непълна. Данните не са в реално време и точността на местоположението не може да се гарантира. Не работете с мобилното си устройство, нито използвайте приложения, които не са предназначени за Android Auto, докато шофирате."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Няма информация"</string>
+    <string name="start_driving" msgid="864023351402918991">"Започнете да шофирате"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index a5eb8b93..ffe9007 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/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-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 65ea6b1..9ad4011 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"অনুসন্ধান করুন"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য উপরের দিকে স্লাইড করুন৷"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাঁ দিকে স্লাইড করুন৷"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেমের আওয়াজ শুনতে পাবেন।"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"অ্যালার্ম ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেমের আওয়াজ শুনতে পাবেন।"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"আপনার নির্দিষ্ট অ্যালার্ম, অনুস্মারক, ইভেন্ট, এবং কলারগুলি ব্যতীত আপনাকে শব্দ এবং কম্পনগুলির দ্বারা বিরক্ত করা হবে না৷"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"কাস্টমাইজ করুন"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷ আপনি এখনও ফোন কলগুলি করতে পারবেন৷"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"আপনি <xliff:g id="APPLICATION">%1$s</xliff:g> এর সাথে সংযুক্ত হয়েছেন, যা ইমেল, অ্যাপ এবং ওয়েবসাইটগুলি সহ আপনার ব্যক্তিগত নেটওয়ার্কের কার্যকলাপ নিরীক্ষণ করবে৷"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইল পরিচালনা করে। প্রোফাইলটি <xliff:g id="APPLICATION">%2$s</xliff:g> এর সাথে সংযুক্ত, যেটি ইমেল, অ্যাপ, ও ওয়েবসাইট সহ আপনার কর্মস্থলের নেটওয়ার্ক কার্যকলাপের উপরে নজর রাখতে পারে।\n\nআরো তথ্যের জন্য প্রশাসকের সাথে যোগাযোগ করুন।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইল পরিচালনা করে। প্রোফাইলটি <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> এর সাথে সংযুক্ত, যেটি ইমেল অ্যাপ, ও ওয়েবসাইট সহ আপনার কর্মস্থলের নেটওয়ার্ক কার্যকলাপের উপরে নজর রাখতে পারে।\n\n এ ছাড়াও আপনি <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> এর সাথে সংযুক্ত, যেটি আপনার ব্যক্তিগত নেটওয়ার্কে নজর রাখে।"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> এর জন্য আনলক করা হয়েছে"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> চালু আছে"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"আপনি নিজে আনলক না করা পর্যন্ত ডিভাইসটি লক হয়ে থাকবে"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"বিজ্ঞপ্তিগুলি আরো দ্রুত পান"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"আপনি আনলক করার আগে ওগুলো দেখুন"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"না থাক"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"সেট আপ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"এখনই বন্ধ করুন"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"এখন সমাপ্ত করুন"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"প্রসারিত করুন"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"সঙ্কুচিত করুন"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্রীন পিন করা হয়েছে"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"বন্ধ আছে"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"পাওয়ার বিজ্ঞপ্তির নিয়ন্ত্রণগুলি ব্যহবার করে, আপনি কোনো অ্যাপ্লিকেশানের বিজ্ঞপ্তির জন্য ০ থেকে ৫ পর্যন্ত একটি গুরুত্বের লেভেলকে সেট করতে পারবেন৷ \n\n"<b>"লেভেল ৫"</b>" \n- বিজ্ঞপ্তি তালিকার শীর্ষে দেখায় \n- পূর্ণ স্ক্রীনের বাধাকে অনুমতি দেয় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৪"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৩"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n\n"<b>"লেভেল ২"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n\n"<b>"লেভেল ১"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n- লক স্ক্রীন এবং স্থিতি দন্ড থেকে লুকায় \n- বিজ্ঞপ্তি তালিকার নীচের দিকে দেখায় \n\n"<b>"লেভেল ০"</b>" \n- অ্যাপ্লিকেশান থেকে সমস্ত বিজ্ঞপ্তিকে অবরূদ্ধ করে"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"বিজ্ঞপ্তি"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"আপনি আর এই বিজ্ঞপ্তিগুলি পাবেন না।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"আপনি এই বিজ্ঞপ্তিগুলি আর পাবেন না"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> বিজ্ঞপ্তির বিভাগগুলি"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"এই অ্যাপটিতে বিজ্ঞপ্তির বিভাগ নেই"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">এই অ্যাপের <xliff:g id="NUMBER_1">%d</xliff:g>টি বিজ্ঞপ্তির বিভাগের মধ্যে ১টি</item>
       <item quantity="other">এই অ্যাপের <xliff:g id="NUMBER_1">%d</xliff:g>টি বিজ্ঞপ্তির বিভাগের মধ্যে ১টি</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"বিজ্ঞপ্তি মনে করিয়ে দেওয়ার বিকল্পগুলি"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"১৫ মিনিট"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"৩০ মিনিট"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"১ ঘণ্টা"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"২ ঘণ্টা"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
diff --git a/packages/SystemUI/res/values-bn/strings_car.xml b/packages/SystemUI/res/values-bn/strings_car.xml
index d8a8732..d014c02 100644
--- a/packages/SystemUI/res/values-bn/strings_car.xml
+++ b/packages/SystemUI/res/values-bn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"সাবধানে চালান"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"গাড়ি চালানোর সময় সর্বদা সতর্ক থাকুন এবং প্রযোজ্য আইন মেনে চলুন৷ দিকনির্দেশ ভুল, অসম্পূর্ণ, বিপজ্জনক, অনুপযুক্ত, নিষিদ্ধ হতে পারে বা প্রশাসনিক এলাকাগুলি অতিক্রম করতে হতে পারে৷ বাণিজ্যিক তথ্য ভুল বা অসম্পূর্ণ হতে পারে৷ ডেটা প্রকৃত সময়ের নয় এবং অবস্থানের নির্ভুলতা নিশ্চিত করাও সম্ভব নয়৷ গাড়ি চালানোর সময় আপনার মোবাইল ডিভাইসটিকে বা Android Auto এর জন্য উপযুক্ত নয় এমন অ্যাপগুলিকে ব্যবহার করবেন না৷"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"অজানা"</string>
+    <string name="start_driving" msgid="864023351402918991">"ড্রাইভিং শুরু করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 27390b9..1d1632f 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -76,7 +76,7 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Došlo je do greške prilikom snimanja ekrana."</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Došlo je do problema prilikom spašavanja snimka ekrana."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu."</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili vaša organizacija ne dopuštaju pravljenje snimaka ekrana."</string>
+    <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Reproduciranje medijskih sadržaja (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Priključiti kao kameru (PTP)"</string>
@@ -91,7 +91,7 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključaj"</string>
-    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Dugme za otključavanje, čeka se na otisak prsta"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Čeka se otisak prsta"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključaj bez korištenja otiska prsta"</string>
     <string name="unlock_label" msgid="8779712358041029439">"otključaj"</string>
     <string name="phone_label" msgid="2320074140205331708">"otvori telefon"</string>
@@ -153,11 +153,12 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Nema SIM kartice."</string>
-    <string name="accessibility_cell_data" msgid="7080312242791850520">"Mobilni podaci"</string>
-    <string name="accessibility_cell_data_on" msgid="4310018593519761767">"Prijenos mobilnih podataka uključen"</string>
-    <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Mobilni podaci isključeni"</string>
+    <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilni podaci"</string>
+    <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilni podaci su uključeni"</string>
+    <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobilni podaci su isključeni"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Dijeljenje Bluetooth veze."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Način rada u avionu."</string>
+    <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN uključen."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Nema SIM kartice."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Promjena mreže operatera."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o potrošnji baterije"</string>
@@ -165,7 +166,7 @@
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavještenja."</string>
-    <string name="notification_shelf_content_description" msgid="5511922384591583913">"Spremnik za prelijevanje obavještenja"</string>
+    <string name="accessibility_overflow_action" msgid="5681882033274783311">"Vidite sva obavještenja"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ukloniti obavještenje."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogućen."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Uspostavljanje GPS veze."</string>
@@ -237,13 +238,12 @@
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Ušteda podataka je isključena."</string>
     <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Ušteda podataka je uključena."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Osvjetljenje ekrana"</string>
-    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
-    <skip />
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Punjenje"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G prijenos podataka je pauzirano"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G prijenos podataka je pauzirano"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilni podaci su pauzirani"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Prijenos podataka je pauziran"</string>
-    <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"Dostigli ste ograničenje za prijenos podataka koje ste postavili. Više ne koristite mobilne podatke.\n\nUkoliko nastavite koristiti mobilne podatke, mogući su troškovi za prijenos podataka."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli ste ograničenje za prijenos podataka koje ste postavili. Više ne koristite mobilne podatke.\n\nUkoliko nastavite koristiti mobilne podatke, mogući su troškovi za prijenos podataka."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Niste povezani na internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi veza aktivna"</string>
@@ -279,7 +279,7 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Osvjetljenje"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatsko rotiranje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Automatsko rotiranje ekrana"</string>
-    <string name="accessibility_quick_settings_rotation_value" msgid="1428962304214992318">"Postaviti način rada: <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Način rada <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotiranje je zaključano"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Uspravno"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Vodoravno"</string>
@@ -300,10 +300,10 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nema dostupnih Wi-Fi mreža"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prebacivanje"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emitiranje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
-    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za prebacivanje"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za emitiranje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nema dostupnih uređaja"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Osvjetljenje"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
@@ -317,7 +317,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Pristupna tačka"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavještenja"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobilni podaci"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Prijenos podataka"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Prekoračeno"</string>
@@ -337,7 +337,6 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> je onemogućena u sigurnom načinu rada."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
-    <string name="recents_incompatible_app_message" msgid="5075812958564082451">"Aplikacija ne podržava dijeljenje ekrana."</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Povucite ovdje za korištenje podijeljenog ekrana"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podjela po vertikali"</string>
@@ -352,10 +351,10 @@
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Do kraja punjenja preostalo <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Ne puni se"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža može \n biti nadzirana"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"Traži"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Povucite gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Povucite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"Zvukovi i vibracije vas neće uznemiravati, osim alarma, podsjetnika, događaja i pozivalaca koje odredite."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivalaca koje odredite."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, videozapise i igre. I dalje ćete moći obavljati pozive."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, video zapise i igre."</string>
@@ -363,7 +362,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da otvorite"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite prema gore da otključate"</string>
-    <string name="do_disclosure_generic" msgid="8498005633306135779">"Ovim uređajem upravlja"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Prevucite preko ikone za glasovnu pomoć"</string>
@@ -416,13 +415,40 @@
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profil može biti nadziran"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"Mreža može biti nadzirana"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"Mreža može biti nadzirana"</string>
-    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Praćenje uređaja"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni promet."</string>
+    <string name="quick_settings_disclosure_named_management_monitoring" msgid="370622174777570853">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može pratiti vaš mrežni promet"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="1085137869053332307">"Uređajem upravlja vaša organizacija i povezan je s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="6290456493852584017">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s aplikacijom <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_management" msgid="3294967280853150271">"Uređajem upravlja vaša organizacija"</string>
+    <string name="quick_settings_disclosure_named_management" msgid="1059403025094542908">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="3698767349925266482">"Uređajem upravlja vaša organizacija i povezan je s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_named_management_vpns" msgid="7777821385318891527">"Uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="5125463987558278215">"Vaša organizacija može pratiti mrežni promet na vašem profilu."</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni promet na vašem radnom profilu"</string>
+    <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Mreža može biti nadzirana"</string>
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Uređaj je povezan s VPN-ovima"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Uređaj je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Upravljanje uređajem"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Praćenje profila"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Praćenje mreže"</string>
     <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN mreža"</string>
-    <string name="monitoring_subtitle_network_logging" msgid="5569072711320784030">"Zapisivanje na mreži"</string>
+    <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"Zapisivanje na mreži"</string>
+    <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA certifikati"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"Isključi VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Prekini VPN vezu"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"Prikaži pravila"</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"Vašim uređajem upravlja organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"Vašim uređajem upravlja vaša organizacija.\n\nVaš administrator može nadgledati i upravljati vašim postavkama, korporativnom pristupu, aplikacijama, podacima koji su povezani s vašim uređajem i informacijama o lokaciji vašeg uređaja.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"Vaša organizacija je instalirala CA certifikat na ovom uređaju. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"Vaša organizacija je instalirala CA certifikat na vašem radnom profilu. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"CA certifikat je instaliran na ovom uređaju. Vaš promet preko sigurne mreže može se pratiti."</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Vaš administrator je uključio zapisivanje na mreži, čime se prati promet na vašem uređaju."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Povezani ste s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g> koja može pratiti vašu aktivnost na mreži, uključujući e-poštu i web lokacije."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Povezani ste s aplikacijama <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g> koje mogu pratiti vašu aktivnost na mreži, uključujući e-poštu, aplikacije i web lokacije."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Vaš radni profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke i web lokacije."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Vaš lični profil je povezan s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web lokacije."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Vašim uređajem upravlja aplikacija <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> koristi aplikaciju <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> za upravljanje vašim uređajem."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"Vaš administrator može pratiti postavke, korporativni pristup, aplikacije, podatke povezane s vašim uređajem i informacije o lokaciji vašeg uređaja."</string>
@@ -431,15 +457,19 @@
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Povezani ste s aplikacijom <xliff:g id="VPN_APP">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke i web lokacije."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Postavke otvorene VPN mreže"</string>
+    <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
+    <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Otvorite pouzdane akreditive"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Vaš administrator je uključio zapisivanje na mreži, čime se prati saobraćaj na vašem uređaju.\n\nZa više informacija, obratite se administratoru."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"Jednoj aplikaciji ste dali odobrenje da uspostavi VPN vezu.\n\nTa aplikacija može pratiti vašu aktivnost na uređaju i mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se administratoru.\n\nPovezani ste i na VPN, koji može pratiti vašu aktivnost na mreži."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poruke, aplikacije i web lokacije."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste na aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vaše privatne aktivnosti na mreži, uključujući e-poštu, aplikacije i web stranice."</string>
-    <string name="monitoring_description_app_work" msgid="7777228449969022305">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se svom administratoru."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Profilom za posao upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vašim radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nZa više informacija, obratite se svom administratoru."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Radnim profilom upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poruke, aplikacije i web lokacije.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Agent <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je pokrenut"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ručno ne otključate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže primaj obavještenja"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Vidi ih prije otključavanja"</string>
@@ -452,7 +482,7 @@
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je prikačen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Nazad."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Pregled."</string>
-    <string name="screen_pinning_positive" msgid="3783985798366751226">"Jasno mi je"</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumijem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li sakriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Pojavit će se sljedeći put kada opciju uključite u postavkama."</string>
@@ -472,10 +502,8 @@
     <skip />
     <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite za postavljanje vibracije. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
-    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
-    <skip />
-    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
-    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da postavite vibraciju."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da isključite zvuk."</string>
     <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Prikazane kontrole jačine zvuka za: %s. Prevucite prema gore za odbacivanje."</string>
     <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole jačine zvuka sakrivene"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Podešavač za korisničko sučelje sistema"</string>
@@ -503,7 +531,7 @@
     <string name="tuner_warning_title" msgid="7094689930793031682">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Podešavač za korisničko sučelje sistema vam omogućava dodatne načine da podesite i prilagodite Androidovo sučelje. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
-    <string name="got_it" msgid="2239653834387972602">"Jasno mi je"</string>
+    <string name="got_it" msgid="2239653834387972602">"Razumijem"</string>
     <string name="tuner_toast" msgid="603429811084428439">"Čestitamo! Podešavač za korisničko sučelje sistema je dodan u Postavke"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Podešavač za korisničko sučelje sistema iz Postavki i prestati koristiti sve njegove funkcije?"</string>
@@ -525,25 +553,37 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Uz kontrolu obavještenja o napajanju, možete postaviti nivo značaja obavještenja iz aplikacije, i to od nivoa 0 do 5. \n\n"<b>"Nivo 5"</b>" \n- Prikaži na vrhu liste obavještenja \n- Dopusti prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nvio 4"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nivo 3"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n\n"<b>"Nivo 2"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n\n"<b>"Nivo 1"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikada ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n- Sakrij sa ekrana za zaključavanje i statusne trake \n- Prikaži na dnu liste obavještenja \n\n"<b>"Nivo 0"</b>" \n- Blokiraj sva obavještenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavještenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nećete više primati ova obavještenja."</string>
-    <plurals name="notification_num_channels_desc" formatted="false" msgid="8808748716499517938">
-      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije iz ove aplikacije</item>
-      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija iz ove aplikacije</item>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nećete više primati ova obavještenja"</string>
+    <string name="notification_num_channels" msgid="2048144408999179471">"Kategorije obavještenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavještenja"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
+    <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
+      <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavještenja iz ove aplikacije</item>
+      <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavještenja iz ove aplikacije</item>
+      <item quantity="other">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorija obavještenja iz ove aplikacije</item>
     </plurals>
+    <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
+    <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="few"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, i još <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
+    </plurals>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Otvorene su kontrole obavještenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="7521619812603693144">"Zatvorene su kontrole obavještenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="notification_channel_switch_accessibility" msgid="3420796005601900717">"Dozvoli obavještenja s ovog kanala"</string>
     <string name="notification_all_categories" msgid="5407190218055113282">"Sve kategorije"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
+    <string name="notification_app_settings" msgid="3743278649182392015">"Prilagodite: <xliff:g id="SUB_CATEGORY">%1$s</xliff:g>"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obavještenja"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije za odgodu obavještenja"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_dont_snooze" msgid="655446566007801922">"Ne odgađaj"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="battery_panel_title" msgid="7944156115535366613">"Upotreba baterije"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
+    <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
@@ -578,7 +618,7 @@
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obavještenja"</string>
-    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Skracenice tastature"</string>
+    <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Prečice tastature"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Promijeni način unosa"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoć"</string>
@@ -602,7 +642,7 @@
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Ušteda podataka je uključena"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Ušteda podataka je isključena"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"Uključeno"</string>
-    <string name="switch_bar_off" msgid="8803270596930432874">"Isključi"</string>
+    <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>
@@ -612,7 +652,7 @@
     <item msgid="1545641631806817203">"Međumemorija"</item>
     <item msgid="5742013440802239414">"Kôd tipke"</item>
     <item msgid="8802889973626281575">"Prebacivač tastatura"</item>
-    <item msgid="8175437057325747277">"Nema"</item>
+    <item msgid="8175437057325747277">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normalna"</item>
@@ -622,7 +662,7 @@
   </string-array>
     <string name="menu_ime" msgid="4998010205321292416">"Prebacivač tastatura"</string>
     <string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
-    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
+    <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"Podesite širinu dugmeta"</string>
     <string name="clipboard" msgid="1313879395099896312">"Međumemorija"</string>
     <string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -630,7 +670,7 @@
     <string name="right_keycode" msgid="708447961000848163">"Kôd tipke desno"</string>
     <string name="left_icon" msgid="3096287125959387541">"Ikona lijevo"</string>
     <string name="right_icon" msgid="3952104823293824311">"Ikona desno"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Povucite da dodate polja"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Prevucite da dodate pločice"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Prevucite ovdje za uklanjanje"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vrijeme"</string>
@@ -668,6 +708,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> obavještenje: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacija možda neće raditi na podijeljenom ekranu"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava dijeljenje ekrana."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacija možda neće raditi na sekundarnom ekranu."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Otvori postavke."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Otvoriti brze postavke."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Zatvoriti brze postavke."</string>
@@ -682,6 +724,17 @@
     <string name="pip_phone_expand" msgid="5889780005575693909">"Proširi"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Umanji"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zatvori"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Povucite prema dolje da odbacite"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Meni za način rada Slika u slici"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je u načinu priakza Slika u slici"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"Ako ne želite da <xliff:g id="NAME">%s</xliff:g> koristi ovu funkciju, dodirnite da otvorite postavke i isključite je."</string>
+    <string name="pip_play" msgid="1417176722760265888">"Reproduciraj"</string>
+    <string name="pip_pause" msgid="8881063404466476571">"Pauziraj"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Preskoči na sljedeći"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"Preskoči na prethodni"</string>
+    <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telefon se isključio zbog pregrijavanja"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"Vaš telefon sada radi normalno"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"Vaš telefon se pregrijao, pa se isključio da se ohladi. Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n	• Koristite aplikacije koje troše puno resursa (kao što su aplikacije za igranje, videozapise ili navigaciju)\n	• Preuzimate ili otpremate velike fajlove\n	• Koristite telefon na visokim temperaturama"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"Telefon se pregrijava"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"Neke funkcije su ograničene dok se telefon hladi"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"Vaš telefon će se automatski pokušati ohladiti. I dalje možete koristi telefon, ali će možda raditi sporije.\n\nNakon što se ohladi, telefon će normalno raditi."</string>
@@ -701,12 +754,22 @@
     <string name="tuner_app" msgid="3507057938640108777">"Aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snimci ekrana"</string>
-    <string name="notification_channel_general" msgid="4525309436693914482">"Općenite poruke"</string>
+    <string name="notification_channel_general" msgid="4525309436693914482">"Opće poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Instant-aplikacije"</string>
-    <!-- no translation found for pip_menu_title (3328510504196964712) -->
-    <skip />
     <string name="instant_apps_message" msgid="8116608994995104836">"Za instant aplikacije nije potrebna instalacija"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Idite na internet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
+    <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi veza je isključena"</string>
+    <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth je isključen"</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Opcija Ne ometaj je isključena"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Opciju Ne ometaju uključilo je automatsko pravilo (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Opciju Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Opciju Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
+    <string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
+    <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
+    <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije koje rade u pozadini"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings_car.xml b/packages/SystemUI/res/values-bs/strings_car.xml
index 744eea8..d38620b 100644
--- a/packages/SystemUI/res/values-bs/strings_car.xml
+++ b/packages/SystemUI/res/values-bs/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvijek budite upoznati s uslovima za vožnju i poštujte važeće zakone. Upute za kretanje mogu biti netačne, nepotpune, opasne, neprikladne, zabranjene ili takve da obuhvataju prelaženje preko administrativnih područja. Poslovne informacije takođe mogu biti netačne ili nepotpune. Podaci nisu u realnom vremenu, a tačnost lokacije se ne može garantirati. U vožnji nemojte rukovati mobilnim uređajem ili koristiti aplikacije koje nisu namijenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Početak vožnje"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml
index 40347dc..b0b3612 100644
--- a/packages/SystemUI/res/values-bs/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs/strings_tv.xml
@@ -19,15 +19,8 @@
 
 <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">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli ekran"</string>
-    <string name="pip_play" msgid="674145557658227044">"Pokreni"</string>
-    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
-    <string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string>
-    <string name="pip_onboarding_title" msgid="7850436557670253991">"Slika u slici"</string>
-    <string name="pip_onboarding_description" msgid="4028124563309465267">"Ovim videozapis ostaje prikazan sve dok pokrenete sljedeći. Pritisnite i držite "<b>" POČETAK "</b>" za kontrole PIP-a."</string>
-    <string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string>
-    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
-  <string-array name="recents_tv_blacklist_array">
-  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 07a8cf4..f354ad4 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -281,7 +281,7 @@
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotació bloquejada"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertical"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horitzontal"</string>
-    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'introducció"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'entrada"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicació"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació desactivada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositiu multimèdia"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Llisca cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Llisca cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"No t\'interromprà cap so ni cap vibració, tret dels sons de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalitza"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música. Encara podràs fer trucades."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els de vídeos, jocs, alarmes i música."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estàs connectat a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa, com ara els correus electrònics, les aplicacions i els llocs web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nPer obtenir més informació, contacta amb l\'administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona el teu perfil professional. El perfil està connectat a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pot supervisar la teva activitat a la xarxa de treball, com ara els correus electrònics, les aplicacions i els llocs web.\n\nTambé estàs connectat a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pot supervisar la teva activitat personal a la xarxa."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloquejat per a <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> s\'està executant"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositiu continuarà bloquejat fins que no el desbloquegis manualment."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Rep notificacions més ràpidament"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Mostra-les abans de desbloquejar"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configura"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactiva ara"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalitza ara"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Amplia"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Replega"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"La pantalla està fixada"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivat"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Amb els controls de notificació millorats, pots establir un nivell d\'importància d\'entre 0 i 5 per a les notificacions d\'una aplicació. \n\n"<b>"Nivell 5"</b>" \n- Mostra les notificacions a la part superior de la llista \n- Permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 4"</b>" \n- No permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 3"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n\n"<b>"Nivell 2"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- Les notificacions no poden emetre sons ni vibracions \n\n"<b>"Nivell 1"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- No activa mai el so ni la vibració \n- Amaga les notificacions de la pantalla de bloqueig i de la barra d\'estat \n- Mostra les notificacions a la part inferior de la llista \n\n"<b>"Nivell 0"</b>" \n- Bloqueja totes les notificacions de l\'aplicació"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacions"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ja no rebràs aquestes notificacions."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ja no rebràs aquestes notificacions"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categories de notificació"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aquesta aplicació no té categories de notificació"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categories de notificació d\'aquesta aplicació</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoria de notificació d\'aquesta aplicació</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controls de notificació"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcions per posposar la notificació"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuts"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuts"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hores"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFÉS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Ús de la bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
@@ -723,7 +724,7 @@
     <string name="pip_notification_message" msgid="4171698133469539591">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
     <string name="pip_play" msgid="1417176722760265888">"Reprodueix"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Posa en pausa"</string>
-    <string name="pip_skip_to_next" msgid="1948440006726306284">"Ves al següent"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"Vés al següent"</string>
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"Torna a l\'anterior"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"Telèfon apagat per la calor"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"Ara el telèfon funciona de manera normal"</string>
@@ -752,7 +753,7 @@
     <string name="instant_apps" msgid="6647570248119804907">"Aplicacions instantànies"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"No cal instal·lar les aplicacions instantànies."</string>
     <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
-    <string name="go_to_web" msgid="1106022723459948514">"Ves al web"</string>
+    <string name="go_to_web" msgid="1106022723459948514">"Vés al web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Dades mòbils"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"La Wi-Fi està desactivada"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"El Bluetooth està desactivat"</string>
diff --git a/packages/SystemUI/res/values-ca/strings_car.xml b/packages/SystemUI/res/values-ca/strings_car.xml
index efcac23..32a019e 100644
--- a/packages/SystemUI/res/values-ca/strings_car.xml
+++ b/packages/SystemUI/res/values-ca/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Condueix amb precaució"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Estigues al cas de la conducció i respecta sempre les lleis aplicables. Les indicacions poden ser inexactes, perilloses, inadequades o incompletes, o bé poden comportar maniobres prohibides o que creuis circumscripcions territorials. La informació de les empreses també pot ser inexacta o incompleta. No s\'ofereixen dades en temps real i no es pot garantir la precisió de les ubicacions. Mentre condueixes, no utilitzis el dispositiu mòbil ni cap aplicació que no estigui destinada a Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconegut"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comença a conduir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 0b7e41a..cb8fa86 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -358,8 +358,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a vybraných volajících. Nadále uslyšíte veškerý obsah, který si sami pustíte (např. hudba, videa nebo hry)."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků. Nadále uslyšíte veškerý obsah, který si sami pustíte (např. hudba, videa nebo hry)."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a volajících, které zadáte."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Přizpůsobit"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her. Telefonovat budete moci i nadále."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her."</string>
@@ -473,13 +472,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Jste připojeni k aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g>, která může sledovat vaši osobní aktivitu v síti, včetně e-mailů, aplikací a webů."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Váš pracovní profil spravuje organizace <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je připojen k aplikaci <xliff:g id="APPLICATION">%2$s</xliff:g>, která může sledovat vaši aktivitu v síti, včetně e-mailů, aplikací a webů.\n\nDalší informace vám poskytne administrátor."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Váš pracovní profil spravuje organizace <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je připojen k aplikaci <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, která může sledovat vaši aktivitu v síti, včetně e-mailů, aplikací a webů.\n\nTaké jste připojeni k aplikaci <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, která může sledovat vaši osobní aktivitu v síti."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odemknuto pro uživatele <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> běží"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Zařízení zůstane uzamčeno, dokud je ručně neodemknete"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Čtěte si oznámení rychleji"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Můžete si je přečíst před odemčením obrazovky."</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, děkuji"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Nastavit"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Vypnout"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Ukončit"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbalit"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sbalit"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je připnuta"</string>
@@ -554,9 +555,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuto"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Rozšířené ovládací prvky oznámení umožňují nastavit úroveň důležitosti oznámení aplikace od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazit na začátku seznamu oznámení \n– Povolit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 4"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 3"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n\n"<b>"Úroveň 2"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat žádný zvukový signál ani nevibrovat \n\n"<b>"Úroveň 1"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat zvukový signál ani nevibrovat \n– Skrýt z obrazovky uzamčení a stavového řádku \n– Zobrazovat na konci seznamu oznámení \n\n"<b>";Úroveň 0"</b>" \n– Blokovat všechna oznámení z aplikace"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Oznámení"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Tato oznámení již nebudete dostávat."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tato oznámení již nebudete dostávat"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie oznámení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tato aplikace nemá kategorie oznámení"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 ze <xliff:g id="NUMBER_1">%d</xliff:g> kategorií oznámení z této aplikace</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorie oznámení z této aplikace</item>
@@ -580,12 +583,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Nastavení oznámení"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Možnosti odložení oznámení"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hodina"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hodiny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VRÁTIT ZPĚT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo o <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Využití baterie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
@@ -728,8 +729,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimalizovat"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zavřít"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Nápovědu zavřete přetažením dolů"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Nabídka režimu obraz v obraze"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v režimu obraz v obraze"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Nabídka typu obraz v obraze"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"Aplikace <xliff:g id="NAME">%s</xliff:g> je v zobrazení obraz v obraze"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Pokud nechcete, aby aplikace <xliff:g id="NAME">%s</xliff:g> tuto funkci používala, klepnutím otevřete nastavení a funkci vypněte."</string>
     <string name="pip_play" msgid="1417176722760265888">"Přehrát"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Pozastavit"</string>
diff --git a/packages/SystemUI/res/values-cs/strings_car.xml b/packages/SystemUI/res/values-cs/strings_car.xml
index d5e3324..b8a0d3e 100644
--- a/packages/SystemUI/res/values-cs/strings_car.xml
+++ b/packages/SystemUI/res/values-cs/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Řiďte bezpečně"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Věnujte plnou pozornost řízení a dodržujte platné předpisy. Trasy mohou být nepřesné, neúplné, nebezpečné, nevhodné, zakázané nebo mohou zahrnovat překročení hranic. Informace o firmách mohou být také nepřesné nebo neúplné. Data se neaktualizují v reálném čase a přesnost polohy nelze zaručit. Mobilní zařízení ani aplikace určené pro Android Auto nepoužívejte za jízdy."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznámé"</string>
+    <string name="start_driving" msgid="864023351402918991">"Zahájit jízdu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
index a928218..f27974f 100644
--- a/packages/SystemUI/res/values-cs/strings_tv.xml
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -21,6 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="notification_channel_tv_pip" msgid="134047986446577723">"Obraz v obraze"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Bez názvu)"</string>
-    <string name="pip_close" msgid="3480680679023423574">"Ukončit obraz v obraze (PIP)"</string>
+    <string name="pip_close" msgid="3480680679023423574">"Ukončit PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 37f92f7..b19e901 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -259,10 +259,10 @@
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Indstillinger for <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skærmen er nu låst i liggende retning."</string>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skærmen er nu låst i stående format."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skærmen er nu låst i stående retning."</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Skærmen roteres nu automatisk."</string>
-    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Skærmen er nu låst i liggende format."</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Skærmen er nu låst i stående format."</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Skærmen er nu låst i liggende tilstand."</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Skærmen er nu låst i stående tilstand."</string>
     <string name="dessert_case" msgid="1295161776223959221">"Dessertcase"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Pauseskærm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
@@ -279,7 +279,7 @@
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Roter skærmen automatisk"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"Tilstanden <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotationen er låst"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Stående format"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Stående"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Liggende"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inputmetode"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Placering"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Du bliver ikke forstyrret af lyde eller vibrationer, undtagen fra alarmer, påmindelser, begivenheder og opkald fra personer, du angiver. Du kan stadig høre alt, du vælger at afspille, bl.a. musik samt lyd i videoer og spil."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Du bliver ikke forstyrret af lyde eller vibrationer, undtagen fra alarmer. Du kan stadig høre alt, du vælger at afspille, bl.a. musik samt lyd i videoer og spil."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Du bliver ikke forstyrret af lyde og vibrationer undtagen fra de alarmer, påmindelser, begivenheder og opkaldere, som du angiver."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpas"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil. Du vil stadig kunne foretage telefonopkald."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du har forbindelse til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåge din private netværksaktivitet, bl.a. e-mails, apps og websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen har forbindelse til <xliff:g id="APPLICATION">%2$s</xliff:g>, som kan overvåge din netværksaktivitet, bl.a. mails, apps og websites.\n\nKontakt din administrator for at få flere oplysninger."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen har forbindelse til <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, som kan overvåge din netværksaktivitet, bl.a. mails, apps og websites.\n\nDu har også forbindelse til <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, som kan overvåge din personlige netværksaktivitet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Låst op for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> kører"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheden vil forblive låst, indtil du manuelt låser den op"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Modtag underretninger hurtigere"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem, før du låser op"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nej tak"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfigurer"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Deaktiver nu"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Afslut nu"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Udvid"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skærmen er fastgjort"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Fra"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med kontrolelementer til underretninger om strøm kan du konfigurere et vigtighedsniveau fra 0 til 5 for en apps underretninger. \n\n"<b>"Niveau 5"</b>\n"- Vis øverst på listen over underretninger \n- Tillad afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 4"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 3"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n\n"<b>"Niveau 2"</b>\n"- Ingen afbrydelse af fuld skærm \n Se aldrig smugkig \n- Ingen lyd og vibration \n\n"<b>"Niveau 1"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n- Ingen lyd eller vibration \n- Skjul fra låseskærm og statusbjælke \n- Vis nederst på listen over underretninger \n\n"<b>"Niveau 0"</b>\n"- Bloker alle underretninger fra appen."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Underretninger"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du modtager ikke længere disse underretninger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du modtager ikke længere disse underretninger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> underretningskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne app har ingen underretningskategorier"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 ud af <xliff:g id="NUMBER_1">%d</xliff:g> underretningskategori fra denne app</item>
       <item quantity="other">1 ud af <xliff:g id="NUMBER_1">%d</xliff:g> underretningskategorier fra denne app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrolelementer til underretninger"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Indstillinger for udsættelse"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timer"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"FORTRYD"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Udsat i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriforbrug"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
diff --git a/packages/SystemUI/res/values-da/strings_car.xml b/packages/SystemUI/res/values-da/strings_car.xml
index 6a421da..26843ac 100644
--- a/packages/SystemUI/res/values-da/strings_car.xml
+++ b/packages/SystemUI/res/values-da/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kør forsigtigt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vær opmærksom på køreforholdene, og overhold altid færdselsloven. Rutevejledningen kan være unøjagtig, ufuldstændig, farlig, upassende, forbudt eller involvere krydsning af forbudte områder. Virksomhedsoplysninger kan også være unøjagtige eller ufuldstændige. Data er ikke i realtid, og placeringers nøjagtighed kan ikke garanteres. Håndter ikke din mobilenhed, og brug ikke apps, der ikke er beregnet til Android Auto, mens du kører."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ukendt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Kør"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index aa8af74..d24cb3a 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -21,6 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="notification_channel_tv_pip" msgid="134047986446577723">"Integreret billede"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program uden titel)"</string>
-    <string name="pip_close" msgid="3480680679023423574">"Luk integreret billede"</string>
+    <string name="pip_close" msgid="3480680679023423574">"Luk PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Fuld skærm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index fe06c12..f6216c2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -161,9 +161,7 @@
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Keine SIM-Karte"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Netzwerk des Mobilfunkanbieters wird gewechselt"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Akkudetails öffnen"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
     <skip />
@@ -301,7 +299,7 @@
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Kein Netz"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN aus"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"WLAN an"</string>
-    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Keine WLANs verfügbar"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Keine WLAN-Netzwerke verfügbar"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Streamen"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Wird übertragen"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unbenanntes Gerät"</string>
@@ -356,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen. Du hörst jedoch weiterhin Sound, wenn du Musik und Videos wiedergibst oder Spiele spielst."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe. Du hörst jedoch weiterhin Sound, wenn du Musik und Videos wiedergibst oder Spiele spielst."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe kannst du jedoch weiterhin tätigen."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string>
@@ -471,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du bist mit der App \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" verbunden. Diese kann deine persönlichen Netzwerkaktivitäten erfassen, einschließlich E-Mails, Apps und Websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit <xliff:g id="APPLICATION">%2$s</xliff:g> verknüpft. Diese App kann deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verknüpft. Diese App kann deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites.\n\nDu bist auch mit <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die deine persönlichen Netzwerkaktivitäten überwachen kann."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Entsperrt für <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> wird ausgeführt"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis du es manuell entsperrst."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Benachrichtigungen schneller erhalten"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Vor dem Entsperren anzeigen"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nein danke"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Einrichten"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Jetzt deaktivieren"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Jetzt beenden"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
@@ -552,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Aus"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Mit den erweiterten Benachrichtigungseinstellungen kannst du für App-Benachrichtigungen eine Wichtigkeitsstufe von 0 bis 5 festlegen. \n\n"<b>"Stufe 5"</b>" \n- Auf der Benachrichtigungsleiste ganz oben anzeigen \n- Vollbildunterbrechung zulassen \n- Immer kurz einblenden \n\n"<b>"Stufe 4"</b>" \n- Keine Vollbildunterbrechung \n- Immer kurz einblenden \n\n"<b>"Stufe 3"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n\n"<b>"Stufe 2"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n\n"<b>"Stufe 1"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n- Auf Sperrbildschirm und Statusleiste verbergen \n- Auf der Benachrichtigungsleiste ganz unten anzeigen \n\n"<b>"Stufe 0"</b>" \n- Alle Benachrichtigungen der App sperren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Benachrichtigungen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du erhältst diese Benachrichtigungen nicht mehr."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du erhältst diese Benachrichtigungen nicht mehr"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> Benachrichtigungskategorien"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Diese App hat keine Benachrichtigungskategorien"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 von <xliff:g id="NUMBER_1">%d</xliff:g> Benachrichtigungskategorien von dieser App</item>
       <item quantity="one">1 von <xliff:g id="NUMBER_0">%d</xliff:g> Benachrichtigungskategorie von dieser App</item>
@@ -574,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> – <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Benachrichtigungseinstellungen"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Optionen für spätere Erinnerung bei Benachrichtigungen"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 Minuten"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 Minuten"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 Stunde"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 Stunden"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"RÜCKGÄNGIG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Erinnerung in <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkunutzung"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
@@ -722,8 +721,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 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_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_notification_message" msgid="4171698133469539591">"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_car.xml b/packages/SystemUI/res/values-de/strings_car.xml
index 5b5920e..76ff268 100644
--- a/packages/SystemUI/res/values-de/strings_car.xml
+++ b/packages/SystemUI/res/values-de/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sicher fahren"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Achte stets auf die Straßenverhältnisse und halte dich an die geltenden Gesetze. Routen können unter Umständen fehlerhaft, unvollständig, gefährlich, ungeeignet oder verboten sein oder das Überqueren von Verwaltungsgrenzen erfordern. Informationen zum Unternehmen können ebenfalls fehlerhaft oder unvollständig sein. Die Datenübertragung erfolgt nicht in Echtzeit und die Genauigkeit der Standortangaben kann nicht gewährleistet werden. Bediene während der Fahrt nicht dein Mobilgerät und verwende keine Apps, die du nicht über Android Auto steuern kannst."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unbekannt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Losfahren"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index adae259..c83a52e 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 im Bild"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bild-in-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 aa7fb92..8fd5e35 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -51,8 +51,8 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Ρύθμιση μεθόδων εισαγωγής"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Φυσικό πληκτρολόγιο"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτού του αξεσουάρ USB;"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Δεν έχετε εφαρμογή που να συνεργάζεται με το αξεσουάρ USB. Για περισσότερα: <xliff:g id="URL">%1$s</xliff:g>"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Δεν θα ενοχλείστε από ήχους και δονήσεις, παρά μόνο από ξυπνητήρια, υπενθυμίσεις, συμβάντα και καλούντες που έχετε καθορίσει. Θα εξακολουθείτε να ακούτε όλο το περιεχόμενο που επιλέγετε να αναπαραγάγετε, συμπεριλαμβανομένων μουσικής, βίντεο και παιχνιδιών."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Δεν θα ενοχλείστε από ήχους και δονήσεις, παρά μόνο από ξυπνητήρια. Θα εξακολουθείτε να ακούτε όλο το περιεχόμενο που επιλέγετε να αναπαραγάγετε, συμπεριλαμβανομένων μουσικής, βίντεο και παιχνιδιών."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Δεν θα διακόπτεστε από ήχους και δονήσεις, με εξαίρεση τα ξυπνητήρια, τις υπενθυμίσεις, τα συμβάντα και τους καλούντες που έχετε ορίσει."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Προσαρμογή"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Αυτή η επιλογή αποκλείει όλους τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών."</string>
@@ -459,21 +458,23 @@
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Άνοιγμα αξιόπιστων διαπιστευτηρίων"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Παραχωρήσατε σε μια εφαρμογή άδεια για τη ρύθμιση σύνδεσης VPN.\n\nΑυτή η εφαρμογή μπορεί να παρακολουθεί τη δραστηριότητα της συσκευής και του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"Η διαχείριση του προφίλ εργασίας γίνεται από τον οργανισμό <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nΟ διαχειριστής έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή.\n\nΕπίσης, είστε συνδεδεμένοι σε VPN, το οποίο μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
-    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστότοπων."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Έχετε συνδεθεί στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του προσωπικού σας δικτύου, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ είναι συνδεδεμένο στην εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>, η οποία μπορεί να παρακολουθήσει τη δραστηριότητα του δικτύου εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΓια περισσότερες πληροφορίες, επικοινωνήστε με τον διαχειριστή σας."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ο οργανισμός <xliff:g id="ORGANIZATION">%1$s</xliff:g> διαχειρίζεται το προφίλ εργασίας σας. Το προφίλ συνδέεται με την εφαρμογή <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, η οποία μπορεί να παρακολουθεί τη δραστηριότητα του δικτύου της εργασίας σας, συμπεριλαμβανομένων μηνυμάτων ηλεκτρονικού ταχυδρομείου, εφαρμογών και ιστοτόπων.\n\nΕπίσης, είστε συνδεδεμένοι στην εφαρμογή <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, που έχει τη δυνατότητα παρακολούθησης της δραστηριότητας του προσωπικού σας δικτύου."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ξεκλειδώθηκε για τον χρήστη <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Εκτελείται ο παράγοντας εμπιστοσύνης <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Η συσκευή θα παραμείνει κλειδωμένη μέχρι να την ξεκλειδώσετε μη αυτόματα"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Λάβετε ειδοποιήσεις γρηγορότερα"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Εμφάνιση πριν το ξεκλείδωμα"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Όχι"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Ρύθμιση"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Απενεργοποίηση τώρα"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Τερματισμός τώρα"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ανάπτυξη"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Σύμπτυξη"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Η οθόνη καρφιτσώθηκε"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Ανενεργή"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Με τα στοιχεία ελέγχου ειδοποίησης ισχύος, μπορείτε να ορίσετε ένα επίπεδο βαρύτητας από 0 έως 5 για τις ειδοποιήσεις μιας εφαρμογής. \n\n"<b>"Επίπεδο 5"</b>" \n- Εμφάνιση στην κορυφή της λίστας ειδοποιήσεων \n- Να επιτρέπεται η διακοπή πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 4"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 3"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n\n"<b>"Επίπεδο 2"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n\n"<b>"Επίπεδο 1"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n- Απόκρυψη από την οθόνη κλειδώματος και τη γραμμή κατάστασης \n- Εμφάνιση στο κάτω μέρος της λίστας ειδοποιήσεων \n\n"<b>"Επίπεδο 0"</b>" \n- Αποκλεισμός όλων των ειδοποιήσεων από την εφαρμογή"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ειδοποιήσεις"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Δεν θα λαμβάνεται πλέον αυτές τις ειδοποιήσεις."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Δεν θα λαμβάνετε πλέον αυτές τις ειδοποιήσεις"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> κατηγορίες ειδοποιήσεων"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Αυτή η εφαρμογή δεν διαθέτει κατηγορίες ειδοποιήσεων"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 από <xliff:g id="NUMBER_1">%d</xliff:g> κατηγορίες ειδοποιήσεων από αυτή την εφαρμογή</item>
       <item quantity="one">1 από <xliff:g id="NUMBER_0">%d</xliff:g> κατηγορία ειδοποιήσεων από αυτή την εφαρμογή</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"στοιχεία ελέγχου ειδοποιήσεων"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"επιλογές αφύπνισης ειδοποιήσεων"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 λεπτά"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 λεπτά"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ώρα"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ώρες"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ΑΝΑΙΡΕΣΗ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Σε αφύπνιση για <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Χρήση της μπαταρίας"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
diff --git a/packages/SystemUI/res/values-el/strings_car.xml b/packages/SystemUI/res/values-el/strings_car.xml
index e960713..09a2a39 100644
--- a/packages/SystemUI/res/values-el/strings_car.xml
+++ b/packages/SystemUI/res/values-el/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Οδηγείτε προσεκτικά"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Μείνετε πλήρως ενημερωμένοι για τις προϋποθέσεις οδήγησης και υπακούτε πάντα τους ισχύοντες νόμους. Οι οδηγίες μπορεί να είναι ανακριβείς, ελλιπείς, επικίνδυνες, ακατάλληλες, απαγορευμένες ή να ανήκουν σε άλλες διοικητικές περιοχές. Οι πληροφορίες επιχειρήσεων μπορεί επίσης να είναι ανακριβείς ή ελλιπείς. Τα δεδομένα δεν είναι σε πραγματικό χρόνο και η ακρίβεια των τοποθεσιών δεν είναι εγγυημένη. Μη χειρίζεστε την κινητή συσκευή σας και μη χρησιμοποιείτε εφαρμογές που δεν προορίζονται για το Android Auto ενώ οδηγείτε."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Άγνωστο"</string>
+    <string name="start_driving" msgid="864023351402918991">"Έναρξη οδήγησης"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 35263c2..93753bb 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"You won’t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, thanks"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Setup"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Turn off now"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"End now"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_car.xml b/packages/SystemUI/res/values-en-rAU/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
index 31cbd83..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rAU/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">"Picture-in-picture"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 35263c2..93753bb 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"You won’t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, thanks"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Setup"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Turn off now"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"End now"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_car.xml b/packages/SystemUI/res/values-en-rGB/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
index 31cbd83..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rGB/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">"Picture-in-picture"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 35263c2..93753bb 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"You won’t be disturbed by sounds and vibrations, except from alarms. You\'ll still hear anything that you choose to play, including music, videos and games."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"You\'re connected to <xliff:g id="APPLICATION">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Your work profile is managed by <xliff:g id="ORGANIZATION">%1$s</xliff:g>. The profile is connected to <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, which can monitor your personal network activity."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Unlocked for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is running"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Get notifications faster"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"See them before you unlock"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, thanks"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Setup"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Turn off now"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"End now"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="one">1 out of <xliff:g id="NUMBER_0">%d</xliff:g> notification category from this app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"notification snooze options"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hours"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_car.xml b/packages/SystemUI/res/values-en-rIN/strings_car.xml
index 81089ba..27b916e 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_car.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Unknown"</string>
+    <string name="start_driving" msgid="864023351402918991">"Start Driving"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
index 31cbd83..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rIN/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">"Picture-in-picture"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3b77658..e04ab5f 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas de los emisores que especifiques. Seguirás escuchando el contenido que reproduzcas, como música, videos y juegos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Seguirás escuchando el contenido que reproduzcas, como música, videos y juegos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"No te molestarán los sonidos ni las vibraciones, excepto que se trate de alarmas, recordatorios, eventos y emisores que especifiques."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluidas las que provienen de alarmas, videos y juegos. Podrás realizar llamadas telefónicas."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluso los que provienen de alarmas, música, videos y juegos."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Te conectaste a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede supervisar la actividad de tu red personal, incluidos los correos electrónicos, las apps y los sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> administra tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que puede controlar tu actividad de red de trabajo, incluidos los correos electrónicos, apps y sitios web.\n\nPara obtener más información, comunícate con tu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> administra tu perfil de red. El perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que puede controlar tu actividad de red de trabajo, incluidos los correos electrónicos, las apps y los sitios web.\n\nTambién estás conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que puede controlar tu actividad de red personal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Se desbloqueó para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Se está ejecutando <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositivo permanecerá bloqueado hasta que lo desbloquees manualmente."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibe notificaciones más rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactivar ahora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar ahora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fija"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Con los controles de activación de notificaciones, puedes establecer un nivel de importancia para las notificaciones de una app. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones. \n- Permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 4"</b>" \n- No permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 3"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n\n"<b>"Nivel 2"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n\n"<b>"Nivel 1"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n- Ocultar de la pantalla bloqueada y la barra de estado. \n- Mostrar al final de la lista de notificaciones. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la app."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificaciones"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta app no tiene categorías de notificación"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificación de esta app</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación de esta app</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificación"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opciones para posponer notificaciones"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posponer <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_car.xml b/packages/SystemUI/res/values-es-rUS/strings_car.xml
index 647236a..382602a 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_car.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conducir de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la situación de conducción y cumple siempre con las leyes vigentes. Es posible que las indicaciones sean imprecisas, inadecuadas o peligrosas, que estén incompletas, que sugieran maniobras prohibidas o que impliquen atravesar áreas administrativas. La información de las empresas también puede ser imprecisa o estar incompleta. Los datos no se proporcionan en tiempo real ni se puede garantizar la precisión de las ubicaciones. No uses tu dispositivo móvil ni apps no diseñadas para Android Auto mientras conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconocido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comenzar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index d005cd8..a7160fa 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Datos móviles"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Datos móviles activados"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"Datos móviles desactivados"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Compartir conexión por Bluetooth"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Compartir por Bluetooth"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"La red VPN está activada."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"No hay tarjeta SIM."</string>
@@ -313,7 +313,7 @@
     <string name="quick_settings_done" msgid="3402999958839153376">"Listo"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
-    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartir conexión"</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Compartir Internet"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona Wi-Fi"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas que especifiques. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"No te interrumpirán sonidos ni vibraciones, salvo los de las alarmas, los recordatorios, los eventos y las llamadas que especifiques."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos). Seguirás pudiendo hacer llamadas de teléfono."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Este modo permite bloquear TODOS los sonidos y todas las vibraciones (p. ej., los de alarmas, música, vídeos y juegos)."</string>
@@ -406,7 +405,7 @@
     <string name="user_remove_user_message" msgid="1453218013959498039">"Se eliminarán todas las aplicaciones y todos los datos de este usuario."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Quitar"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Ahorro de batería activado"</string>
-    <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduce el rendimiento y los datos en segundo plano"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduce el rendimiento y el envío de datos en segundo plano"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Desactivar ahorro de batería"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> empezará a capturar todo lo que aparezca en la pantalla."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estas conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que puede controlar tu actividad de red personal, como correos electrónicos, aplicaciones y sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que puede supervisar tu actividad de red profesional, como los correos electrónicos, las aplicaciones y los sitios web.\n\nPara obtener más información, ponte en contacto con el administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> gestiona tu perfil de trabajo. El perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que puede supervisar tu actividad de red profesional, como los correos electrónicos, las aplicaciones y los sitios web.\n\nTambién te has conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que puede supervisar tu actividad de red personal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> se está ejecutando"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"El dispositivo permanecerá bloqueado hasta que se desbloquee manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibe notificaciones más rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, gracias"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactivar"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar ahora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mostrar"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ocultar"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fijada"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Los controles de energía de las notificaciones permiten establecer un nivel de importancia de 0 a 5 para las notificaciones de las aplicaciones. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones \n- Permitir interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 4"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 3"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n\n"<b>"Nivel 2"</b>" \n- Evitar interrumpir en el modo de pantalla completa\n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n\n"<b>"Nivel 1"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n- Ocultar de la pantalla de bloqueo y de la barra de estado \n- Mostrar en la parte inferior de la lista de notificaciones \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la aplicación"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificación"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación no tiene categorías de notificación"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificación de esta aplicación</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación de esta aplicación</item>
@@ -572,16 +575,14 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Controles de las notificaciones"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Opciones para posponer las notificaciones"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Volverá a mostrarse en <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
-    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y los datos en segundo plano"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y las conexiones automáticas"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="2243500072071305073">"Inicio"</string>
     <string name="keyboard_key_back" msgid="2337450286042721351">"Atrás"</string>
diff --git a/packages/SystemUI/res/values-es/strings_car.xml b/packages/SystemUI/res/values-es/strings_car.xml
index e19ca78..47a40b0 100644
--- a/packages/SystemUI/res/values-es/strings_car.xml
+++ b/packages/SystemUI/res/values-es/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la conducción y respeta siempre las normas de tráfico. Las indicaciones pueden ser inexactas, incompletas, peligrosas o inadecuadas o dar lugar a maniobras prohibidas o al cruce de zonas regionales diferentes. La información sobre empresas también puede ser inexacta o estar incompleta. No se ofrecen datos en tiempo real ni se puede garantizar la exactitud de las ubicaciones. No utilices el dispositivo móvil ni aplicaciones que no estén destinadas a Android Auto mientras conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconocido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Empezar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f4605e0..e21baa6 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Helid ja vibratsioonid ei sega teid. Kuulete siiski enda määratud alarme, meeldetuletusi, sündmusi ja helistajaid. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Helid ja vibratsioonid ei sega teid. Kuulete siiski alarme. Samuti kuulete kõike, mille esitamise ise valite, sh muusika, videod ja mängud."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Teid segatakse helide ja värinaga vaid teie määratud alarmide, meeldetuletuste, sündmuste ning helistajate puhul."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Kohanda"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja värinad. Saate siiski helistada."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja vibratsioonid."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Olete ühendatud rakendusega <xliff:g id="APPLICATION">%1$s</xliff:g>, mis võib jälgida teie isiklikke võrgutegevusi, sh meile, rakendusi ja veebisaite."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Teie tööprofiili haldab <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profiil on ühendatud rakendusega <xliff:g id="APPLICATION">%2$s</xliff:g>, mis saab jälgida teie töökoha võrgutegevusi, sh meile, rakendusi ja veebisaite.\n\nLisateabe saamiseks võtke ühendust administraatoriga."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Teie tööprofiili haldab <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profiil on ühendatud rakendusega <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, mis saab jälgida teie töökoha võrgutegevusi, sh meile, rakendusi ja veebisaite.\n\nOlete ühendatud ka rakendusega <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, mis saab jälgida teie isiklikke võrgutegevusi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Avatud kasutaja <xliff:g id="USER_NAME">%1$s</xliff:g> jaoks"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Funktsioon <xliff:g id="TRUST_AGENT">%1$s</xliff:g> töötab"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Seade jääb lukku, kuni selle käsitsi avate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Saate märguandeid kiiremini"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Näete neid enne avamist"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Tänan, ei"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Seadistus"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Lülita kohe välja"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Lõpeta nüüd"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Laiendamine"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ahendamine"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekraan on kinnitatud"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Väljas"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Toite märguannete juhtnuppudega saate määrata rakenduse märguannete tähtsuse taseme vahemikus 0–5. \n\n"<b>"5. tase"</b>" \n- Kuva märguannete loendi ülaosas\n- Luba täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"4. tase"</b>" \n- Keela täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"3. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n\n"<b>"2. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n\n"<b>"1. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n- Peida lukustuskuval ja olekuribal \n- Kuva märguannete loendi allosas \n\n"<b>"Tase 0"</b>" \n- Blokeeri kõik rakenduse märguanded"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Märguanded"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Te ei saa enam neid märguandeid."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Te ei saa enam neid märguandeid"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> märguandekategooriat"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Sellel rakendusel ei ole märguannete kategooriaid"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 <xliff:g id="NUMBER_1">%d</xliff:g>-st märguannete kategooriast sellelt rakenduselt</item>
       <item quantity="one">1 <xliff:g id="NUMBER_0">%d</xliff:g>-st märguannete kategooriast sellelt rakenduselt</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"märguannete juhtnupud"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"märguannete edasilükkamise valikud"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Üks tund"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"kaks tundi"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VÕTA TAGASI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Edasi lükatud <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akukasutus"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
diff --git a/packages/SystemUI/res/values-et/strings_car.xml b/packages/SystemUI/res/values-et/strings_car.xml
index c41385a..a63c3f3 100644
--- a/packages/SystemUI/res/values-et/strings_car.xml
+++ b/packages/SystemUI/res/values-et/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sõitke turvaliselt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Olge teadlik sõidutingimustest ja järgige alati kohaldatavaid seadusi. Juhised võivad olla ebatäpsed, mittetäielikud, ohtlikud, sobimatud, keelatud või hõlmata kattuvaid administratiivpiirkondi. Ka ettevõtteteave võib olla ebatäpne või mittetäielik. Andmed pole reaalajas ja asukoha täpsust ei saa garanteerida. Ärge kasutage auto juhtimisel mobiilseadet ega rakendusi, mis pole mõeldud teenuse Android Auto jaoks."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Teadmata"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sõidu alustamine"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 06432b8..9276020 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Bilatu"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Lerratu gora hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Lerratu ezkerrera hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Gailuak ez du egingo ez soinurik ez dardararik, baina alarmak, gertaeren abisu-tonuak eta aukeratzen dituzun deitzaileen dei-tonuak joko ditu. Bestalde, zuk erreproduzitutako guztia entzungo duzu, besteak beste, musika, bideoak eta jokoak."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Gailuak ez du egingo ez soinurik ez dardararik, baina alarmak joko ditu. Hala ere, zuk erreproduzitutako guztia entzun ahal izango duzu, besteak beste, musika, bideoak eta jokoak."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Soinuek eta dardarek ez zaituzte oztoporik egingo, zehazten dituzun alarmek, abisuek, gertaerek eta deitzaileek izan ezik."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Pertsonalizatu"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak. Telefono-deiak egiteko aukera izaten jarraituko duzu."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikaziora konektatuta zaude. Aplikazio horrek sarean egiten dituzun jarduera pertsonalak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> erakundeak kudeatzen dizu laneko profila. <xliff:g id="APPLICATION">%2$s</xliff:g> aplikaziora dago konektatuta profila, eta aplikazio horrek sarean egiten dituzun jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne.\n\nInformazio gehiago lortzeko, jarri administratzailearekin harremanetan."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> erakundeak kudeatzen dizu laneko profila. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> aplikaziora dago konektatuta profila, eta aplikazio horrek sarean egiten dituzun jarduerak kontrola ditzake, mezu elektronikoak, aplikazioak eta webguneak barne. \n\n<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> aplikaziora ere zaude konektatuta, eta hark sare pertsonalean egiten dituzun jarduerak kontrola ditzake."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> erabiltzailearentzat desblokeatu da"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> abian da"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Gailua blokeatuta egongo da eskuz desblokeatu arte"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Eskuratu jakinarazpenak azkarrago"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ikusi desblokeatu baino lehen"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ez, eskerrik asko"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfiguratu"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desaktibatu"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Amaitu"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zabaldu"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tolestu"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Pantaila ainguratuta dago"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desaktibatuta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bateria-mailaren arabera jakinarazpenak kontrolatzeko aukerekin, 0 eta 5 bitarteko garrantzi-mailetan sailka ditzakezu aplikazioen jakinarazpenak. \n\n"<b>"5. maila"</b>" \n- Erakutsi jakinarazpenen zerrendaren goialdean. \n- Baimendu etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"4. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"3. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n\n"<b>"2. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n\n"<b>"1. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n- Ezkutatu pantaila blokeatutik eta egoera-barratik. \n- Erakutsi jakinarazpenen zerrendaren behealdean. \n\n"<b>"0. maila"</b>" \n- Blokeatu aplikazioaren jakinarazpen guztiak."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Jakinarazpenak"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Jakinarazpenen <xliff:g id="NUMBER">%d</xliff:g> kategoria"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikazio honek ez du jakinarazpen-kategoriarik"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Aplikazio honen 1/<xliff:g id="NUMBER_1">%d</xliff:g> jakinarazpen-kategoria</item>
       <item quantity="one">Aplikazio honen 1/<xliff:g id="NUMBER_0">%d</xliff:g> jakinarazpen-kategoria</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"jakinarazpena kontrolatzeko aukerak"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"jakinarazpena atzeratzeko aukerak"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutu"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutu"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ordu"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ordu"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESEGIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>z atzeratu da"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Bateriaren erabilera"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
@@ -720,8 +721,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimizatu"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Itxi"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Baztertzeko, arrastatu behera"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Pantaila txiki gainjarriaren menua"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Pantaila txikiaren menua"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"Pantaila txikian dago <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Ez baduzu nahi <xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string>
     <string name="pip_play" msgid="1417176722760265888">"Erreproduzitu"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Pausatu"</string>
diff --git a/packages/SystemUI/res/values-eu/strings_car.xml b/packages/SystemUI/res/values-eu/strings_car.xml
index c4371f7..59c2bb2 100644
--- a/packages/SystemUI/res/values-eu/strings_car.xml
+++ b/packages/SystemUI/res/values-eu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Gidatu zentzuz"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Egon erne errepidera begira eta gorde lege aplikagarri oro. Agian jarraibideak ez dira guztiz zehatzak, osatuak edo egokiak izango; arriskutsuak izan daitezke edo debekatuta dagoen zerbait egitea edo mugak zeharkatzea proposa diezazukete. Baliteke enpresei buruzko informazioa ere guztiz zehatza edo osatua ez izatea. Datuak ez dira une-unekoak eta ezin da bermatu kokapenaren zehaztasuna. Gidatu bitartean, ez erabili gailu mugikorrik edo Android Auto zerbitzuarekin erabiltzeko egina ez dagoen aplikaziorik."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ezezaguna"</string>
+    <string name="start_driving" msgid="864023351402918991">"Hasi gidatzen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml
index 081d1fe..6dd81a6 100644
--- a/packages/SystemUI/res/values-eu/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu/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">"Pantaila txiki gainjarria"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Pantaila txikia"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa izengabea)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Itxi PIPa"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantaila osoa"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ec567dc..cc5f46e 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"بجز هشدارها، یادآوری‌ها، رویدادها و تماس‌گیرندگانی که خودتان مشخص می‌کنید، هیچ صدا و لرزشی نخواهید داشت. همچنان صدای مواردی را که پخش می‌کنید می‌شنوید از جمله صدای موسیقی، ویدیو و بازی."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"بجز هشدارها، هیچ صدا و لرزشی نخواهید داشت. همچنان صدای مواردی را که پخش می‌کنید می‌شنوید از جمله صدای موسیقی، ویدیو و بازی."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"صداها و لرزش‌هایی به جز هشدارها، یادآوری‌ها، رویدادها و تماس‌گیرنده‌هایی که مشخص می‌کنید، مزاحم شما نمی‌شوند."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"سفارشی کردن"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"این کار «همه» صداها و لرزش‌ها از جمله هشدارها، موسیقی، ویدئوها و بازی‌ها را مسدود می‌کند. همچنان می‌توانید تماس تلفنی برقرار کنید."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"این کار «همه» صداها و لرزش‌ها از جمله هشدارها، موسیقی، ویدئوها و بازی‌ها را مسدود می‌کند."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شده‌اید، که می‌تواند فعالیت شبکه شخصی شما را (ازجمله رایانامه‌‌ها، برنامه‌‌ها و وب‌سایت‌ها) کنترل کند."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت می‌شود. این نمایه به <xliff:g id="APPLICATION">%2$s</xliff:g> متصل است که می‌تواند فعالیت شما در شبکه (ازجمله رایانامه‌ها، برنامه‌ها و وب‌سایت‌ها) را پایش کند.\n\nبرای اطلاعات بیشتر، با سرپرست سیستم تماس بگیرید."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"نمایه کاری‌تان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت می‌شود. این نمایه به <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> متصل است که می‌تواند تنظیمات، دسترسی شرکتی، برنامه‌ها، داده‌های مرتبط با دستگاه و اطلاعات مکان دستگاه شما را پایش کند.\n\nشما همچنین به <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> متصل هستید که می‌تواند فعالیت خصوصی شما را در شبکه پایش کند."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"قفل برای <xliff:g id="USER_NAME">%1$s</xliff:g> باز شد"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> درحال اجرا است"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"دستگاه قفل باقی می‌ماند تا زمانی که قفل آن را به صورت دستی باز کنید"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"دریافت سریع‌تر اعلان‌ها"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"قبل از باز کردن قفل آنها را مشاهده کنید"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"نه متشکرم"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"راه‌اندازی"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. ‏<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"اکنون خاموش کنید"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"اکنون به پایان برسد"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"بزرگ کردن"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"کوچک کردن"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"صفحه نمایش پین شد"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"خاموش"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"با کنترل‌های قدرتمند اعلان می‌توانید سطح اهمیت اعلان‌های هر برنامه را از ۰ تا ۵ تعیین کنید. \n\n"<b>"سطح ۵"</b>" \n- در صدر فهرست اعلان‌ها نشان داده می‌شود \n- وقفه برای نمایش تمام‌صفحه مجاز است \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۴"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۳"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n\n"<b>"سطح ۲"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا و لرزش ایجاد نمی‌کند \n\n"<b>"سطح ۱"</b>" \n- نمایش تمام صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا یا لرزش ایجاد نمی‌کند \n- در قفل صفحه و نوار وضعیت پنهان است \n- در پایین فهرست اعلان‌ها نشان داده می‌شود \n\n"<b>"سطح ۰"</b>" \n- همه اعلان‌های این برنامه مسدود است"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اعلان‌ها"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"دیگر این اعلان‌ها را دریافت نخواهید کرد."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"دیگر این اعلان‌ها را دریافت نخواهید کرد"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> دسته اعلان"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"این برنامه دسته اعلان ندارد"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">۱ از <xliff:g id="NUMBER_1">%d</xliff:g> دسته اعلان این برنامه</item>
       <item quantity="other">۱ از <xliff:g id="NUMBER_1">%d</xliff:g> دسته اعلان این برنامه</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"کنترل‌های اعلان"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"گزینه‌های تعویق اعلان"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"۱۵ دقیقه"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"۳۰ دقیقه"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"۱ ساعت"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"۲ ساعت"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"واگرد"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> به تعویق افتاد"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"مصرف باتری"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینه‌سازی باتری» در دسترس نیست"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینه‌سازی باتری"</string>
@@ -707,7 +708,7 @@
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"باز کردن تنظیمات سریع."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"بستن تنظیمات سریع."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"تنظیم زنگ ساعت."</string>
-    <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"با <xliff:g id="ID_1">%s</xliff:g> به سیستم وارد شده‌اید"</string>
+    <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"واردشده به سیستم به‌عنوان <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_no_internet" msgid="31890692343084075">"عدم اتصال به اینترنت."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"باز کردن جزئیات."</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"باز کردن تنظیمات <xliff:g id="ID_1">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fa/strings_car.xml b/packages/SystemUI/res/values-fa/strings_car.xml
index e8433fa..e914796 100644
--- a/packages/SystemUI/res/values-fa/strings_car.xml
+++ b/packages/SystemUI/res/values-fa/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"با ایمنی برانید"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏کاملاً از شرایط رانندگی آگاه باشید و همیشه قوانین مربوطه را رعایت کنید. مسیرها ممکن است غیردقیق، ناقص، ناکامل، خطرناک، نامناسب، ممنوع یا مستلزم عبور از تقسیمات کشوری باشند. اطلاعات کسب و کار نیز ممکن است غیردقیق یا ناکامل باشند. داده‌ها بی‌درنگ نیستند و دقت مکان نمی‌تواند تضمین شود. هنگام رانندگی دستگاه همراه را در دست نگیرید یا از برنامه‌هایی که ویژه Android Auto نیستند استفاده نکنید."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"نامشخص"</string>
+    <string name="start_driving" msgid="864023351402918991">"شروع رانندگی"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f4e5616..e630cfc4 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia. Kuulet edelleen kaiken valitsemasi sisällön, kuten musiikin, videot ja pelit."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä. Kuulet edelleen kaiken valitsemasi sisällön, kuten musiikin, videot ja pelit."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Muokkaa"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät. Voit kuitenkin soittaa puheluita."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Olet muodostanut yhteyden sovellukseen <xliff:g id="APPLICATION">%1$s</xliff:g>, joka voi valvoa henkilökohtaista toimintaasi verkossa. Sovellus voi esimerkiksi seurata avaamiasi sähköposteja, sovelluksia ja verkkosivustoja."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> hallinnoi työprofiiliasi. Se on yhteydessä sovellukseen <xliff:g id="APPLICATION">%2$s</xliff:g>, joka voi valvoa toimintaasi verkossa, esimerkiksi sähköposteja, sovelluksia ja verkkosivustoja.\n\nPyydä lisätietoja järjestelmänvalvojalta."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> hallinnoi työprofiiliasi. Se on yhteydessä sovellukseen <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, joka voi valvoa toimintaasi verkossa, esimerkiksi sähköposteja, sovelluksia ja verkkosivustoja.\n\nLisäksi olet yhteydessä sovellukseen <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, joka voi valvoa henkilökohtaista toimintaasi verkossa."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Lukitus avattu käyttäjälle <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> on käytössä"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Laite pysyy lukittuna, kunnes se avataan käsin"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Näe ilmoitukset nopeammin"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Näytä ennen lukituksen avaamista"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ei kiitos"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Määritä asetukset"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Sammuta nyt"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Lopeta nyt"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Laajenna."</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tiivistä."</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Näyttö on kiinnitetty"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Pois käytöstä"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ilmoitusten tehohallinnan avulla voit määrittää sovelluksen ilmoituksille tärkeystason väliltä 0–5. \n\n"<b>"Taso 5"</b>" \n– Ilmoitukset näytetään ilmoitusluettelon yläosassa \n– Näkyminen koko näytön tilassa sallitaan \n– Ilmoitukset kurkistavat aina näytölle\n\n"<b>"Taso 4"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ilmoitukset kurkistavat aina näytölle \n\n"<b>"Taso 3"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n\n"<b>"Taso 2"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n\n"<b>"Taso 1"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n– Ilmoitukset piilotetaan lukitusnäytöltä ja tilapalkista \n– Ilmoitukset näytetään ilmoitusluettelon alaosassa \n\n"<b>"Taso 0"</b>" \n– Kaikki sovelluksen ilmoitukset estetään"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ilmoitukset"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Et saa näitä ilmoituksia enää."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Et saa näitä ilmoituksia enää."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ilmoitusluokkaa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tällä sovelluksella ei ole ilmoitusluokkia."</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Tämä sovellus: 1/<xliff:g id="NUMBER_1">%d</xliff:g> ilmoitusluokkaa</item>
       <item quantity="one">Tämä sovellus: 1/<xliff:g id="NUMBER_0">%d</xliff:g> ilmoitusluokkaa</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Ilmoitusten hallinta"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Ilmoitusten torkkuasetukset"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuuttia"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuuttia"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 tunti"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 tuntia"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"KUMOA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Torkku: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akun käyttö"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
diff --git a/packages/SystemUI/res/values-fi/strings_car.xml b/packages/SystemUI/res/values-fi/strings_car.xml
index fc94b90..927b13d 100644
--- a/packages/SystemUI/res/values-fi/strings_car.xml
+++ b/packages/SystemUI/res/values-fi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aja varovasti"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tarkkaile huolellisesti ajo-olosuhteita ja noudata aina voimassa olevia lakeja. Reittiohjeet saattavat olla epätarkkoja, epätäydellisiä, vaarallisia, epäsopivia, kiellettyjä tai kulkea hallintoalueiden läpi. Myös yritystiedot voivat olla epätarkkoja tai epätäydellisiä. Tietoja ei päivitetä reaaliajassa eikä sijaintien tarkkuutta taata. Älä käytä ajon aikana mobiililaitettasi tai sovelluksia, joita ei ole suunniteltu Android Autolle."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tuntematon"</string>
+    <string name="start_driving" msgid="864023351402918991">"Aloita ajaminen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 827958c..4dd3c47 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Vous ne serez pas dérangé par les sons et les vibrations, sauf pour les alarmes, les rappels, les événements et les appelants. Vous entendrez tout ce que vous choisissez d\'écouter, y compris la musique, les vidéos et les jeux."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Vous ne serez pas dérangé par les sons et les vibrations, sauf pour les alarmes. Vous entendrez tout ce que vous choisissez d\'écouter, y compris la musique, les vidéos et les jeux."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni par les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous spécifiez."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez quand même faire des appels téléphoniques."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris les courriels, les applications et les sites Web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux courriels, aux applications et aux sites Web.\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux courriels, aux applications et aux sites Web.\n\nVous êtes également connecté à <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, qui peut contrôler votre activité personnelle sur le réseau."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Déverrouillé pour for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> fonctionne"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"L\'appareil restera verrouillé jusqu\'à ce que vous le déverrouilliez manuellement"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Voir les notifications plus rapidement"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Afficher les notifications avant de déverrouiller l\'appareil"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Non, merci"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurer"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Désactiver maintenant"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Arrêter maintenant"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"L\'écran est épinglé"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Avec les réglages avancés des notifications, vous pouvez définir un degré d\'importance de 0 à 5 pour les notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher dans le haut de la liste des notifications \n- Autoriser les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 4"</b>" \n- Empêcher les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 3"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n\n"<b>"Niveau 2"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n\n"<b>"Niveau 1"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n- Masquer de l\'écran de verrouillage et de la barre d\'état status bar \n- Afficher dans le bas de la liste des notifications \n\n"<b>"Level 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
       <item quantity="other">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"options de répétition des notifications"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 heures"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Reporté pour <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation de la pile"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_car.xml b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
index 10e1fd5..a88dc3b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_car.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduisez prudemment"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de la route et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et ils peuvent traverser des zones administratives. Les renseignements sur les entreprises peuvent également être incorrects ou incomplets. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Inconnu"</string>
+    <string name="start_driving" msgid="864023351402918991">"Commencer à conduire"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index e78c892..6494710 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes, des rappels, des événements et des appelants de votre choix. Vous entendrez toujours les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes. Vous entendrez toujours les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous avez spécifiées."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez toujours passer des appels téléphoniques."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Vous êtes connecté à <xliff:g id="APPLICATION">%1$s</xliff:g>. Cette application peut contrôler votre activité personnelle sur le réseau, y compris les e-mails, les applications et les sites Web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux e-mails, aux applications et aux sites Web.\n\nPour plus d\'informations, contactez votre administrateur."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ce profil est connecté à <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, qui peut contrôler votre activité professionnelle sur le réseau, y compris l\'activité relative aux e-mails, aux applications et aux sites Web.\n\nVous êtes également connecté à <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, qui peut contrôler votre activité personnelle sur le réseau."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Déverrouillé pour <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> est en cours d\'exécution"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"L\'appareil restera verrouillé jusqu\'à ce que vous le déverrouilliez manuellement."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recevoir les notifications plus vite"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Afficher les notifications avant de déverrouiller l\'appareil"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Non, merci"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurer"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Désactiver"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Arrêter maintenant"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Écran épinglé"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Grâce aux commandes de gestion des notifications, vous pouvez définir le niveau d\'importance (compris entre 0 et 5) des notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher en haut de la liste des notifications \n- Autoriser l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 4"</b>" \n- Empêcher l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 3"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n\n"<b>"Niveau 2"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n\n"<b>"Niveau 1"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n- Masquer les notifications dans l\'écran de verrouillage et la barre d\'état \n- Afficher au bas de la liste des notifications \n\n"<b>"Niveau 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
       <item quantity="other">1 catégorie de notification sur <xliff:g id="NUMBER_1">%d</xliff:g> provenant de cette application</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> : <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"options de répétition des notifications"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 heures"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Répétée après <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation batterie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
diff --git a/packages/SystemUI/res/values-fr/strings_car.xml b/packages/SystemUI/res/values-fr/strings_car.xml
index d42586e..a88dc3b 100644
--- a/packages/SystemUI/res/values-fr/strings_car.xml
+++ b/packages/SystemUI/res/values-fr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Soyez prudent sur la route"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de conduite et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et traverser des frontières administratives. Les informations sur les établissements peuvent également être incorrectes ou incomplètes. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Inconnu"</string>
+    <string name="start_driving" msgid="864023351402918991">"Commencer à conduire"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3cd4e71..f8daa9e 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Pasa o dedo cara arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos. Aínda podes facer chamadas de teléfono."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Estás conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode supervisar a túa actividade persoal na rede, incluídos os correos electrónicos, as aplicacións e os sitios web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> xestiona o teu perfil de traballo, que está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>. Esta aplicación pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web.\n\nPara obter máis información, contacta co administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> xestiona o teu perfil de traballo, que está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>. Esta aplicación pode controlar a túa actividade na rede, mesmo os correos electrónicos, as aplicacións e os sitios web.\n\nTamén estás conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode controlar a túa actividade persoal na rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Estase executando: <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado ata que o desbloquees manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Recibir notificacións máis rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Consúltaas antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Non, grazas"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactivar agora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ampliar"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A pantalla está fixada"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivar"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Cos controis de notificacións mellorados, podes asignarlles un nivel de importancia comprendido entre 0 e 5 ás notificacións dunha aplicación determinada. \n\n"<b>"Nivel 5"</b>" \n- Mostrar na parte superior da lista de notificacións. \n- Permitir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 4"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 3"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n\n"<b>"Nivel 2"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n\n"<b>"Nivel 1"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n- Ocultar na pantalla de bloqueo e na barra de estado. \n- Mostrar na parte inferior da lista de notificacións. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas as notificacións da aplicación."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacións"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Deixarás de recibir estas notificacións."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixarás de recibir estas notificacións"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificacións"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación non ten categorías de notificacións"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorías de notificacións desta aplicación</item>
       <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoría de notificación desta aplicación</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controis de notificacións"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcións para adiar notificacións"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiouse <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de batería"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función de aforro da batería non está dispoñible durante a carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
diff --git a/packages/SystemUI/res/values-gl/strings_car.xml b/packages/SystemUI/res/values-gl/strings_car.xml
index bb3f8eb..e6c6298 100644
--- a/packages/SystemUI/res/values-gl/strings_car.xml
+++ b/packages/SystemUI/res/values-gl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ten moi en conta as condicións de condución e respecta sempre as leis aplicables. É posible que as indicacións sexan imprecisas, incompletas, perigosas, inadecuadas, estean prohibidas ou que impliquen atravesar áreas administrativas. A información das empresas tamén pode ser imprecisa ou estar incompleta. Os datos non se proporcionan en tempo real e non se garante a precisión da localización. Non manipules o teu dispositivo móbil nin utilices aplicacións que non estean deseñadas para Android Auto mentres conduces."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Descoñecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Comezar a conducir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2cb19ed..13e47f9 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"શોધો"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ઉપર સ્લાઇડ કરો."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ડાબે સ્લાઇડ કરો."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"તમને ધ્વનિ કે વાઇબ્રેશનો દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં, સિવાય કે અલાર્મ, સ્મૃતિપત્રો, ઇવેન્ટ અને તમે ઉલ્લેખ કરો તે કૉલર. તમે સંગીત, વીડિયો અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરો તે હજુ પણ સંભળાશે."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"તમને ધ્વનિ કે વાઇબ્રેશનો દ્વારા ખલેલ પહોંચાડવામાં આવશે નહીં, સિવાય કે અલાર્મ. તમે સંગીત, વીડિયો અને રમતો સહિત તમે જે કંઈપણ ચલાવવાનું પસંદ કરો તે હજુ પણ સંભળાશે."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"તમને તમે ઉલ્લેખિત એલાર્મ્સ, સ્મૃતિપત્રો, ઇવેન્ટ્સ અને કૉલર્સ સિવાયના ધ્વનિઓ અને વાઇબ્રેશન્સથી ખલેલ પહોંચાડવામાં આવશે નહીં."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"કસ્ટમાઇઝ કરો"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે.  તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને આ અવરોધિત કરે છે."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિત તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા  સંચાલિત કરાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. આ પ્રોફાઇલ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ કરેલું છે, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> માટે અનલૉક કર્યુ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ચાલી રહ્યું છે"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"તમે ઉપકરણને મેન્યુઅલી અનલૉક કરશો નહીં ત્યાં સુધી તે લૉક રહેશે"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"વધુ ઝડપથી સૂચનાઓ મેળવો"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"તમે અનલૉક કરો તે પહેલાં તેમને જુઓ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"નહીં આભાર"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"સેટ અપ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"હમણાં બંધ કરો"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"હવે સમાપ્ત કરો"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"વિસ્તૃત કરો"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"સંકુચિત કરો"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"સ્ક્રીન પિન કરેલ છે"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"બંધ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"પાવર સૂચના નિયંત્રણો સાથે, તમે ઍપ્લિકેશનની સૂચનાઓ માટે 0 થી 5 સુધીના મહત્વના સ્તરને સેટ કરી શકો છો. \n\n"<b>"સ્તર 5"</b>" \n- સૂચના સૂચિની ટોચ પર બતાવો \n- પૂર્ણ સ્ક્રીન અવરોધની મંજૂરી આપો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 4"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 3"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n\n"<b>"સ્તર 2"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અને વાઇબ્રેશન કરશો નહીં \n\n"<b>"સ્તર 1"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અથવા વાઇબ્રેટ કરશો નહીં \n- લૉક સ્ક્રીન અને સ્થિતિ બારથી છુપાવો \n- સૂચના સૂચિના તળિયા પર બતાવો \n\n"<b>"સ્તર 0"</b>" \n- ઍપ્લિકેશનની તમામ સૂચનાઓને અવરોધિત કરો"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"સૂચનાઓ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"તમને હવે આ સૂચનાઓ મળશે નહીં."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"તમને હવે આ સૂચનાઓ મળશે નહીં"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> સૂચના કૅટેગરીઓ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"આ ઍપ્લિકેશનમાં સૂચના કૅટેગરી નથી"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">આ ઍપ્લિકેશનમાંની <xliff:g id="NUMBER_1">%d</xliff:g> સૂચના કૅટેગરીમાંથી 1</item>
       <item quantity="other">આ ઍપ્લિકેશનમાંની <xliff:g id="NUMBER_1">%d</xliff:g> સૂચના કૅટેગરીમાંથી 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"સૂચના નિયંત્રણો"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"સૂચના સ્નૂઝ કરવાના વિકલ્પો"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 મિનિટ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 મિનિટ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 કલાક"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 કલાક"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"પૂર્વવત્ કરો"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"બૅટરી વપરાશ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
diff --git a/packages/SystemUI/res/values-gu/strings_car.xml b/packages/SystemUI/res/values-gu/strings_car.xml
index b22b688..57a6f02 100644
--- a/packages/SystemUI/res/values-gu/strings_car.xml
+++ b/packages/SystemUI/res/values-gu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"સુરક્ષિત રીતે વાહન ચલાવો"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ડ્રાઇવિંગ સ્થિતિઓથી સંપૂર્ણપણે વાકેફ રહો અને હંમેશા લાગુ કાયદાઓનું પાલન કરો. દિશા નિર્દેશો અચોક્કસ, અપૂર્ણ, જોખમમકારક, બિન અનુકૂળ, પ્રતિબંધિત અથવા વહીવટી વિસ્તારોને ઓળંગવાનું સમાવતા હોઇ શકે છે. વ્યવસાય માહિતી પણ અચોક્કસ અથવા અપૂર્ણ હોઇ શકે છે. ડેટા રિઅલ-ટાઇમ નથી અને સ્થાન ચોકસાઈની ગેરંટી આપી શકતાં નથી. ડ્રાઇવિંગ કરતી વખતે Android Auto માટે તમારું મોબાઇલ સાધન હેન્ડલ કરવું અથવા ઍપ્લિકેશનનો ઉપયોગ કરવાનું કોઇ પ્રયોજન નથી."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"અજાણ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ડ્રાઇવિંગ શરૂ કરો"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a61499b..65eda75 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -29,7 +29,7 @@
       <item quantity="one">अवलोकन में %d स्‍क्रीन</item>
       <item quantity="other">अवलोकन में %d स्‍क्रीन</item>
     </plurals>
-    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई नोटिफ़िकेशन नहीं"</string>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई नोटिफिकेशन नहीं"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ऑनगोइंग"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"सूचनाएं"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"बैटरी कम है"</string>
@@ -166,7 +166,7 @@
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्टम सेटिंग."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाएं."</string>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"सभी नोटिफ़िकेशन देखें"</string>
-    <string name="accessibility_remove_notification" msgid="3603099514902182350">"नोटिफ़िकेशन साफ़ करें"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"नोटिफिकेशन साफ़ करें"</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS सक्षम."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS प्राप्त करना."</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"टेलीटाइपराइटर सक्षम."</string>
@@ -181,8 +181,8 @@
     <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"<xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन जानकारी खोलें."</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ हो रहा है."</string>
     <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
-    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"नोटिफ़िकेशन खारिज की गई."</string>
-    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"नोटिफ़िकेशन शेड."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"नोटिफिकेशन खारिज की गई."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"नोटिफिकेशन शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"लॉक स्क्रीन."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"सेटिंग"</string>
@@ -255,7 +255,7 @@
       <item quantity="one">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और नोटिफ़िकेशन हैं.</item>
       <item quantity="other">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और नोटिफ़िकेशन हैं.</item>
     </plurals>
-    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"नोटिफ़िकेशन सेटिंग"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"नोटिफिकेशन सेटिंग"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिंग"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्‍क्रीन स्‍वचालित रूप से घूमेगी."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्‍क्रीन लैंडस्केप अभिविन्यास में लॉक है."</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"आपको अलार्म, रिमाइंडर, इवेंट और आपने जिन कॉलर के बारे में विशेष रूप से बताया है, उन्हें छोड़कर ध्‍वनियों और कंपनों से परेशान नहीं किया जाएगा. आपको अभी भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"आपको अलार्म छोड़कर दूसरी ध्‍वनियों और कंपनों से परेशान नहीं किया जाएगा. आपको अभी भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, इवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्‍वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string>
@@ -410,7 +409,7 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"फिर से न दिखाएं"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सभी साफ करें"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अब प्रारंभ करें"</string>
-    <string name="empty_shade_text" msgid="708135716272867002">"कोई नोटिफ़िकेशन नहीं"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"कोई नोटिफिकेशन नहीं"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"प्रोफ़ाइल को मॉनीटर किया जा सकता है"</string>
     <string name="vpn_footer" msgid="2388611096129106812">"नेटवर्क को मॉनीटर किया जा सकता है"</string>
     <string name="branded_vpn_footer" msgid="2168111859226496230">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइट सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि को मॉनिटर कर सकता है."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"आपकी कार्य प्रोफ़ाइल का प्रबंधन <xliff:g id="ORGANIZATION">%1$s</xliff:g> करता है. प्रोफ़ाइल <xliff:g id="APPLICATION">%2$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nअधिक जानकारी के लिए, अपने व्यवस्थापक से संपर्क करें."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"आपकी कार्य प्रोफ़ाइल का प्रबंधन <xliff:g id="ORGANIZATION">%1$s</xliff:g> करता है. प्रोफ़ाइल <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nआप <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> से भी कनेक्ट हैं, जो आपकी व्यक्तिगत नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> के लिए अनलॉक किया गया"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चल रहा है"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"जब तक कि आप मैन्‍युअल रूप से अनलॉक नहीं करते तब तक डिवाइस लॉक रहेगा"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"सूचनाएं अधिक तेज़ी से प्राप्त करें"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"आपके द्वारा उन्हें अनलॉक किए जाने से पहले देखें"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"रहने दें"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"सेट करें"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"अभी बंद करें"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"अब समाप्त करें"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करें"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त करें"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"स्‍क्रीन पिन कर दी गई है"</string>
@@ -539,8 +540,8 @@
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ चालू करें?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"अपने कीबोर्ड को अपने टैबलेट से कनेक्ट करने के लिए, आपको पहले ब्लूटूथ चालू करना होगा."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करें"</string>
-    <string name="show_silently" msgid="6841966539811264192">"नोटिफ़िकेशन मौन रूप से दिखाएं"</string>
-    <string name="block" msgid="2734508760962682611">"सभी नोटिफ़िकेशन अवरुद्ध करें"</string>
+    <string name="show_silently" msgid="6841966539811264192">"नोटिफिकेशन मौन रूप से दिखाएं"</string>
+    <string name="block" msgid="2734508760962682611">"सभी नोटिफिकेशन अवरुद्ध करें"</string>
     <string name="do_not_silence" msgid="6878060322594892441">"मौन ना करें"</string>
     <string name="do_not_silence_block" msgid="4070647971382232311">"मौन या अवरुद्ध ना करें"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पावर नोटिफ़िकेशन नियंत्रण"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"पावर नोटिफ़िकेशन नियंत्रण के द्वारा, आप किसी ऐप्लिकेशन के नोटिफ़िकेशन के लिए 0 से 5 तक महत्व का लेवल सेट कर सकते हैं. \n\n"<b>"लेवल 5"</b>" \n- नोटिफ़िकेशन सूची के शीर्ष पर दिखाएं \n- पूर्ण स्क्रीन बाधा की अनुमति दें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 4"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 3"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n\n"<b>"लेवल 2"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n\n"<b>"लेवल 1"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n- लॉक स्क्रीन और स्थिति बार से छिपाएं \n- नोटिफ़िकेशन सूची के नीचे दिखाएं \n\n"<b>"लेवल 0"</b>" \n- ऐप्लिकेशन के सभी नोटिफ़िकेशन अवरुद्ध कर दें"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"नोटिफ़िकेशन"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"अब आपको ये नोटिफ़िकेशन नहीं मिलेंगे."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"अब आपको ये नोटिफ़िकेशन नहीं मिलेंगे"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"नोटिफ़िकेशन की <xliff:g id="NUMBER">%d</xliff:g> श्रेणियां"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"इस ऐप्लिकेशन में नोटिफ़िकेशन श्रेणियां नहीं हैं"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">इस ऐप्लिकेशन की <xliff:g id="NUMBER_1">%d</xliff:g> नोटिफ़िकेशन श्रेणियों में से 1 श्रेणी</item>
       <item quantity="other">इस ऐप्लिकेशन की <xliff:g id="NUMBER_1">%d</xliff:g> नोटिफ़िकेशन श्रेणियों में से 1 श्रेणी</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"नोटिफ़िकेशन नियंत्रण"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"नोटिफ़िकेशन की याद दिलाने के विकल्प"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनट"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनट"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 घंटा"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 घंटे"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"पहले जैसा करें"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"बैटरी उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
@@ -719,7 +720,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="4171698133469539591">"अगर आप नहीं चाहते कि <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-hi/strings_car.xml b/packages/SystemUI/res/values-hi/strings_car.xml
index a643bd8..3cf1fb3 100644
--- a/packages/SystemUI/res/values-hi/strings_car.xml
+++ b/packages/SystemUI/res/values-hi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित ढंग से गाड़ी चलाएं"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"गाड़ी चलाने की स्थितियों के प्रति पूरी तरह से सतर्क रहें और हमेशा लागू कानूनों का पालन करें. दिशाएं गलत, अपूर्ण, खतरनाक, निषिद्ध हो सकती हैं या उनमें प्रशासनिक क्षेत्रों को पार करना शामिल हो सकता है. व्यावसायिक जानकारी भी गलत या अपूर्ण हो सकती है. डेटा रीयल-टाइम नहीं है और स्थान सटीकता की गारंटी नहीं दी जा सकती. गाड़ी चलाते समय अपने मोबाइल डिवाइस या फ़ोन या Android Auto के लिए अभिप्रेत न किए गए ऐप्स का उपयोग ना करें."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"ड्राइविंग शुरू करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
index 5e65e46..39f06f6 100644
--- a/packages/SystemUI/res/values-hi/strings_tv.xml
+++ b/packages/SystemUI/res/values-hi/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-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e71a6a6..99df2bf 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Neće vas ometati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete. I dalje ćete čuti sve što želite reproducirati, uključujući glazbu, videozapise i igre."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Neće vas ometati zvukovi i vibracije, osim alarma. I dalje ćete čuti sve što želite reproducirati, uključujući glazbu, videozapise i igre."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Neće vas prekidati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre. I dalje ćete moći telefonirati."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste s aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g> koja može nadzirati vašu osobnu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vašim radnim profilom upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g> koja može nadzirati vaše poslovne aktivnosti na mreži, uključujući e-poruke, aplikacije i web-lokacije.\n\nAko vam je potrebno više informacija, obratite se administratoru."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Vašim radnim profilom upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan s aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> koja može nadzirati vaše poslovne aktivnosti na mreži, uključujući e-poruke, aplikacije i web-lokacije.\n\nPovezani ste i s aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> koja može nadzirati vaše osobne aktivnosti na mreži."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Otključano za korisnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Izvodi se <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ručno ne otključate"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Primajte obavijesti brže"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Pogledajte ih prije otključavanja"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Postavi"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Odmah isključi"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Prekini sada"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširivanje"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sažimanje"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je prikvačen"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Napredne kontrole obavijesti omogućuju vam da postavite razinu važnosti za obavijesti aplikacije od 0 do 5. \n\n"<b>"Razina 5"</b>" \n– prikaži na vrhu popisa obavijesti \n– dopusti prekide prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 4"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 3"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled\n\n"<b>"Razina 2"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n\n"<b>"Razina 1"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n– ne prikazuj na zaključanom zaslonu i traci statusa \n– prikaži na dnu popisa obavijesti \n\n"<b>"Razina 0"</b>" \n– blokiraj sve obavijesti aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavijesti"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete primati te obavijesti."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete primati te obavijesti"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Broj kategorija obavijesti: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavijesti"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavijesti iz ove aplikacije</item>
       <item quantity="few">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obavijesti iz ove aplikacije</item>
@@ -574,12 +577,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrole obavijesti"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcije odgode obavijesti"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 sata"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"PONIŠTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
diff --git a/packages/SystemUI/res/values-hr/strings_car.xml b/packages/SystemUI/res/values-hr/strings_car.xml
index 034bd71d..d38620b 100644
--- a/packages/SystemUI/res/values-hr/strings_car.xml
+++ b/packages/SystemUI/res/values-hr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pažljivo pratite promet i uvijek se pridržavajte primjenjivih zakona. Upute mogu biti neprecizne, nepotpune, opasne, neprikladne, zabranjene ili mogu uključivati prelazak administrativnih granica. Podaci o tvrtkama također mogu biti neprecizni i nepotpuni. Podaci nisu u stvarnom vremenu i preciznost lokacije nije zajamčena. Tijekom vožnje ne rukujte mobilnim uređajem i ne upotrebljavajte aplikacije koje nisu namijenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nepoznato"</string>
+    <string name="start_driving" msgid="864023351402918991">"Početak vožnje"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 05dd386..2afaf61 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Az Ön által meghatározott ébresztéseken, emlékeztetőkön, eseményeken és hívókon kívül nem fogja Önt más hang vagy rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Az ébresztéseken kívül nem fogja Önt más hang és rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Nem zavarják majd hanghatások, sem rezgés, kivéve az ébresztéseket, emlékeztetőket, eseményeket és az Ön által megjelölt hívókat."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Személyre szabás"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is. Telefonhívást továbbra is indíthat majd."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ön a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazáshoz csatlakozik, amely figyelheti személyes hálózati tevékenységét, beleértve az e-maileket, alkalmazásokat és webhelyeket."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Munkaprofilját a(z) <xliff:g id="ORGANIZATION">%1$s</xliff:g> kezeli. A profil csatlakozik a(z) <xliff:g id="APPLICATION">%2$s</xliff:g> alkalmazáshoz, amely figyelheti az Ön hálózati tevékenységeit, beleértve az e-maileket, alkalmazásokat és webhelyeket.\n\nTovábbi információért forduljon a rendszergazdához."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Munkaprofilját a(z) <xliff:g id="ORGANIZATION">%1$s</xliff:g> kezeli. A profil csatlakozik a(z) <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> alkalmazáshoz, amely figyelheti az Ön hálózati tevékenységeit, beleértve az e-maileket, alkalmazásokat és webhelyeket.\n\nCsatlakoztatta továbbá a(z) <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> alkalmazást, amely figyelheti az Ön személyes hálózati tevékenységeit."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Felnyitva a következő számára: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"A(z) <xliff:g id="TRUST_AGENT">%1$s</xliff:g> jelenleg fut"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Az eszköz addig zárolva marad, amíg kézileg fel nem oldja"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Gyorsabban megkaphatja az értesítéseket"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Már a képernyőzár feloldása előtt megtekintheti őket"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nem, köszönöm"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Beállítás"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Kikapcsolás most"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Befejezés most"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kibontás"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Összecsukás"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A képernyő rögzítve van"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kikapcsolva"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Az értesítési beállítások révén 0-tól 5-ig állíthatja be a fontossági szintet az alkalmazás értesítéseinél. \n\n"<b>"5. szint"</b>" \n– Megjelenítés az értesítési lista tetején \n– Teljes képernyő megszakításának engedélyezése \n– Mindig felugrik \n\n"<b>"4. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Mindig felugrik \n\n"<b>"3. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n\n"<b>"2. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés és rezgés \n\n"<b>"1. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés vagy rezgés \n– Elrejtés a lezárási képernyőről és az állapotsávról \n– Megjelenítés az értesítési lista alján \n\n"<b>"0. szint"</b>" \n– Az alkalmazás összes értesítésének letiltása"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Értesítések"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Többé nem jelennek meg ezek az értesítések."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Többé nem jelennek meg ezek az értesítések"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> értesítéskategória"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Az alkalmazás nem rendelkezik értesítési kategóriákkal"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g>/1 értesítési kategória az alkalmazásból</item>
       <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g>/1 értesítési kategória az alkalmazásból</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> – <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"értesítésvezérlők"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"értesítések halasztási beállításai"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 perc"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 perc"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 óra"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 óra"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"VISSZAVONÁS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Elhalasztva: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkumulátorhasználat"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
diff --git a/packages/SystemUI/res/values-hu/strings_car.xml b/packages/SystemUI/res/values-hu/strings_car.xml
index 688d88b..46bf09d 100644
--- a/packages/SystemUI/res/values-hu/strings_car.xml
+++ b/packages/SystemUI/res/values-hu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vezessen óvatosan"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mindig legyen teljes mértékben tisztában a vezetési körülményekkel, és a vonatkozó törvényeket tartsa be! Az útvonaltervek pontatlanok, hiányosak, veszélyesek, nem megfelelők vagy tiltottak lehetnek, illetve a közforgalom számára nem használható utakat érinthetnek. Az üzleti információk is pontatlanok vagy hiányosak lehetnek. Az adatok nem valós idejűek, ezért nem garantálhatjuk a helyadatok pontosságát. Vezetés közben ne kezelje mobileszközét, illetve ne használjon olyan alkalmazásokat az Android Auto rendszerrel, amelyeket nem ahhoz terveztek."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ismeretlen"</string>
+    <string name="start_driving" msgid="864023351402918991">"Kezdhet vezetni"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 37a7cbd..cc6608a 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Ձայները և թրթռոցները չեն անհանգստացնի ձեզ, բացի ձեր կողմից նշված զարթուցիչները, հիշեցումները, միջոցառումների ծանուցումները և զանգերը։ Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Ձայները և թրթռոցները, բացի զարթուցիչներից, չեն անհանգստացնի ձեզ: Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Բոլոր ձայներն ու թրթռոցները կանջատվեն։ Ձեզ կանհանգստացնեն միայն զարթուցիչը, հիշեցումները, միջոցառումների մասին ծանուցումները և զանգերը ձեր ընտրած մարդկանցից։"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Հարմարեցնել"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռոցները, այդ թվում զարթուցիչները, երաժշտությունը, տեսանյութերի և խաղերի ձայները: Դուք կկարողանաք հեռախոսազանգեր անել։"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Այս գործողությունն արգելափակում է ԲՈԼՈՐ ձայներն ու թրթռոցները, այդ թվում նաև զարթուցիչների, երաժշտության, տեսանյութերի և խաղերի ձայներն ու թրթռոցները:"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Դուք կապակցված եք <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին, որը կարող է վերահսկել անձնական ցանցում կատարած ձեր գործողությունները, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ձեր աշխատանքային պրոֆիլի կառավարիչն է <xliff:g id="ORGANIZATION">%1$s</xliff:g> կազմակերպությունը: Այն կապակցված է <xliff:g id="APPLICATION">%2$s</xliff:g> հավելվածին, որը կարող է վերահսկել աշխատանքային ցանցում կատարած գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:\n\nԼրացուցիչ տեղեկություններ ստանալու համար դիմեք ձեր ադմինիստրատորին։"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ձեր աշխատանքային պրոֆիլի կառավարիչն է <xliff:g id="ORGANIZATION">%1$s</xliff:g> կազմակերպությունը: Այն կապակցված է <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> հավելվածին, որը կարող է վերահսկել աշխատանքային ցանցում կատարած գործունեությունը, այդ թվում նաև էլփոստի հաշիվները, հավելվածները և կայքերը:\n\nԴուք կապակցված եք նաև <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> հավելվածին, որը կարող է վերահսկել անձնական ցանցում կատարած ձեր գործողությունները:"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ապակողպվել է <xliff:g id="USER_NAME">%1$s</xliff:g> օգտատիրոջ համար"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g>-ն աշխատում է"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Սարքը կմնա արգելափակված՝ մինչև ձեռքով չբացեք"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Ավելի արագ ստացեք ծանուցումները"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Տեսեք դրանք մինչև ապակողպելը"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ոչ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Կարգավորել"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Անջատել հիմա"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Ավարտել"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ընդարձակել"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Կոծկել"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Էկրանն ամրացված է"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Անջատել"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ծանուցումների ընդլայնված կառավարման օգնությամբ կարող եք յուրաքանչյուր հավելվածի ծանուցումների համար նշանակել կարևորության աստիճան՝ 0-5 սահմաններում: \n\n"<b>"5-րդ աստիճան"</b>" \n- Ցուցադրել ծանուցումների ցանկի վերևում \n- Թույլատրել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"4-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"3-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n\n"<b>"2-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n\n"<b>"1-ին աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n- Չցուցադրել կողպէկրանում և կարգավիճակի գոտում \n- Ցուցադրել ծանուցումների ցանկի ներքևում \n\n"<b>"0-րդ աստիճան"</b>\n"- Արգելափակել հավելվածի բոլոր ծանուցումները"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ծանուցումներ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Այս ծանուցումներն այլևս չեք ստանա։"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Այս ծանուցումներն այլևս չեք ստանա"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ծանուցման կատեգորիաներ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Այս հավելվածը ծանուցման կատեգորիաներ չունի"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="other">1 ալիք` այս հավելվածի <xliff:g id="NUMBER_1">%d</xliff:g> կատեգորիաներից</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ծանուցման կառավարներ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ծանուցման հետաձգման ընտրանքներ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 րոպե"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 րոպե"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ժամ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ժամ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ՀԵՏԱՐԿԵԼ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Հետաձգվել է <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ով"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Մարտկոցի օգտագործում"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
@@ -719,7 +720,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="4171698133469539591">"Եթե չեք ցանկանում, որ <xliff:g id="NAME">%s</xliff:g>-ն օգտագործի այս գործառույթը, հպեք՝ կարգավորումները բացելու և այն անջատելու համար։"</string>
     <string name="pip_play" msgid="1417176722760265888">"Նվագարկել"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Դադարեցնել"</string>
@@ -748,7 +749,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Էկրանի պատկերներ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Ընդհանուր հաղորդագրություններ"</string>
-    <string name="notification_channel_storage" msgid="3077205683020695313">"Տարածք"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"Հիշողություն"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Ակնթարթորեն գործարկվող հավելվածներ"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"Ակնթարթորեն գործարկվող հավելվածները տեղադրում չեն պահանջում։"</string>
     <string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
diff --git a/packages/SystemUI/res/values-hy/strings_car.xml b/packages/SystemUI/res/values-hy/strings_car.xml
index 4f214f7..3d7f225 100644
--- a/packages/SystemUI/res/values-hy/strings_car.xml
+++ b/packages/SystemUI/res/values-hy/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Վարեք ապահով"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Երթևեկության պայմաններին միշտ լավատեղյակ եղեք և կատարեք համապատասխան օրենքների պահանջները: Երթուղիները կարող են լինել սխալ, կիսատ, վտանգավոր, ոչ պատշաճ, արգելված կամ կարող են անցնել վարչական միավորների միջով: Բիզնես տվյալները նույնպես կարող են լինել սխալ կամ կիսատ: Տվյալներն իրական ժամանակում չեն թարմացվում, իսկ տեղադրության ճշգրտությունը չի կարող երաշխավորվել: Մեքենա վարելիս մի օգտագործեք ձեր շարժական սարքը, ինչպես նաև Android Auto-ի համար չնախատեսված հավելվածները:"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Անհայտ"</string>
+    <string name="start_driving" msgid="864023351402918991">"Սկսել վարումը"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3e77a71..e71a999 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Anda tidak akan terganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon yang Anda tentukan. Anda akan tetap mendengar apa pun yang telah dipilih untuk diputar, termasuk musik, video, dan game."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Anda tidak akan terganggu oleh suara dan getaran, kecuali dari alarm. Anda akan tetap mendengar apa pun yang telah dipilih untuk diputar, termasuk musik, video, dan game."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon tertentu."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Sesuaikan"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir. Anda tetap dapat melakukan panggilan telepon."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Anda tersambung ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang dapat memantau aktivitas jaringan pribadi, termasuk email, aplikasi, dan situs web.."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profil kerja Anda dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil tersambung ke <xliff:g id="APPLICATION">%2$s</xliff:g>, yang dapat memantau aktivitas jaringan kerja, termasuk email, aplikasi, dan situs.\n\nHubungi admin untuk mendapatkan informasi lebih lanjut."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profil kerja Anda dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil tersambung ke <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, yang dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs.\n\nAnda juga tersambung ke <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, yang dapat memantau aktivitas jaringan pribadi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Dibuka kuncinya untuk <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> sedang berjalan"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Perangkat akan tetap terkunci hingga Anda membukanya secara manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum membuka kunci"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Tidak"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Siapkan"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Nonaktifkan sekarang"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Akhiri sekarang"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Luaskan"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ciutkan"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Layar dipasangi pin"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Nonaktif"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kontrol notifikasi daya, Anda dapt menyetel level kepentingan notifikasi aplikasi dari 0 sampai 5. \n\n"<b>"Level 5"</b>" \n- Muncul di atas daftar notifikasi \n- Izinkan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 4"</b>" \n- Jangan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 3"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n\n"<b>"Level 2"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara dan getaran \n\n"<b>"Level 1"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara atau getaran \n- Sembunyikan dari layar kunci dan bilah status \n- Muncul di bawah daftar notifikasi \n\n"<b>"Level 0"</b>" \n- Blokir semua notifikasi dari aplikasi"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifikasi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan mendapatkan notifikasi ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan mendapatkan notifikasi ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori notifikasi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikasi ini tidak memiliki kategori notifikasi"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 dari <xliff:g id="NUMBER_1">%d</xliff:g> kategori notifikasi dari aplikasi ini</item>
       <item quantity="one">1 dari <xliff:g id="NUMBER_0">%d</xliff:g> kategori notifikasi dari aplikasi ini</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrol notifikasi"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opsi tunda notifikasi"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 menit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 menit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 jam"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"URUNG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Pemakaian baterai"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
@@ -718,8 +719,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimalkan"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Tutup"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Seret ke bawah untuk menutup"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Menu picture in picture"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Menu gambar dalam gambar"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> adalah gambar-dalam-gambar"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, tap untuk membuka setelan dan menonaktifkannya."</string>
     <string name="pip_play" msgid="1417176722760265888">"Putar"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Jeda"</string>
diff --git a/packages/SystemUI/res/values-in/strings_car.xml b/packages/SystemUI/res/values-in/strings_car.xml
index cc23ecf..09f31b0 100644
--- a/packages/SystemUI/res/values-in/strings_car.xml
+++ b/packages/SystemUI/res/values-in/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Hati-hati saat berkendara"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tetap perhatikan keadaan saat mengemudi dan selalu patuhi peraturan yang berlaku. Petunjuk arah mungkin tidak akurat, tidak lengkap, berbahaya, tidak cocok, terlarang, atau dapat melewati wilayah administratif. Informasi bisnis juga mungkin tidak akurat atau tidak lengkap. Data tidak dalam waktu nyata dan keakuratan lokasi tidak dijamin. Jangan menggunakan perangkat seluler atau aplikasi yang tidak berkaitan dengan Android Auto saat mengemudi."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tidak diketahui"</string>
+    <string name="start_driving" msgid="864023351402918991">"Mulai Mengemudi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index a1aa168..ca3b32f 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/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">"Picture-in-picture"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Gambar-dalam-Gambar"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program tanpa judul)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Layar penuh"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index ce665e2..bc5bcaa 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Leita"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Strjúktu upp til að <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Strjúktu til vinstri til að <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Þú verður ekki fyrir truflunum frá hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl frá þeim sem þú leyfir fyrirfram. Þú heyrir áfram í öllu sem þú velur að spila, svo sem tónlist, myndskeiðum og leikjum."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Þú verður ekki fyrir truflunum frá hljóðmerkjum og titringi, fyrir utan vekjara. Þú heyrir áfram í öllu sem þú velur að spila, svo sem tónlist, myndskeiðum og leikjum."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Þú verður ekki fyrir truflunum af hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl sem þú leyfir fyrir fram."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Sérsníða"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum. Þú getur áfram hringt símtöl."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Þú ert með tengingu við <xliff:g id="APPLICATION">%1$s</xliff:g>, sem getur fylgst með persónulegri netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Vinnusniðinu þínu er stýrt af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Sniðið er tengt <xliff:g id="APPLICATION">%2$s</xliff:g>, sem getur fylgst með netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum\n\nFrekari upplýsingar fást hjá kerfisstjóra."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Vinnusniðinu þínu er stýrt af <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Sniðið er tengt <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, sem getur fylgst með netnotkun þinni, þ. á m. tölvupósti, forritum og vefsvæðum\n\nÞú ert einnig með tengingu við <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, sem getur fylgst með persónulegri netnotkun þinni."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Opnað fyrir <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> er í gangi"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Tækið verður læst þar til þú opnar það handvirkt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Fáðu tilkynningar hraðar"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Sjáðu þær áður en þú opnar"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei, takk"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Setja upp"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Slökkva núna"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Hætta núna"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Stækka"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minnka"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skjárinn er festur"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Slökkt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Með orkutilkynningastýringum geturðu stillt mikilvægi frá 0 upp í 5 fyrir tilkynningar forrita. \n\n"<b>"Stig 5"</b>" \n- Sýna efst á tilkynningalista \n- Leyfa truflun þegar birt er á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 4"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 3"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n\n"<b>"Stig 2"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n\n"<b>"Stig 1"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n- Fela á lásskjá og stöðustiku \n- Sýna neðst á tilkynningalista \n\n"<b>"Stig 0"</b>" \n- Setja allar tilkynningar frá forriti á bannlista"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Tilkynningar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Þú færð þessar tilkynningar ekki framar."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Þú færð þessar tilkynningar ekki framar"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> tilkynningaflokkar"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Þetta forrit er ekki með tilkynningaflokka"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 af <xliff:g id="NUMBER_1">%d</xliff:g> tilkynningaflokki frá þessu forriti</item>
       <item quantity="other">1 af <xliff:g id="NUMBER_1">%d</xliff:g> tilkynningaflokkum frá þessu forriti</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"tilkynningastýringar"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"þöggunarstillingar tilkynninga"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 mínútur"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 mínútur"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 klukkustund"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 klukkustundir"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"AFTURKALLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Rafhlöðunotkun"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
diff --git a/packages/SystemUI/res/values-is/strings_car.xml b/packages/SystemUI/res/values-is/strings_car.xml
index 65117be..5c89c76 100644
--- a/packages/SystemUI/res/values-is/strings_car.xml
+++ b/packages/SystemUI/res/values-is/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aktu varlega"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vertu vakandi fyrir akstursskilyrðum hverju sinni og farðu ævinlega eftir gildandi lögum. Leiðarlýsing kann að vera ónákvæm, ófullkomin, ekki við hæfi, bönnuð eða fela í sér ferðir um opinber svæði. Upplýsingar um fyrirtæki kunna einnig að vera ónákvæmar eða ófullkomnar. Gögn eru ekki í rauntíma og ekki er hægt að tryggja nákvæmni staðsetningarupplýsinga. Ekki handleika fartækið þitt meðan á akstri stendur eða nota forrit sem ekki eru hugsuð fyrir Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Óþekkt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Keyra af stað"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7bd3201..90838c0 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Non verrai disturbato da suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi, chiamate da contatti da te specificati ed elementi che hai scelto di continuare a riprodurre, inclusi video, musica e giochi."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Non verrai disturbato da suoni e vibrazioni, ad eccezione delle sveglie e degli elementi che hai scelto di continuare a riprodurre, inclusi video, musica e giochi."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Non ti disturberanno: suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi e chiamate da contatti da te specificati."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizza"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi. Potrai ancora telefonare."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Sei collegato a <xliff:g id="APPLICATION">%1$s</xliff:g>, che consente di monitorare la tua attività di rete personale, inclusi siti web, email e app."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Il tuo profilo di lavoro è gestito da <xliff:g id="ORGANIZATION">%1$s</xliff:g> ed è collegato a <xliff:g id="APPLICATION">%2$s</xliff:g>, da cui è possibile monitorare la tua attività di rete lavorativa, inclusi siti web, email e app.\n\nPer ulteriori informazioni, contatta l\'amministratore."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Il tuo profilo di lavoro è gestito da <xliff:g id="ORGANIZATION">%1$s</xliff:g> ed è collegato a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, da cui è possibile monitorare la tua attività di rete lavorativa, inclusi siti web, email e app.\n\nSei collegato anche a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, da cui è possibile monitorare la tua attività di rete personale."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Sbloccato per <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> in esecuzione"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Il dispositivo resterà bloccato fino allo sblocco manuale"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Ricevi notifiche più velocemente"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Visualizza prima di sbloccare"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"No, grazie"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configura"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Disattiva ora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Termina adesso"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Espandi"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Comprimi"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"La schermata è bloccata"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"I controlli di gestione delle notifiche ti consentono di impostare un livello di importanza compreso tra 0 e 5 per le notifiche di un\'app. \n\n"<b>"Livello 5"</b>" \n- Mostra in cima all\'elenco di notifiche \n- Consenti l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 4"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 3"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n\n"<b>"Livello 2"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n\n"<b>"Livello 1"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n- Nascondi da schermata di blocco e barra di stato \n- Mostra in fondo all\'elenco di notifiche \n\n"<b>"Livello 0"</b>" \n- Blocca tutte le notifiche dell\'app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifiche"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Non riceverai più queste notifiche."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Non riceverai più queste notifiche"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorie di notifica"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Questa app non ha categorie di notifica"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 categoria di notifica su <xliff:g id="NUMBER_1">%d</xliff:g> di questa app</item>
       <item quantity="one">1 categoria di notifica su <xliff:g id="NUMBER_0">%d</xliff:g> di questa app</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"gestione delle notifiche"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opzioni di posticipazione notifiche"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuti"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuti"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ore"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posticipato di <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizzo batteria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
@@ -720,8 +721,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Riduci a icona"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Chiudi"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Trascina verso il basso per ignorare"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Menu Picture in picture"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> è in Picture in picture"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Menu Picture-in-picture"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> è in picture-in-picture"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Se non desideri che l\'app <xliff:g id="NAME">%s</xliff:g> utilizzi questa funzione, tocca per aprire le impostazioni e disattivarla."</string>
     <string name="pip_play" msgid="1417176722760265888">"Riproduci"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Metti in pausa"</string>
diff --git a/packages/SystemUI/res/values-it/strings_car.xml b/packages/SystemUI/res/values-it/strings_car.xml
index 19c4e2b..65a90f8 100644
--- a/packages/SystemUI/res/values-it/strings_car.xml
+++ b/packages/SystemUI/res/values-it/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Guida in modo sicuro"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"È necessario essere sempre pienamente informati sulle condizioni della strada e rispettare la legislazione vigente. Le indicazioni stradali potrebbero essere imprecise, incomplete, pericolose, inadatte, vietate o richiedere l\'attraversamento di aree amministrative. Anche le informazioni sugli esercizi commerciali potrebbero essere imprecise o incomplete. I dati forniti non sono aggiornati in tempo reale e non è possibile garantire la precisione della geolocalizzazione. Non maneggiare dispositivi mobili e app non destinate ad Android Auto durante la guida."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Sconosciuto"</string>
+    <string name="start_driving" msgid="864023351402918991">"Inizia la guida"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index 81d76d5..629e306 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/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">"Picture in picture"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programma senza titolo)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Chiudi PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Schermo intero"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9d5c11e..687156f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -356,8 +356,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות, תזכורות, אירועים ושיחות ממתקשרים מסוימים לבחירתך. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"כדי לא להפריע לך, המכשיר לא ירטוט ולא ישמיע שום צליל, חוץ מהתראות. המצב הזה לא ישפיע על צלילים שהם חלק מתוכן שבחרת להפעיל, כמו מוזיקה, סרטונים ומשחקים."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"צלילים ורטט לא יופעלו, פרט להתראות, תזכורות, אירועים ואנשים מסוימים שמתקשרים אליך, אם יש כאלה שציינת."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"התאמה אישית"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"פעולה זו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. בכל מקרה, עדיין אפשר להתקשר."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"פעולה זו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string>
@@ -471,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"אתה מחובר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת הפרטית, כולל הודעות אימייל, אפליקציות ואתרים."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nלמידע נוסף, פנה למנהל המערכת."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"פרופיל העבודה שלך מנוהל על ידי <xliff:g id="ORGANIZATION">%1$s</xliff:g>. הפרופיל מחובר לאפליקציה <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים.\n\nהפרופיל מחובר גם לאפליקציה <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"הנעילה בוטלה על ידי <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> פועל"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"המכשיר יישאר נעול עד שתבטל את נעילתו באופן ידני"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"קבל התראות מהר יותר"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"צפה בהן לפני שתבטל נעילה"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"לא, תודה"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"הגדר"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>‏. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"כבה עכשיו"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"סיים כעת"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"הרחב"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"כווץ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"המסך מוצמד"</string>
@@ -531,7 +532,7 @@
     <string name="tuner_warning" msgid="8730648121973575701">"‏System UI Tuner מספק לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string>
     <string name="got_it" msgid="2239653834387972602">"הבנתי"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"‏מזל טוב! ה-System UI Tuner נוסף ל\'הגדרות\'"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"‏מזל טוב! System UI Tuner נוסף ל\'הגדרות\'"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"הסר מההגדרות"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"‏האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string>
     <string name="activity_not_found" msgid="348423244327799974">"האפליקציה אינה מותקנת במכשיר"</string>
@@ -552,9 +553,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"כבוי"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של הודעות הפעלה, תוכל להגדיר רמת חשיבות מ-0 עד 5 להודעות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצג בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתר ממסך הנעילה ומשורת הסטטוס \n- הצג בתחתית רשימת ההודעות \n\n"<b>"רמה 0"</b>" \n- חסום את כל ההודעות מהאפליקציה"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"הודעות"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"לא תקבל את ההודעות האלה יותר."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"לא תקבל את ההודעות האלה יותר"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> קטגוריות של התראות"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"האפליקציה הזו לא תומכת בקטגוריות של הודעות"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="two">קטגוריית הודעות אחת מתוך <xliff:g id="NUMBER_1">%d</xliff:g> מאפליקציה זו</item>
       <item quantity="many">קטגוריית הודעות אחת מתוך <xliff:g id="NUMBER_1">%d</xliff:g> מאפליקציה זו</item>
@@ -578,12 +581,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"בקרת הודעות"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"אפשרויות של דחיית הודעות לטיפול בהמשך"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 דקות"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 דקות"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"שעה אחת"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"שעתיים"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ביטול"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"נדחה לטיפול בעוד <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"שימוש בסוללה"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
diff --git a/packages/SystemUI/res/values-iw/strings_car.xml b/packages/SystemUI/res/values-iw/strings_car.xml
index 4b7ba97..d172094 100644
--- a/packages/SystemUI/res/values-iw/strings_car.xml
+++ b/packages/SystemUI/res/values-iw/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"נסיעה בטוחה"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏שמור על עירנות לתנאי הנסיעה וציית תמיד לכללים והחוקים. ייתכן שהמסלול לא מדויק, לא שלם, מסוכן, לא מתאים, אסור למעבר או כרוך בחציית אזורים מנהליים. ייתכן גם שחלק מהמידע העסקי לא מדויק או לא שלם. הנתונים אינם מדווחים בזמן אמת ולא ניתן להבטיח דיוק במיקום. אל תתעסק במכשיר הנייד ואל תשתמש באפליקציות שאינן מיועדות ל-Android Auto בזמן הנהיגה."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"לא ידוע"</string>
+    <string name="start_driving" msgid="864023351402918991">"עבור למצב נהיגה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d426a8c..cf553b3 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"アラーム、リマインダー、予定、指定した人からの着信以外の音やバイブレーションに煩わされることはありません。音楽、動画、ゲームなど再生対象として選択したコンテンツは引き続き再生されます。"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"アラーム以外の音やバイブレーションに煩わされることはありません。音楽、動画、ゲームなど再生対象として選択したコンテンツは引き続き再生されます。"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"アラーム、リマインダー、予定、指定した人からの着信以外で音やバイブレーションに煩わされることはありません。"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"カスタマイズ"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。電話をかけることはできます。"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。"</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」に接続しています。このアプリはあなたの個人のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"この仕事用プロファイルは<xliff:g id="ORGANIZATION">%1$s</xliff:g>によって管理され、<xliff:g id="APPLICATION">%2$s</xliff:g> に接続しています。このアプリはあなたの仕事のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を監視できます。\n\n詳しくは管理者にお問い合わせください。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"この仕事用プロファイルは<xliff:g id="ORGANIZATION">%1$s</xliff:g>によって管理され、<xliff:g id="APPLICATION_WORK">%2$s</xliff:g> に接続しています。このアプリはあなたの仕事のネットワーク アクティビティ(メール、アプリ、ウェブサイトなど)を管理できます。\n\nまた、<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> にも接続しているため、あなたの個人のネットワーク アクティビティも監視できます。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> さんのロックを解除しました"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> を実行しています"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"手動でロックを解除するまでロックされたままとなります"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"通知をすばやく確認できます"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ロックを解除する前にご確認ください"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"キャンセル"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"設定"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"OFF にする"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"今すぐ終了"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"折りたたむ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"画面が固定されました"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"OFF"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"電源通知管理では、アプリの通知の重要度をレベル 0~5 で設定できます。\n\n"<b>"レベル 5"</b>" \n- 通知リストの一番上に表示する \n- 全画面表示を許可する \n- 常にポップアップする \n\n"<b>"レベル 4"</b>" \n- 全画面表示しない \n- 常にポップアップする \n\n"<b>"レベル 3"</b>" \n- 全画面表示しない \n- ポップアップしない \n\n"<b>"レベル 2"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n\n"<b>"レベル 1"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n- ロック画面やステータスバーに表示しない \n- 通知リストの一番下に表示する \n\n"<b>"レベル 0"</b>" \n- アプリからのすべての通知をブロックする"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"今後、この通知は配信されません。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"今後、この通知は配信されません"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個の通知カテゴリ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"このアプリでは通知カテゴリが設定されていません"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">このアプリの通知カテゴリ <xliff:g id="NUMBER_1">%d</xliff:g> 件中 1 件</item>
       <item quantity="one">このアプリの通知カテゴリ <xliff:g id="NUMBER_0">%d</xliff:g> 件中 1 件</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知管理"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知スヌーズ設定"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15分"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30分"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1時間"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2時間"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"元に戻す"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"スヌーズ: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"電池の使用状況"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
@@ -720,8 +721,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">"PIP メニュー"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g>は PIP 表示中です"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"<xliff:g id="NAME">%s</xliff:g>でこの機能を使用しない場合は、タップして設定を開いて OFF にしてください。"</string>
     <string name="pip_play" msgid="1417176722760265888">"再生"</string>
     <string name="pip_pause" msgid="8881063404466476571">"一時停止"</string>
diff --git a/packages/SystemUI/res/values-ja/strings_car.xml b/packages/SystemUI/res/values-ja/strings_car.xml
index 667de81..15caa95 100644
--- a/packages/SystemUI/res/values-ja/strings_car.xml
+++ b/packages/SystemUI/res/values-ja/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全運転を心がけましょう"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"道路状況に十分気を配り、適用される法律を遵守してください。経路は、不正確、不完全、危険、不適切である場合や、通行が禁止されている、管理区域を通行する必要があるなどの場合があります。ビジネス情報も不正確または不完全である可能性があります。データはリアルタイムではなく、場所の正確性は保証されません。運転中はモバイル端末を手に持って操作したり、Android Auto とは無関係のアプリを使用したりしないでください。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"運転を開始"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index 4596551..134bb18 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/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">"PIP"</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-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index e07b041..f19c9dd 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"თქვენ მიერ მითითებული მაღვიძარების, შეხსენებების, ღონისძიებებისა და ზარების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ. თქვენ მაინც შეგეძლებათ ნებისმიერი სასურველი რამის, მაგალითად, მუსიკის, ვიდეოებისა და თამაშების მოსმენა."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"მაღვიძარების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ. თქვენ მაინც შეგეძლებათ ნებისმიერი სასურველი რამის, მაგალითად, მუსიკის, ვიდეოებისა და თამაშების მოსმენა."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"თქვენ მიერ მითითებული გაფრთხილებების, შეხსენებების, ღონისძიებებისა და აბონენტების გარდა, არავითარი ხმა და ვიბრაცია არ შეგაწუხებთ."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"მორგება"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების. მიუხედავად ამისა, თქვენ მაინც შეძლებთ სატელეფონო ზარების განხორციელებას."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ეს ბლოკავს ყველა ხმასა და ვიბრაციას, მათ შორის, მაღვიძარების, მუსიკის, ვიდეოებისა და თამაშების."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"თქვენ დაუკავშირდით <xliff:g id="APPLICATION">%1$s</xliff:g>-ს, რომელსაც თქვენი პირადი ქსელის აქტივობის მონიტორინგი შეუძლია, მათ შორის, ელფოსტის, აპებისა და ვებსაიტების."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"თქვენს სამსახურის პროფილს მართავს <xliff:g id="ORGANIZATION">%1$s</xliff:g>. პროფილი დაკავშირებულია <xliff:g id="APPLICATION">%2$s</xliff:g>-თან, რომელსაც შეუძლია ქსელში თქვენი სამსახურეობრივი აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი.\n\nდამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"თქვენს სამსახურის პროფილს მართავს <xliff:g id="ORGANIZATION">%1$s</xliff:g>. პროფილი დაკავშირებულია <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-თან, რომელსაც შეუძლია ქსელში თქვენი სამსახურეობრივი აქტივობის (მათ შორის, ელფოსტის, აპებისა და ვებსაიტების) მონიტორინგი.\n\nგარდა ამისა, თქვენ დაკავშირებული ხართ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-თან, რომელსაც ქსელში თქვენი პირადი აქტივობის მონიტორინგი შეუძლია."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"განბლოკილია მომხმარებლისთვის: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> გაშვებულია"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"მოწყობილობის დარჩება ჩაკეტილი, სანამ ხელით არ გახსნით"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"შეტყობინებების უფრო სწრაფად მიღება"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"იხილეთ განბლოკვამდე"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"არა, გმადლობთ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"დაყენება"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ახლავე გამორთვა"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"გამორთვა"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"გავრცობა"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ჩაკეცვა"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ეკრანი ჩამაგრებულია"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"გამორთული"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"შეტყობინებების მართვის საშუალებების მეშვეობით, შეგიძლიათ განსაზღვროთ აპის შეტყობინებების მნიშვნელობის დონე 0-დან 5-მდე დიაპაზონში. \n\n"<b>"დონე 5"</b>" \n— შეტყობინებათა სიის თავში ჩვენება \n— სრულეკრანიანი რეჟიმის შეფერხების დაშვება \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 4"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 3"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n\n"<b>"დონე 2"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n\n"<b>"დონე 1"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n— ჩაკეტილი ეკრანიდან და სტატუსის ზოლიდან დამალვა \n— შეტყობინებათა სიის ბოლოში ჩვენება \n\n"<b>"დონე 0"</b>" \n— აპის ყველა შეტყობინების დაბლოკვა"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"შეტყობინებები"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ამ შეტყობინებებს აღარ მიიღებთ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ამ შეტყობინებებს აღარ მიიღებთ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"შეტყობინებების <xliff:g id="NUMBER">%d</xliff:g> კატეგორია"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ამ აპს შეტყობინებების კატეგორიები არ აქვს"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ამ აპის შეტყობინებების <xliff:g id="NUMBER_1">%d</xliff:g> კატეგორიიდან 1</item>
       <item quantity="one">ამ აპის შეტყობინებების <xliff:g id="NUMBER_0">%d</xliff:g> კატეგორიიდან 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"შეტყობინებების მართვის საშუალებები"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"შეტყობინებების ჩაჩუმების ვარიანტები"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 წუთი"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 წუთი"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 საათი"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 საათი"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"მოქმედების გაუქმება"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ჩაჩუმებული იქნება <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ბატარეის მოხმარება"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
@@ -718,8 +719,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="4171698133469539591">"თუ არ გსურთ, რომ <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_car.xml b/packages/SystemUI/res/values-ka/strings_car.xml
index c8e17dd..d6f5693 100644
--- a/packages/SystemUI/res/values-ka/strings_car.xml
+++ b/packages/SystemUI/res/values-ka/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"უსაფრთხოდ მართვის წესები"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ყოველთვის გულდასმით გაეცანით მდგომარეობას გზებზე და დაიცავით მოქმედი კანონები. შეთავაზებული მიმართულებები შეიძლება იყოს უზუსტო, არასრული, სახიფათო, შეუფერებელი, აკრძალული, ან ადმინისტრაციული ერთეულების გადაკვეთას გულისხმობდეს. ბიზნეს-ინფორმაცია შეიძლება ასევე იყოს უზუსტო ან არასრული. მონაცემების განახლება რეალური დროის რეჟიმში არ ხდება და შესაბამისად, მდებარეობის სიზუსტე გარანტირებული ვერ იქნება. ავტომობილის მართვისას ნუ შეეცდებით თქვენი მობილური მოწყობილობით მანიპულირებას, ან ისეთი აპების გამოყენებას, რომლებიც Android Auto-სთვის შექმნილი არ არის."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"უცნობი"</string>
+    <string name="start_driving" msgid="864023351402918991">"დაიწყეთ მართვა"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml
index f4f818b..1a97590 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 9478a96..3ba4cab 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Іздеу"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үшін жоғары сырғыту."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үшін солға сырғыту."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Дабылдар, еске салғыштар, оқиғалар мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойындар сияқты ойнатылатын мазмұндардың дыбысы өшірілмейді."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Дабылдардан басқа ешқандай дыбыстар мен дірілдер мазаламайтын болады. Музыка, бейне және ойындар сияқты ойнатылатын мазмұндардың дыбысы өшірілмейді."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Дабылдар, еске салғыштар, оқиғалар мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Реттеу"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі. Бірақ телефон қоңыраулары шалына береді."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"БАРЛЫҚ, соның ішінде дабылдардың, музыканың, бейнелердің және ойындардың дыбыстары мен дірілдері өшіріледі."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Жеке желідегі әрекеттеріңізді, соның ішінде электрондық пошта хабарларын, қолданбаларды және вебсайттарды бақылай алатын <xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына қосылғансыз."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Жұмыс профиліңізді <xliff:g id="ORGANIZATION">%1$s</xliff:g> басқарады. Бұл профиль жұмыс желісіндегі белсенділігіңізді, соның ішінде электрондық хабарларды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION">%2$s</xliff:g> қолданбасына қосылған.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Жұмыс профиліңізді <xliff:g id="ORGANIZATION">%1$s</xliff:g> басқарады. Бұл профиль жұмыс желісіндегі белсенділігіңізді, соның ішінде электрондық хабарларды, қолданбаларды және веб-сайттарды бақылай алатын <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> қолданбасына қосылған.\n\nСондай-ақ сіз жеке желідегі белсенділігіңізді бақылай алатын <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> қолданбасына қосылғансыз."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> үшін құлпы ашылды"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> белсенді"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Қолмен бекітпесін ашқанша құрылғы бекітілген күйде қалады"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Хабарландыруларды тезірек алу"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Бекітпесін ашу алдында оларды көру"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Жоқ, рақмет"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Реттеу"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Қазір өшіру"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Қазір өшіру"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жаю"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жию"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Экран түйрелді"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өшірулі"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Қуат хабарландыруының басқару элементтерімен қолданбаның хабарландырулары үшін 0-ден бастап 5-ке дейін маңыздылық деңгейін орнатуға болады. \n\n"<b>"5-деңгей"</b>" \n- Хабарландыру тізімінің ең басында көрсету \n- Толық экранға ашылуын рұқсат ету \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"4-деңгей"</b>" \n- Толық экранға шығармау \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"3-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n\n"<b>"2-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс және діріл шығармау \n\n"<b>"1-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс немесе діріл шығармау \n- Құлыпталған экраннан және күйін көрсету жолағынан жасыру \n- Хабарландыру тізімінің ең астында көрсету \n\n"<b>"0-деңгей"</b>" \n- Қолданбадағы барлық хабарландыруларға тыйым салу"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Хабарландырулар"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Сізге енді бұл хабарландырулар жіберілмейді."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Енді сізге бұл хабарландырулар жіберілмейді"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> хабарландыру санаттары"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бұл қолданбада хабарландыру санаттары жоқ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Осы қолданбадан <xliff:g id="NUMBER_1">%d</xliff:g> ішінен 1 хабарландыру санаты</item>
       <item quantity="one">Осы қолданбадан <xliff:g id="NUMBER_0">%d</xliff:g> ішінен 1 хабарландыру санаты</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"хабарландыруларды басқару элементтері"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"хабарландыруды кідірту опциялары"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сағат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 сағат"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"КЕРІ ҚАЙТАРУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> кідіртілді"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Батареяны пайдалану"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
diff --git a/packages/SystemUI/res/values-kk/strings_car.xml b/packages/SystemUI/res/values-kk/strings_car.xml
index 056b75c..d8c6337 100644
--- a/packages/SystemUI/res/values-kk/strings_car.xml
+++ b/packages/SystemUI/res/values-kk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Қауіпсіз жүргізу"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жүргізу жағдайларын толығымен ұғыныңыз және тиісті заңдарды әрқашан сақтаңыз. Бағыттар дәл емес, толық емес, қауіпті, жарамсыз, тыйым салынған болуы немесе әкімшілік аумақтарды қиып өтуі мүмкін. Іскери ақпарат та дәл емес немесе толық емес болуы мүмкін. Деректер нақты уақыттағы деректер емес және орын дәлдігіне кепілдік берілмейді. Жүргізу кезінде мобильді құрылғыңызды ұстамаңыз немесе Android Auto қолданбасына арналмаған қолданбаларды пайдаланбаңыз."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Белгісіз"</string>
+    <string name="start_driving" msgid="864023351402918991">"Жүргізуді бастау"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml
index 7112017..305ad2e 100644
--- a/packages/SystemUI/res/values-kk/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk/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-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2388327..1784aab 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"រុញ​ទៅ​ឆ្វេង​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"សំឡេង និងរំញ័រមិន​រំខានដល់អ្នកឡើយ លើកលែងតែសំឡេងរោទ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅទូរសព្ទដែលអ្នកបញ្ជាក់។ អ្នកនៅតែឮអ្វីគ្រប់យ៉ាងដែលអ្នកជ្រើសរើសឲ្យលេង រួមទាំងតន្រ្តី វីដេអូ និងហ្គេមផងដែរ។"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"សំឡេង និងរំញ័រមិន​រំខានដល់អ្នកឡើយ លើកលែងតែសំឡេងរោទ៍។ អ្នកនៅតែឮអ្វីគ្រប់យ៉ាងដែលអ្នកជ្រើសរើសឲ្យលេង រួមទាំងតន្រ្តី វីដេអូ និងហ្គេមផងដែរ។"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"អ្នកនឹងគ្មានការរំខានដោយសារសំឡេង និងភាពរំញ័រឡើយ លើកលែងតែសំឡេងរោទ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅទូរសព្ទដែលអ្នកបានបញ្ជាក់ប៉ុណ្ណោះ។"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ប្ដូរតាមបំណង"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ ដោយរួមបញ្ចូលទាំងសំឡេងរោទ៍ តន្ត្រី វីដេអូ និងហ្គេម។ អ្នកនឹងនៅតែអាចធ្វើការហៅទូរសព្ទបានដដែល។"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ដែលចេញពីម៉ោងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"អ្នកត្រូវបានភ្ជាប់ទៅ <xliff:g id="APPLICATION">%1$s</xliff:g> ដែលអាចឃ្លាំមើលសកម្មភាពបណ្តាញរបស់អ្នក រាប់បញ្ចូលទាំងអ៊ីមែល កម្មវិធី និងគេហទំព័រ។"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"កម្រង​ព័ត៌មាន​ការងារ​របស់អ្នក​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ។ កម្រងព័ត៌មាន​នេះត្រូវ​បាន​ភ្ជាប់ទៅ <xliff:g id="APPLICATION">%2$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​របស់អ្នក រួមទាំង​អ៊ីមែល កម្មវិធី និង​គេហទំព័រ​ផងដែរ។\n\nសម្រាប់​ព័ត៌មាន​បន្ថែម សូម​ទាក់ទង​ទៅអ្នក​គ្រប់គ្រង​របស់​អ្នក។"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"កម្រងព័ត៌មាន​ការងារ​របស់អ្នក​ស្ថិតក្រោម​គ្រប់គ្រង​របស់ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ។ កម្រង​ព័ត៌មាននេះ​ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​របស់អ្នក រួមទាំង​អ៊ីមែល កម្មវិធី និង​គេហទំព័រ​ផងដែរ។\n\nអ្នកក៏ត្រូវបាន​ភ្ជាប់​ទៅ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ដែលអាច​តាមដាន​សកម្មភាព​បណ្តាញ​ផ្ទាល់ខ្លួន​របស់​អ្នក។"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"បាន​ដោះសោ​សម្រាប់ <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ឧបករណ៍​នឹង​ចាក់​សោ​រហូត​ដល់​អ្នក​ដោះ​សោ​ដោយ​ដៃ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ទទួល​បាន​ការ​ជូន​ដំណឹង​កាន់តែ​លឿន"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ឃើញ​ពួកវា​មុន​ពេល​ដោះ​សោ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ទេ អរគុណ!"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"រៀបចំ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"បិទឥឡូវនេះ"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"បញ្ចប់ឥឡូវនេះ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ពង្រីក"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"បង្រួម"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"អេក្រង់​ត្រូវ​បាន​ភ្ជាប់"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"បិទ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ជាមួយអង្គគ្រប់គ្រងការជូនដំណឹងថាមពល អ្នកអាចកំណត់កម្រិតសំខាន់ពី 0 ទៅ 5 សម្រាប់ការជូនដំណឹងរបស់កម្មវិធី។ \n\n"<b>"កម្រិត 5"</b>" \n- បង្ហាញនៅផ្នែកខាងលើបញ្ជីជូនដំណឹង \n- អនុញ្ញាតការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 4"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 3"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 2"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n\n"<b>"កម្រិត 1"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n- លាក់ពីអេក្រង់ចាក់សោ និងរបារស្ថានភាព \n- បង្ហាញនៅផ្នែកខាងក្រោមបញ្ជីជូនដំណឹង \n\n"<b>"កម្រិត 0"</b>" \n- រារាំងការជូនដំណឹងទាំងអស់ពីកម្មវិធី"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ការ​ជូនដំណឹង"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"អ្នក​នឹង​មិន​ទទួល​បាន​ការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ។"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"អ្នក​នឹង​មិន​ទទួល​បានការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"ប្រភេទនៃការជូនដំណឹងចំនួន <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"កម្មវិធីនេះ​មិនមាន​ប្រភេទនៃ​ការជូនដំណឹង​ទេ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ប្រភេទនៃការ​ជូនដំណឹង 1 ក្នុង​ចំណោម <xliff:g id="NUMBER_1">%d</xliff:g> ដែលបានពី​កម្មវិធី​នេះ</item>
       <item quantity="one">ប្រភេទនៃការ​ជូនដំណឹង 1 ក្នុង​ចំណោម <xliff:g id="NUMBER_0">%d</xliff:g> ដែលបានពី​កម្មវិធី​នេះ</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ការគ្រប់គ្រង​ការជូន​ដំណឹង"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ជម្រើស​ផ្អាកការ​ជូនដំណឹង"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 នាទី"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 នាទី"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ម៉ោង"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ម៉ោង"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"មិន​ធ្វើវិញ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"បាន​ផ្អាក​រយៈពេល <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ការប្រើប្រាស់ថ្ម"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
@@ -718,8 +719,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="4171698133469539591">"ប្រសិនបើ​អ្នក​មិន​ចង់​ឲ្យ <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-km/strings_car.xml b/packages/SystemUI/res/values-km/strings_car.xml
index 9648a5fb..5c9b1d6 100644
--- a/packages/SystemUI/res/values-km/strings_car.xml
+++ b/packages/SystemUI/res/values-km/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"បើកបរដោយសុវត្ថិភាព"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ត្រូវមានការគ្រប់គ្រងពេញលេញលើស្ថានភាពបើកបរ និងគោរពច្បាប់ដែលត្រូវអនុវត្តជានិច្ច។ ទិសដៅអាចនឹងមិនមានភាពសុក្រិត មិនពេញលេញ គ្រោះថ្នាក់ មិនសមស្រប ឬពាក់ព័ន្ធនឹងការឆ្លងកាត់តំបន់រដ្ឋបាល។ ព័ត៌មានផ្នែកអាជីវកម្មក៏អាចនឹងមិនមានភាពសុក្រិត ឬមិនពេញលេញផងដែរ។ ទិន្នន័យគឺមិនមែនបញ្ជូនបន្តផ្ទាល់នោះទេ ហើយភាពសុក្រិតនៃទីតាំងក៏មិនអាចធានាបានផងដែរ។ កុំកាន់ឧបករណ៍ចល័តរបស់អ្នក ឬប្រើកម្មវិធីដែលមិនមែនសម្រាប់ Android Auto ខណៈពេលកំពុងបើកបរ។"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"មិន​ស្គាល់"</string>
+    <string name="start_driving" msgid="864023351402918991">"ចាប់ផ្តើមបើកបរ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml
index 641bba3..5da818e 100644
--- a/packages/SystemUI/res/values-km/strings_tv.xml
+++ b/packages/SystemUI/res/values-km/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-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 096416e..4357e8c 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ಹುಡುಕಿ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊ ನಿಮಗೆ ಕೇಳಿಸುತ್ತದೆ."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"ಅಲಾರಾಂಗಳನ್ನು ಹೊರತುಪಡಿಸಿ, ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊ ನಿಮಗೆ ಕೇಳಿಸುತ್ತದೆ."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"ಅಲಾರಮ್‌ಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಮತ್ತು ನೀವು ಸೂಚಿಸುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ, ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್‌ಗಳಿಂದ ನಿಮಗೆ ತೊಂದರೆ ಆಗುವುದಿಲ್ಲ."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ಕಸ್ಟಮೈಸ್ ಮಾಡು"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ಇದು ಅಲಾರಮ್‌ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಗೇಮ್‌ಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. ನಿಮಗೆ ಈಗಲೂ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ಇದು ಅಲಾರಮ್‌ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಗೇಮ್‌ಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ನೀವು ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದಾದ <xliff:g id="APPLICATION">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಿರಿ."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು <xliff:g id="ORGANIZATION">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ. <xliff:g id="APPLICATION">%2$s</xliff:g> ಗೆ ಪ್ರೊಫೈಲ್ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಕಾರಣ, ಅದು ನಿಮ್ಮ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಾಗೂ ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು.\n\nಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು <xliff:g id="ORGANIZATION">%1$s</xliff:g> ನಿರ್ವಹಿಸುತ್ತಿದೆ. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ಗೆ ಪ್ರೊಫೈಲ್ ಸಂಪರ್ಕಗೊಂಡಿರುವ ಕಾರಣ, ಅದು ನಿಮ್ಮ ಇಮೇಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವೆಬ್‌ಸೈಟ್‌ಗಳೂ ಸೇರಿದಂತೆ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು.\n\nನೀವು <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ಗೆ ಕೂಡಾ ಸಂಪರ್ಕಗೊಂಡಿದ್ದೀರಿ, ಇದು ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ನೆಟ್‌ವರ್ಕ್ ಚಟುವಟಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> ಗಾಗಿ ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ಚಾಲನೆಯಲ್ಲಿದೆ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ನೀವಾಗಿಯೇ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವವರೆಗೆ ಸಾಧನವು ಲಾಕ್‌ ಆಗಿಯೇ ಇರುತ್ತದೆ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ವೇಗವಾಗಿ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ನೀವು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಮೊದಲೇ ಅವುಗಳನ್ನು ನೋಡಿ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ಧನ್ಯವಾದಗಳು"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ಹೊಂದಿಸು"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ಈಗ ಆಫ್ ಮಾಡಿ"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ಈಗಲೇ ಅಂತ್ಯಗೊಳಿಸು"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ವಿಸ್ತರಿಸು"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ಸಂಕುಚಿಸು"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ಪರದೆಯನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ಆಫ್"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಅಧಿಸೂಚನೆಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ಅಧಿಸೂಚನೆಗಳು"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳು"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆ ವರ್ಗಗಳನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ <xliff:g id="NUMBER_1">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳಲ್ಲಿ 1 ವರ್ಗ</item>
       <item quantity="other">ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ <xliff:g id="NUMBER_1">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳಲ್ಲಿ 1 ವರ್ಗ</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ಅಧಿಸೂಚನೆ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ನಿಮಿಷಗಳು"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ನಿಮಿಷಗಳು"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ಗಂಟೆ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ಗಂಟೆಗಳು"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ರದ್ದುಮಾಡಿ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ಬ್ಯಾಟರಿ ಬಳಕೆ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್‌‌ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
diff --git a/packages/SystemUI/res/values-kn/strings_car.xml b/packages/SystemUI/res/values-kn/strings_car.xml
index e8e99c4..bc1f7fc 100644
--- a/packages/SystemUI/res/values-kn/strings_car.xml
+++ b/packages/SystemUI/res/values-kn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ಸುರಕ್ಷಿತವಾಗಿ ಚಾಲನೆ ಮಾಡಿ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ಚಾಲನೆ ಸ್ಥಿತಿಗಳ ಕುರಿತು ಸಂಪೂರ್ಣವಾಗಿ ತಿಳಿದುಕೊಳ್ಳಿ ಮತ್ತು ಅನ್ವಯವಾಗುವ ಕಾನೂನುಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಸರಿಸಿ. ದಿಕ್ಕುಗಳು ಸರಿಯಾಗಿ ಇಲ್ಲದಿರಬಹುದು, ಅಪೂರ್ಣವಾಗಿರಬಹುದು, ಅಪಾಯಕಾರಿಯಾಗಿರಬಹುದು, ಸೂಕ್ತವಾಗಿಲ್ಲದಿರಬಹುದು, ನಿಷೇಧಿಸಿರಬಹುದು ಅಥವಾ ನಿರ್ವಹಣೆ ಪ್ರದೇಶಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬೇಕಾಗಬಹುದು. ವ್ಯಾಪಾರ ಮಾಹಿತಿಯು ಸಹ ತಪ್ಪಾಗಿರಬಹುದು ಅಥವಾ ಅಪೂರ್ಣವಾಗಿರಬಹುದು. ಡೇಟಾ ನೈಜ ಸಮಯದ್ದಾಗಿರದಿರಬಹುದು ಮತ್ತು ಸ್ಥಳ ನಿಖರತೆಗೆ ಖಾತ್ರಿ ನೀಡಲಾಗುವುದಿಲ್ಲ. ನಿಮ್ಮ ಮೊಬೈಲ್ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಬೇಡಿ ಅಥವಾ ಚಾಲನೆ ಮಾಡುತ್ತಿರುವಾಗ Android Auto ಗೆ ಅಲ್ಲದಿರುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬಳಸಬೇಡಿ."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ಅಪರಿಚಿತ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ಡ್ರೈವ್ ಮಾಡಲು ಆರಂಭಿಸಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ce2f47f..898618b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"알람, 알림, 일정 및 지정한 발신자부터 받은 연락을 제외하고 소리와 진동을 끕니다. 음악, 동영상, 게임 등에서 재생하도록 선택한 소리는 정상적으로 들립니다."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"알람을 제외하고 소리와 진동을 끕니다. 음악, 동영상, 게임 등에서 재생하도록 선택한 소리는 정상적으로 들립니다."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"지정한 알람, 알림, 이벤트, 발신자를 제외하고 소리와 진동을 끕니다."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"맞춤설정"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다. 전화는 걸 수 있습니다."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g>에 연결되었습니다. 이 앱은 이메일, 앱, 웹사이트와 같은 내 개인 네트워크 활동을 모니터링할 수 있습니다."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"직장 프로필은 <xliff:g id="ORGANIZATION">%1$s</xliff:g>에서 관리합니다. 프로필이 <xliff:g id="APPLICATION">%2$s</xliff:g>에 연결되어 이메일, 앱, 웹사이트와 같은 직장 네트워크 활동을 모니터링할 수 있습니다.\n\n자세한 내용을 확인하려면 관리자에게 문의하세요."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"직장 프로필은 <xliff:g id="ORGANIZATION">%1$s</xliff:g>에서 관리합니다. 이 프로필은 <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>에 연결되어 이메일, 앱, 웹사이트와 같은 직장 네트워크 활동을 모니터링할 수 있습니다.\n\n개인 네트워크 활동을 모니터링할 수 있는 <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>에도 연결됩니다."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>님 잠금 해제됨"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> 실행 중"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"수동으로 잠금 해제할 때까지 기기가 잠금 상태로 유지됩니다."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"알림을 더욱 빠르게 받기"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"잠금 해제하기 전에 알림을 봅니다."</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"사용 안함"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"설정"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"지금 사용 중지"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"지금 종료"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"펼치기"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"접기"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"화면 고정됨"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"사용 안함"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"전원 알림 컨트롤을 사용하면 앱 알림 관련 중요도를 0부터 5까지로 설정할 수 있습니다. \n\n"<b>"레벨 5"</b>" \n- 알림 목록 상단에 표시 \n- 전체 화면일 경우 알림 표시 허용 \n- 항상 엿보기 표시 \n\n"<b>"레벨 4"</b>" \n- 전체 화면에 알림 표시 금지 \n- 항상 엿보기 표시 \n\n"<b>"레벨 3"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n\n"<b>"레벨 2"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n\n"<b>"레벨 1"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n- 잠금 화면 및 상태 표시줄에서 숨김 \n- 알림 목록 하단에 표시 \n\n"<b>"레벨 0"</b>" \n- 앱의 모든 알림 차단"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"알림"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"더 이상 다음의 알림을 받지 않습니다."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"더 이상 다음의 알림을 받지 않습니다."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"알림 카테고리 <xliff:g id="NUMBER">%d</xliff:g>개"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"이 앱에는 알림 카테고리가 없습니다."</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">이 앱에서 <xliff:g id="NUMBER_1">%d</xliff:g>개의 알림 카테고리 중 1개가 정의됨</item>
       <item quantity="one">이 앱에서 <xliff:g id="NUMBER_0">%d</xliff:g>개의 알림 카테고리 중 1개가 정의됨</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"알림 관리"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"알림 일시 중지 옵션"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15분"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30분"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1시간"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2시간"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"실행취소"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> 동안 일시 중지됨"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"배터리 사용량"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
@@ -666,7 +667,7 @@
     <string name="left_icon" msgid="3096287125959387541">"왼쪽 아이콘"</string>
     <string name="right_icon" msgid="3952104823293824311">"오른쪽 아이콘"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"드래그하여 타일 추가"</string>
-    <string name="drag_to_remove_tiles" msgid="3361212377437088062">"여기로 드래그하여 삭제"</string>
+    <string name="drag_to_remove_tiles" msgid="3361212377437088062">"삭제하려면 여기를 드래그"</string>
     <string name="qs_edit" msgid="2232596095725105230">"수정"</string>
     <string name="tuner_time" msgid="6572217313285536011">"시간"</string>
   <string-array name="clock_options">
@@ -750,7 +751,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"알림"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"스크린샷"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"일반 메시지"</string>
-    <string name="notification_channel_storage" msgid="3077205683020695313">"저장공간"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"저장소"</string>
     <string name="instant_apps" msgid="6647570248119804907">"인스턴트 앱"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"인스턴트 앱은 설치가 필요하지 않습니다."</string>
     <string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
diff --git a/packages/SystemUI/res/values-ko/strings_car.xml b/packages/SystemUI/res/values-ko/strings_car.xml
index fcc2d7b..6d31bbf 100644
--- a/packages/SystemUI/res/values-ko/strings_car.xml
+++ b/packages/SystemUI/res/values-ko/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"안전 운전"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"도로 상황에 주의를 기울이고 관련 법규를 항상 준수하세요. 경로가 정확하지 않거나 불완전하거나 위험하거나 적합하지 않을 수 있으며 금지된 지역이나 여러 행정 구역을 통과할 수 있습니다. 비즈니스 정보 또한 부정확하거나 불완전할 수 있습니다. 데이터는 실시간이 아니며 위치의 정확도를 보증할 수 없습니다. 운전 중에 휴대기기를 조작하거나 Android Auto가 지원되지 않는 앱을 사용해서는 안 됩니다."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"알 수 없음"</string>
+    <string name="start_driving" msgid="864023351402918991">"운전 시작"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index aceb1c2..464f866 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Издөө"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үчүн жогору жылмыштырыңыз."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үчүн солго жылмыштырыңыз."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Ойготкучтардан, эскертүүлөрдөн, жылнаамадагы иш-чараларды эстеткичтерден жана белгиленген байланыштардын чалууларынан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт. Бирок ойнотулуп жаткан музыканы, видеолорду жана оюндарды мурдагыдай эле уга бересиз."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Ойготкучтардан башка үндөр жана дирилдөөлөр тынчыңызды албайт. Бирок ойнотулуп жаткан музыканы, видеолорду жана оюндарды мурдагыдай эле уга бересиз."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Эскертүүлөрдөн, жылнаамадагы иш-чараларды эстеткичтерден жана белгиленген байланыштардын чалууларынан тышкары башка үндөр жана дирилдөөлөр тынчыңызды албайт."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Ыңгайлаштыруу"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү өчүрүлөт. Бирок телефон менен сүйлөшө бересиз."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ушуну менен эскертүүлөрдүн, музыканын, видеолордун жана оюндардын үндөрү жана дирилдөөлөрү өчүрүлөт."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Электрондук почта, колдонмолор жана вебсайттар сыяктуу тармактагы жеке аракеттериңизди тескей турган <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна туташып турасыз."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Жумуш профилиңизди <xliff:g id="ORGANIZATION">%1$s</xliff:g> башкарат. Ал электрондук почта, колдонмолор жана вебсайттар сыяктуу жумуш тармагыңыздагы аракеттерди көзөмөлдөй турган <xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосуна туташкан.\n\nКөбүрөөк маалымат алуу үчүн администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Жумуш профилиңизди <xliff:g id="ORGANIZATION">%1$s</xliff:g> башкарат. Ал электрондук почта, колдонмолор жана вебсайттар сыяктуу жумуш тармагыңыздагы аракеттерди көзөмөлдөй турган <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> колдонмосуна туташкан.\n\nМындан тышкары, тармактагы жеке аракеттериңизди көзөмөлдөгөн <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> колдонмосуна туташып турасыз."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> үчүн кулпусу ачылды"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> иштеп жатат"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Түзмөктүн кулпусу кол менен ачылмайынча кулпуланган бойдон алат"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Эскертмелерди тезирээк алуу"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Аларды кулпудан чыгараардан мурун көрүңүз"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Жок, рахмат"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Орнотуу"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Азыр өчүрүлсүн"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Азыр бүтүрүү"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жайып көрсөтүү"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жыйнап коюу"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Экран кадалган"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өчүк"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Бул функциянын жардамы менен ар бир колдонмо үчүн эскертменин маанилүүлүк деңгээлин 0дон 5ке чейин койсоңуз болот. \n\n"<b>"5-деңгээл"</b>" \n- Эскертмелер тизмесинин башында көрсөтүлсүн \n- Эскертмелер толук экранда көрсөтүлсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"4-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"3-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n\n"<b>"2-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n\n"<b>"1-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n- Кулпуланган экрандан жана абал тилкесинен жашырылсын \n- Эскертмелер тизмесинин аягында көрсөтүлсүн \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык эскертмелер бөгөттөлсүн"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Эскертмелер"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Эскертмелердин <xliff:g id="NUMBER">%d</xliff:g> категориясы"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бул колдонмонун эскертме категориялары жок"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Бул колдонмодогу <xliff:g id="NUMBER_1">%d</xliff:g> эскертме категориянын ичинен 1 категория</item>
       <item quantity="one">Бул колдонмодогу <xliff:g id="NUMBER_0">%d</xliff:g> эскертме категориянын ичинен 1 категория</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"эскертмелерди башкаруу каражаттары"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"эскертмени тындыруу опциялары"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 мүнөт"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 мүнөт"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 саат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 саат"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"КАЙТАРУУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> тындырылды"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Батарея колдонулушу"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
diff --git a/packages/SystemUI/res/values-ky/strings_car.xml b/packages/SystemUI/res/values-ky/strings_car.xml
index 1d99ff2..51a46b9 100644
--- a/packages/SystemUI/res/values-ky/strings_car.xml
+++ b/packages/SystemUI/res/values-ky/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Коопсуздук эрежелерин сактаңыз"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Унаа айдап бара жатканда жолдогу шарттар менен эрежелерге ар дайым көңүл буруңуз. Багыттар так же толук эмес берилип, кесип өтүү үчүн опурталдуу же ылайыксыз болгон административдик аймактар аркылуу өтүшү мүмкүн. Ишканалар тууралуу маалымат да так же толук эмес болушу мүмкүн. Дайындар тез-тез жаңыртылып турбагандыктан, жайгашкан жердин так аныкталгандыгына кепилдик жок. Андыктан унаа айдап бара жатканда, мобилдик түзмөгүңүздү же Android Auto\'го арналбаган колдонмолорду пайдаланбаңыз."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Белгисиз"</string>
+    <string name="start_driving" msgid="864023351402918991">"Унаа айдап баштоо"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index d7f1200..a401e8a 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"ທ່ານຈະບໍ່ໄດ້ຮັບການລົບກວນຈາກສຽງ ຫຼື ການສັ່ງເຕືອນ, ຍົກເວັ້ນໃນເວລາໂມງ, ການແຈ້ງເຕືອນ, ນັດໝາຍ ແລະປະຕິທິນທີ່ທ່ານບຸ . ທ່ານອາດຍັງຄົງໄດ້ຍິນຫາກທ່ານເລືອກຫຼິ້ນເພລງ, ວິດີໂອ ລລະ ເກມ."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"ທ່ານຈະບໍ່ໄດ້ຮັບການລົບກວນຈາກສຽງ ຫຼື ການສັ່ງເຕືອນ, ຍົກເວັ້ນໃນເວລາໂມງປຸກດັງ. ທ່ານອາດຍັງຄົງໄດ້ຍິນຫາກທ່ານເລືອກຫຼິ້ນເພລງ, ວິດີໂອ ລລະ ເກມ."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"ທ່ານ​ຈະ​ບໍ່​ຖືກ​ລົບ​ກວນ​ຈາກ​ສຽງ ແລະ​ການ​ສັ່ນ, ຍົກ​ເວັ້ນ​ຈາກ​ໂມງ​ປຸກ, ການ​ເຕືອນ, ເຫດ​ການ, ແລະ​ຜູ້​ໂທ​ທີ່​ທ່ານ​ລະ​ບຸ."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ປັບແຕ່ງ"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ນີ້ຈະເປັນການປິດສຽງ ແລະ ການສັ່ນທັງໝົດ ຮວມທັງສຽງໂມງປຸກ, ເພງ, ວິດີໂອ ແລະ ເກມນຳ. ແຕ່ທ່ານຍັງສາມາດໂທລະສັບໄດ້ປົກກະຕິ."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ອັນ​ນີ້ບ​ລັອກ​ທຸກ​ສຽງ ແລະ​ການ​ສັ່ນ, ລວມ​ທັງ​ຈາກ​ໂມງ​ປຸກ, ເພງ, ວິ​ດີ​ໂອ, ແລະ​ເກມ."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ທ່ານເຊື່ອມຕໍ່ກັບ <xliff:g id="APPLICATION">%1$s</xliff:g> ແລ້ວ, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍສ່ວນຕົວຂອງທ່ານ ຮວມທັງອີເມວ, ​ແອັບ ແລະເວັບໄຊໄດ້."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານແມ່ນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION">%1$s</xliff:g>. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກດັ່ງກ່າວເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION">%2$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ, ແອັບ ແລະ ເວັບໄຊໄດ້.\nສຳລັບຂໍ້ມູນເພີ່ມເຕີມ, ໃຫ້ຕິດຕໍ່ຫາຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ\n."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານແມ່ນຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION">%1$s</xliff:g>. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກດັ່ງກ່າວເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ, ແອັບ ແລະ ເວັບໄຊໄດ້.\n\nນອກຈາກນັ້ນ, ທ່ານຍັງເຊື່ອມຕໍ່ຫາ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ເຊິ່ງສາມາດຕິດຕາມການເຄື່ອນໄຫວເຄືອຂ່າຍສ່ວນຕົວຂອງທ່ານໄດ້."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ປົດລັອກສຳລັບ <xliff:g id="USER_NAME">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ກຳລັງເຮັດວຽກຢູ່"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Device will stay locked until you manually unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ຮັບເອົາການ​ແຈ້ງເຕືອນ​ໄວຂຶ້ນ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ເບິ່ງພວກ​ມັນກ່ອນ​ທ່ານຈະ​ປົດລັອກ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ບໍ່, ຂອບໃຈ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ຕັ້ງຄ່າ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ປິດດຽວນີ້"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ຢຸດດຽວນີ້"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ຂະຫຍາຍ"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ຫຍໍ້ລົງ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ປັກ​ໝຸດໜ້າ​ຈໍ​ແລ້ວ"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ປິດ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ດ້ວຍການຄວບຄຸມການແຈ້ງເຕືອນ, ທ່ານສາມາດຕັ້ງລະດັບຄວາມສຳຄັນຈາກ 0 ຮອດ 5 ໃຫ້ກັບການແຈ້ງເຕືອນແອັບໃດໜຶ່ງໄດ້. \n\n"<b>"ລະດັບ 5"</b>" \n- ສະແດງຢູ່ເທິງສຸດຂອງລາຍການແຈ້ງເຕືອນ \n- ອະນຸຍາດໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 4"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 3"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n\n"<b>"ລະດັບ 2"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n\n"<b>"ລະດັບ 1"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n- ເຊື່ອງຈາກໜ້າຈໍລັອກ ແລະ ແຖບສະຖານະ \n- ສະແດງຢູ່ລຸ່ມສຸດຂອງລາຍການແຈ້ງເຕືອນ \n\n"<b>"ລະດັບ 0"</b>" \n- ປິດກັ້ນການແຈ້ງເຕືອນທັງໝົດຈາກແອັບ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ການແຈ້ງເຕືອນ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ແອັບນີ້ບໍ່ມີໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 ຈາກທັງໝົດ <xliff:g id="NUMBER_1">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນຈາກແອັບນີ້</item>
       <item quantity="one">1 ຈາກທັງໝົດ <xliff:g id="NUMBER_0">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນຈາກແອັບນີ້</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ການຄວບຄຸມການແຈ້ງເຕືອນ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ຕົວເລືອກການເລື່ອນການແຈ້ງເຕືອນ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ນາທີ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ນາທີ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ຊົ່ວໂມງ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ຊົ່ວໂມງ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ຍົກເລີກ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ເລື່ອນໄປ <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ນາທີແລ້ວ"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ການໃຊ້ແບັດເຕີຣີ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
diff --git a/packages/SystemUI/res/values-lo/strings_car.xml b/packages/SystemUI/res/values-lo/strings_car.xml
index 3388f54..038e43b 100644
--- a/packages/SystemUI/res/values-lo/strings_car.xml
+++ b/packages/SystemUI/res/values-lo/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ຂັບຂີ່ຢ່າງປອດໄພ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ຮູ້ຈັກສະພາບການຂັບຂີ່ຢ່າງຄົບຖ້ວນ ແລະ ປະຕິບັດຕາມກົດໝາຍທີ່ນຳໃຊ້ສະເໝີ. ຄຳແນະນຳເສັ້ນທາງອາດຈະບໍ່ຖືກຕ້ອງ, ບໍ່ຄົບຖ້ວນ, ອັນຕະລາຍ, ບໍ່ເໝາະສົມ, ຖືກຫ້າມ ຫຼື ກ່ຽວຂ້ອງກັບການຂ້າມເຂດປົກຄອງ. ຂໍ້ມູນທຸລະກິດອາດຈະບໍ່ຖືກຕ້ອງ ຫຼື ບໍ່ຄົບຖ້ວນ. ຂໍ້ມູນບໍ່ແມ່ນຂໍ້ມູນສົດ ແລະ ບໍ່ສາມາດຮັບປະກັນຄວາມຖືກຕ້ອງຂອງສະຖານທີ່ໄດ້. ຢ່າໃຊ້ອຸປະກອນມືຖືຂອງທ່ານ ຫຼື ໃຊ້ແອັບທີ່ບໍ່ມີໄວ້ສຳລັບ Android Auto ໃນຂະນະທີ່ຂັບຂີ່."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ບໍ່​ຮູ້ຈັກ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ເລີ່ມການຂັບ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 8b03861..26552d6 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -356,8 +356,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus. Vis tiek girdėsite viską, ką pasirinksite leisti, įskaitant muziką, vaizdo įrašus ir žaidimus."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Jūsų netrikdys garsai ir vibravimas, išskyrus signalus. Vis tiek girdėsite viską, ką pasirinksite leisti, įskaitant muziką, vaizdo įrašus ir žaidimus."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Jūsų netrikdys garsai ir vibravimas, išskyrus nurodytų signalų, priminimų, įvykių ir skambintojų garsus ir vibravimą."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tinkinti"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą. Vis tiek galėsite skambinti telefonu."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Taip bus užblokuoti VISI garsai ir vibravimas, įskaitant signalų, muzikos, vaizdo įrašų ir žaidimų garsus ir vibravimą."</string>
@@ -471,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Esate prisijungę prie programos „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kuri gali stebėti asmeninio tinklo veiklą, įskaitant el. laiškus, programas ir svetaines."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jūsų darbo profilį tvarko „<xliff:g id="ORGANIZATION">%1$s</xliff:g>“. Profilis susietas su programa „<xliff:g id="APPLICATION">%2$s</xliff:g>“, kuri gali stebėti jūsų tinklo veiklą, įskaitant el. laiškus, programas ir svetaines.\n\nJei reikia daugiau informacijos, susisiekite su administratoriumi."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jūsų darbo profilį tvarko „<xliff:g id="ORGANIZATION">%1$s</xliff:g>“. Profilis susietas su programa „<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>“, kuri gali stebėti jūsų tinklo veiklą, įskaitant el. laiškus, programas ir svetaines.\n\nTaip pat esate prisijungę prie programos „<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>“, kuri gali stebėti asmeninio tinklo veiklą."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Atrakinta (<xliff:g id="USER_NAME">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"„<xliff:g id="TRUST_AGENT">%1$s</xliff:g>“ vykdoma"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Įrenginys liks užrakintas, kol neatrakinsite jo neautomatiniu būdu"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Greičiau gaukite pranešimus"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Peržiūrėti prieš atrakinant"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, ačiū"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Nustatyti"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Išjungti dabar"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Baigti dabar"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Išskleisti"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sutraukti"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekranas prisegtas"</string>
@@ -552,9 +553,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Išjungta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Naudodami pranešimų valdiklius galite nustatyti programos pranešimų svarbos lygį nuo 0 iki 5. \n\n"<b>"5 lygis"</b>" \n– Rodyti pranešimų sąrašo viršuje \n– Leisti pertraukti, kai veikia viso ekrano režimas \n– Visada rodyti pranešimus \n\n"<b>"4 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Visada rodyti pranešimus \n\n"<b>"3 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n\n"<b>"2 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n\n"<b>"1 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n– Slėpti užrakinimo ekrane ir būsenos juostoje \n– Rodyti pranešimų sąrašo apačioje \n\n"<b>"0 lygis"</b>" \n– Blokuoti visus programos pranešimus"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pranešimai"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nebegausite šių pranešimų."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nebegausite šių pranešimų"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Pranešimų kategorijų: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Šioje programoje nėra pranešimų kategorijų"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 iš <xliff:g id="NUMBER_1">%d</xliff:g> šios programos pranešimų kategorijos</item>
       <item quantity="few">1 iš <xliff:g id="NUMBER_1">%d</xliff:g> šios programos pranešimų kategorijų</item>
@@ -578,12 +581,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"pranešimų valdikliai"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"pranešimų snaudimo parinktys"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min."</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 min."</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 val."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 val."</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULIUOTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Nustatyta snausti <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akum. energ. vartoj."</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
diff --git a/packages/SystemUI/res/values-lt/strings_car.xml b/packages/SystemUI/res/values-lt/strings_car.xml
index 03d656a..4bdd5a7 100644
--- a/packages/SystemUI/res/values-lt/strings_car.xml
+++ b/packages/SystemUI/res/values-lt/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vairuokite saugiai"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Visada atsižvelkite į vairavimo sąlygas ir laikykitės galiojančių įstatymų. Nuorodos gali būti netikslios, neužbaigtos, pavojingos, netinkamos, draudžiamos ar nukreipiančios per administracines sritis. Įmonių informacija taip pat gali būti netiksli ar neužbaigta. Duomenys nėra teikiami realiuoju laiku ir vietovių tikslumo negalima garantuoti. Vairuodami nenaudokite mobiliojo įrenginio ar programų, kurios nėra skirtos „Android Auto“."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nežinoma"</string>
+    <string name="start_driving" msgid="864023351402918991">"Pradėti vairuoti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 26f4370..f635178 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Jūs netraucēs skaņas un vibrācija, izņemot signālus, atgādinājumus, pasākumus un zvanītājus, ko būsiet norādījis. Jūs joprojām dzirdēsiet atskaņošanai izvēlētos vienumus, tostarp mūziku, videoklipus un spēles."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Jūs netraucēs skaņas un vibrācija, izņemot signālus. Jūs joprojām dzirdēsiet atskaņošanai izvēlētos vienumus, tostarp mūziku, videoklipus un spēles."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Jūs netraucēs skaņas un vibrosignāli, ja vien tie nebūs modinātāji, atgādinājumi, pasākumi vai konkrēti zvanītāji, kurus būsiet norādījis."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Pielāgot"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli. Jūs joprojām varēsiet veikt tālruņa zvanus."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Tiks bloķētas VISAS skaņas un vibrosignāli, tostarp modinātāja, mūzikas, videoklipu un spēļu skaņas un signāli."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ir izveidots savienojums ar lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, kas var pārraudzīt jūsu tīklā veiktās privātās darbības, tostarp e-pasta ziņojumus, lietotnes un vietnes."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jūsu darba profilu pārvalda <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profils ir saistīts ar lietotni <xliff:g id="APPLICATION">%2$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, izmantotās lietotnes un apmeklētās tīmekļa vietnes.\n\nLai iegūtu plašāku informāciju, sazinieties ar administratoru."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jūsu darba profilu pārvalda <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profils ir saistīts ar lietotni <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, kura var pārraudzīt jūsu tīklā veiktās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, instalētās lietotnes un apmeklētās tīmekļa vietnes.\n\nIr izveidots savienojums ar lietotni <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, kas var pārraudzīt jūsu tīklā veiktās privātās darbības, tostarp saņemtos un nosūtītos e-pasta ziņojumus, instalētās lietotnes un apmeklētās tīmekļa vietnes."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Atbloķēta lietotājam <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> darbojas"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Ierīce būs bloķēta, līdz to manuāli atbloķēsiet."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Saņemiet paziņojumus ātrāk"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Skatiet tos pirms atbloķēšanas."</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nē"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Iestatīt"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Izslēgt tūlīt"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Izslēgt"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Izvērst"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sakļaut"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrāns ir piesprausts"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izslēgts"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Izmantojot barošanas paziņojumu vadīklas, varat lietotnes paziņojumiem iestatīt svarīguma līmeni (no 0 līdz 5). \n\n"<b>"5. līmenis"</b>" \n- Tiek rādīts paziņojumu saraksta augšdaļā \n- Tiek atļauta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"4. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"3. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n\n"<b>"2. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n\n"<b>"1. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n- Paziņojumi tiek paslēpti bloķēšanas ekrānā un statusa joslā \n- Paziņojumi tiek rādīti paziņojumu saraksta apakšdaļā \n\n"<b>"0. līmenis"</b>" \n- Visi lietotnes paziņojumi tiek bloķēti"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Paziņojumi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jūs vairs nesaņemsiet šos paziņojumus."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jūs vairs nesaņemsiet šos paziņojumus"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> paziņojumu kategorijas"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Paziņojumu kategorijas šajā lietotnē nav pieejamas."</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="zero">1 no <xliff:g id="NUMBER_1">%d</xliff:g> šīs lietotnes paziņojumu kategorijām.</item>
       <item quantity="one">1 no <xliff:g id="NUMBER_1">%d</xliff:g> šīs lietotnes paziņojumu kategorijas.</item>
@@ -574,12 +577,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"paziņojumu vadīklas"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"paziņojumu atlikšanas opcijas"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minūtes"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minūtes"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 stunda"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 stundas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ATSAUKT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Atlikts: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Akumulatora lietojums"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
diff --git a/packages/SystemUI/res/values-lv/strings_car.xml b/packages/SystemUI/res/values-lv/strings_car.xml
index 0171624..d804f86 100644
--- a/packages/SystemUI/res/values-lv/strings_car.xml
+++ b/packages/SystemUI/res/values-lv/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Droša braukšana"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pievērsiet visu uzmanību braukšanas apstākļiem un vienmēr ievērojiet piemērojamos tiesību aktus. Norādes var būt neprecīzas, nepilnīgas, bīstamas, nepiemērotas, aizliegtas vai var ietvert administratīvo teritoriju šķērsošanu. Arī uzņēmumu informācija var būt neprecīza vai nepilnīga. Dati netiek nodrošināti reāllaikā, un netiek garantēta atrašanās vietu precizitāte. Vadot transportlīdzekli, nelietojiet mobilo ierīci rokās un neizmantojiet lietotnes, kas nav paredzētas pakalpojumam Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Nezināms"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sākt braukšanu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
new file mode 100644
index 0000000..7dadae7
--- /dev/null
+++ b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+</resources>
+
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 4d4e227..fd773ad 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Пребарај"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Лизгај нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Лизгај налево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Нема да ве вознемируваат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, што опфаќа музика, видеа и игри."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Нема да ве вознемируваат звуци и вибрации, освен од аларми. Сѐ уште ќе слушате сѐ што ќе изберете да пуштите, што опфаќа музика, видеа и игри."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Нема да ви пречат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Приспособи"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите. Сѐ уште ќе може да воспоставувате телефонски повици."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Поврзани сте на <xliff:g id="APPLICATION">%1$s</xliff:g>, којашто може да ја следи вашата лична активност на мрежата, вклучувајќи ги е-пораките, апликациите и веб-локациите."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управува со вашиот работен профил. Профилот е поврзан на <xliff:g id="APPLICATION">%2$s</xliff:g>, што може да ја следи вашата работна активност на мрежата, заедно со е-пораките, апликациите и веб-сајтовите.\n\nЗа повеќе информации, контактирајте со вашиот администратор."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> управува со вашиот работен профил. Профилот е поврзан на <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, што може да ја следи вашата работна активност на мрежата, заедно со е-пораките, апликациите и веб-сајтовите.\n\nПоврзани сте и на <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, што може да ја следи вашата лична активност на мрежата."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Отклучен за <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> работи"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Уредот ќе остане заклучен додека рачно не го отклучите"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Добивајте известувања побрзо"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Видете ги пред да отклучите"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Не, фала"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Постави"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Исклучи сега"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Заврши сега"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Собери"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екранот е прикачен"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Исклучено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Со контролите за известувањата за напојување, може да поставите ниво на важност од 0 до 5 за известувањата на која било апликација. \n\n"<b>"Ниво 5"</b>" \n- Прикажувај на врвот на списокот со известувања \n- Дозволи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 4"</b>" \n- Спречи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 3"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n\n"<b>"Ниво 2"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n\n"<b>"Ниво 1"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n- Сокриј од заклучен екран и статусна лента \n- Прикажувај на дното на списокот со известувања \n\n"<b>"Ниво 0"</b>" \n- Блокирај ги сите известувања од апликацијата"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известувања"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Веќе нема да ги добивате овие известувања."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Веќе нема да ги добивате овие известувања"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известувања"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Апликацијава нема катерии известувања"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорија известувања од апликацијава</item>
       <item quantity="other">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категории известувања од апликацијава</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроли за известувањето"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опции за одложување на известувањето"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ВРАТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Користење батерија"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
diff --git a/packages/SystemUI/res/values-mk/strings_car.xml b/packages/SystemUI/res/values-mk/strings_car.xml
index f5ed824..9220ccb 100644
--- a/packages/SystemUI/res/values-mk/strings_car.xml
+++ b/packages/SystemUI/res/values-mk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возете безбедно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Секогаш бидете известени за условите за возење и почитувајте ги важечките закони. Насоките може да бидат неточни, нецелосни, опасни, несоодветни, забранети или да вклучуваат премин преку административни области. Бизнис информациите исто така може да бидат неточни или нецелосни. Податоците не се даваат во реално време и не може да се гарантира точноста на локацијата. Не ракувајте со вашиот мобилен уред и не користете апликации што не се наменети за Android Auto додека возите."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Непознато"</string>
+    <string name="start_driving" msgid="864023351402918991">"Започнете да возите"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 67d7404..32a36b3 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"തിരയൽ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി മുകളിലേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി ഇടത്തേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"അലാറങ്ങളിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"നിങ്ങൾ വ്യക്തമാക്കിയിട്ടുള്ള അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവ ഒഴികെയുള്ള ശബ്‌ദങ്ങളോ വൈബ്രേഷനുകളോ കാരണം നിങ്ങൾക്ക് ശല്യമുണ്ടാകില്ല."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു. നിങ്ങൾക്ക് തുടർന്നും ഫോൺ വിളിക്കാനാകും."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"നിങ്ങൾ <xliff:g id="APPLICATION">%1$s</xliff:g> ആപ്പിലേക്ക് കണക്റ്റുചെയ്‌തിരിക്കുന്നു, ഇമെയിലുകൾ, ആപ്‌സ്, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ആണ് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ മാനേജുചെയ്യുന്നത്. <xliff:g id="APPLICATION">%2$s</xliff:g> ആപ്പിലേക്ക് പ്രൊഫൈൽ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ ഔദ്യോഗിക നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും.\n\nകൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ആണ് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ മാനേജുചെയ്യുന്നത്. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ആപ്പിലേക്ക് പ്രൊഫൈൽ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്‌സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ ഔദ്യോഗിക നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും.\n\n<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ആപ്പിലേക്കും നിങ്ങൾ കണക്റ്റുചെയ്‌തിരിക്കുന്നു, അതിന് നിങ്ങളുടെ വ്യക്തിഗത നെറ്റ്‌വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാനാകും."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> എന്നയാൾക്കായി അൺലോക്കുചെയ്‌തു"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> റൺ ചെയ്യുന്നു"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"നിങ്ങൾ സ്വമേധയാ അൺലോക്കുചെയ്യുന്നതുവരെ ഉപകരണം ലോക്കുചെയ്‌തതായി തുടരും"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"അറിയിപ്പുകൾ വേഗത്തിൽ സ്വീകരിക്കുക"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"അൺലോക്കുചെയ്യുന്നതിന് മുമ്പ് അവ കാണുക"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"വേണ്ട, നന്ദി"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"സജ്ജീകരിക്കുക"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ഇപ്പോൾ ഓഫ് ചെയ്യുക"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ഇപ്പോള്‍ അവസാനിപ്പിക്കുക"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"വികസിപ്പിക്കുക"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ചുരുക്കുക"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"സ്‌ക്രീൻ പിൻ ചെയ്‌തു"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ഓഫ്"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"പവർ അറിയിപ്പ് നിയന്ത്രണം ഉപയോഗിച്ച്, ഒരു ആപ്പിനായുള്ള അറിയിപ്പുകൾക്ക് 0 മുതൽ 5 വരെയുള്ള പ്രാധാന്യ ലെവലുകളിലൊന്ന് നിങ്ങൾക്ക് സജ്ജമാക്കാവുന്നതാണ്. \n\n"<b>"ലെവൽ 5"</b>" \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ മുകളിൽ കാണിക്കുക \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം അനുവദിക്കുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 4"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 3"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും സൃശ്യമാക്കരുത് \n\n"<b>"ലെവൽ 2"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n\n"<b>"ലെവൽ 1"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n- ലോക്ക് സ്ക്രീനിൽ നിന്നും സ്റ്റാറ്റസ് ബാറിൽ നിന്നും മറയ്ക്കുക \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ അടിയിൽ കാണിക്കുക \n\n"<b>"ലെവൽ 0"</b>" \n- ആപ്പിൽ നിന്നുള്ള എല്ലാ അറിയിപ്പുകളും ബ്ലോക്കുചെയ്യുക"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"അറിയിപ്പുകൾ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"നിങ്ങൾക്ക് ഈ അറിയിപ്പുകൾ ഇനിയങ്ങോട്ട് ലഭിക്കില്ല."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"നിങ്ങൾക്ക് ഇനി ഈ അറിയിപ്പുകൾ ലഭിക്കില്ല"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> അറിയിപ്പ് വിഭാഗങ്ങൾ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ഈ ആപ്പിന് അറിയിപ്പ് വിഭാഗങ്ങളില്ല"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ഈ ആപ്പിൽ നിന്ന് 1 / <xliff:g id="NUMBER_1">%d</xliff:g> അറിയിപ്പ് വിഭാഗങ്ങൾ</item>
       <item quantity="one">ഈ ആപ്പിൽ നിന്ന് 1 / <xliff:g id="NUMBER_0">%d</xliff:g> അറിയിപ്പ് വിഭാഗം</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"അറിയിപ്പ് സ്‌നൂസ് ഓപ്ഷനുകൾ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 മിനിറ്റ്"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 മിനിറ്റ്"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"ഒരു മണിക്കൂർ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 മണിക്കൂർ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"പഴയപടിയാക്കുക"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്‌നൂസ് ‌ചെയ്‌തു"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ബാറ്ററി ഉപയോഗം"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
diff --git a/packages/SystemUI/res/values-ml/strings_car.xml b/packages/SystemUI/res/values-ml/strings_car.xml
index b53029c..eb4e1e6 100644
--- a/packages/SystemUI/res/values-ml/strings_car.xml
+++ b/packages/SystemUI/res/values-ml/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"സുരക്ഷിതമായി ഡ്രൈവ് ചെയ്യുക"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ഡ്രൈവിംഗ് സാഹചര്യങ്ങളെ കുറിച്ച് നല്ലവണ്ണം അറിഞ്ഞുവയ്ക്കുക, എല്ലായ്പ്പോഴും ബാധകമായ നിയമങ്ങൾ അനുസരിക്കുക. ദിശാസൂചനകൾ കൃത്യമല്ലാത്തതും അപൂർണ്ണവും അപകടകരവും അനുയോജ്യമല്ലാത്തതും നിരോധിക്കപ്പെട്ടതും അഡ്‌മിനിസ്ട്രേറ്റീവ് ഏരിയകൾ അതിലംഘിച്ച് പോകേണ്ടതുമായിരിക്കാം. വിവരങ്ങൾ തത്സമയം എടുത്തിട്ടുള്ളതല്ല, അതിനാൽ ലൊക്കേഷൻ കൃത്യത ഉറപ്പാക്കാൻ കഴിയില്ല. ഡ്രൈവ് ചെയ്യുന്ന സമയത്ത് മൊബൈൽ ഉപകരണങ്ങളോ Android Auto-യ്ക്കായി ഉദ്ദേശിക്കപ്പെട്ടിട്ടില്ലാത്ത ആപ്‌സോ കൈകാര്യം ചെയ്യരുത്"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"അറിഞ്ഞുകൂടാത്തത്"</string>
+    <string name="start_driving" msgid="864023351402918991">"ഡ്രൈവ് ചെയ്തുതുടങ്ങുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index ec0dcee..faa09f6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -350,8 +350,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Танд сэрүүлэг, сануулга, үйл ажиллагаа, таны сонгосон дуудлага илгээгчээс бусад дуу, чичиргээ саад болохгүй. Та хөгжим, видео, тоглоом зэрэг тоглуулахыг хүссэн бүх зүйлээ сонсох боломжтой хэвээр байна."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Танд сэрүүлгээс бусад дуу, чичиргээ саад болохгүй. Та хөгжим, видео, тоглоом зэрэг тоглуулахыг хүссэн бүх зүйлээ сонсох боломжтой хэвээр байна."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Танд сэрүүлгэ, сануулга, үйл явдлын сануулга, таны сануулсан дуудлага зэргээс бусад дуу чимээ, чичиргээ танд садаа болохгүй."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Тохируулах"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог. Та дуудлага хийх боломжтой хэвээр байна."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог."</string>
@@ -465,13 +464,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Та имэйл, апп, вэб хуудас зэрэг хувийн сүлжээнийхээ үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон байна."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг ажлын сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%2$s</xliff:g>-д холбогдсон. \n\nДэлгэрэнгүй мэдээллийг авахын тулд админтай холбогдоно уу."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Таны ажлын профайлыг <xliff:g id="ORGANIZATION">%1$s</xliff:g> удирддаг. Энэ нь таны имэйл, апп, вэб хуудас зэрэг сүлжээний үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>-тай холбогдсон. \n\nМөн таны сүлжээний хувийн үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>-д холбогдсон байна."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>-н түгжээг тайлсан"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ажиллаж байна"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Таныг гараар нээх хүртэл төхөөрөмж түгжээтэй байх болно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Мэдэгдлийг хурдан авах"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Түгжээг тайлахын өмнө үзнэ үү"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Үгүй"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Тохируулах"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Одоо унтраах"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Одоо дуусгах"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Дэлгэх"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Хураах"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Дэлгэц эхэнд байрлуулагдсан"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Идэвхгүй"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Тэжээлийн мэдэгдлийн удирдлагын тусламжтайгаар та апп-н мэдэгдэлд 0-5 хүртэлх ач холбогдлын түвшин тогтоох боломжтой. \n\n"<b>"5-р түвшин"</b>" \n- Мэдэгдлийн жагсаалтын хамгийн дээр харуулна \n- Бүтэн дэлгэцэд саад болно \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"4-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"3-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n\n"<b>"2-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n\n"<b>"1-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n- Түгжигдсэн дэлгэц болон статусын самбараас нууна \n- Мэдэгдлийн жагсаалтын доор харуулна \n\n"<b>"0-р түвшин"</b>" \n- Энэ апп-н бүх мэдэгдлийг блоклоно"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Мэдэгдэл"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ta цаашид мэдэгдэл авахгүй."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ta цаашид эдгээр мэдэгдлийг авахгүй"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> мэдэгдлийн ангилал"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Энэ апп-д мэдэгдлийн категори алга"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Энэ аппын <xliff:g id="NUMBER_1">%d</xliff:g> мэдэгдлийн категорийн 1</item>
       <item quantity="one">Энэ аппын <xliff:g id="NUMBER_0">%d</xliff:g> мэдэгдлийн категорийн 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"мэдэгдлийн удирдлага"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"мэдэгдэл түр хойшлуулагчийн сонголт"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 цаг"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 цаг"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"БУЦААХ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>-д түр хойшлуулсан"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Тэжээл ашиглалт"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
@@ -718,8 +719,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="4171698133469539591">"Та <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-mn/strings_car.xml b/packages/SystemUI/res/values-mn/strings_car.xml
index d48580f..74b983a 100644
--- a/packages/SystemUI/res/values-mn/strings_car.xml
+++ b/packages/SystemUI/res/values-mn/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Жолооны аюулгүй байдал"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жолоодох нөхцөлийн талаар бүрэн ойлгож, холбогдох дүрэм журмыг мөрдөөрэй. Чиглэл нь тодорхой бус, гүйцэт бус, аюултай, тохиромжгүй, хориглосон эсвэл тусгай хамгаалалттай газар нутагт нэвтэрсэн байж болзошгүй. Бизнесийн мэдээлэл мөн адил тохиромжгүй эсвэл гүйцэт бус байна. Өгөгдөл нь тухайн цаг хугацааных биш учир байршлыг зөв тодорхойлсон эсэхийг батлах боломжгүй. Жолоодож байхдаа гар утсаа болон Android Автод зориулаагүй апп-г бүү ашиглаарай."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Тодорхойгүй"</string>
+    <string name="start_driving" msgid="864023351402918991">"Жолоо барьж эхлэх"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml
index e250c2d..bbc94c8 100644
--- a/packages/SystemUI/res/values-mn/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn/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-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fd6b0c3..ed8b034 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"शोध"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी वर स्लाइड करा."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"अलार्म, रिमाइंडर्स, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलरचा अपवाद वगळता तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तसे असले तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज चालू ठेवले जातील."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"अलार्मचा अपवाद सोडल्यास तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तसे असले तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज चालू ठेवले जातील."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"आपण निर्दिष्‍ट करता ते अलार्म, स्मरणपत्रे, इव्हेंट आणि कॉलर व्यतिरिक्त, आपल्याला आवाज आणि कंपनांमुळे व्यत्यय येणार नाही."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"सानुकूलित करा"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते. आपण तरीही फोन कॉल करण्यात सक्षम व्हाल."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"आपण <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते. प्रोफाइल <xliff:g id="APPLICATION">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या कार्य नेटवर्क क्रियाकलापाचे परीक्षण करू शकते.\n\nअधिक माहितीसाठी, आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"आपले कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते. प्रोफाइल <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या कार्य नेटवर्क क्रियाकलापाचे परीक्षण करू शकते.\n\nआपण <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> शीदेखील कनेक्‍ट केले आहे, जे आपल्या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> साठी अनलॉक केले"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चालू आहे"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"आपण व्यक्तिचलितपणे अनलॉक करेपर्यंत डिव्हाइस लॉक केलेले राहील"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"सूचना अधिक जलद मिळवा"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"आपण अनलॉक करण्‍यापूर्वी त्यांना पहा"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"नाही धन्यवाद"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"सेट अप"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"आता बंद करा"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"आता समाप्त करा"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करा"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संकुचित करा"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"स्क्रीन पिन केलेली आहे"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांसह, आपण अॅपच्या सूचनांसाठी महत्त्व स्तर 0 ते 5 पर्यंत सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दर्शवा \n- पूर्ण स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n\n"<b>"स्तर 1"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना अवरोधित करा"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"आपल्याला यापुढे या सूचना प्राप्त होणार नाहीत."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तुम्हाला यापुढे या सूचना प्राप्त होणार नाहीत"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचना श्रेण्या"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"या अ‍ॅपला सूचना श्रेण्या नाहीत"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">या अॅपकडील <xliff:g id="NUMBER_1">%d</xliff:g> पैकी 1 सूचना श्रेणी</item>
       <item quantity="other">या अॅपकडील <xliff:g id="NUMBER_1">%d</xliff:g> पैकी 1 सूचना श्रेणी</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"सूचना नियंत्रणे"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना स्नूझ पर्याय"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनिटे"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनिटे"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 तास"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 तास"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"पूर्ववत करा"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> साठी स्नूझ करा"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"बॅटरी वापर"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
diff --git a/packages/SystemUI/res/values-mr/strings_car.xml b/packages/SystemUI/res/values-mr/strings_car.xml
index 7dc5d17..5d66f14 100644
--- a/packages/SystemUI/res/values-mr/strings_car.xml
+++ b/packages/SystemUI/res/values-mr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षितपणे वाहन चालवा"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"वाहन चालविण्‍याच्या शर्तींची पूर्णपणे माहिती असू द्या आणि नेहमी लागू असलेल्या कायद्यांचे पालन करा. दिशानिर्देश कदाचित चुकीचे, अपूर्ण, धोकादायक, अनुकूल नसलेले, प्रतिबंधित किंवा प्रशासकीय क्षेत्रांना ओलांडणारे असू शकतात. व्यवसाय माहिती देखील चुकीची किंवा अपूर्ण असू शकते. डेटा हा रिअल-टाइम नसतो आणि स्थान अचूकतेची हमी दिली जाऊ शकत नाही. वाहन चालविताना Android Auto च्या उद्देशासाठी नसलेले आपले मोबाईल डिव्हाइस हाताळू नका किंवा अॅप्स वापरू नका."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"वाहन चालवणे सुरू करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 46fcf43..0e60d5d 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Anda tidak akan diganggu oleh bunyi dan getaran, kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tetapkan. Anda masih mendengar item lain yang anda pilih untuk dimainkan termasuk muzik, video dan permainan."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Anda tidak akan diganggu oleh bunyi dan getaran, kecuali daripada penggera. Anda masih mendengar item lain yang anda pilih untuk dimainkan termasuk muzik, video dan permainan."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh bunyi dan getaran kecuali daripada penggera, peringatan, acara dan pemanggil yang anda tentukan."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Peribadikan"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan. Anda masih boleh membuat panggilan telefon."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Mod ini menyekat SEMUA bunyi dan getaran, termasuk daripada penggera, muzik, video dan permainan."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Anda disambungkan ke <xliff:g id="APPLICATION">%1$s</xliff:g>, yang boleh memantau aktiviti rangkaian peribadi anda, termasuk e-mel, apl dan tapak web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profil kerja anda diurus oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil itu dihubungkan ke <xliff:g id="APPLICATION">%2$s</xliff:g>, yang boleh memantau aktiviti rangkaian kerja anda, termasuk e-mel, apl dan tapak web.\n\nUntuk mendapatkan maklumat lanjut, hubungi pentadbir anda."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profil kerja anda diurus oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil itu dihubungkan ke <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, yang boleh memantau aktiviti rangkaian kerja anda, termasuk e-mel, apl dan tapak web.\n\nAnda turut dihubungkan ke <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, yang boleh memantau aktiviti rangkaian peribadi anda."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Kunci dibuka untuk <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> sedang berjalan"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Peranti akan kekal terkunci sehingga anda membuka kunci secara manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum anda membuka kunci"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Tidak"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Sediakan"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Matikan sekarang"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Tamatkan sekarang"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kembangkan"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Runtuhkan"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skrin telah disemat"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Mati"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kawalan pemberitahuan berkuasa, anda boleh menetapkan tahap kepentingan dari 0 hingga 5 untuk pemberitahuan apl. \n\n"<b>"Tahap 5"</b>" \n- Tunjukkan pada bahagian atas senarai pemberitahuan \n- Benarkan gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 4"</b>" \n- Halang gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 3"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n\n"<b>"Tahap 2"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi dan bergetar \n\n"<b>"Tahap 1"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi atau bergetar \n- Sembunyikan daripada skrin kunci dan bar status \n- Tunjukkan di bahagian bawah senarai pemberitahuan \n\n"<b>"Tahap 0"</b>" \n- Sekat semua pemberitahuan daripada apl"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pemberitahuan"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan menerima pemberitahuan ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan menerima pemberitahuan ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori pemberitahuan"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Apl ini tiada kategori pemberitahuan"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 daripada <xliff:g id="NUMBER_1">%d</xliff:g> kategori pemberitahuan daripada apl ini</item>
       <item quantity="one">1 daripada <xliff:g id="NUMBER_0">%d</xliff:g> kategori pemberitahuan daripada apl ini</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kawalan pemberitahuan"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"pilihan tunda pemberitahuan"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minit"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minit"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 jam"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"BUAT ASAL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Penggunaan bateri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
diff --git a/packages/SystemUI/res/values-ms/strings_car.xml b/packages/SystemUI/res/values-ms/strings_car.xml
index 392530a..0daa093 100644
--- a/packages/SystemUI/res/values-ms/strings_car.xml
+++ b/packages/SystemUI/res/values-ms/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Pandu dengan selamat"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pastikan anda sentiasa sedar sepenuhnya akan keadaan pemanduan dan mematuhi undang-undang yang dikenakan pada sepanjang masa. Arah mungkin tidak tepat, tidak lengkap, berbahaya, tidak sesuai, dilarang atau melibatkan lintasan kawasan pentadbiran. Maklumat perniagaan juga mungkin tidak tepat atau tidak lengkap. Data bukan masa sebenar dan ketepatan lokasi tidak dapat dijamin. Jangan kendalikan peranti mudah alih anda atau gunakan apl yang bukan untuk Android Auto semasa memandu."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Tidak diketahui"</string>
+    <string name="start_driving" msgid="864023351402918991">"Mulakan Pemanduan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 39dac57..740ded7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -262,7 +262,7 @@
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ဖန်သားပြင် အနေအထားက ဒေါင်လိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
     <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"ယခုတော့ မျက်နှာပြင်သည် အလိုအလျောက် လည်နေမည်။"</string>
     <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"မျက်နှာပြင် အနေအထားကို ဘေးတိုက် အဖြစ် သော့ချထားသည်။"</string>
-    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"မျက်နှာပြင်အနေအထားကို ထောင်လိုက်အဖြစ် ပုံသေသတ်မှတ်ထားသည်။"</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"မျက်နှာပြင် အနေအထားကို ထောင်လိုက် အဖြစ် သော့ချထားသည်။"</string>
     <string name="dessert_case" msgid="1295161776223959221">"မုန့်ထည့်သော ပုံး"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ဖန်သားပြင်အသုံးပြုမှု ချွေတာမှုစနစ်"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"အီသာနက်"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ရှာဖွေရန်"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် အပေါ်ကို ပွတ်ဆွဲပါ"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် ဖယ်ဘက်ကို ပွတ်ဆွဲပါ"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"နှိုးစက်သံ၊ သတိပေးချက်အသံများ၊ ပွဲစဉ်သတိပေးသံများနှင့် သင်ခွင့်ပြုထားသူများထံမှ ဖုန်းခေါ်မှုများမှလွဲ၍ အခြားအသံများနှင့် တုန်ခါမှုများက သင့်ကို အနှောင့်အယှက်ပြုမည် မဟုတ်ပါ။ သို့သော်လည်း သီချင်း၊ ဗီဒီယိုနှင့် ဂိမ်းများအပါအဝင် သင်ကရွေးချယ်ဖွင့်ထားသည့် အရာတိုင်း၏ အသံကိုမူ ကြားနေရဆဲဖြစ်ပါလိမ့်မည်။"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"နှိုးစက်သံမှလွဲ၍ အခြားအသံများနှင့် တုန်ခါမှုများက သင့်ကို အနှောင့်အယှက်ပြုမည် မဟုတ်ပါ။ သို့သော်လည်း သီချင်း၊ ဗီဒီယိုနှင့် ဂိမ်းများအပါအဝင် သင်ကရွေးချယ်ဖွင့်ထားသည့် အရာတိုင်း၏ အသံကိုမူ ကြားနေရဆဲဖြစ်ပါလိမ့်မည်။"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"နှိုးစက်များ၊ အသိပေးချက်များ၊ ဖြစ်ရပ်များ နှင့် သင်သတ်မှတ်ထားသည့် ခေါ်ဆိုသူများမှ လွဲ၍ အသံများနှင့် တုန်ခါမှုများသည် သင့်အား နှောင့်ယှက်မည် မဟုတ်ပါ။"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"စိတ်ကြိုက် ပြုလုပ်ရန်"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ဤအရာမှ နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား တားဆီးပေးသည်။ ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်နိုင်ဆဲဖြစ်မည်။"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား ဤအရာမှ တားဆီးပေး၏။"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"သင်သည် အီးမေးလ်၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင့်ကိုယ်ရေးကိုယ်တာ ကွန်ရက်အသုံးပြုမှုကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"သင်၏ အလုပ်ပရိုဖိုင်ကို <xliff:g id="ORGANIZATION">%1$s</xliff:g> က စီမံခန့်ခွဲထားပါသည်။ ပရိုဖိုင်သည် အီးမေး၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင်၏ကွန်ရက် လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။\n\nနောက်ထပ် အချက်အလက်များအတွက် သင်၏ စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"သင်၏ အလုပ်ပရိုဖိုင်ကို <xliff:g id="ORGANIZATION">%1$s</xliff:g> က စီမံခန့်ခွဲထားသည်။ ပရိုဖိုင်သည် အီးမေး၊ အက်ပ်နှင့် ဝဘ်ဆိုက်များအပါအဝင် သင်၏ကွန်ရက် လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> သို့ ချိတ်ဆက်ထားပါသည်။\n\nသင်၏ ကိုယ်ရေးကိုယ်တာ ကွန်ရက်လုပ်ဆောင်ချက်များကို စောင့်ကြည့်နိုင်သည့် <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> သို့လည်း ချိတ်ဆက်ထားပါသည်။"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> အတွက် လော့ခ်ဖွင့်ထားသည်"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ပွင့်နေပါသည်"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"သင်က လက်ဖြင့် သော့မဖွင့်မချင်း ကိရိယာမှာ သော့ပိတ်လျက် ရှိနေမည်"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"အကြောင်းကြားချက်များ မြန်မြန်ရရန်"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"မဖွင့်ခင် ၎င်းတို့ကို ကြည့်ပါ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"မလိုအပ်ပါ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"သတ်မှတ်ရန်"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>။ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ပိတ်ရန်"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ယခု အဆုံးသတ်ရန်"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"တိုးချဲ့ရန်"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ခေါက်သိမ်းရန်..."</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"မျက်နှာပြင် ပင်ထိုးပြီးပါပြီ"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ပိတ်ပါ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ပါဝါအကြောင်းကြားချက် ထိန်းချုပ်မှုများကိုအသုံးပြုပြီး အက်ပ်တစ်ခု၏ အကြောင်းကြားချက် အရေးပါမှု ၀ မှ ၅ အထိသတ်မှတ်ပေးနိုင်သည်။ \n\n"<b>"အဆင့် ၅"</b>" \n- အကြောင်းကြားချက်စာရင်း၏ ထိပ်ဆုံးတွင် ပြသည် \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်းကို ခွင့်ပြုသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၄"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၃"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n\n"<b>"အဆင့် ၂"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n\n"<b>"အဆင့် ၁"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n- လော့ခ်ချထားသည့် မျက်နှာပြင်နှင့် အခြေအနေဘားတန်းတို့တွင် မပြပါ \n- အကြောင်းကြားချက်စာရင်း အောက်ဆုံးတွင်ပြသည် \n\n"<b>"အဆင့် ၀"</b>" \n- အက်ပ်မှ အကြောင်းကြားချက်များ အားလုံးကို ပိတ်ဆို့သည်"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"အကြောင်းကြားချက်များ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"သင်သည် ဤအကြောင်းကြားချက်များကို လက်ခံရရှိတော့မည် မဟုတ်ပါ။"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"သင်သည် ဤအကြောင်းကြားချက်များကို နောက်ထပ် လက်ခံရရှိတော့မည် မဟုတ်ပါ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"အကြောင်းကြားချက် အမျိုးအစား <xliff:g id="NUMBER">%d</xliff:g> ခု"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ဤအက်ပ်တွင် အကြောင်းကြားချက် အမျိုးအစားများ မရှိပါ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ဤအက်ပ်ရှိ အကြောင်းကြားချက်အမျိုးအစား <xliff:g id="NUMBER_1">%d</xliff:g> ခု အနက်မှ ၁ ခု</item>
       <item quantity="one">ဤအက်ပ်ရှိ အကြောင်းကြားချက်အမျိုးအစား <xliff:g id="NUMBER_0">%d</xliff:g> ခု အနက်မှ ၁ ခု</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"အကြောင်းကြားချက် ထိန်းချုပ်မှုများ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"အကြောင်းကြားချက်များကို ဆိုင်းငံ့ရန် ရွေးချယ်စရာများ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"၁၅ မိနစ်"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"၃၀ မိနစ်"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"၁ နာရီ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"၂ နာရီ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"တစ်ဆင့် နောက်ပြန်ပြန်ပါ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ဆိုင်းငံ့ရန်"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ဘက်ထရီ အသုံးပြုမှု"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
diff --git a/packages/SystemUI/res/values-my/strings_car.xml b/packages/SystemUI/res/values-my/strings_car.xml
index dd41713..c2700c4 100644
--- a/packages/SystemUI/res/values-my/strings_car.xml
+++ b/packages/SystemUI/res/values-my/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ဘေးကင်းလုံခြုံစွာ မောင်းနှင်ပါ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ယာဉ်မောင်းမှုအခြေအနေများကို အပြည့်အဝအာရုံစိုက်ပြီး သက်ဆိုင်ရာဥပဒေများကို အမြဲတမ်းလိုက်နာပါ။ လမ်းညွှန်ချက်များသည် မှန်ကန်မှုမရှိခြင်း၊ မပြည့်စုံခြင်း၊ အန္တရာယ်ရှိခြင်း၊ ကိုက်ညီမှုမရှိခြင်း၊ တားမြစ်ထားခြင်း၊ သို့မဟုတ် လမ်းဖြတ်ကူးခြင်း ကြီးကြပ်ထားသည့်နေရာများ ဖြစ်နေနိုင်ပါသည်။ စီးပွားရေးအချက်အလက်များသည်လည်း မမှန်ကန်ခြင်း သို့မဟုတ် မပြည့်စုံခြင်းများ ရှိနိုင်ပါသည်။ ဒေတာသည် အချိန်နှင့်တစ်ပြေးညီ မဟုတ်ပါ၊ တည်နေရာမှန်ကန်မှုကိုလည်း အာမ မခံနိုင်ပါ။ ယာဉ်မောင်းနှင်နေစဉ် Android Auto အတွက်ရည်ရွယ်ထားခြင်းမဟုတ်သည့် မိုဘိုင်းစက်ပစ္စည်း ကိုမကိုင်တွယ်ပါနှင့် သို့မဟုတ် အက်ပ်များကို အသုံးမပြုပါနှင့်။ိ"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"အမျိုးအမည်မသိ"</string>
+    <string name="start_driving" msgid="864023351402918991">"စတင် မောင်းနှင်ရန်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3fdc266..b86c256 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Du blir ikke forstyrret av lyder og vibrasjoner, med unntak av alarmer, påminnelser, aktiviteter og oppringere du angir. Du kan fremdeles høre alt du velger å spille av, for eksempel musikk, videoer og spill."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Du blir ikke forstyrret av lyder og vibrasjoner, med unntak av alarmer. Du kan fremdeles høre alt du velger å spille av, for eksempel musikk, videoer og spill."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir ikke forstyrret av lyder og vibrasjoner, bortsett fra alarmer, påminnelser, aktiviteter og oppringere du angir."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpass"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill. Du kan fremdeles ringe."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Enheten er koblet til <xliff:g id="APPLICATION">%1$s</xliff:g>, som kan overvåke den personlige nettverksaktiviteten din, inkludert e-post, apper og nettsteder."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jobbprofilen din administreres av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen er koblet til <xliff:g id="APPLICATION">%2$s</xliff:g>, som kan overvåke nettverksaktiviteten din på jobben, inkludert e-poster, apper og nettsteder.\n\nTa kontakt med administratoren hvis du vil ha mer informasjon."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jobbprofilen din administreres av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen er koblet til <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, som kan overvåke nettverksaktiviteten din på jobben, inkludert e-poster, apper og nettsteder.\n\nDu er også koblet til <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, som kan overvåke den personlige nettverksaktiviteten din."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Låst opp for <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> kjører"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten forblir låst til du låser den opp manuelt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Motta varsler raskere"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem før du låser opp"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei takk"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfigurer"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Slå av nå"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Avslutt nå"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utvid"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skjermen er låst"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Av"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med effektive varselinnstillinger kan du angi viktighetsnivåer fra 0 til 5 for appvarsler. \n\n"<b>"Nivå 5"</b>" \n– Vis øverst på varsellisten \n– Tillat forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 4"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 3"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n\n"<b>"Nivå 2"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri fort \n– Tillat aldri lyder eller vibrering \n\n"<b>"Nivå 1"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n– Tillat aldri lyder eller vibrering \n– Skjul fra låseskjermen og statusfeltet \n– Vis nederst på varsellisten \n\n"<b>"Nivå 0"</b>" \n– Blokkér alle varsler fra appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Varsler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du får ikke disse varslene lenger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du får ikke disse varslene lenger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> varselkategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne appen har ikke varselkategorier"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 av <xliff:g id="NUMBER_1">%d</xliff:g> varselkategorier fra denne appen</item>
       <item quantity="one">1 av <xliff:g id="NUMBER_0">%d</xliff:g> varselkategori fra denne appen</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"varselinnstillinger"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"slumrealternativer for varsler"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timer"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANGRE"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Slumrer i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteribruk"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
diff --git a/packages/SystemUI/res/values-nb/strings_car.xml b/packages/SystemUI/res/values-nb/strings_car.xml
index 421420e..2a1b3ca 100644
--- a/packages/SystemUI/res/values-nb/strings_car.xml
+++ b/packages/SystemUI/res/values-nb/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kjør forsiktig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ha full oversikt over kjøreforhold, og følg alltid gjeldende lov og rett. Veibeskrivelser kan være unøyaktige, ufullstendige, farlige, upassende, forbudte eller de kan involvere kjøring på administrative områder. Bedriftsinformasjon kan også være unøyaktig eller ufullstendig. Data er ikke i sanntid, og posisjonsnøyaktighet kan ikke garanteres. Ikke bruk mobilenheten din eller apper som ikke er ment for Android Auto, mens du kjører."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Ukjent"</string>
+    <string name="start_driving" msgid="864023351402918991">"Begynn å kjøre"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e21da54..601fcae 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"तपाईंलाई अलार्म, रिमाइन्डर, कार्यक्रम र तपाईंले निर्दिष्ट गर्नुभएका कलरहरू बाहेकका ध्वनि र कम्पनहरूले बाधा पुऱ्याउने छैनन्। तपाईंले अझै संगीत, भिडियो र खेलहरू लगायत आफूले प्ले गर्न छनौट गरेका जुनसुकै कुरा सुन्न सक्नुहुन्छ।"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"तपाईंलाई अलार्म बाहेकका ध्वनि र कम्पनहरूले बाधा पुऱ्याउने छैनन्। तपाईंले अझै संगीत, भिडियो र खेलहरू लगायत आफूले प्ले गर्न छनौट गरेका जुनसुकै कुरा पनि सुन्न सक्नुहुन्छ।"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"अलार्म, रिमाइन्डर, घटना, र तपाईंले निर्दिष्ट गर्नुहुने कलरहरू देखि बाहेक, आवाज र कम्पनले तपाईं लाई वाधा गर्ने छैन।"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"आफू अनुकूल बनाउनुहोस्"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन रोक्छ। तपाईं अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"यसले अलार्म, संगीत, भिडियोहरू र खेलहरूसहित सबै ध्वनिहरू र कम्पनहरूलाई रोक्छ।"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"तपाईं <xliff:g id="APPLICATION">%1$s</xliff:g> मा जोडिनुभएको छ जसले इमेल, अनुप्रयोग र वेबसाइटहरू लगायतको तपाईंको  व्यक्तिगत नेटवर्क सम्बन्धी गतिविधिको अनुगमन गर्न सक्छ।"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION">%2$s</xliff:g> मा जडान छ।\n\nथप जानकारीका लागि, आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> ले तपाईंको कार्य प्रोफाइलको व्यवस्थापन गर्छ। उक्त प्रोफाइल तपाईंका इमेल, अनुप्रयोग र वेवसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> मा जडान छ। \n\nतपाईं आफ्नो व्यक्तिगत नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> मा पनि जडान हुनुहुन्छ।"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> का लागि अनलक गरियो"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> चल्दै छ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"तपाईँले नखोले सम्म उपकरण बन्द रहनेछ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"छिटो सूचनाहरू प्राप्त गर्नुहोस्"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"तपाईँले अनलक गर्नअघि तिनीहरूलाई हेर्नुहोस्"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"धन्यवाद पर्दैन"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"सेटअप गर्नुहोस्"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"अहिले नै निष्क्रिय पार्नुहोस्"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"अहिल्यै अन्त्य गर्नुहोस्"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार गर्नुहोस्"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त पार्नुहोस्"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"पर्दा राखेका छ"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"निष्क्रिय"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"सशक्त सूचना नियन्त्रणहरू मार्फत तपाईं अनुप्रयाेगका सूचनाहरूका लागि ० देखि ५ सम्मको महत्व सम्बन्धी स्तर सेट गर्न सक्नुहुन्छ। \n\n"<b>"स्तर ५"</b>" \n- सूचनाको सूचीको माथिल्लो भागमा देखाउने \n- पूर्ण स्क्रिनमा अवरोधका लागि अनुमति दिने \n- सधैँ चियाउने \n\n"<b>"स्तर ४"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- सधैँ चियाउने \n\n"<b>"स्तर ३"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n\n"<b>"स्तर २"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने र कम्पन नगर्ने \n\n"<b>"स्तर १"</b>" \n- पूर्ण स्क्रिनमा अवरोध रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने वा कम्पन नगर्ने \n- लक स्क्रिन र वस्तुस्थिति पट्टीबाट लुकाउने \n- सूचनाको सूचीको तल्लो भागमा देखाउने \n\n"<b>"स्तर ०"</b>" \n- अनुप्रयोगका सबै सूचनाहरूलाई रोक्ने"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचनाहरू"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"तपाईंले अबदेखि यी सूचनाहरू प्राप्त गर्नुहुने छैन।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तपाईंले अब उप्रान्त यी सूचनाहरू प्राप्त गर्नुहुने छैन"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचनाका कोटिहरू"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"यस अनुप्रयोगमा सूचना सम्बन्धी कोटीहरू छैनन्"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">यस अनुप्रयोगका <xliff:g id="NUMBER_1">%d</xliff:g> सूचना कोटिहरू मध्ये १</item>
       <item quantity="one"> यस अनुप्रयोगको <xliff:g id="NUMBER_0">%d</xliff:g> सूचना कोटी मध्ये १</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"सूचना सम्बन्धी नियन्त्रणहरू"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"सूचना स्नुज गर्ने विकल्पहरू"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"१५ मिनेट"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"३० मिनेट"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"१ घन्टा"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"२ घन्टा"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"अनडू गर्नुहोस्"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> का लागि स्नुज गरियो"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ब्याट्री उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
@@ -719,7 +720,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> Picture-in-picture मा छ"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> तस्बिरभित्रको तस्बिरमा छ"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"तपाईं <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-ne/strings_car.xml b/packages/SystemUI/res/values-ne/strings_car.xml
index 1a4f8ef9..d81a488 100644
--- a/packages/SystemUI/res/values-ne/strings_car.xml
+++ b/packages/SystemUI/res/values-ne/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित तरिकाले सवारी चलाउनुहोस्"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ड्राइभिङ सर्तहरूका बारे पूर्ण सजग रहनुहोस् र जहिले पनि लागू हुने नियमहरूको पालना गर्नुहोस्। दिशा निर्देशनहरू अशुद्ध, अपूर्ण, खतरनाक, अनुपयुक्त, निषेधित वा प्रशासनिक क्षेत्र पार गर्ने हुन सक्छ। व्यवसायिक जानकारी अशुद्ध वा अपूर्ण पनि हुन सक्छ। डेटा वास्तविक समयको हुँदैन र स्थान सटीकताको ग्यारेन्टी गर्न सकिँदैन। आफ्नो मोबाइल यन्त्र ह्याण्डल गर्ने वा सवारी चलाएको बेलामा Android स्वतःको लागि लक्षित नगरिएका अनुप्रयोगहरूको प्रयोग गर्ने नगर्नुहोस्।"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"अज्ञात"</string>
+    <string name="start_driving" msgid="864023351402918991">"ड्राइभिङ सुरू गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml
index 2e42b6c..2c5c186 100644
--- a/packages/SystemUI/res/values-ne/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne/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">"Picture-in-Picture"</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-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3e36c13..91a953d 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">"Batterij is bijna leeg"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Accu 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 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_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_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">"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_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_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>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Je wordt niet gestoord door geluiden en trillingen, behalve bij alarmen, herinneringen, afspraken en specifieke bellers die je selecteert. Je kunt nog steeds alles horen wat je wilt afspelen, waaronder muziek, video\'s en games."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Je wordt niet gestoord door geluiden en trillingen, behalve bij alarmen. Je kunt nog steeds alles horen wat je wilt afspelen, waaronder muziek, video\'s en games."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"U wordt niet gestoord door geluiden en trillingen, behalve voor alarmen, herinneringen, afspraken en bellers die u specificeert."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Aanpassen"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games. U kunt wel nog steeds bellen."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Je bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Het profiel is verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden.\n\nNeem contact op met je beheerder voor meer informatie."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Het profiel is verbonden met <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit (waaronder e-mails, apps en websites) kan worden bijgehouden.\n\nJe bent ook verbonden met <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden bijgehouden."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Ontgrendeld voor <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> is actief"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Het apparaat blijft vergrendeld totdat u het handmatig ontgrendelt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Sneller meldingen ontvangen"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Weergeven voordat u ontgrendelt"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nee, bedankt"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configureren"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Nu uitschakelen"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Nu uitschakelen"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Uitvouwen"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Samenvouwen"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Scherm is vastgezet"</string>
@@ -502,7 +503,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 batterij weergeven"</string>
+    <string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu 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>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Uit"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Boven aan de lijst met meldingen weergeven \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelingsscherm en statusbalk \n- Onder aan de lijst met meldingen weergeven \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Meldingen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Je ontvangt deze meldingen niet meer."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Je ontvangt deze meldingen niet meer"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> meldingscategorieën"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Deze app heeft geen meldingscategorieën"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 van <xliff:g id="NUMBER_1">%d</xliff:g> meldingscategorieën van deze app</item>
       <item quantity="one">1 van <xliff:g id="NUMBER_0">%d</xliff:g> meldingscategorie van deze app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"beheeropties voor meldingen"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"snooze-opties voor meldingen"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuten"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuten"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uur"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ONGEDAAN MAKEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterijbesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterijbesparing"</string>
@@ -718,8 +719,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimaliseren"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Sluiten"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Sleep omlaag om te sluiten"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Scherm-in-scherm-menu"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> is in scherm-in-scherm"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Beeld-in-beeld-menu"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> is in beeld-in-beeld"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Als je niet wilt dat <xliff:g id="NAME">%s</xliff:g> deze functie gebruikt, tik je om de instellingen te openen en schakel je de functie uit."</string>
     <string name="pip_play" msgid="1417176722760265888">"Afspelen"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Onderbreken"</string>
diff --git a/packages/SystemUI/res/values-nl/strings_car.xml b/packages/SystemUI/res/values-nl/strings_car.xml
index be66e01..32582e5 100644
--- a/packages/SystemUI/res/values-nl/strings_car.xml
+++ b/packages/SystemUI/res/values-nl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Rijd veilig"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Blijf je volledig bewust van de rijomstandigheden en houd je altijd aan de wet. Aanwijzingen kunnen onnauwkeurig, onvolledig, gevaarlijk, ongeschikt of verboden zijn of het doorkruisen van overheidszones vereisen. Bedrijfsinformatie kan ook onnauwkeurg of onvolledig zijn. De gegevens worden niet in realtime verstrekt en de nauwkeurigheid van een locatie kan niet worden gegarandeerd. Bedien tijdens het rijden je mobiele apparaat niet en gebruik geen apps die niet bedoeld zijn voor Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Onbekend"</string>
+    <string name="start_driving" msgid="864023351402918991">"Beginnen met rijden"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml
index 8270fee..fae484f 100644
--- a/packages/SystemUI/res/values-nl/strings_tv.xml
+++ b/packages/SystemUI/res/values-nl/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">"Scherm-in-scherm"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Beeld-in-beeld"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Naamloos programma)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP sluiten"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Volledig scherm"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 12b1dcb..5fc0b1b 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ਖੋਜੋ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਲਈ ਉੱਪਰ ਸਲਾਈਡ ਕਰੋ।"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਨਿਰਧਾਰਤ ਕੀਤੇ ਕਾਲਰਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਤੁਹਾਨੂੰ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕਰਨਗੀਆਂ, ਸਿਵਾਏ ਅਲਾਰਮਾਂ ਦੀ ਸੂਰਤ ਵਿੱਚ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਸੰਗੀਤ, ਵੀਡੀਓ ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ ਆਪਣੀ ਚੋਣ ਅਨੁਸਾਰ ਕੁਝ ਵੀ ਸੁਣ ਸਕਦੇ ਹੋ।"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਤੈਅ ਕੀਤੇ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਕਾਲ ਕਰਨ ਵਾਲਿਆਂ ਨੂੰ ਛੱਡਕੇ, ਤੁਹਾਨੂੰ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਵੱਲੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓ, ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਂਗੇ।"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ।"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫ਼ਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਹ ਪ੍ਰੋਫ਼ਾਈਲ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਕਾਰਜ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਪ੍ਰੋਫਾਈਲ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਕਾਰਜ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਤੁਸੀਂ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋਂ, ਜੋ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> ਲਈ ਅਨਲੌਕ ਕੀਤੀ ਗਈ"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ਡੀਵਾਈਸ ਲੌਕ ਰਹੇਗੀ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਮੈਨੂਅਲੀ ਅਨਲੌਕ ਨਹੀਂ ਕਰਦੇ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"ਤੇਜ਼ੀ ਨਾਲ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ਅਨਲੌਕ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹਨਾਂ ਨੂੰ ਦੇਖੋ"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ਸਥਾਪਤ ਕਰੋ"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ਹੁਣੇ ਬੰਦ ਕਰੋ"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ਹੁਣੇ ਸਮਾਪਤ ਕਰੋ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ਨਸ਼ਟ ਕਰੋ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ਬੰਦ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ਪਾਵਰ ਸੂਚਨਾ ਕੰਟਰੋਲਾਂ ਨਾਲ, ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਦੀਆਂ ਸੂਚਨਾਵਾਂ ਲਈ ਮਹੱਤਤਾ ਪੱਧਰ ਨੂੰ 0 ਤੋਂ 5 ਤੱਕ ਸੈੱਟ ਕਰ ਸਕਦੇ ਹੋ। \n\n"<b>"ਪੱਧਰ 5"</b>" \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਦੀ ਆਗਿਆ ਦਿਓ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 4"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 3"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 2"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਵੀ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n\n"<b>"ਪੱੱਧਰ 1"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n- ਲੌਕ ਸਕ੍ਰੀਨ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਤੋਂ ਲੁਕਾਓ \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਹੇਠਾਂ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 0"</b>" \n- ਐਪ ਤੋਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲੌਕ ਕਰੋ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ਸੂਚਨਾਵਾਂ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ਤੁਸੀਂ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰੋਂਗੇ।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ਤੁਹਾਨੂੰ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਹੋਣਗੀਆਂ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ਇਸ ਐਪ ਵਿੱਚ ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ ਨਹੀਂ ਹਨ"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">ਇਸ ਐਪ ਤੋਂ <xliff:g id="NUMBER_1">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀ ਵਿੱਚੋਂ 1</item>
       <item quantity="other">ਇਸ ਐਪ ਤੋਂ <xliff:g id="NUMBER_1">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ ਵਿੱਚੋਂ 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ਸੂਚਨਾ ਸਨੂਜ਼ ਵਿਕਲਪ"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ਮਿੰਟ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 ਮਿੰਟ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ਘੰਟਾ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ਘੰਟੇ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ਲਈ ਸਨੂਜ਼ ਕੀਤਾ ਗਿਆ"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"ਬੈਟਰੀ ਵਰਤੋਂ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings_car.xml b/packages/SystemUI/res/values-pa/strings_car.xml
index ac38625d..1c023a3 100644
--- a/packages/SystemUI/res/values-pa/strings_car.xml
+++ b/packages/SystemUI/res/values-pa/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਗੱਡੀ ਚਲਾਓ"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ਗੱਡੀ ਚਲਾਉਣ ਦੇ ਹਾਲਾਤਾਂ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਜਾਣੂ ਰਹੋ ਅਤੇ ਸਦਾ ਲਾਗੂ ਕਾਨੂੰਨਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ। ਦਿਸ਼ਾਵਾਂ ਗਲਤ, ਅਧੂਰੀਆਂ, ਖ਼ਤਰਨਾਕ, ਢੁੱਕਵੀਆਂ ਨਹੀਂ, ਪ੍ਰਤਿਬੰਧਿਤ ਹੋ ਸਕਦੀਆਂ ਹਨ ਜਾਂ ਪ੍ਰਸ਼ਾਸਕੀ ਖੇਤਰਾਂ ਵਿੱਚੋਂ ਲੰਘਣਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ। ਵਪਾਰਕ ਜਾਣਕਾਰੀ ਵੀ ਗਲਤ ਜਾਂ ਅਧੂਰੀ ਹੋ ਸਕਦੀ ਹੈ। ਡੈਟਾ ਰੀਅਲ-ਟਾਈਮ ਨਹੀਂ ਹੈ ਅਤੇ ਟਿਕਾਣਾ ਸਟੀਕਤਾ ਗਾਰੰਟੀਸ਼ੁਦਾ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ। ਗੱਡੀ ਚਲਾਉਣ ਦੌਰਾਨ ਆਪਣੀ ਮੋਬਾਈਲ ਡੀਵਾਈਸ ਜਾਂ ਉਹਨਾਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰੋ ਜੋ ਕਿ Android Auto ਲਈ ਨਹੀਂ ਬਣੀਆਂ ਹਨ।"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ਅਗਿਆਤ"</string>
+    <string name="start_driving" msgid="864023351402918991">"ਗੱਡੀ ਚਲਾਉਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fd59150..86a6272 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -356,8 +356,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Nie będą Cię niepokoić żadne dźwięki ani wibracje z wyjątkiem alarmów, przypomnień, wydarzeń i połączeń od wybranych osób. Będziesz słyszeć wszystkie odtwarzane treści, takie jak muzyka, filmy czy gry."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Nie będą Cię niepokoić żadne dźwięki ani wibracje z wyjątkiem alarmów. Będziesz słyszeć wszystkie odtwarzane treści, takie jak muzyka, filmy czy gry."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Urządzenie nie będzie odtwarzać dźwięków ani włączać wibracji, z wyjątkiem wybranych przez Ciebie alarmów, przypomnień, wydarzeń i kontaktów."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Dostosuj"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To zablokuje WSZYSTKIE dźwięki i wibracje, w tym alarmy, muzykę, filmy i gry. Nadal będzie można wykonywać połączenia."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"To zablokuje WSZYSTKIE dźwięki i wibracje – w tym alarmy, muzykę, filmy i gry."</string>
@@ -471,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Masz połączenie z aplikacją <xliff:g id="APPLICATION">%1$s</xliff:g>, która może monitorować Twoją prywatną aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Organizacja <xliff:g id="ORGANIZATION">%1$s</xliff:g> zarządza Twoim profilem do pracy. Profil jest połączony z aplikacją <xliff:g id="APPLICATION">%2$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nSkontaktuj się z administratorem, aby uzyskać więcej informacji."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Organizacja <xliff:g id="ORGANIZATION">%1$s</xliff:g> zarządza Twoim profilem do pracy. Profil jest połączony z aplikacją <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nMasz też połączenie z aplikacją <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, która może monitorować Twoją osobistą aktywność w sieci."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odblokowano dla: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Aplikacja <xliff:g id="TRUST_AGENT">%1$s</xliff:g> jest uruchomiona"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Urządzenie pozostanie zablokowane, aż odblokujesz je ręcznie"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Szybszy dostęp do powiadomień"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zobacz powiadomienia, jeszcze zanim odblokujesz ekran"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nie, dziękuję"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Skonfiguruj"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Wyłącz teraz"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Zakończ teraz"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozwiń"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zwiń"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran jest przypięty"</string>
@@ -552,9 +553,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Wył."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dzięki zaawansowanym ustawieniom możesz określić poziom ważności powiadomień z aplikacji w skali od 0 do 5. \n\n"<b>"Poziom 5"</b>" \n– Pokazuj u góry listy powiadomień \n– Zezwalaj na powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 4"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 3"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n\n"<b>"Poziom 2"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n\n"<b>"Poziom 1"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n– Ukrywaj na ekranie blokady i pasku stanu \n– Pokazuj u dołu listy powiadomień \n\n"<b>"Poziom 0"</b>" \n– Blokuj wszystkie powiadomienia aplikacji"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Powiadomienia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nie będziesz już otrzymywać tych powiadomień."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nie będziesz już otrzymywać tych powiadomień"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie powiadomień: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacja nie ma kategorii powiadomień"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorii powiadomień z tej aplikacji</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategorii powiadomień z tej aplikacji</item>
@@ -578,12 +581,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"sterowanie powiadomieniami"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opcje odkładania powiadomień"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 min"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 godz."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 godziny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"COFNIJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odłożono na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Wykorzystanie baterii"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
diff --git a/packages/SystemUI/res/values-pl/strings_car.xml b/packages/SystemUI/res/values-pl/strings_car.xml
index dbb0373..0841e27 100644
--- a/packages/SystemUI/res/values-pl/strings_car.xml
+++ b/packages/SystemUI/res/values-pl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jedź bezpiecznie"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Androida Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Brak informacji"</string>
+    <string name="start_driving" msgid="864023351402918991">"Uruchom tryb Jazda samochodem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a8bdd91..ba62df4 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -214,10 +214,10 @@
     <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth conectado."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"O Bluetooth foi desativado."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"O Bluetooth foi ativado."</string>
-    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Relatório de localização desativado."</string>
-    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Relatório de localização ativado."</string>
-    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"O Relatório de localização foi desativado."</string>
-    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"O Relatório de localização foi ativado."</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Relatório de Localização desativado."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Relatório de Localização ativado."</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"O Relatório de Localização foi desativado."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"O Relatório de Localização foi ativado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Fechar painel."</string>
     <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Mais tempo."</string>
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Você não será perturbado por sons e vibrações, com exceção de alarmes, lembretes, eventos e autores de chamadas que você especificar."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos. Você ainda poderá fazer chamadas telefônicas."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nPara saber mais informações, entre em contato com seu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nVocê também está conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorar sua atividade pessoal de rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> está em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até que você o desbloqueie manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receba notificações mais rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Veja-as antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desligar agora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categoria de notificação deste app</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação deste app</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de adiamento de notificação"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_car.xml b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
index 5d754ef..b113ed7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_car.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições da estrada  e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a dirigir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 65b130b..796e0d3 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Os ecrãs recentes aparecem aqui"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ignorar aplicações recentes"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
-      <item quantity="one">1 ecrã na Vista geral</item>
+      <item quantity="one">%d screens in Overview</item>
       <item quantity="other">%d ecrãs na Vista geral</item>
     </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
@@ -252,7 +252,7 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
     <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
-      <item quantity="one">Mais <xliff:g id="NUMBER_0">%s</xliff:g> notificação no grupo.</item>
+      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
       <item quantity="other">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
     </plurals>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Definições de notificação"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Não é incomodado por sons e vibrações, exceto de alarmes. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos. Continua a ser possível telefonar."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o administrador para obter mais informações."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até ser desbloqueado manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receber notificações mais rapidamente"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desativar agora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Terminar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Reduzir"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"O ecrã está fixado"</string>
@@ -548,16 +549,18 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com os controlos de notificações do consumo de energia, pode definir um nível de importância de 0 a 5 para as notificações de aplicações. \n\n"<b>"Nível 5"</b>" \n- Mostrar no início da lista de notificações \n- Permitir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre \n\n"<b>"Nível 4"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre\n\n"<b>"Nível 3"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n\n"<b>"Nível 2"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n- Ocultar do ecrã de bloqueio e da barra de estado \n- Mostrar no fim da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações da aplicação"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Já não recebe estas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixará de receber estas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicação não tem categorias de notificação"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
-      <item quantity="one">1 de <xliff:g id="NUMBER_0">%d</xliff:g> categoria de notificação desta aplicação</item>
+      <item quantity="one">1 out of <xliff:g id="NUMBER_1">%d</xliff:g> notification categories from this app</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação desta aplicação</item>
     </plurals>
     <string name="notification_channels_list_desc_2" msgid="6214732715833946441">"<xliff:g id="CHANNEL_NAME_1">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2">%2$s</xliff:g>"</string>
     <plurals name="notification_channels_list_desc_2_and_others" formatted="false" msgid="2747813553355336157">
-      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_0">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_1">%2$s</xliff:g> e mais <xliff:g id="NUMBER_2">%3$d</xliff:g></item>
+      <item quantity="one"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g>, and <xliff:g id="NUMBER_5">%3$d</xliff:g> others</item>
       <item quantity="other"><xliff:g id="CHANNEL_NAME_1_3">%1$s</xliff:g>, <xliff:g id="CHANNEL_NAME_2_4">%2$s</xliff:g> e mais <xliff:g id="NUMBER_5">%3$d</xliff:g></item>
     </plurals>
     <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"Controlos de notificações da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> abertos"</string>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controlos de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de suspensão de notificações"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAR"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Suspensa por <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Utiliz. da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
@@ -718,8 +719,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimizar"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Fechar"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Arrastar para baixo para ignorar"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Menu de ecrã no ecrã"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"A aplicação <xliff:g id="NAME">%s</xliff:g> está no modo de ecrã no ecrã"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Menu de imagem na imagem"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"A aplicação <xliff:g id="NAME">%s</xliff:g> está no modo de imagem na imagem"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Se não pretende que a aplicação <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
     <string name="pip_play" msgid="1417176722760265888">"Reproduzir"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Colocar em pausa"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_car.xml b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
index afb030a..6a8b40d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_car.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduza com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se completamente atento às condições de condução e respeite sempre as leis aplicáveis. As direções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver a travessia de áreas administrativas. Os dados das empresas também podem ser imprecisos ou incompletos. Os dados não são fornecidos em tempo real e não é possível garantir a precisão da localização. Não manuseie o dispositivo móvel nem utilize aplicações não destinadas ao Android Auto durante a condução."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a conduzir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index ee90009..a621877 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/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">"Ecrã no ecrã"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imagem na imagem"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Sem título do programa)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ecrã inteiro"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a8bdd91..ba62df4 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -214,10 +214,10 @@
     <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth conectado."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"O Bluetooth foi desativado."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"O Bluetooth foi ativado."</string>
-    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Relatório de localização desativado."</string>
-    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Relatório de localização ativado."</string>
-    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"O Relatório de localização foi desativado."</string>
-    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"O Relatório de localização foi ativado."</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Relatório de Localização desativado."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Relatório de Localização ativado."</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"O Relatório de Localização foi desativado."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"O Relatório de Localização foi ativado."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Fechar painel."</string>
     <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Mais tempo."</string>
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Você não será perturbado por sons e vibrações, com exceção de alarmes, lembretes, eventos e autores de chamadas que você especificar."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos. Você ainda poderá fazer chamadas telefônicas."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nPara saber mais informações, entre em contato com seu administrador."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorar sua atividade profissional de rede, incluindo e-mails, apps e websites.\n\nVocê também está conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorar sua atividade pessoal de rede."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> está em execução"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até que você o desbloqueie manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receba notificações mais rápido"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Veja-as antes de desbloquear"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Desligar agora"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categoria de notificação deste app</item>
       <item quantity="other">1 de <xliff:g id="NUMBER_1">%d</xliff:g> categorias de notificação deste app</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opções de adiamento de notificação"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 horas"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
diff --git a/packages/SystemUI/res/values-pt/strings_car.xml b/packages/SystemUI/res/values-pt/strings_car.xml
index 5d754ef..b113ed7 100644
--- a/packages/SystemUI/res/values-pt/strings_car.xml
+++ b/packages/SystemUI/res/values-pt/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições da estrada  e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Desconhecido"</string>
+    <string name="start_driving" msgid="864023351402918991">"Começar a dirigir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5799bc3..8c39954 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -356,8 +356,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Căutați"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Glisați în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Glisați spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Se vor anunța prin sunete și vibrații numai alarmele, mementourile, evenimentele și apelanții specificați de dvs. Totuși, veți auzi tot ce alegeți să redați, inclusiv muzică, videoclipuri și jocuri."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Se vor anunța prin sunete și vibrații numai alarmele. Totuși, veți auzi tot ce alegeți să redați, inclusiv muzică, videoclipuri și jocuri."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Nu veți fi deranjat(ă) de sunete și vibrații, exceptând alarmele, mementourile, evenimentele și apelanții pe care îi menționați."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizați"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor. Totuși, veți putea iniția apeluri."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Această opțiune blochează TOATE sunetele și vibrațiile, inclusiv cele ale alarmelor, muzicii, videoclipurilor și jocurilor."</string>
@@ -471,13 +470,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"V-ați conectat la aplicația <xliff:g id="APPLICATION">%1$s</xliff:g>, care vă poate monitoriza activitatea personală în rețea, inclusiv e-mailurile, aplicațiile și site-urile accesate."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profilul de serviciu este gestionat de <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilul este conectat la <xliff:g id="APPLICATION">%2$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua de serviciu, inclusiv e-mailurile, aplicațiile și site-urile accesate.\n\nPentru mai multe informații, contactați administratorul."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profilul de serviciu este gestionat de <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilul este conectat la <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua de serviciu, inclusiv e-mailurile, aplicațiile și site-urile accesate.\n\nDe asemenea, v-ați conectat la <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, care vă poate monitoriza activitatea în rețeaua personală."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Deblocat pentru <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> rulează"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Dispozitivul va rămâne blocat până când îl deblocați manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Obțineți notificări mai rapid"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Doresc să se afișeze înainte de deblocare"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nu, mulț."</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Config."</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Dezactivați acum"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Opriți acum"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Extindeți"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Restrângeți"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ecranul este fixat"</string>
@@ -552,9 +553,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Dezactivate"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Folosind comenzile de gestionare a notificărilor, puteți să setați un nivel de importanță de la 0 la 5 pentru notificările unei aplicații. \n\n"<b>"Nivelul 5"</b>" \n– Se afișează la începutul listei de notificări \n– Se permite întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 4"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 3"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n\n"<b>"Nivelul 2"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n\n"<b>"Nivelul 1"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n– Se ascunde în ecranul de blocare și în bara de stare \n– Se afișează la finalul listei de notificări \n\n"<b>"Nivelul 0"</b>" \n– Se blochează toate notificările din aplicație"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificări"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nu veți mai primi aceste notificări."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nu veți mai primi aceste notificări"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorii de notificări"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Această aplicație nu are categorii de notificare"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 din <xliff:g id="NUMBER_1">%d</xliff:g> categorii de notificare din această aplicație</item>
       <item quantity="other">1 din <xliff:g id="NUMBER_1">%d</xliff:g> de categorii de notificare din această aplicație</item>
@@ -576,12 +579,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"comenzile notificării"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opțiuni de amânare a notificării"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 de minute"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oră"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ore"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAȚI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Amânată <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizarea bateriei"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
@@ -724,7 +725,7 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimizați"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Închideți"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Trageți în jos pentru a închide"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Meniul picture-in-picture"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Meniul imagine în imagine"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> este în modul picture-in-picture"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Dacă nu doriți ca <xliff:g id="NAME">%s</xliff:g> să utilizeze această funcție, atingeți pentru a deschide setările și dezactivați-o."</string>
     <string name="pip_play" msgid="1417176722760265888">"Redați"</string>
diff --git a/packages/SystemUI/res/values-ro/strings_car.xml b/packages/SystemUI/res/values-ro/strings_car.xml
index 54d8585..27751f6 100644
--- a/packages/SystemUI/res/values-ro/strings_car.xml
+++ b/packages/SystemUI/res/values-ro/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduceți atent"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Aflați mereu condițiile de trafic și respectați întotdeauna legislația aplicabilă. Indicațiile de orientare pot fi inexacte, incomplete, periculoase, neadecvate, interzise sau pot implica trecerea prin zone administrative. Informațiile despre companii pot fi, de asemenea, inexacte sau incomplete. Datele nu sunt în timp real și nu se poate garanta exactitatea locației. Nu manipulați dispozitivul mobil și nu folosiți aplicații neconcepute pentru Android Auto când sunteți la volan."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Necunoscut"</string>
+    <string name="start_driving" msgid="864023351402918991">"Începeți să conduceți"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2fa3ad2..956179e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -358,8 +358,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Настроить"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео). При этом вы сможете разговаривать по телефону."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео)."</string>
@@ -473,13 +472,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Запущено приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\", которое может отслеживать ваши действия в сети, включая работу с электронной почтой, приложениями и веб-сайтами."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Вашим рабочим профилем управляет организация \"<xliff:g id="ORGANIZATION">%1$s</xliff:g>\". Приложение \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" может отслеживать ваши действия в корпоративной сети, включая работу с электронной почтой, приложениями и веб-сайтами.\n\nЧтобы получить подробную информацию, обратитесь к администратору."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Вашим рабочим профилем управляет организация \"<xliff:g id="ORGANIZATION">%1$s</xliff:g>\". Приложение \"<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>\" может отслеживать ваши действия в корпоративной сети, включая работу с электронной почтой, приложениями и веб-сайтами.\n\nТакже запущено приложение \"<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>\", которое может отслеживать ваши действия в сети, выполняемые в личном профиле."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Разблокировано для пользователя <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Агент \"<xliff:g id="TRUST_AGENT">%1$s</xliff:g>\" работает"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Устройство необходимо будет разблокировать вручную"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Быстрый доступ к уведомлениям"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Просматривайте уведомления на заблокированном экране."</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Закрыть"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Настроить"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Отключить"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Завершить"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Развернуть"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Свернуть"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Блокировка в приложении включена"</string>
@@ -554,9 +555,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Отключено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощью этой функции вы можете устанавливать уровень важности уведомлений от 0 до 5 для каждого приложения.\n\n"<b>"Уровень 5"</b>\n"‒ Помещать уведомления в начало списка.\n‒ Показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 4\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 3\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\nУровень 2\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\nУровень 1\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\n‒ Не показывать на экране блокировки и в строке состояния.\n‒ Помещать уведомления в конец списка.\nУровень 0\n"<b></b>\n"‒ Блокировать все уведомления приложения."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Уведомления"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больше не будете получать эти уведомления."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больше не будете получать эти уведомления"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорий оповещений: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"В приложении нет категорий уведомлений"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 из <xliff:g id="NUMBER_1">%d</xliff:g> категории уведомлений этого приложения</item>
       <item quantity="few">1 из <xliff:g id="NUMBER_1">%d</xliff:g> категорий уведомлений этого приложения</item>
@@ -580,12 +583,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g>: <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"настройки уведомлений"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметры отсрочки уведомлений"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 часа"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЕНИТЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Уровень заряда"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
diff --git a/packages/SystemUI/res/values-ru/strings_car.xml b/packages/SystemUI/res/values-ru/strings_car.xml
index cbdb8d7..f697cbd 100644
--- a/packages/SystemUI/res/values-ru/strings_car.xml
+++ b/packages/SystemUI/res/values-ru/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Безопасность движения"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Всегда учитывайте дорожную обстановку и соблюдайте правила. Маршруты могут быть неточными, неполными, проходить по опасным, неподходящим или запрещенным для движения участкам или пересекать границы. Сведения об организациях также могут быть неточными и неполными. Данные не обновляются в режиме реального времени, и точность определения местоположения не гарантируется. Не пользуйтесь мобильным устройством и не используйте приложения, не предназначенные для Android Auto, управляя автомобилем."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Неизвестный пользователь"</string>
+    <string name="start_driving" msgid="864023351402918991">"Запустить навигацию"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c8865ae..b6743e1 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"සෙවීම"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා උඩට සර්පණය කරන්න."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා වමට සර්පණය කරන්න."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"එලාම සිහිකැඳවීම්, සිදුවීම්, සහ ඔබ සඳහන් කළ අමතන්නන් හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත. සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු ඔබ වාදනය කිරීමට තෝරන ලද සියලු දේ ඔබට තවම ඇසෙනු ඇත."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"එලාම හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත. සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු ඔබ වාදනය කිරීමට තෝරන ලද සියලු දේ ඔබට තවම ඇසෙනු ඇත."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"එලාම, සිහිකැඳවීම්, සිදුවීම් සහ ඔබ සඳහන් කරන අමතන්නන් වෙතින් හැර, ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"අභිරුචිකරණය"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"මෙය එලාම්, සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි. ඔබට තවමත් දුරකථන ඇමතුම් ගැනීමට හැකියාව ඇත."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"මෙය එලාම්, සංගීතය, වීඩියෝ, සහ ක්‍රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ පෞද්ගලික ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ඔබ සම්බන්ධ වී ඇත."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"ඔබේ කාර්ය පැතිකඩ කළමනාකරණය කරන්නේ <xliff:g id="ORGANIZATION">%1$s</xliff:g> මගිනි. ඔබේ ඊ-තැපැල්, යෙදුම්, සහ වෙබ් අඩවි ඇතුළු, ඔබේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION">%2$s</xliff:g> වෙත පැතිකඩ සම්බන්ධය.\n\nවැඩිදුර තොරතුරු සඳහා, ඔබගේ පරිපාලක අමතන්න."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"ඔබේ කාර්යාල පැතිකඩ කළමනාකරණය කරන්නේ <xliff:g id="ORGANIZATION">%1$s</xliff:g> විසිනි. ඊ-තැපැල්, යෙදුම් සහ වෙබ් අඩවි ඇතුළු ඔබේ කාර්යාල ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, වෙත පැතිකඩ සම්බන්ධ වී ඇත.\n\nඔබ ඔබේ පෞද්ගලික ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කළ හැකි, <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> වෙතද සම්බන්ධ වී ඇත."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> සඳහා අගුලු හරින ලදී"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ධාවනය වේ"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ඔබ අතින් අගුළු අරින තුරු උපකරණය අගුළු වැටි තිබේ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"දැනුම්දීම් ඉක්මනින් ලබාගන්න"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ඔබ අඟුළු හැරීමට කලින් ඒවා බලන්න"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"එපා ස්තූතියි"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"සකසන්න"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"දැන් ක්‍රියාවිරහිත කරන්න"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"දැන් අවසන් කරන්න"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"දිග හරින්න"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"හකුළන්න"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"තීරය අමුණන ලදි"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ක්‍රියාවිරහිතයි"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"බල දැනුම්දීම් පාලන සමගින්, ඔබට යෙදුමක දැනුම්දීම් සඳහා වැදගත්කම 0 සිට 5 දක්වා සැකසිය හැකිය. \n\n"<b>"5 මට්ටම"</b>" \n- දැනුම්දීම් ලැයිස්තුවේ ඉහළින්ම පෙන්වන්න \n- පූර්ණ තිර බාධාවට ඉඩ දෙන්න \n- සැම විට එබී බලන්න \n\n"<b>"4 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- සැම විට එබී බලන්න \n\n"<b>"3 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n\n"<b>"2 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n\n"<b>"1 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n- අගුලු තිරය සහ තත්ත්ව තීරුව වෙතින් සඟවන්න \n- දැනුම්දීම් ලැයිස්තුවේ පහළින්ම පෙන්වන්න \n\n"<b>"0 මට්ටම"</b>" \n- යෙදුම වෙතින් වන සියලු දැනුම් දීම් සඟවන්න."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"දැනුම් දීම්"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ඔබ තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ඔබට තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"දැනුම්දීම් කාණ්ඩ <xliff:g id="NUMBER">%d</xliff:g>ක්"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"මෙම යෙදුම හට දැනුම්දීම් ප්‍රවර්ග නොමැත"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">මෙම යෙදුමෙන් දැනුම්දීම් ප්‍රවර්ග <xliff:g id="NUMBER_1">%d</xliff:g>න් 1ක්</item>
       <item quantity="other">මෙම යෙදුමෙන් දැනුම්දීම් ප්‍රවර්ග <xliff:g id="NUMBER_1">%d</xliff:g>න් 1ක්</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"දැනුම්දීම් පාලන"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"දැනුම්දීම් මදක් නතර කිරීමේ විකල්ප"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"මිනිත්තු 15"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"මිනිත්තු 30"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"පැය 1"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"පැය 2"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"අස් කරන්න"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ක් මදක් නතර කරන ලදී"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"බැටරි භාවිතය"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
diff --git a/packages/SystemUI/res/values-si/strings_car.xml b/packages/SystemUI/res/values-si/strings_car.xml
index 549e89b..14ec53b 100644
--- a/packages/SystemUI/res/values-si/strings_car.xml
+++ b/packages/SystemUI/res/values-si/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ආරක්ෂිතව රිය පදවන්න"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"රිය පැදවීම් තත්ත්වයන් ගැන පූර්ණ අවධානයෙන් සිටින්න, සැම විටම අදාළ සියලු නීතිවලට ගරු කරන්න. මග පෙන්වීම් නිවැරදි නොවීමට, අසම්පූර්ණ වීමට, භයානක වීමට, නුසුදුසු වීමට, තහනම් ඒවා වීමට, හෝ පරිපාලන ප්‍රදේශ තරණයට අදාළ ඒවා වීමට හැකිය. දත්ත තථ්‍ය කාල නොවීමට හැකි අතර, ස්ථාන නිරවද්‍යතාව සහතික කළ නොහැකිය. රිය පදවන අතරතුර ඔබේ ජංගම උපාංගය භාවිත කිරීම හෝ Android Auto සඳහා නිපදවා නැති යෙදුම් භාවිත කිරීම නොකරන්න."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"නොදනී"</string>
+    <string name="start_driving" msgid="864023351402918991">"රිය පැදවීම ආරම්භ කරන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0741d84..d102dda 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -66,7 +66,7 @@
     <string name="usb_debugging_message" msgid="2220143855912376496">"Digitálny odtlačok RSA počítača je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Vždy povoliť z tohto počítača"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ladenie cez USB nie je povolené"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Používateľ, ktorý je práve prihlásený na tomto zariadení, nemôže zapnúť ladenie cez USB. Ak chcete použiť túto funkciu, prepnite na používateľa s oprávneniami správcu."</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Používateľ, ktorý je práve prihlásený na tomto zariadení, nemôže zapnúť ladenie USB. Ak chcete použiť túto funkciu, prepnite na používateľa s oprávneniami správcu."</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Priblížiť na celú obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celú obrazovku"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Prebieha ukladanie snímky obrazovky..."</string>
@@ -358,8 +358,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Nebudú vás vyrušovať zvuky ani vibrácie, iba budíky, pripomenutia, udalosti a volajúci, ktorých určíte. Budete naďalej počuť všetko, čo sa rozhodnete prehrať, ako napríklad hudbu, videá a hry."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Nebudú vás vyrušovať zvuky ani vibrácie, iba budíky. Budete naďalej počuť všetko, čo sa rozhodnete prehrať, ako napríklad hudbu, videá a hry."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudú vás rušiť zvuky ani vibrácie s výnimkou budíkov, pripomenutí, udalostí a vybraných volajúcich."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prispôsobiť"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Budú zablokované všetky zvuky a vibrácie vrátane budíkov, hudby, videí a hier. Stále však budete môcť telefonovať."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier."</string>
@@ -473,13 +472,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ste pripojený/-á k aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g>, ktorá môže sledovať vašu osobnú aktivitu v sieti vrátane e-mailových správ, aplikácií a webových stránok."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Váš pracovný profil spravuje organizácia <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je pripojený k aplikácii <xliff:g id="APPLICATION">%2$s</xliff:g>, ktorá môže sledovať vašu pracovnú aktivitu v sieti vrátane správ, aplikácií a webových stránok.\n\nĎalšie informácie vám poskytne správca."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Váš pracovný profil spravuje organizácia <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Je pripojený k aplikácii <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ktorá môže sledovať vašu pracovnú aktivitu v sieti vrátane správ, aplikácií a webových stránok.\n\nPripojili ste sa k aplikácii <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ktorá môže sledovať vašu osobnú aktivitu v sieti."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odomknuté pre používateľa <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Agent <xliff:g id="TRUST_AGENT">%1$s</xliff:g> je spustený"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Zariadenie zostane uzamknuté, dokým ho ručne neodomknete."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Získavať upozornenia rýchlejšie"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zobraziť pred odomknutím"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nie, vďaka"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Nastaviť"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Vypnúť"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Skončiť"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbaliť"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zbaliť"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je pripnutá"</string>
@@ -554,9 +555,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuté"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomocou ovládacích prvkov zobrazovania upozornení môžete nastaviť pre upozornenia aplikácie úroveň dôležitosti od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazovať v hornej časti zoznamu upozornení. \n– Povoliť prerušenia na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 4"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 3"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n\n"<b>"Úroveň 2"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n\n"<b>"Úroveň 1"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n– Skryť na uzamknutej obrazovke a v stavovom riadku. \n– Zobraziť v dolnej časti zoznamu upozornení. \n\n"<b>"Úroveň 0"</b>" \n– Blokovať všetky upozornenia z aplikácie."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Upozornenia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Takéto upozornenia už nebudete dostávať."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tieto upozornenia už nebudete dostávať"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Počet kategórií upozornení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Táto aplikácia nemá kategórie upozornení"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="few">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategórií upozornení z tejto aplikácie</item>
       <item quantity="many">1 z <xliff:g id="NUMBER_1">%d</xliff:g> kategórie upozornení z tejto aplikácie</item>
@@ -580,12 +583,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ovládacie prvky pre upozornenia"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"možnosti stlmenia upozornení"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minút"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minút"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hod."</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 hodiny"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"SPÄŤ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Stlmené na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Využitie batérie"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
@@ -728,8 +729,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimalizovať"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Zavrieť"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Zrušíte presunutím nadol"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Ponuka režimu obraz v obraze"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je v režime obraz v obraze"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Ponuka obrazu v obraze"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> je na obraze v obraze"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Ak nechcete, aby aplikácia <xliff:g id="NAME">%s</xliff:g> používala túto funkciu, klepnutím otvorte nastavenia a vypnite ju."</string>
     <string name="pip_play" msgid="1417176722760265888">"Prehrať"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Pozastaviť"</string>
diff --git a/packages/SystemUI/res/values-sk/strings_car.xml b/packages/SystemUI/res/values-sk/strings_car.xml
index bd9410d..6512065 100644
--- a/packages/SystemUI/res/values-sk/strings_car.xml
+++ b/packages/SystemUI/res/values-sk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jazdite bezpečne"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Zachovajte si úplný prehľad o jazdných podmienkach a vždy dodržiavajte príslušné zákony. Trasy môžu byť nepresné, neúplné, nebezpečné, nevhodné, zakázané alebo môžu zahŕňať cestu cez rôzne správne oblasti. Obchodné informácie môžu byť tiež nepresné alebo neúplné. Údaje nie sú aktualizované v reálnom čase a presnosť polohy nemôžeme zaručiť. Počas jazdy nemanipulujte s mobilným zariadením ani nepoužívajte aplikácie, ktoré nie sú určené pre funkciu Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznáme"</string>
+    <string name="start_driving" msgid="864023351402918991">"Začať šoférovať"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8289516..f61049d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -358,8 +358,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Ne bodo vas motili zvoki ali tresenje, razen od alarmov, opomnikov, dogodkov in klicateljev, ki jih določite. Še vedno pa boste slišali vse, kar se boste odločili predvajati, vključno z glasbo, videoposnetki in igrami."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Ne bodo vas motili zvoki ali tresenje, razen alarmov. Še vedno pa boste slišali vse, kar se boste odločili predvajati, vključno z glasbo, videoposnetki in igrami."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Ne bodo vas motili zvoki in vibriranje, razen od alarmov, opomnikov, dogodkov in klicateljev, ki jih določite."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger. Še vedno boste lahko opravljali telefonske klice."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger."</string>
@@ -473,13 +472,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nZa več informacij se obrnite na skrbnika."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profil je povezan z aplikacijo <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nPovezani ste tudi z aplikacijo <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Odklenjeno za uporabnika <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> se izvaja"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Naprava bo ostala zaklenjena, dokler je ročno ne odklenete."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Hitrejše prejemanje obvestil"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Oglejte si jih pred odklepanjem"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Nastavitev"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Izklopi"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Končaj zdaj"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Razširi"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Strni"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je pripet"</string>
@@ -554,9 +555,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izklopljeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"S kontrolniki za pomebnost obvestila je mogoče za obvestila aplikacije nastaviti stopnjo pomembnosti od 0 do 5. \n\n"<b>"Stopnja 5"</b>" \n– Prikaz na vrhu seznama obvestil \n– Omogočanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 4"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 3"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n\n"<b>"Stopnja 2"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n\n"<b>"Stopnja 1"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n– Skrivanje na zaklenjenem zaslonu in v vrstici stanja \n– Prikaz na dnu seznama obvestil \n\n"<b>"Stopnja 0"</b>" \n– Blokiranje vseh obvestil aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obvestila"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Teh obvestil ne boste več prejemali."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Teh obvestil ne boste več prejemali"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Št. kategorij obvestil: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacija nima kategorij obvestil"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorije obvestil iz te aplikacije</item>
       <item quantity="two">1 od <xliff:g id="NUMBER_1">%d</xliff:g> kategorij obvestil iz te aplikacije</item>
@@ -580,12 +583,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrolniki obvestil"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"možnosti preložitve obvestil"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ura"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 uri"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"RAZVELJAVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Preloženo za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Poraba akumulatorja"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
diff --git a/packages/SystemUI/res/values-sl/strings_car.xml b/packages/SystemUI/res/values-sl/strings_car.xml
index 0102799..8e05730 100644
--- a/packages/SystemUI/res/values-sl/strings_car.xml
+++ b/packages/SystemUI/res/values-sl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Varna vožnja"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bodite pozorni na vozne razmere in vselej upoštevajte veljavno zakonodajo. Navodila za pot so morda nenatančna, nepopolna, nevarna, neprimerna ali prepovedana oziroma vključujejo prečkanje upravnih območij. Prav tako nenatančni ali nepopolni so lahko podatki o podjetjih. Podatki niso sprotni in natančnosti lociranja ni mogoče zagotoviti. Med vožnjo ne uporabljajte mobilne naprave ali aplikacij, ki niso namenjene za Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Neznano"</string>
+    <string name="start_driving" msgid="864023351402918991">"Začnite voziti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 15cc542..1ad24eb 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Kërko"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Rrëshqit lart për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Rrëshqit majtas për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç alarmeve, alarmeve rikujtuese, ngjarjeve dhe telefonuesve që specifikon. Do të vazhdosh të dëgjosh gjithçka që zgjedh të luash duke përfshirë muzikën, videot dhe lojërat."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç alarmeve. Do të vazhdosh të dëgjosh gjithçka që zgjedh të luash duke përfshirë muzikën, videot dhe lojërat."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç atyre nga alarmet, rikujtesat, ngjarjet dhe telefonuesit që specifikon."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizo"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat. Përsëri do të mund të bësh telefonata."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd personal në rrjet, përfshirë mailet, aplikacionet dhe sajtet e uebit."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profili është i lidhur me <xliff:g id="APPLICATION">%2$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd të punës në rrjet, duke përfshirë mail-et, aplikacionet dhe sajtet e uebit.\n\nPër më shumë informacione, kontakto me administratorin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profili është i lidhur me <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd të punës në rrjet, duke përfshirë mail-et, aplikacionet dhe sajtet e uebit.\n\nJe lidhur gjithashtu edhe me <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, i cili mund të monitorojë aktivitetin tënd personal në rrjet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Shkyçur për <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> po ekzekutohet"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Pajisje do të qëndrojë e kyçur derisa ta shkyçësh manualisht"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Merr njoftime më shpejt"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Shikoji para se t\'i shkyçësh"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Jo, faleminderit!"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfiguro"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Çaktivizoje tani"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Përfundo tani"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zgjeroje"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Mbylle"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrani u gozhdua"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Joaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Me kontrollet e njoftimit të energjisë, mund të caktosh një nivel rëndësie nga 0 në 5 për njoftimet e një aplikacioni. \n\n"<b>"Niveli 5"</b>" \n- Shfaq në krye të listës së njoftimeve \n- Lejo ndërprerjen e ekranit të plotë \n- Gjithmonë shfaq shpejt \n\n"<b>"Niveli 4"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Gijthmonë shfaq shpejt \n\n"<b>"Niveli 3"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n\n"<b>"Niveli 2"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull dhe dridhje \n\n"<b>"Niveli 1"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull ose dridhje \n- Fshih nga ekrani i kyçjes dhe shiriti i statusit \n- Shfaq në fund të listës së njoftimeve \n\n"<b>"Niveli 0"</b>" \n- Blloko të gjitha njoftimet nga aplikacioni"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Njoftime"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Këto njoftime nuk do t\'i marrësh më."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Këto njoftime nuk do t\'i marrësh më"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori njoftimesh"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ky aplikacion nuk ka kategori njoftimesh"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 nga <xliff:g id="NUMBER_1">%d</xliff:g> kategori njoftimi nga ky aplikacion</item>
       <item quantity="one">1 nga <xliff:g id="NUMBER_0">%d</xliff:g> kategori njoftimi nga ky aplikacion</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"kontrollet e njoftimit"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"opsionet e shtyrjes së njoftimit"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 orë"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 orë"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ZHBËJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"U shty për <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Përdorimi i baterisë"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
diff --git a/packages/SystemUI/res/values-sq/strings_car.xml b/packages/SystemUI/res/values-sq/strings_car.xml
index 2e63877..b3a52b8 100644
--- a/packages/SystemUI/res/values-sq/strings_car.xml
+++ b/packages/SystemUI/res/values-sq/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drejtoje makinën në mënyrë të sigurt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ji plotësisht i vetëdijshëm për kushtet e lëvizjes me makinë dhe respekto gjithmonë ligjet përkatëse. Udhëzimet mund të jenë të pasakta, jo të plota, të rrezikshme, të papërshtatshme, të ndaluara ose mund të përfshijnë kalimin në zona administrative. Informacionet e biznesit mund të jenë po ashtu të pasakta ose jo të plota. Të dhënat nuk janë në kohë reale dhe saktësia e vendndodhjes nuk mund të garantohet. Gjatë drejtimit të makinës mos e përdor pajisjen celulare ose mos përdor aplikacionet që nuk janë të planifikuara për Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"E panjohur"</string>
+    <string name="start_driving" msgid="864023351402918991">"Fillo të drejtosh makinën"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4ef7267..163a09d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Неће вас узнемиравати звукови и вибрације осим за аларме, подсетнике, догађаје и позиваоце које наведете. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Неће вас узнемиравати звукови и вибрације осим за аларме. И даље ћете чути све што одаберете да пустите, укључујући музику, видео снимке и игре."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Неће вас узнемиравати звукови и вибрације, осим за аларме, подсетнике, догађаје и позиваоце које изаберете."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Прилагоди"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Повезани сте са апликацијом <xliff:g id="APPLICATION">%1$s</xliff:g>, која може да надгледа активности на личној мрежи, укључујући имејлове, апликације и веб-сајтове."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Профилом за Work управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Повезан је са апликацијом <xliff:g id="APPLICATION">%2$s</xliff:g>, која може да надгледа активности на пословној мрежи, укључујући имејлове, апликације и веб-сајтове.\n\nВише информација потражите од администратора."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Профилом за Work управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Повезан је са апликацијом <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, која може да надгледа активности на пословној мрежи, укључујући имејлове, апликације и веб-сајтове.\n\nПовезани сте и са апликацијом <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, која може да надгледа активности на личној мрежи."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Откључано за корисника <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Функција <xliff:g id="TRUST_AGENT">%1$s</xliff:g> је покренута"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Уређај ће остати закључан док га не откључате ручно"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Брже добијајте обавештења"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Прегледајте их пре откључавања"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Не, хвала"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Активирај"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Искључи одмах"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Прекини одмах"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Скупи"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екран је закачен"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Искључено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Обавештења"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Више нећете да добијате ова обавештења."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Више нећете добијати ова обавештења"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорија обавештења: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ова апликација нема категорије обавештења"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорије обавештења за ову апликацију</item>
       <item quantity="few">1 од <xliff:g id="NUMBER_1">%d</xliff:g> категорије обавештења за ову апликацију</item>
@@ -574,12 +577,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"контроле обавештења"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"опције за одлагање обавештења"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минута"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 минута"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сат"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 сата"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ОПОЗОВИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Потрошња батерије"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
diff --git a/packages/SystemUI/res/values-sr/strings_car.xml b/packages/SystemUI/res/values-sr/strings_car.xml
index 7f99120..88e2714 100644
--- a/packages/SystemUI/res/values-sr/strings_car.xml
+++ b/packages/SystemUI/res/values-sr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возите безбедно"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Увек водите рачуна о условима вожње и увек поштујте примењиве законе. Упутства могу да буду нетачна, непотпуна, опасна, неприкладна или забрањена, односно да подразумевају прелазак између административних области. И подаци о предузећу могу да буду нетачни или непотпуни. Подаци не настају у реалном времену и не можемо да гарантујемо прецизност локације. Немојте да употребљавате мобилни уређај нити да користите апликације које нису намењене за Android Auto током вожње."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Непознато"</string>
+    <string name="start_driving" msgid="864023351402918991">"Почните да возите"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a479bea..b6e5434 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, event och specifika samtal. Ljudet är fortfarande på för sådant du väljer att spela upp, till exempel musik, videor och spel."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Du blir inte störd av ljud och vibrationer, förutom från alarm. Ljudet är fortfarande på för sådant du väljer att spela upp, till exempel musik, videor och spel."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, event och specifika samtal."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassa"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel. Du kan fortfarande ringa."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Du är ansluten till <xliff:g id="APPLICATION">%1$s</xliff:g> som kan övervaka din privata aktivitet på nätverket, inklusive e-postmeddelanden, appar och webbplatser."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Jobbprofilen hanteras av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen är ansluten till <xliff:g id="APPLICATION">%2$s</xliff:g> som kan bevaka din nätverksaktivitet, exempelvis e-post, appar och webbplatser.\n\nKontakta administratören om du vill veta mer."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Jobbprofilen hanteras av <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Profilen är ansluten till <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> som kan bevaka din nätverksaktivitet på jobbet, exempelvis e-post, appar och webbplatser.\n\nDu är även ansluten till <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> som kan bevaka din privata nätverksaktivitet."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Upplåst för <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> körs"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten förblir låst tills du låser upp den manuellt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Få aviseringar snabbare"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Visa dem innan du låser upp"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nej tack"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfig."</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Inaktivera nu"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Sluta nu"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utöka"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Komprimera"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skärmen har fästs"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"På"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med aviseringsinställningarna kan du ange prioritetsnivå från 0 till 5 för aviseringar från en app. \n\n"<b>"Nivå 5"</b>" \n– Visa högst upp i aviseringslistan\n– Tillåt avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 4"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 3"</b>" \n- Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n\n"<b>"Nivå 2"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n\n"<b>"Nivå 1"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n– Visa inte på låsskärmen och i statusfältet \n– Visa längst ned i aviseringslistan \n\n"<b>"Nivå 0"</b>" \n– Blockera alla aviseringar från appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Aviseringar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Inga fler aviseringar av det här slaget visas."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Inga fler aviseringar av det här slaget visas"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> aviseringskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Det finns inga aviseringskategorier i appen"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 av <xliff:g id="NUMBER_1">%d</xliff:g> aviseringskategorier från denna app</item>
       <item quantity="one">1 av <xliff:g id="NUMBER_0">%d</xliff:g> aviseringskategorier från denna app</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"inställningar för aviseringar"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"alternativ för att snooza aviseringar"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuter"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuter"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 timme"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 timmar"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ÅNGRA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozad i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriförbrukning"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
diff --git a/packages/SystemUI/res/values-sv/strings_car.xml b/packages/SystemUI/res/values-sv/strings_car.xml
index 0c03fb6..25b1136 100644
--- a/packages/SystemUI/res/values-sv/strings_car.xml
+++ b/packages/SystemUI/res/values-sv/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kör försiktigt"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Håll koll på trafik- och körförhållanden och följ gällande lagar. Det kan hända att vägbeskrivningen inte stämmer, att den är ofullständig, farlig, olämplig, förbjuden eller att den innebär att du måste korsa en administrativ enhet. Det kan även hända att företagsuppgifter är felaktiga eller ofullständiga. Uppgifter visas inte i realtid och det går inte att garantera att platsen är korrekt. Hantera inte din mobila enhet och använd inte appar som inte är ämnade för Android Auto medan du kör."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Okänt"</string>
+    <string name="start_driving" msgid="864023351402918991">"Börja köra"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 462b1ed..b51f442 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -240,7 +240,7 @@
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Inachaji"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data ya 2G-3G imesitishwa"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data ya 4G imesitishwa"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Data ya mtandao wa simu imesitishwa"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Data ya simu imesitishwa"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Data imesitishwa"</string>
     <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Umefikia kikomo cha data ulichoweka. Hutumii tena data ya simu.\n\nUkiendelea, huenda ukatozwa ada ya matumizi ya data."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Endelea"</string>
@@ -315,7 +315,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Mtandao-hewa"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Arifa"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Tochi"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data ya mtandao wa simu"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data ya simu"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Matumizi ya data"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Data iliyosalia"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Imezidi kikomo"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na watu wanaokupigia simu ambao umechagua. Bado utasikia chochote utakachochagua kucheza, ikiwa ni pamoja na muziki, video na michezo."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele. Bado utasikia chochote utakachochagua kucheza, ikiwa ni pamoja na muziki, video na michezo."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na wapigaji simu utakaobainisha."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Badilisha upendavyo"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa ni pamoja na ile inayotokana na kengele, muziki, video na michezo. Bado utaweza kupiga simu."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa ni pamoja na ile inayotokana na kengele, muziki, video na michezo."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Umeunganishwa kwenye <xliff:g id="APPLICATION">%1$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako, ikiwa ni pamoja na barua pepe, programu na tovuti."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Wasifu wako wa kazini unasimamiwa na <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Wasifu umeunganishwa kwenye <xliff:g id="APPLICATION">%2$s</xliff:g>, ambayo inaweza kufuatilia shughuli za mtandao wako wa kazini, ikiwa ni pamoja na barua pepe, programu na tovuti.\n\n Wasiliana na msimamizi wako kwa maelezo zaidi."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Wasifu wako wa kazini unasimamiwa na <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Wasifu umeunganishwa kwenye <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ambayo inaweza kufuatilia shughuli zako kwenye mtandao wa kazini, ikiwa ni pamoja na barua pepe, programu na tovuti.\n\n Umeunganishwa pia kwenye  <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ambayo inaweza kufuatilia shughuli zako kwenye mtandao wa binafsi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Imefunguliwa kwa ajili ya <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> inatumika"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Kifaa kitaendelea kuwa katika hali ya kufungwa hadi utakapokifungua mwenyewe"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Pata arifa kwa haraka"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Zitazame kabla hujafungua"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Hapana, asante"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Sanidi"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Zima sasa"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Komesha sasa"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Panua"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Kunja"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skrini imebandikwa"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Imezimwa"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ukiwa na udhibiti wa arifa, unaweza kuweka kiwango cha umuhimu wa arifa za programu kuanzia 0 hadi 5. \n\n"<b>"Kiwango cha 5"</b>" \n- Onyesha katika sehemu ya juu ya orodha ya arifa \n- Ruhusu ukatizaji wa skrini nzima \n- Ruhusu arifa za kuchungulia kila wakati\n\n"<b>"Kiwango cha 4"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Ruhusu arifa za kuchungulia kila wakati \n\n"<b>"Kiwango cha 3"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia\n\n"<b>"Kiwango cha 2"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti au mtetemo \n\n"<b>"Kiwango cha 1"</b>" \n- Zuia ukatizaji wa skrini nzima \n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti na mtetemo \n- Usionyeshe skrini iliyofungwa na sehemu ya arifa \n- Onyesha katika sehemu ya chini ya orodha ya arifa \n\n"<b>"Kiwango cha 0"</b>" \n- Zuia arifa zote kutoka programu"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Arifa"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hutapokea arifa hizi tena."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hutapokea arifa hizi tena"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Aina <xliff:g id="NUMBER">%d</xliff:g> za arifa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Programu hii haina aina za arifa"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Aina 1 ya arifa kati ya <xliff:g id="NUMBER_1">%d</xliff:g> kutoka kwenye kifaa hiki</item>
       <item quantity="one">Aina 1 ya arifa kati ya <xliff:g id="NUMBER_0">%d</xliff:g> kutoka kwenye kifaa hiki</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"vidhibiti vya arifa"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"chaguo za kuahirisha arifa"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"Dakika 15"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"Dakika 30"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"Saa 1"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"Saa 2"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"TENDUA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Imeahirishwa kwa <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Matumizi ya betri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
@@ -719,7 +720,7 @@
     <string name="pip_phone_close" msgid="8416647892889710330">"Funga"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Buruta ili uondoe"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"Menyu ya picha ndani ya picha"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> iko katika hali ya picha ndani ya picha nyingine"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> iko katika picha ndani ya picha"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"Ikiwa hutaki <xliff:g id="NAME">%s</xliff:g> kutumia kipengele hiki, gonga ili ufungue mipangilio na ukizime."</string>
     <string name="pip_play" msgid="1417176722760265888">"Cheza"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Sitisha"</string>
@@ -753,7 +754,7 @@
     <string name="instant_apps_message" msgid="8116608994995104836">"Huhitaji kusakinisha programu zinazofunguka papo hapo."</string>
     <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Nenda kwenye wavuti"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"Data ya mtandao wa simu"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"Data ya simu"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi imezimwa"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth imezimwa"</string>
     <string name="dnd_is_off" msgid="6167780215212497572">"Kipengele cha Usinisumbue kimezimwa"</string>
diff --git a/packages/SystemUI/res/values-sw/strings_car.xml b/packages/SystemUI/res/values-sw/strings_car.xml
index e4bb25c..319f882 100644
--- a/packages/SystemUI/res/values-sw/strings_car.xml
+++ b/packages/SystemUI/res/values-sw/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Endesha gari kwa usalama"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Jifahamishe kikamilifu kuhusu masharti ya kuendesha gari na utii kila wakati sheria zilizopo. Huenda maelekezo yasiwe sahihi, hayajakamilika, ni hatari, hayafai, hayaruhusiwi au yanahusisha kuvuka maeneo ya kiutawala. Huenda pia maelezo ya biashara yasiwe sahihi au hayajakamilika. Data si ya wakati halisi na hatuwezi kukupa hakikisho kuhusu usahihi wa mahali. Usitumie kifaa chako cha mkononi au programu zisizo za Android Auto wakati unapoendesha gari."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Haijulikani"</string>
+    <string name="start_driving" msgid="864023351402918991">"Anza Kuendesha Gari"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw372dp/config.xml b/packages/SystemUI/res/values-sw372dp/config.xml
new file mode 100644
index 0000000..07b797a
--- /dev/null
+++ b/packages/SystemUI/res/values-sw372dp/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Nav bar button default ordering/layout -->
+    <string name="config_navBarLayout" translatable="false">left[.25W],back[.5WC];home;recent[.5WC],right[.25W]</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e8ff85c..57aa04a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"தேடு"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு மேலாக இழுக்கவும்."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு இடதுபக்கமாக இழுக்கவும்."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள் மற்றும் குறிப்பிட்ட அழைப்பாளர்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"அலாரங்களைத் தவிர்த்து, பிற ஒலிகள் மற்றும் அதிர்வுகளின் தொந்தரவு இருக்காது. எனினும், நீங்கள் எதையேனும் (இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட) ஒலிக்கும்படி தேர்ந்தெடுத்திருந்தால், அவை வழக்கம் போல் ஒலிக்கும்."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள், குறிப்பிட்ட அழைப்புகள் தவிர, ஒலிகளினாலும் அதிர்வினாலும் தொந்தரவு இருக்காது."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"தனிப்பயனாக்கு"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்தப் பயன்பாட்டால் மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"உங்கள் பணி விவரத்தை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nமேலும் தகவலுக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"உங்கள் பணி விவரத்தை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nஉங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g>க்குத் திறக்கப்பட்டது"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> இயங்குகிறது"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"நீங்கள் கைமுறையாகத் திறக்கும் வரை, சாதனம் பூட்டப்பட்டிருக்கும்"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"விரைவாக அறிவிப்புகளைப் பெறுதல்"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"திறக்கும் முன் அவற்றைப் பார்க்கவும்"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"வேண்டாம்"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"அமை"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"இப்போதே முடக்கு"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"இப்போது முடி"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"விரிவாக்கு"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"சுருக்கு"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"திரை பொருத்தப்பட்டது"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"முடக்கத்தில்"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ஆற்றல்மிக்க அறிவிப்புக் கட்டுப்பாடுகள் மூலம், பயன்பாட்டின் அறிவிப்புகளுக்கு முக்கியத்துவ நிலையை (0-5) அமைக்கலாம். \n\n"<b>"நிலை 5"</b>" \n- அறிவிப்புப் பட்டியலின் மேலே காட்டும் \n- முழுத் திரைக் குறுக்கீட்டை அனுமதிக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 4"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 3"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n\n"<b>"நிலை 2"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது, அதிர்வுறாது \n\n"<b>"நிலை 1"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது அல்லது அதிர்வுறாது \n- பூட்டுத்திரை மற்றும் நிலைப்பட்டியிலிருந்து மறைக்கும் \n- அறிவிப்புகள் பட்டியலின் கீழே காட்டும் \n\n"<b>"நிலை 0"</b>" \n- பயன்பாட்டின் எல்லா அறிவிப்புகளையும் தடுக்கும்"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"அறிவிப்புகள்"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> அறிவிப்பு வகைகள்"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"இந்தப் பயன்பாட்டில் அறிவிப்பு வகைகள் இல்லை"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">இந்தப் பயன்பாடு வழங்கும் <xliff:g id="NUMBER_1">%d</xliff:g> அறிவிப்பு வகைகளில் ஒரு அறிவிப்பு வகை</item>
       <item quantity="one">இந்தப் பயன்பாடு வழங்கும் <xliff:g id="NUMBER_0">%d</xliff:g> அறிவிப்பு வகையில் ஒரு அறிவிப்பு வகை</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"அறிவிப்புக் கட்டுப்பாடுகள்"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"அறிவிப்பை உறக்கநிலையாக்கும் விருப்பங்கள்"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 நிமிடங்கள்"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 நிமிடங்கள்"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 மணிநேரம்"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 மணிநேரம்"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"செயல்தவிர்"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"உறக்கநிலையில் வைத்திருந்த நேரம்: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"பேட்டரி உபயோகம்"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
@@ -718,8 +719,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="4171698133469539591">"<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-ta/strings_car.xml b/packages/SystemUI/res/values-ta/strings_car.xml
index 7ddd5e0..9a53db0 100644
--- a/packages/SystemUI/res/values-ta/strings_car.xml
+++ b/packages/SystemUI/res/values-ta/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"பாதுகாப்பாக வண்டியோட்டவும்"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"வாகனம் ஓட்டுவதற்கான சூழ்நிலைகளை முழுவதுமாகத் தெரிந்து வைத்திருக்கவும் மற்றும் பொருந்தும் விதிகளை எப்போதும் பின்பற்றவும். வழிகள் துல்லியமற்றதாக, முழுமையற்றதாக, ஆபத்துக்குரியதாக, பொருத்தமில்லாததாக, தடைசெய்யப்பட்டதாக அல்லது அரசின் கட்டுப்பாட்டில் உள்ள எல்லைகளைக் கடப்பதாக இருக்கலாம். வணிகத் தகவலும் துல்லியமற்றதாக அல்லது முழுமையற்றதாக இருக்கலாம். தரவு நிகழ்நேர அடிப்படையிலானது அல்ல மற்றும் இருப்பிடத் துல்லியத்திற்கு உத்தரவாதம் வழங்க முடியாது. வாகனம் ஓட்டும் போது மொபைல் சாதனத்தையோ அல்லது Android Auto மூலம் கட்டுப்படுத்த முடியாத பயன்பாடுகளையோ பயன்படுத்த வேண்டாம்."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"தெரியாதது"</string>
+    <string name="start_driving" msgid="864023351402918991">"வாகனம் ஓட்டத் தொடங்கு"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml
index f7c81ee..5ddab56 100644
--- a/packages/SystemUI/res/values-ta/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta/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-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 97763d4..56b271f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"శోధించండి"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం పైకి స్లైడ్ చేయండి."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం ఎడమవైపుకు స్లైడ్ చేయండి."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"అలారాలు నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"మీరు అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు పేర్కొనే కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"అనుకూలీకరించు"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్‌లను బ్లాక్ చేస్తుంది. మీరు ఇప్పటికీ ఫోన్ కాల్‌లు చేయగలుగుతారు."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్‌లను బ్లాక్ చేస్తుంది."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"మీరు <xliff:g id="APPLICATION">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ కార్యాలయ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమరింత సమాచారం కోసం, మీ నిర్వాహకులను సంప్రదించండి."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"మీ కార్యాలయ ప్రొఫైల్ <xliff:g id="ORGANIZATION">%1$s</xliff:g> నిర్వహణలో ఉంది. ఇమెయిల్‌లు, అనువర్తనాలు మరియు వెబ్‌సైట్‌లతో సహా మీ కార్యాలయ నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>కి ప్రొఫైల్ కనెక్ట్ చేయబడింది.\n\nమీ వ్యక్తిగత నెట్‌వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>కి కూడా మీరు కనెక్ట్ చేయబడ్డారు."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> కోసం అన్‌లాక్ చేయబడింది"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> అమలులో ఉంది"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"మీరు మాన్యువల్‌గా అన్‌లాక్ చేస్తే మినహా పరికరం లాక్ చేయబడి ఉంటుంది"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"నోటిఫికేషన్‌లను వేగంగా పొందండి"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"వీటిని మీరు అన్‌లాక్ చేయకముందే చూడండి"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"వద్దు, ధన్యవాదాలు"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"సెటప్ చేయి"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ఇప్పుడు ఆఫ్ చేయండి"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ఇప్పుడే ముగించు"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"విస్తరింపజేయండి"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"కుదించండి"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"స్క్రీన్ పిన్ చేయబడింది"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ఆఫ్‌లో ఉన్నాయి"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"పవర్ నోటిఫికేషన్ నియంత్రణలతో, మీరు అనువర్తన నోటిఫికేషన్‌ల కోసం ప్రాముఖ్యత స్థాయిని 0 నుండి 5 వరకు సెట్ చేయవచ్చు. \n\n"<b>"స్థాయి 5"</b>" \n- నోటిఫికేషన్ జాబితా పైభాగంలో చూపబడతాయి \n- పూర్తి స్క్రీన్ అంతరాయం అనుమతించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 4"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 3"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n\n"<b>"స్థాయి 2"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం మరియు వైబ్రేషన్ చేయవు \n\n"<b>"స్థాయి 1"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం లేదా వైబ్రేట్ చేయవు \n- లాక్ స్క్రీన్ మరియు స్థితి పట్టీ నుండి దాచబడతాయి \n- నోటిఫికేషన్ జాబితా దిగువ భాగంలో చూపబడతాయి \n\n"<b>"స్థాయి 0"</b>" \n- అనువర్తనం నుండి అన్ని నోటిఫికేషన్‌లు బ్లాక్ చేయబడతాయి"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"నోటిఫికేషన్‌లు"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> నోటిఫికేషన్ వర్గాలు"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ఈ అనువర్తనానికి నోటిఫికేషన్ వర్గాలు లేవు"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">ఈ అనువర్తనం నుంచి <xliff:g id="NUMBER_1">%d</xliff:g> నోటిఫికేషన్ వర్గాలలో 1</item>
       <item quantity="one">ఈ అనువర్తనం నుంచి <xliff:g id="NUMBER_0">%d</xliff:g> నోటిఫికేషన్ వర్గంలో 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 నిమిషాలు"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 నిమిషాలు"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 గంట"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 గంటలు"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"చర్య రద్దు చేయి"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> వరకు తాత్కాలికంగా ఆపివేయబడింది"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"బ్యాటరీ వినియోగం"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
diff --git a/packages/SystemUI/res/values-te/strings_car.xml b/packages/SystemUI/res/values-te/strings_car.xml
index 6f60b3a..1831422 100644
--- a/packages/SystemUI/res/values-te/strings_car.xml
+++ b/packages/SystemUI/res/values-te/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"సురక్షితంగా డ్రైవ్ చేయండి"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"డ్రైవింగ్ షరతులపై పూర్తి అవగాహనను కలిగి ఉండండి మరియు ఎల్లప్పుడూ వర్తించే చట్టాలకు అనుగుణంగా నడుచుకోండి. దిశలు నిర్దిష్టంగా ఉండకపోవచ్చు, అసంపూర్ణంగా ఉండవచ్చు, ప్రమాదకరంగా ఉండవచ్చు, అనుకూలంగా ఉండకపోవచ్చు, నిషేధించబడి ఉండవచ్చు లేదా పాలనా ప్రాంతాల మీదుగా వెళ్లే విధంగా ఉండవచ్చు. వ్యాపార సమాచారం కూడా నిర్దిష్టంగా లేదా సంపూర్ణంగా ఉండకపోవచ్చు. డేటా నిజ-సమయానికి సంబంధించినది కాదు మరియు స్థాన ఖచ్చితత్వానికి ఎలాంటి హామీ ఉండకపోవచ్చు. డ్రైవింగ్ చేస్తున్నప్పుడు మీ మొబైల్ పరికరాన్ని ఉపయోగించవద్దు లేదా Android Auto కోసం ఉద్దేశించబడని అనువర్తనాలను ఉపయోగించవద్దు."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"తెలియని"</string>
+    <string name="start_driving" msgid="864023351402918991">"డ్రైవింగ్‌ను ప్రారంభించండి"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 28957c5..2259681 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก การช่วยเตือน กิจกรรม และผู้โทรที่ระบุไว้ คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นการปลุก การช่วยเตือน กิจกรรม และผู้โทรที่คุณระบุ"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"กำหนดค่า"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม คุณจะยังโทรออกได้อยู่"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"คุณเชื่อมต่อกับ <xliff:g id="APPLICATION">%1$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายส่วนตัวของคุณ รวมถึงอีเมล แอป และเว็บไซต์ได้"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> เป็นผู้จัดการโปรไฟล์งานของคุณ โปรไฟล์ดังกล่าวเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION">%2$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ รวมถึงอีเมล แอป และเว็บไซต์\n\nโปรดติดต่อผู้ดูแลระบบของคุณสำหรับข้อมูลเพิ่มเติม"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> เป็นผู้จัดการโปรไฟล์งานของคุณ โปรไฟล์ดังกล่าวเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายของคุณ รวมถึงอีเมล แอป และเว็บไซต์\n\nคุณยังเชื่อมต่ออยู่กับ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ด้วย ซึ่งสามารถตรวจสอบกิจกรรมในเครือข่ายส่วนตัวของคุณ"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"ปลดล็อกสำหรับ <xliff:g id="USER_NAME">%1$s</xliff:g> แล้ว"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> กำลังทำงาน"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"อุปกรณ์จะล็อกจนกว่าคุณจะปลดล็อกด้วยตนเอง"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"รับการแจ้งเตือนเร็วขึ้น"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"ดูก่อนปลดล็อก"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ไม่เป็นไร"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ตั้งค่า"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g> <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ปิดเลย"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ไม่ใช้แล้ว"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ขยาย"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ยุบ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ตรึงหน้าจอแล้ว"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ปิด"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ส่วนควบคุมการแจ้งเตือนแบบเปิด/ปิดช่วยให้คุณตั้งค่าระดับความสำคัญสำหรับการแจ้งเตือนของแอปได้ตั้งแต่ระดับ 0-5 \n\n"<b>"ระดับ 5"</b>" \n- แสดงที่ด้านบนของรายการแจ้งเตือน \n- อนุญาตให้รบกวนแบบเต็มหน้าจอ \n- อนุญาตให้แสดงชั่วครู่ \n\n"<b>"ระดับ 4"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- แสดงชั่วครู่เสมอ \n\n"<b>"ระดับ 3"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n\n"<b>"ระดับ 2"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n\n"<b>"ระดับ 1"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n- ซ่อนจากหน้าจอล็อกและแถบสถานะ \n- แสดงที่ด้านล่างของรายการแจ้งเตือน \n\n"<b>"ระดับ 0"</b>" \n- บล็อกการแจ้งเตือนทั้งหมดจากแอป"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"การแจ้งเตือน"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"หมวดหมู่การแจ้งเตือน <xliff:g id="NUMBER">%d</xliff:g> หมวด"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"แอปนี้ไม่มีหมวดหมู่การแจ้งเตือน"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">การแจ้งเตือน 1 ใน <xliff:g id="NUMBER_1">%d</xliff:g> หมวดหมู่จากแอปนี้</item>
       <item quantity="one">การแจ้งเตือน 1 ใน <xliff:g id="NUMBER_0">%d</xliff:g> หมวดหมู่จากแอปนี้</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"ส่วนควบคุมการแจ้งเตือน"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"ตัวเลือกการปิดเสียงแจ้งเตือนชั่วคราว"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 นาที"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 นาที"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ชั่วโมง"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 ชั่วโมง"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"เลิกทำ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ปิดเสียงเตือนชั่วคราวไว้เป็นเวลา <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"การใช้งานแบตเตอรี่"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
diff --git a/packages/SystemUI/res/values-th/strings_car.xml b/packages/SystemUI/res/values-th/strings_car.xml
index b40584a..d6cd225 100644
--- a/packages/SystemUI/res/values-th/strings_car.xml
+++ b/packages/SystemUI/res/values-th/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ขับขี่อย่างปลอดภัย"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"มีสติรู้ตัวเต็มที่ในสภาพการขับขี่ต่างๆ เและปฏิบัติตามกฎหมายที่บังคับใช้เสมอ ทั้งนี้เส้นทางอาจไม่ถูกต้อง ไม่ครบถ้วน เป็นอันตราย ไม่เหมาะสม ห้ามใช้ หรือมีการข้ามเขตปกครอง นอกจากนี้ข้อมูลทางธุรกิจอาจไม่ถูกต้องหรือไม่สมบูรณ์ ข้อมูลไม่ใช่แบบเรียลไทม์ และไม่สามารถรับประกันความถูกต้องของตำแหน่ง อย่าใช้งานอุปกรณ์เคลื่อนที่หรือใช้แอปที่ไม่ได้ออกแบบมาสำหรับ Android Auto ขณะขับรถ"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"ไม่ทราบ"</string>
+    <string name="start_driving" msgid="864023351402918991">"เริ่มขับรถ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 4788a0e..7b9135a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Hindi ka maiistorbo ng mga tunog at pag-vibrate, maliban sa mga alarm, paalala, kaganapan, at tumatawag na tutukuyin mo. Maririnig mo pa rin ang anumang pipiliin mong i-play kabilang ang musika, mga video, at mga laro."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Hindi ka maiistorbo ng mga tunog at pag-vibrate, maliban sa mga alarm. Maririnig mo pa rin ang anumang pipiliin mong i-play kabilang ang musika, mga video, at mga laro."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Hindi ka magagambala ng mga tunog at pag-vibrate, maliban mula sa mga alarm, paalala, kaganapan at mga tinukoy mong tumatawag."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"I-customize"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro. Magagawa mo pa ring tumawag."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Nakakonekta ka sa <xliff:g id="APPLICATION">%1$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong personal na network, kabilang ang mga email, app at website."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Pinamamahalaan ng <xliff:g id="ORGANIZATION">%1$s</xliff:g> ang iyong profile sa trabaho. Nakakonekta ang profile sa <xliff:g id="APPLICATION">%2$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong network sa trabaho, kasama ang mga email, app, at website.\n\nPara sa higit pang impormasyon, makipag-ugnayan sa iyong admin."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Pinamamahalaan ng <xliff:g id="ORGANIZATION">%1$s</xliff:g> ang iyong profile sa trabaho. Nakakonekta ang profile sa <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong network sa trabaho, kasama ang mga email, app, at website.\n\nNakakonekta ka rin sa <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, na maaaring sumubaybay sa aktibidad sa iyong personal na network."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Na-unlock para kay <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"Gumagana ang <xliff:g id="TRUST_AGENT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Mananatiling naka-lock ang device hanggang sa manu-mano mong i-unlock"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Kunin ang notification nang mas mabilis"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Tingnan ang mga ito bago ka mag-unlock"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Hindi"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"I-set up"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"I-off na ngayon"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Tapusin ngayon"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Palawakin"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"I-collapse"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Naka-pin ang screen"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Naka-off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Sa pamamagitan ng mga kontrol sa notification ng power, magagawa mong itakda ang antas ng kahalagahan ng mga notification ng isang app mula 0 hanggang 5. \n\n"<b>"Antas 5"</b>" \n- Ipakita sa itaas ng listahan ng notification \n- Payagan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 4"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 3"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n\n"<b>"Antas 2"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n\n"<b>"Antas 1"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n- Itago sa lock screen at status bar \n- Ipakita sa ibaba ng listahan ng notification \n\n"<b>"Antas 0"</b>" \n- I-block ang lahat ng notification mula sa app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Mga Notification"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hindi mo na matatanggap ang mga notification na ito."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hindi ka na makakatanggap ng ganitong mga notification"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> (na) kategorya ng notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Walang kategorya ng notification ang app na ito"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 sa <xliff:g id="NUMBER_1">%d</xliff:g> kategorya ng notification mula sa app na ito</item>
       <item quantity="other">1 sa <xliff:g id="NUMBER_1">%d</xliff:g> na kategorya ng notification mula sa app na ito</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"mga kontrol ng notification"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"mga opsyon sa pag-snooze ng notification"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuto"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuto"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oras"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 oras"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"I-UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Na-snooze ng <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Paggamit ng baterya"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
diff --git a/packages/SystemUI/res/values-tl/strings_car.xml b/packages/SystemUI/res/values-tl/strings_car.xml
index c6926ed..16442b85 100644
--- a/packages/SystemUI/res/values-tl/strings_car.xml
+++ b/packages/SystemUI/res/values-tl/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Magmaneho nang ligtas"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Manatiling lubos na nakakaalam sa mga kondisyon sa pagmamaneho at palaging sumunod sa mga naaangkop na batas. Ang mga direksyon ay maaaring hindi tumpak, hindi kumpleto, mapanganib, hindi naaangkop, ipinagbabawal o kinasasangkutan ng pagtawid sa mga administratibong lugar. Maaari ding hindi tumpak o hindi kumpleto ang impormasyon ng negosyo. Hindi real-time ang data at hindi magagarantiya ang katumpakan ng lokasyon. Huwag gamitin ang iyong mobile device o gumamit ng mga app na hindi ginawa para sa Android Auto habang nagmamaneho."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Hindi Alam"</string>
+    <string name="start_driving" msgid="864023351402918991">"Simulan ang Pagmamaneho"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 20002f6..2743fcc 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Alarmlar, hatırlatıcılar, etkinlikler ve sizin seçtiğiniz arayan kişiler dışında hiçbir ses ve titreşimle rahatsız edilmeyeceksiniz. O sırada çaldığınız, seyrettiğiniz ya da oynadığınız müzik, video ve oyunların sesini duymaya devam edeceksiniz"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Alarmlar dışında hiçbir ses ve titreşimle rahatsız edilmeyeceksiniz. O sırada çaldığınız, seyrettiğiniz ya da oynadığınız müzik, video ve oyunların sesini duymaya devam edeceksiniz."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Belirttiğiniz alarmlar, hatırlatıcılar, etkinlikler ve arayanlar hariç olmak üzere, sesler ve titreşimlerle rahatsız edilmeyeceksiniz."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Özelleştir"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir. Telefon aramaları yapmaya devam edebileceksiniz."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"E-postalarınız, uygulamalarınız ve web siteleriniz dahil olmak üzere kişisel ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasına bağlısınız."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tarafından yönetiliyor. Profil; e-postalar, uygulamalar ve web siteleri de dahil olmak üzere iş ağı etkinliğinizi izleyebilen <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasına bağlı.\n\nDaha fazla bilgi için yöneticinize başvurun."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"İş profiliniz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tarafından yönetiliyor. Profil; e-postalar, uygulamalar ve web siteleri de dahil olmak üzere iş ağı etkinliğinizi izleyebilen <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> uygulamasına bağlı.\n\nAyrıca, kişisel ağ etkinliğinizi izleyebilen <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> uygulamasına bağlısınız."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> için kilit açıldı"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> çalışıyor"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Cihazınızın kilidini manuel olarak açmadıkça cihaz kilitli kalacak"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirimleri daha hızlı alın"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Kilidi açmadan bildirimleri görün"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Hayır, teşekkürler"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Kur"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Şimdi kapat"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Şimdi sona erdir"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Genişlet"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Daralt"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran sabitlendi"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kapalı"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Güç bildirim kontrolleriyle, bir uygulamanın bildirimleri için 0 ile 5 arasında bir önem düzeyi ayarlayabilirsiniz. \n\n"<b>"5. Düzey"</b>" \n- Bildirim listesinin en üstünde gösterilsin \n- Tam ekran kesintisine izin verilsin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"4. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"3. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n\n"<b>"2. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman belirmesin \n- Hiçbir zaman ses çıkarmasın ve titreştirmesin \n\n"<b>"1. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n- Hiçbir zaman ses çıkarmasın veya titreştirmesin \n- Kilit ekranından ve durum çubuğundan gizlensin \n- Bildirim listesinin en altında gösterilsin \n\n"<b>"0. Düzey"</b>" \n- Uygulamadan gelen tüm bildirimler engellensin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirimler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirimleri artık almayacaksınız."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirimleri artık almayacaksınız"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildirim kategorisi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu uygulamanın bildirim kategorisi yok"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu uygulamadaki <xliff:g id="NUMBER_1">%d</xliff:g> bildirim kategorisinden 1 tanesi</item>
       <item quantity="one">Bu uygulamadaki <xliff:g id="NUMBER_0">%d</xliff:g> bildirim kategorisinden 1 tanesi</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"Bildirim kontrolleri"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildirim erteleme seçenekleri"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dakika"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 dakika"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 saat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ AL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> süreyle ertelendi"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Pil kullanımı"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
@@ -718,8 +719,8 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Simge durumuna getir"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Kapat"</string>
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Kapatmak için aşağıya sürükleyin"</string>
-    <string name="pip_menu_title" msgid="3328510504196964712">"Pencere içinde pencere menüsü"</string>
-    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g>, pencere içinde pencere özelliğini kullanıyor"</string>
+    <string name="pip_menu_title" msgid="3328510504196964712">"Ekran içinde ekran menüsü"</string>
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g>, ekran içinde ekran özelliğini kullanıyor"</string>
     <string name="pip_notification_message" msgid="4171698133469539591">"<xliff:g id="NAME">%s</xliff:g> uygulamasının bu özelliği kullanmasını istemiyorsanız dokunarak ayarları açın ve özelliği kapatın."</string>
     <string name="pip_play" msgid="1417176722760265888">"Oynat"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Duraklat"</string>
diff --git a/packages/SystemUI/res/values-tr/strings_car.xml b/packages/SystemUI/res/values-tr/strings_car.xml
index 72018e2..126789f 100644
--- a/packages/SystemUI/res/values-tr/strings_car.xml
+++ b/packages/SystemUI/res/values-tr/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Güvenli bir şekilde sürün"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Sürüş koşullarına karşı dikkatli olun ve geçerli yasalara her zaman uyun. Yol tarifi yanlış, eksik, tehlikeli, uygunsuz, yasak olabilir veya idari bölgelerden geçişleri içerebilir. İşletme bilgileri de yanlış veya eksik olabilir. Veriler gerçek zamanlı değildir ve konum doğruluğu garanti edilemez. Sürüş sırasında mobil cihazınızı veya Android Auto için geliştirilmemiş uygulamaları kullanmayın."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Bilinmiyor"</string>
+    <string name="start_driving" msgid="864023351402918991">"Sürmeye Başla"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index fb39510..ec2c784 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/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">"Pencere İçinde Pencere"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Ekran İçinde Ekran"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Başlıksız program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP\'yi kapat"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 51005c1..a224545 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -157,7 +157,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Мобільне передавання даних"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Мобільне передавання даних увімкнено"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"Мобільне передавання даних вимкнено"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-модем"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Прив’язка Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"Мережу VPN увімкнено."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Немає SIM-карти."</string>
@@ -358,8 +358,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Ви отримуватиме звукові та вібросигнали лише для вибраних будильників, нагадувань, подій і абонентів. Однак ви чутимете все, що захочете відтворити, зокрема музику, відео й ігри."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Ви отримуватиме звукові та вібросигнали лише для будильників. Однак ви чутимете все, що захочете відтворити, зокрема музику, відео й ігри."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Ви отримуватимете звукові й вібросигнали лише для вибраних сповіщень, нагадувань, повідомлень про події та викликів абонентів."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Налаштувати"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри. Ви зможете телефонувати."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри."</string>
@@ -473,13 +472,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Ваш профіль під’єднано до додатка <xliff:g id="APPLICATION">%1$s</xliff:g>, який може відстежувати вашу особисту активність у мережі, зокрема доступ до електронної пошти, додатків і веб-сайтів."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Вашим робочим профілем керує адміністратор організації <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Цей профіль під’єднано до додатка <xliff:g id="APPLICATION">%2$s</xliff:g>, який може відстежувати вашу активність у мережі, зокрема в електронній пошті, додатках і на веб-сайтах.\n\nЩоб дізнатися більше, зв’яжіться з адміністратором."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Вашим робочим профілем керує адміністратор організації <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Цей профіль під’єднано до додатка <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, який може відстежувати вашу активність у мережі, зокрема а електронній пошті, додатках і на веб-сайтах.\n\nВаш профіль також під’єднано до додатка <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, який може відстежувати вашу особисту активність у мережі."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Розблоковано для користувача <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> працює"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Пристрій залишатиметься заблокованим, доки ви не розблокуєте його вручну"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Швидше отримуйте сповіщення"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Переглядайте сповіщення, перш ніж розблокувати екран"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ні, дякую"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Налаштув."</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Вимкнути"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Закрити"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Розгорнути"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Згорнути"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екран закріплено"</string>
@@ -554,9 +555,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Вимк."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"За допомогою елементів керування сповіщеннями ви можете налаштувати пріоритет сповіщень додатка – від 0 до 5 рівня. \n\n"<b>"Рівень 5"</b>\n"- Показувати сповіщення вгорі списку \n- Виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 4"</b>\n"- Не виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 3"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n\n"<b>"Рівень 2"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n\n"<b>"Рівень 1"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n- Не показувати на заблокованому екрані та в рядку стану \n- Показувати сповіщення внизу списку \n\n"<b>"Рівень 0"</b>\n"- Блокувати всі сповіщення з додатка"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Сповіщення"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ви більше не отримуватимете ці сповіщення."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ви більше не отримуватимете ці сповіщення"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорії сповіщень (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"У цьому додатку немає категорій сповіщень"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 з <xliff:g id="NUMBER_1">%d</xliff:g> категорії сповіщень із цього додатка</item>
       <item quantity="few">1 з <xliff:g id="NUMBER_1">%d</xliff:g> категорій сповіщень із цього додатка</item>
@@ -580,12 +583,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"елементи керування сповіщеннями"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"параметри відкладення сповіщень"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвилин"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвилин"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 годину"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 години"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ВІДМІНИТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Відкладено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Використання заряду"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим енергозбереження не можна ввімкнути під час заряджання"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим енергозбереження"</string>
diff --git a/packages/SystemUI/res/values-uk/strings_car.xml b/packages/SystemUI/res/values-uk/strings_car.xml
index 4fda0ab..852e1c6 100644
--- a/packages/SystemUI/res/values-uk/strings_car.xml
+++ b/packages/SystemUI/res/values-uk/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Будьте уважні за кермом"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Стежте умовами дорожнього руху та завжди дотримуйтеся відповідних законів. Маршрути можуть бути неточними, неповними, небезпечними, непридатними або перетинати межі адміністративних одиниць. Інформація про компанії також може бути неточною або неповною. Дані надаються не в реальному часі. Точність визначення місцезнаходжень не гарантується. Коли ви за кермом, не користуйтеся мобільним пристроєм або додатками, не призначеними для Android Auto."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Невідомо"</string>
+    <string name="start_driving" msgid="864023351402918991">"Почати рух"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 23a0626..2ad6bb8 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"تلاش کریں"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے اوپر سلائیڈ کریں۔"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> کیلئے بائیں سلائیڈ کریں۔"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"الارمز، یاد دہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔ موسیقی، ویڈیوز اور گیمز سمیت آپ ابھی بھی ہر وہ چیز سنیں گے جسے چلانے کا آپ انتخاب کرتے ہیں۔"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"الارمز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔ موسیقی، ویڈیوز اور گیمز سمیت آپ ہر وہ چیز سنیں گے جسے چلانے کا آپ انتخاب کرتے ہیں۔"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"الارمز، یاد دہانیوں، ایونٹس اور آپ کے متعین کردہ کالرز کے علاوہ، آپ آوازوں اور وائبریشنز سے ڈسٹرب نہیں ہوں گے۔"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"حسب ضرورت بنائیں"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔ آپ ابھی بھی فون کالز کر سکیں گے۔"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"یہ الارمز، موسیقی، ویڈیوز اور گیمز کی آوازوں اور وائبریشنز سمیت سبھی آوازیں اور وائبریشنز مسدود کر دیتا ہے۔"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"آپ <xliff:g id="APPLICATION">%1$s</xliff:g> سے منسلک ہیں، جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے نجی نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"آپ کا دفتری پروفائل <xliff:g id="ORGANIZATION">%1$s</xliff:g> کے زیر انتظام ہے۔ پروفائل <xliff:g id="APPLICATION">%2$s</xliff:g> سے منسلک ہے جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے دفتری نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔\n\nمزید معلومات کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"آپ کا دفتری پروفائل <xliff:g id="ORGANIZATION">%1$s</xliff:g> کے زیر انتظام ہے۔ پروفائل <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> سے منسلک ہے جو ای میلز، ایپس اور ویب سائٹس سمیت آپ کے دفتری نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔\n\nآپ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> سے بھی منسلک ہیں، جو آپ کے ذاتی نیٹ ورک کی سرگرمی مانیٹر کر سکتی ہے۔"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> کے لیے غیر مقفل کر دیا گیا"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> چل رہا ہے"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"آلہ اس وقت تک مقفل رہے گا جب تک آپ دستی طور پر اسے غیر مقفل نہ کریں"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"تیزی سے اطلاعات حاصل کریں"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"غیر مقفل کرنے سے پہلے انہیں دیکھیں"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"نہیں شکریہ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"ترتیب دیں"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>۔ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"ابھی بند کریں"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"ابھی ختم کریں"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"پھیلائیں"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"سکیڑیں"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"اسکرین پن کردہ ہے"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"آف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"پاور اطلاع کنٹرولز کے ساتھ آپ کسی ایپ کی اطلاعات کیلئے 0 سے 5 تک اہمیت کی سطح سیٹ کر سکتے ہیں۔ \n\n"<b>"سطح 5"</b>\n"- اطلاعات کی فہرست کے اوپر دکھائیں \n- پوری اسکرین کی مداخلت کی اجازت دیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 4"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 3"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n\n"<b>"سطح 2"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n- کبھی آواز اور ارتعاش پیدا نہ کرنا \n\n"<b>" سطح 1"</b>\n"- پوری اسکرین کی مداخلت کو روکنا \n- کبھی نہ جھانکنا \n- کبھی بھی آواز یا ارتعاش پیدا نہ کرنا\n- مقفل اسکرین اور اسٹیٹس بار سے چھپانا \n - اطلاع کی فہرست کی نیچے دکھانا \n\n"<b>"سطح 0"</b>\n"- ایپ سے تمام اطلاعات مسدود کریں"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اطلاعات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"آپ کو یہ اطلاعات مزید نہیں ملیں گی۔"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"آپ کو یہ اطلاعات مزید نہیں ملیں گی"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"اطلاع کے <xliff:g id="NUMBER">%d</xliff:g> زمرے"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"اس ایپ میں اطلاعاتی زمرے نہیں ہیں"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">اس ایپ کے <xliff:g id="NUMBER_1">%d</xliff:g> اطلاعاتی زمروں میں سے 1</item>
       <item quantity="one">اس ایپ کے <xliff:g id="NUMBER_0">%d</xliff:g> اطلاعاتی زمرے میں سے 1</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"اطلاع کے کنٹرولز"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"اطلاع اسنوز کرنے کے اختیارات"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 منٹ"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 منٹ"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 گھنٹہ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 گھنٹے"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"کالعدم کریں"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"بیٹری کا استعمال"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
diff --git a/packages/SystemUI/res/values-ur/strings_car.xml b/packages/SystemUI/res/values-ur/strings_car.xml
index 151ca09..653a59b 100644
--- a/packages/SystemUI/res/values-ur/strings_car.xml
+++ b/packages/SystemUI/res/values-ur/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"احتیاط سے گاڑی چلائیں"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏گاڑی چلاتے وقت اپنے گردونواح سے مکمل طور پر باخبر رہیں اور ہمیشہ قابل اطلاق قوانین کی پابندی کریں۔ ہدایات غلط، نامکمل، خطرناک، موزوں نہیں، ممنوع یا انتظامی علاقوں میں سے گزرنے کے متعلق ہو سکتی ہیں۔ کاروباری معلومات بھی غلط یا نامکمل ہو سکتی ہے۔ گاڑی چلاتے وقت اپنا موبائل آلہ یا وہ ایپس استعمال نہ کریں جو Android Auto کیلئے نہیں ہیں۔"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"نامعلوم"</string>
+    <string name="start_driving" msgid="864023351402918991">"ڈرائیونگ شروع کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index a60dc07..72fca86 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Qidirish"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun yuqoriga suring."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun chapga suring."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq, signallar, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan chaqiruvlar bundan mustasno. Lekin, ijro etiladigan barcha narsalar, jumladan, musiqa, video va o‘yinlar eshitiladi."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq, signallar bundan mustasno. Lekin, ijro etiladigan barcha narsalar, jumladan, musiqa, video va o‘yinlar eshitiladi."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq signallar, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan qo‘ng‘iroqlar bundan mustasno."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Sozlash"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu BARCHA, jumladan signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi. Siz telefon qo‘ng‘iroqlarini bemalol amalga oshirishingiz mumkin."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu BARCHA, jumladan, signallar, musiqa, videolar va o‘yinlardan keladigan tovush va tebranishlarni to‘sib qo‘yadi."</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasi ishga tushirilgan. U internetdagi harakatlaringiz, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi. <xliff:g id="APPLICATION">%2$s</xliff:g> ilovasi ish tarmog‘idagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin.\n\nBatafsil axborot olish uchun administrator bilan bog‘laning."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi. <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ilovasi ish tarmog‘idagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin.\n\nShuningdek, <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ilovasi ham shaxsiy tarmoqdagi harakatlaringizni kuzatishi mumkin."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"<xliff:g id="USER_NAME">%1$s</xliff:g> uchun qulfdan chiqarilgan"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> ishlamoqda"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Qurilma qo‘lda qulfdan chiqarilmaguncha qulflangan holatda qoladi"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirishnomalarni tezroq oling"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ularni qulfdan chiqarishdan oldin ko‘ring"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Yo‘q, kerak emas"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Sozlash"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"O‘chiring"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Tugatish"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Yoyish"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Yig‘ish"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran qadaldi"</string>
@@ -487,7 +488,7 @@
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Keyingi safar sozlamalardan yoqilgan paydo bo‘ladi."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Berkitish"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string>
-    <string name="stream_voice_call" msgid="4410002696470423714">"Chaqiruv"</string>
+    <string name="stream_voice_call" msgid="4410002696470423714">"Qo‘ng‘iroq qilish"</string>
     <string name="stream_system" msgid="7493299064422163147">"Tizim"</string>
     <string name="stream_ring" msgid="8213049469184048338">"Jiringlatish"</string>
     <string name="stream_music" msgid="9086982948697544342">"Multimedia"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"O‘chiq"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bildirishnomalar uchun kengaytirilgan boshqaruv yordamida ilova bildirishnomalarining muhimlik darajasini (0-5) sozlash mumkin. \n\n"<b>"5-daraja"</b>" \n- Bildirishnomani ro‘yxatning boshida ko‘rsatish \n- To‘liq ekranli bildirishnomalarni ko‘rsatish \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"4-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"3-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n\n"<b>"2-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n\n"<b>"1-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n- Ekran qulfi va holat qatorida ko‘rsatmaslik \n- Bildirishnomani ro‘yxatning oxirida ko‘rsatish \n\n"<b>"0-daraja"</b>" \n- Ilovadan keladigan barcha bildirishnomalarni bloklash"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirishnomalar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ushbu bildirishnomalar endi ko‘rsatilmaydi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ushbu bildirishnomalar endi ko‘rsatilmaydi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ta bildirishnoma turkumi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu ilovada bildirishnomalar turkumi yo‘q"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">Bu ilovadagi <xliff:g id="NUMBER_1">%d</xliff:g> ta bildirishnomalar turkumidan 1 tasi</item>
       <item quantity="one">Bu ilovadagi <xliff:g id="NUMBER_0">%d</xliff:g> ta bildirishnomalar turkumidan 1 tasi</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"bildirishnoma sozlamalari"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"bildirishnomalarni kechiktirish parametrlari"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 daqiqa"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 daqiqa"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 soat"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 soat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"BEKOR QILISH"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> muddatga kechiktirildi"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya sarfi"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
diff --git a/packages/SystemUI/res/values-uz/strings_car.xml b/packages/SystemUI/res/values-uz/strings_car.xml
index 610dc1f..29951be 100644
--- a/packages/SystemUI/res/values-uz/strings_car.xml
+++ b/packages/SystemUI/res/values-uz/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Xavfsiz haydash"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Harakat xavfsizligi va amaldagi qonunchilikka doim rioya qiling. Yo‘l ko‘rsatmalari noaniq, chala, xavfli, mos emas, taqiqlangan yoki ma’muriy hududlarni kesib o‘tadigan bo‘lishi mumkin. Biznes ma’lumotlari ham noaniq yoki chala bo‘lishi mumkin. Ma’lumotlar real vaqt rejimida bo‘lmasligi hamda joylashuv ma’lumotining aniqligi kafolatlanmaydi. Avtomobilni haydash mobaynida Android Auto xizmati bilan bog‘liq bo‘lmagan hollarda mobil qurilma yoki ilovalardan foydalanmang."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Noma’lum"</string>
+    <string name="start_driving" msgid="864023351402918991">"Navigatsiyani boshlash"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 29c70c6..ad6d85b 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, nhắc nhở, sự kiện và người gọi mà bạn chỉ định. Bạn sẽ vẫn nghe thấy mọi thứ bạn chọn phát, bao gồm nhạc, video và trò chơi."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức. Bạn sẽ vẫn nghe thấy mọi thứ bạn chọn phát, bao gồm nhạc, video và trò chơi."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, nhắc nhở, sự kiện và người gọi mà bạn chỉ định."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tùy chỉnh"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Chế độ này sẽ chặn TẤT CẢ âm thanh và tiếng rung, bao gồm báo thức, âm nhạc, video và trò chơi. Bạn vẫn có thể gọi điện thoại."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Chế độ này sẽ chặn TẤT CẢ âm thanh và tiếng rung, bao gồm báo thức, âm nhạc, video và trò chơi."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Bạn đang kết nối với <xliff:g id="APPLICATION">%1$s</xliff:g>. Ứng dụng này có thể giám sát hoạt động mạng cá nhân của bạn bao gồm email, ứng dụng và trang web."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Hồ sơ công việc của bạn do <xliff:g id="ORGANIZATION">%1$s</xliff:g> quản lý. Hồ sơ này được kết nối với <xliff:g id="APPLICATION">%2$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng cơ quan của bạn, bao gồm email, ứng dụng và trang web.\n\nĐể biết thêm thông tin, hãy liên hệ với quản trị viên của bạn."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Hồ sơ công việc của bạn do <xliff:g id="ORGANIZATION">%1$s</xliff:g> quản lý. Hồ sơ này được kết nối với <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng của bạn, bao gồm email, ứng dụng và trang web.\n\nBạn cũng đang kết nối với <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ứng dụng này có thể giám sát hoạt động mạng cá nhân của bạn."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Được mở khóa cho <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> đang chạy"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Thiết bị sẽ vẫn bị khóa cho tới khi bạn mở khóa theo cách thủ công"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Nhận thông báo nhanh hơn"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Xem thông báo trước khi bạn mở khóa"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ko, cảm ơn"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Thiết lập"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Tắt ngay bây giờ"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Kết thúc bây giờ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mở rộng"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Thu gọn"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Màn hình được ghim"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Tắt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Với các kiểm soát thông báo nguồn, bạn có thể đặt cấp độ quan trọng từ 0 đến 5 cho các thông báo của ứng dụng. \n\n"<b>"Cấp 5"</b>" \n- Hiển thị ở đầu danh sách thông báo \n- Cho phép gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 4"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 3"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n\n"<b>"Cấp 2"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n\n"<b>"Cấp 1"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n- Ẩn khỏi màn hình khóa và thanh trạng thái \n- Hiển thị ở cuối danh sách thông báo \n\n"<b>"Cấp 0"</b>" \n- Chặn tất cả các thông báo từ ứng dụng"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Thông báo"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bạn sẽ không nhận được những thông báo này nữa."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bạn sẽ không nhận được những thông báo này nữa"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> danh mục thông báo"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ứng dụng này không có loại thông báo"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">1 trên tổng số <xliff:g id="NUMBER_1">%d</xliff:g> loại thông báo từ ứng dụng này</item>
       <item quantity="one">1 trên tổng số <xliff:g id="NUMBER_0">%d</xliff:g> loại thông báo từ ứng dụng này</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"điều khiển thông báo"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"Tùy chọn báo lại thông báo"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 phút"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 phút"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 giờ"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 giờ"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"HOÀN TÁC"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Báo lại sau <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Mức sử dụng pin"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
diff --git a/packages/SystemUI/res/values-vi/strings_car.xml b/packages/SystemUI/res/values-vi/strings_car.xml
index 2aee7d5..fb47969 100644
--- a/packages/SystemUI/res/values-vi/strings_car.xml
+++ b/packages/SystemUI/res/values-vi/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Lái xe an toàn"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Luôn biết rõ điều kiện lái xe và luôn tuân thủ luật pháp hiện hành. Chỉ đường có thể không chính xác, không hoàn chỉnh, nguy hiểm, không thích hợp, bị cấm hoặc bao gồm tuyến đường giao các khu vực hành chính. Thông tin doanh nghiệp cũng có thể không chính xác hoặc không hoàn chỉnh. Dữ liệu không ở thời gian thực và không thể đảm bảo độ chính xác của vị trí. Không sử dụng thiết bị di động của bạn hoặc sử dụng ứng dụng không dành cho Android Auto trong khi lái xe."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Không xác định"</string>
+    <string name="start_driving" msgid="864023351402918991">"Bắt đầu lái xe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9152dcb..d41c251 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -60,7 +60,7 @@
     <string name="label_view" msgid="6304565553218192990">"查看"</string>
     <string name="always_use_device" msgid="1450287437017315906">"默认情况下用于该USB设备"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"默认情况下用于该USB配件"</string>
-    <string name="usb_debugging_title" msgid="4513918393387141949">"允许 USB 调试吗?"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"允许USB调试吗?"</string>
     <string name="usb_debugging_message" msgid="2220143855912376496">"这台计算机的 RSA 密钥指纹如下:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"一律允许使用这台计算机进行调试"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允许使用 USB 调试功能"</string>
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"您将不会受到声音和振动的打扰(闹钟、提醒、活动和所指定来电者的相关提示音除外)。您依然可以听到您选择播放的任何内容(包括音乐、视频和游戏)的相关音效。"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"您将不会受到声音和振动的打扰(闹钟提示音除外)。您依然可以听到您选择播放的任何内容(包括音乐、视频和游戏)的相关音效。"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"您将不会受声音和振动的打扰,但闹钟、提醒、活动和您指定的来电者除外。"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"自定义"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。您仍然可以拨打电话。"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"这会阻止所有声音和振动(包括闹钟、音乐、视频和游戏)打扰您。"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"您已连接到<xliff:g id="APPLICATION">%1$s</xliff:g>,该应用可以监控您的个人网络活动,包括收发电子邮件、使用应用和浏览网站。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"您的工作资料由“<xliff:g id="ORGANIZATION">%1$s</xliff:g>”负责管理,且已连接到“<xliff:g id="APPLICATION">%2$s</xliff:g>”(该应用能够监控您的工作网络活动,其中包括收发电子邮件、使用应用和浏览网站)。\n\n如需更多信息,请与您的管理员联系。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"您的工作资料由“<xliff:g id="ORGANIZATION">%1$s</xliff:g>”负责管理,且已连接到“<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>”(该应用能够监控您的工作网络活动,其中包括收发电子邮件、使用应用和浏览网站)。\n\n此外,您还连接到了“<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>”(该应用能够监控您的个人网络活动)。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已为<xliff:g id="USER_NAME">%1$s</xliff:g>解锁"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"“<xliff:g id="TRUST_AGENT">%1$s</xliff:g>”正在运行"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在您手动解锁之前,设备会保持锁定状态"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快捷地查看通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"无需解锁即可查看通知"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"不用了"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"设置"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>(<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>)"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"立即关闭"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"立即结束"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展开"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收起"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"已固定屏幕"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"关闭"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您将不会再收到这类通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您将不会再收到这类通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 个通知类别"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此应用没有通知类别"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">此应用指定的 1 个通知类别(共 <xliff:g id="NUMBER_1">%d</xliff:g> 个)</item>
       <item quantity="one">此应用指定的 1 个通知类别(共 <xliff:g id="NUMBER_0">%d</xliff:g> 个)</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g><xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知设置"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延后选项"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分钟"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分钟"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小时"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小时"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"撤消"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延后 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"电池使用情况"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用省电模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省电模式"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_car.xml b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
index 6a5a4e8..27dd755 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全驾驶"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"请充分了解驾驶条件并务必遵守适用的法律。路线指示可能不准确,不完整,也可能包含危险、不适合通行、禁止通行或跨越行政区域的路段。商家信息也可能不准确或不完整。数据并非实时提供,因此无法保证位置信息的精确度。请勿在驾驶过程中操作您的移动设备或使用不支持 Android Auto 的应用。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"未知"</string>
+    <string name="start_driving" msgid="864023351402918991">"开始驾驶"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index cab3aea..fc923bc 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -354,8 +354,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"您不會受音效和震動騷擾 (鬧鐘、提醒、活動,以及您指定的來電者鈴聲除外)。如果您選擇播放特定音樂、影片和遊戲等內容,仍可以聽到相關音訊。"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"您不會受音效和震動騷擾 (鬧鐘除外)。如果您選擇播放特定音樂、影片和遊戲等內容,仍可以聽到相關音訊。"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"除了指定的鬧鐘、提醒、活動及來電者,您將不會受到其他聲音和震動騷擾。"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲,但您仍可撥打電話。"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲。"</string>
@@ -469,13 +468,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"您已連接至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,此應用程式可以監控您的個人網絡活動,包括電郵、應用程式及網站。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"您的工作設定檔由<xliff:g id="ORGANIZATION">%1$s</xliff:g>管理。設定檔已連結至「<xliff:g id="APPLICATION">%2$s</xliff:g>」,此應用程式可以監控您的工作網絡活動,包括電郵、應用程式和網站。\n\n如需瞭解詳情,請聯絡您的管理員。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"您的工作設定檔由<xliff:g id="ORGANIZATION">%1$s</xliff:g>管理。設定檔已連結至「<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>」,此應用程式可以監控您的工作網絡活動,包括電郵、應用程式和網站。\n\n您亦已連結至「<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>」,此應用程式可以監控您的個人網絡活動。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已為<xliff:g id="USER_NAME">%1$s</xliff:g>解鎖"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> 執行中"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"裝置將保持上鎖,直到您手動解鎖"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"不用了,謝謝"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"設定"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"立即關閉"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"立即終止"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收合"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
@@ -550,9 +551,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"通知控制項讓您設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您不會再收到這些通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您不會再收到這些通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此應用程式沒有通知類別"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">此應用程式的 1 個通知類別 (共 <xliff:g id="NUMBER_1">%d</xliff:g> 個)</item>
       <item quantity="one">此應用程式的 1 個通知類別 (共 <xliff:g id="NUMBER_0">%d</xliff:g> 個)</item>
@@ -572,12 +575,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延後選項"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小時"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_car.xml b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
index 18f9e50..01f3b14 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"請安全駕駛"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時留意路面情況,並遵守適用的交通規則。系統提供的路線可能不準確、不完整、存在危險、不適合、禁止通行,或涉及跨越行政區域的路段。此外,商家資訊也可能不準確或不完整。路況資料並非即時更新,也無法保證定位資訊的準確性。駕駛時請勿操作流動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"開始駕駛"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9526426..f4d1fbd1 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"裝置不會發出音效或震動造成干擾,但會保留鬧鐘、提醒、活動和你指定的來電者響鈴。如果你選擇播放特定音樂、影片和遊戲等內容,還是可以聽見相關音訊。"</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"裝置不會發出音效或震動造成干擾,但會保留鬧鐘響鈴。如果你選擇播放特定音樂、影片和遊戲等內容,還是可以聽見相關音訊。"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"你不會受到聲音和震動干擾,但鬧鐘、提醒、活動和指定來電者除外。"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內,但你仍然可以撥打電話。"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖「所有」聲音和震動干擾,包括鬧鐘、音樂、影片和遊戲在內。"</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"由於你已連結至「<xliff:g id="APPLICATION">%1$s</xliff:g>」,你的個人網路活動 (包括收發電子郵件、使用應用程式及瀏覽網站) 可能會受到這個應用程式監控。"</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"你的 Work 設定檔是由「<xliff:g id="ORGANIZATION">%1$s</xliff:g>」所管理。由於該設定檔已連結至「<xliff:g id="APPLICATION">%2$s</xliff:g>」,因此你的網路活動 (包括收發電子郵件、使用應用程式和瀏覽網站) 可能會受到這個應用程式監控。\n\n如要瞭解詳情,請與你的管理員聯絡。"</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"你的 Work 設定檔是由「<xliff:g id="ORGANIZATION">%1$s</xliff:g>」所管理。由於該設定檔已連結至「<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>」,因此你的網路活動 (包括收發電子郵件、使用應用程式和瀏覽網站) 可能會受到這個應用程式監控。\n\n此外,你還與「<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>」建立了連結,因此你的個人網路活動也可能會受到該應用程式監控。"</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"已為<xliff:g id="USER_NAME">%1$s</xliff:g>解鎖"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"「<xliff:g id="TRUST_AGENT">%1$s</xliff:g>」執行中"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在你手動解鎖前,裝置將保持鎖定狀態"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"不用了,謝謝"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"設定"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"立即停用"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"立刻結束"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收合"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"只要使用電源通知控制項,你就能為應用程式通知設定從 0 到 5 的重要性等級。\n\n"<b>"等級 5"</b>" \n- 顯示在通知清單頂端 \n- 允許全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 4"</b>" \n- 禁止全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 3"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n\n"<b>"等級 2"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n\n"<b>"等級 1"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n- 在鎖定畫面和狀態列中隱藏 \n- 顯示在通知清單底端 \n\n"<b>"等級 0"</b>" \n- 封鎖應用程式的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"你不會再收到這類通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"你不會再收到這類通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"這個應用程式沒有通知類別"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="other">在 <xliff:g id="NUMBER_1">%d</xliff:g> 個通知類別中,有 1 個類別是來自這個應用程式</item>
       <item quantity="one">在 <xliff:g id="NUMBER_0">%d</xliff:g> 個通知類別中,有 1 個類別是來自這個應用程式</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延後選項"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 小時"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_car.xml b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
index e420fe7..01f3b14 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_car.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全駕駛"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時注意周遭路況並遵守交通規則。系統所提供的路線可能有誤、不完整,或包含危險、不合適、禁止通行或管制區域的路段;此外,商家資訊也可能有誤或不完整。路況資料並非即時更新,也無法保證定位資訊必然準確無誤。駕駛時請勿操作你的行動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"不明"</string>
+    <string name="start_driving" msgid="864023351402918991">"開始駕駛"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 80ce905..bc82fc0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -352,8 +352,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="zen_priority_introduction" msgid="7577965386868311310">"Ngeke uphazanyiswe yimisindo nokudlidliza, ngaphandle kwama-alamu, izikhumbuzi, izehlakalo, nabashayi obacacisayo. Usazokuzwa okuthile okhetha ukudlala kufaka phakathi umculo, amavidiyo, namageyimu."</string>
-    <string name="zen_alarms_introduction" msgid="7034415210361973827">"Ngeke uphazanyiswe yimisindo nokudlidliza, ngaphandle kwama-alamu. Usazokuzwa okuthile okhetha ukudlala kufaka phakathi umculo, amavidiyo, namageyimu."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Ngeke uze uphazanyiswe yimisindo nokudlidliza, ngaphandle kokuvela kuma-alamu, izikhumbuzi, imicimbi, nabashayi obacacisayo."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Enza ngendlela oyifisayo"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Lokhu kuvimbela YONKE imisindo nokudludliza, kufaka phakathi ama-alamu, umculo, amavidiyo, namageyimu. Usazokwazi ukwenza amkholi wefoni."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Lokhu kuvimbela YONKE imisindo nokudlidliza, kufaka phakathi kusuka kuma-alamu, umculo, amavidiyo, namageyimu."</string>
@@ -467,13 +466,15 @@
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Uxhumeke ku-<xliff:g id="APPLICATION">%1$s</xliff:g>, engaqapha umsebenzi wakho womuntu siqu wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi."</string>
     <string name="monitoring_description_app_work" msgid="4612997849787922906">"Iphrofayela yakho yomsebenzi iphethwe i-<xliff:g id="ORGANIZATION">%1$s</xliff:g>. Iphrofayela ixhumeke ku-<xliff:g id="APPLICATION">%2$s</xliff:g>, engaqapha umsebenzi wenethiwekhi yakho yokusebenza, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi.\n\nUkuze uthole olunye ulwazi, xhumana nomlawuli wakho."</string>
     <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"Iphrofayela yakho yomsebenzi iphethwe i-<xliff:g id="ORGANIZATION">%1$s</xliff:g>. Iphrofayela ixhumeke ku-<xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, engaqapha umsebenzi wakho wenethiwekhi, ofaka ama-imeyili, izinhlelo zokusebenza, namawebhusayithi.\n\nFuthi uxhumeke ku-<xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, engaqapha umsebenzi wakho siqu wenethiwekhi."</string>
+    <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Kuvulelwe u-<xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> iyasebenza"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Idivayisi izohlala ikhiyekile uze uyivule ngokwenza"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Thola izaziso ngokushesha"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ibone ngaphambi kokuthi uyivule"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Cha ngiyabonga"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Lungisa"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="volume_zen_end_now" msgid="6930243045593601084">"Vala manje"</string>
+    <string name="volume_zen_end_now" msgid="3179845345429841822">"Qeda manje"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Nweba"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Goqa"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Isikrini siphiniwe"</string>
@@ -548,9 +549,11 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Valiwe"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ngezilawuli zesaziso zamandla, ungasetha ileveli ebalulekile kusuka ku-0 kuya ku-5 kusuka kuzaziso zohlelo lokusebenza. \n\n"<b>"Ileveli 5"</b>" \n- Ibonisa phezulu kuhlu lwesaziso \n- Vumela ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 4"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 3"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n\n"<b>"Ileveli 2"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo nokudlidliza \n\n"<b>"Ileveli 1"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo noma ukudlidliza \n- Fihla kusuka kusikrini sokukhiya nebha yesimo \n- Bonisa phansi kohlu lwesaziso \n\n"<b>"Ileveli 0"</b>" \n- Vimbela zonke izaziso kusuka kuhlelo lokusebenza"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Izaziso"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ngeke usathola lezi zaziso."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ngeke usathola izaziso"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> izigaba zesaziso"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Lolu hlelo lokusebenza alunazo izigaba zesaziso"</string>
+    <!-- no translation found for notification_unblockable_desc (3561016061737896906) -->
+    <skip />
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
       <item quantity="one">1 isigaba kwezingu-<xliff:g id="NUMBER_1">%d</xliff:g> sezaziso kusukela kulolu hlelo lokusebenza</item>
       <item quantity="other">1 isigaba kwezingu-<xliff:g id="NUMBER_1">%d</xliff:g> sezaziso kusukela kulolu hlelo lokusebenza</item>
@@ -570,12 +573,10 @@
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"izilawuli zesaziso"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"izinketho zokusnuza zesaziso"</string>
-    <string name="snooze_option_15_min" msgid="1068727451405610715">"15 amaminithi"</string>
-    <string name="snooze_option_30_min" msgid="867081342535195788">"30 amaminithi"</string>
-    <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ihora"</string>
-    <string name="snooze_option_2_hour" msgid="8332218255658969475">"2 amahora"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"HLEHLISA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Kusnuzwe u-<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
     <string name="battery_panel_title" msgid="7944156115535366613">"Ukusetshenziswa kwebhethri"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
diff --git a/packages/SystemUI/res/values-zu/strings_car.xml b/packages/SystemUI/res/values-zu/strings_car.xml
index 83301ac..3eddfd4 100644
--- a/packages/SystemUI/res/values-zu/strings_car.xml
+++ b/packages/SystemUI/res/values-zu/strings_car.xml
@@ -19,6 +19,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Shayela ngokuqophelela"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Hlala wazi ngokugcwele izimo zokushayela uphinde uthobele yonke imithetho esebenzayo. Izikhombisi-ndlela kungenzeka azilungile, aziphelele, ziyingozi, azifanelekile, zivinjiwe, noma zifaka ukweqa izindawo zokulawula. Ulwazi lwebhizinisi kungenzeka lungalungi noma lungapheleli. Idatha akuyona isikhathi sangempela, futhi ukunemba kwendawo akukwazi ukuqinisekiswa. Ungaphathi idivayisi yakho yeselula noma usebenzise izinhlelo zokusebenza ezihloselwe i-Android Auto ngenkathi ushayela."</string>
+    <string name="unknown_user_label" msgid="4323896111737677955">"Akwaziwa"</string>
+    <string name="start_driving" msgid="864023351402918991">"Qala ukushayela"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 06b945d..745d6015 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -124,12 +124,10 @@
     <declare-styleable name="PluginInflateContainer">
         <attr name="viewType" format="string" />
     </declare-styleable>
-    <declare-styleable name="ScrimView">
-        <!-- The initial color for the scrim. -->
-        <attr name="scrimColor" format="color" />
-    </declare-styleable>
 
     <attr name="lightIconTheme" format="reference" />
     <attr name="darkIconTheme" format="reference" />
+    <attr name="wallpaperTextColor" format="reference|color" />
+    <attr name="wallpaperTextColorSecondary" format="reference|color" />
 </resources>
 
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 83a0b7b..f72f379 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -32,7 +32,6 @@
     <color name="qs_detail_button">@*android:color/quaternary_device_default_settings</color>
     <color name="qs_detail_button_white">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_detail_transition">#66FFFFFF</color>
-    <color name="scrim_behind_color">@android:color/black</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
     <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
     <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
@@ -78,6 +77,9 @@
     <!-- The color of the material notification background when low priority -->
     <color name="notification_material_background_low_priority_color">#fff5f5f5</color>
 
+    <!-- The color of the dividing line between grouped notifications. -->
+    <color name="notification_divider_color">#FF616161</color>
+
     <!-- The background color of the notification shade -->
     <color name="notification_shade_background_color">#ffeeeeee</color>
 
@@ -144,4 +146,6 @@
 
     <color name="instant_apps_color">#ff4d5a64</color>
 
+    <color name="zen_introduction">#ffffffff</color>
+
 </resources>
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml
new file mode 100644
index 0000000..4faf252
--- /dev/null
+++ b/packages/SystemUI/res/values/colors_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+<resources>
+    <color name="car_user_switcher_progress_bgcolor">#00000000</color> <!-- Transparent -->
+    <color name="car_user_switcher_progress_fgcolor">#80CBC4</color> <!-- Teal 200 -->
+    <color name="car_start_driving_background">#FAFAFA</color> <!-- Grey 50 -->
+    <color name="car_start_driving_text">#212121</color> <!-- Grey 900 -->
+</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index fd7e165..a077fdb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -210,9 +210,12 @@
     <!-- Set to true to enable the user switcher on the keyguard. -->
     <bool name="config_keyguardUserSwitcher">false</bool>
 
-    <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND?  -->
+    <!-- Doze: does this device support STATE_DOZE?  -->
     <bool name="doze_display_state_supported">false</bool>
 
+    <!-- Doze: does this device support STATE_DOZE_SUSPEND?  -->
+    <bool name="doze_suspend_display_state_supported">false</bool>
+
     <!-- Doze: should the significant motion sensor be used as a pulse signal? -->
     <bool name="doze_pulse_on_significant_motion">false</bool>
 
@@ -244,6 +247,11 @@
     -->
     <string name="doze_pickup_subtype_performs_proximity_check"></string>
 
+    <!-- Type of a sensor that provides a low-power estimate of the desired display
+         brightness, suitable to listen to while the device is asleep (e.g. during
+         always-on display) -->
+    <string name="doze_brightness_sensor_type" translatable="false"></string>
+
     <!-- Doze: pulse parameter - how long does it take to fade in? -->
     <integer name="doze_pulse_duration_in">900</integer>
 
@@ -259,6 +267,31 @@
     <!-- Doze: alpha to apply to small icons when dozing -->
     <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
 
+    <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+               to brightness values; -1 means keeping the current brightness. -->
+    <integer-array name="config_doze_brightness_sensor_to_brightness">
+        <item>-1</item> <!-- 0: OFF -->
+        <item>2</item> <!-- 1: NIGHT -->
+        <item>5</item> <!-- 2: LOW -->
+        <item>27</item> <!-- 3: HIGH -->
+        <item>28</item> <!-- 4: SUN -->
+    </integer-array>
+
+    <!-- Doze: Table that translates sensor values from the doze_brightness_sensor_type sensor
+               to an opacity value for a black scrim that is overlayed in AOD1.
+               Valid range is from 0 (transparent) to 255 (opaque).
+               -1 means keeping the current opacity. -->
+    <integer-array name="config_doze_brightness_sensor_to_scrim_opacity">
+        <item>-1</item> <!-- 0: OFF -->
+        <item>0</item> <!-- 1: NIGHT -->
+        <item>0</item> <!-- 2: LOW -->
+        <item>0</item> <!-- 3: HIGH -->
+        <item>0</item> <!-- 4: SUN -->
+    </integer-array>
+
+    <!-- Doze: whether the double tap sensor reports 2D touch coordinates -->
+    <bool name="doze_double_tap_reports_touch_coordinates">false</bool>
+
     <!-- Hotspot tile: number of days to show after feature is used. -->
     <integer name="days_to_show_hotspot_tile">30</integer>
 
@@ -287,7 +320,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
 
     <!-- Nav bar button default ordering/layout -->
-    <string name="config_navBarLayout" translatable="false">left,back;home;recent,right</string>
+    <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
 
     <bool name="quick_settings_show_full_alarm">false</bool>
 
@@ -295,9 +328,13 @@
     <integer name="config_showTemperatureWarning">0</integer>
 
     <!-- Temp at which to show a warning notification if config_showTemperatureWarning is true.
-         If < 0, uses the value from HardwarePropertiesManager#getDeviceTemperatures. -->
+         If < 0, uses the value from
+         HardwarePropertiesManager#getDeviceTemperatures - config_warningTemperatureTolerance. -->
     <integer name="config_warningTemperature">-1</integer>
 
+    <!-- Fudge factor for how much below the shutdown temp to show the warning. -->
+    <integer name="config_warningTemperatureTolerance">2</integer>
+
     <!-- Accessibility actions -->
     <item type="id" name="action_split_task_to_left" />
     <item type="id" name="action_split_task_to_right" />
@@ -336,4 +373,64 @@
     <!-- Whether to show activity indicators in the status bar -->
     <bool name="config_showActivity">false</bool>
 
+    <!-- Whether or not the button to clear all notifications will be shown. -->
+    <bool name="config_enableNotificationsClearAll">true</bool>
+
+    <!-- Whether or not to show the notification shelf that houses the icons of notifications that
+     have been scrolled off-screen. -->
+    <bool name="config_showNotificationShelf">true</bool>
+
+    <!-- Whether or not the notifications should always fade as they are dismissed. -->
+    <bool name="config_fadeNotificationsOnDismiss">false</bool>
+
+    <!-- Whether or not the parent of the notification row itself is being translated when swiped or
+         its children views. If true, then the contents are translated and vice versa. -->
+    <bool name="config_translateNotificationContentsOnSwipe">true</bool>
+
+    <!-- Whether or not the fade on the notification is based on the amount that it has been swiped
+         off-screen. -->
+    <bool name="config_fadeDependingOnAmountSwiped">false</bool>
+
+    <!-- Whether or not to show the expand button at the end of the notification header. -->
+    <bool name="config_showNotificationExpandButtonAtEnd">false</bool>
+
+    <!-- Whether or the notifications should be clipped to be reduced in height if it has been
+         scrolled to the top of the screen. -->
+    <bool name="config_clipNotificationScrollToTop">true</bool>
+
+    <!-- Whether or not the notification contents should be clipped to any background that is
+         set on the notification container. For example, if this value is true and the background
+         has rounded corners, then the contents will be clipped to those corners. -->
+    <bool name="config_clipNotificationsToOutline">false</bool>
+
+    <!-- Whether or not notifications that can be expanded will always be in their expanded state.
+         This value only affects notifications that are not a group of notifications from the same
+         applications. If this value is false, then only the first notification will be expanded;
+         the other notifications need to be manually expanded by the user. -->
+    <bool name="config_alwaysExpandNonGroupedNotifications">false</bool>
+
+    <!-- Whether or not an expandable notification can be manually expanded or collapsed by the
+         user. Grouped notifications are still expandable even if this value is false. -->
+    <bool name="config_enableNonGroupedNotificationExpand">true</bool>
+
+    <!-- Whether or not there should be dividing lines between child notifications when the
+         group has been expanded. -->
+    <bool name="config_showDividersWhenGroupNotificationExpanded">false</bool>
+
+    <!-- Whether or not the dividing lines should be shown when the container is expanding and
+         collapsing. If this value is true, then the lines will only show when the container has
+         been completely expanded. -->
+    <bool name="config_hideDividersDuringExpand">false</bool>
+
+    <!-- Whether or not child notifications that are part of a group will have shadows. -->
+    <bool name="config_enableShadowOnChildNotifications">true</bool>
+
+    <!-- Whether or not a view containing child notifications will have a custom background when
+         it has been expanded to reveal its children. -->
+    <bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
+
+    <!-- Whether to artificially interpret all signal strengths as
+         one bar higher than they actually are -->
+    <bool name="config_inflateSignalStrength">false</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f66a09e..94687de 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -101,6 +101,9 @@
     <!-- Height of a the shelf with the notification icons -->
     <dimen name="notification_shelf_height">32dp</dimen>
 
+    <!-- Minimum height of a notification to be interactable -->
+    <dimen name="notification_min_interaction_height">40dp</dimen>
+
     <!-- the padding of the shelf icon container -->
     <dimen name="shelf_icon_container_padding">13dp</dimen>
 
@@ -204,8 +207,18 @@
     <!-- Width for the notification panel and related windows -->
     <dimen name="match_parent">-1px</dimen>
     <dimen name="standard_notification_panel_width">416dp</dimen>
+
+    <!-- The top margin of the panel that holds the list of notifications. -->
+    <dimen name="notification_panel_margin_top">0dp</dimen>
+
+    <!-- The bottom margin of the panel that holds the list of notifications. -->
+    <dimen name="notification_panel_margin_bottom">0dp</dimen>
+
     <dimen name="notification_panel_width">@dimen/match_parent</dimen>
 
+    <!-- The width of the panel that holds the quick settings. -->
+    <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
+
     <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
 
     <!-- Gravity for the notification panel -->
@@ -323,6 +336,22 @@
     <!-- The height of the divider between the individual notifications. -->
     <dimen name="notification_divider_height">0.5dp</dimen>
 
+    <!-- The corner radius of the shadow behind the notification. -->
+    <dimen name="notification_shadow_radius">0dp</dimen>
+
+    <!-- The alpha of the dividing line between child notifications of a notification group. -->
+    <item name="notification_divider_alpha" format="float" type="dimen">0.5</item>
+
+    <!-- The height of the divider between the individual notifications in a notification
+         group. -->
+    <dimen name="notification_children_container_divider_height">@dimen/notification_divider_height</dimen>
+
+    <!-- The height of the header for a container containing child notifications. -->
+    <dimen name="notification_children_container_header_height">53dp</dimen>
+
+    <!-- The top margin for the notification children container in its non-expanded form. -->
+    <dimen name="notification_children_container_margin_top">@*android:dimen/notification_content_margin_top</dimen>
+
     <!-- The height of a notification header -->
     <dimen name="notification_header_height">53dp</dimen>
 
@@ -755,6 +784,9 @@
     <!-- The shortest-edge size of the expanded PiP. -->
     <dimen name="pip_expanded_shortest_edge_size">160dp</dimen>
 
+    <!-- The additional offset to apply to the IME animation to account for the input field. -->
+    <dimen name="pip_ime_offset">48dp</dimen>
+
     <!-- The padding between actions in the PiP in landscape  Note that the PiP does not reflect
          the configuration of the device, so we can't use -land resources. -->
     <dimen name="pip_between_action_padding_land">8dp</dimen>
@@ -774,9 +806,34 @@
 
     <dimen name="signal_icon_size">17dp</dimen>
 
-    <dimen name="qs_gutter_height">6dp</dimen>
+    <dimen name="hwui_edge_margin">16dp</dimen>
 
-    <!-- Width of the hollow triangle for empty signal state -->
-    <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
+    <dimen name="global_actions_panel_width">120dp</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 -->
+    <dimen name="burn_in_prevention_offset_x">8dp</dimen>
+
+    <!-- the maximum offset in either direction that elements are moved vertically to prevent
+            burn-in on AOD -->
+    <dimen name="burn_in_prevention_offset_y">50dp</dimen>
+
+    <!-- padding between the notification stack and the keyguard status view when dozing -->
+    <dimen name="dozing_stack_padding">10dp</dimen>
+
+    <dimen name="corner_size">16dp</dimen>
+    <dimen name="top_padding">0dp</dimen>
+    <dimen name="bottom_padding">48dp</dimen>
+    <dimen name="edge_margin">16dp</dimen>
+
+    <dimen name="rounded_corner_radius">0dp</dimen>
+    <dimen name="rounded_corner_content_padding">8dp</dimen>
+
+    <!-- Intended corner radius when drawing the mobile signal -->
+    <dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
+    <!-- How far to inset the rounded edges -->
+    <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
 </resources>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 988caf5..d5d4e10 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -16,18 +16,24 @@
 */
 -->
 <resources>
-    <dimen name="car_lockscreen_disclaimer_title_size">48sp</dimen>
-    <dimen name="car_lockscreen_disclaimer_title_padding_start">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_title_padding_top">82dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_size">28sp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_start">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_end">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_top">8dp</dimen>
-    <dimen name="car_lockscreen_user_grid_view_padding_start">10dp</dimen>
-    <dimen name="car_lockscreen_user_grid_view_padding_end">10dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_width">128dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_height">128dp</dimen>
-    <dimen name="car_fullscreen_user_pod_text_size">24sp</dimen>
+    <dimen name="car_margin">148dp</dimen>
+
+    <dimen name="car_fullscreen_user_pod_margin_side">44dp</dimen>
+    <dimen name="car_fullscreen_user_pod_margin_above_text">24dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_width">192dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_height">192dp</dimen>
+    <dimen name="car_fullscreen_user_pod_text_size">40sp</dimen> <!-- B1 -->
+
     <dimen name="car_navigation_button_width">64dp</dimen>
     <dimen name="car_navigation_bar_width">760dp</dimen>
+
+    <dimen name="car_page_indicator_dot_diameter">12dp</dimen>
+    <dimen name="car_page_indicator_margin_top">32dp</dimen>
+
+    <dimen name="car_user_switcher_progress_bar_height">6dp</dimen>
+    <dimen name="car_user_switcher_progress_bar_margin_top">@dimen/status_bar_height</dimen>
+    <dimen name="car_start_driving_corner_radius">16dp</dimen>
+    <dimen name="car_start_driving_padding_side">30dp</dimen>
+    <dimen name="car_start_driving_height">80dp</dimen>
+    <dimen name="car_start_driving_text_size">32sp</dimen> <!-- B2 -->
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index fc0c82c..b27dedd 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -45,6 +45,7 @@
     <item type="id" name="shadow_alpha_animator_start_value_tag"/>
     <item type="id" name="doze_saved_filter_tag"/>
     <item type="id" name="qs_icon_tag"/>
+    <item type="id" name="qs_slash_tag"/>
     <item type="id" name="scrim"/>
     <item type="id" name="scrim_target"/>
     <item type="id" name="scrim_alpha_start"/>
@@ -77,5 +78,13 @@
     <item type="id" name="action_move_tl_50" />
     <item type="id" name="action_move_tl_30" />
     <item type="id" name="action_move_rb_full" />
+
+    <!-- Accessibility actions for the notification menu -->
+    <item type="id" name="action_snooze_undo"/>
+    <item type="id" name="action_snooze_15_min"/>
+    <item type="id" name="action_snooze_30_min"/>
+    <item type="id" name="action_snooze_1_hour"/>
+    <item type="id" name="action_snooze_2_hours"/>
+    <item type="id" name="action_snooze_assistant_suggestion_1"/>
 </resources>
 
diff --git a/packages/SystemUI/res/values/integers_car.xml b/packages/SystemUI/res/values/integers_car.xml
new file mode 100644
index 0000000..320ee9f
--- /dev/null
+++ b/packages/SystemUI/res/values/integers_car.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <integer name="car_user_switcher_timeout_ms">15000</integer>
+    <!-- This values less than ProgressBar.PROGRESS_ANIM_DURATION for a smooth animation. -->
+    <integer name="car_user_switcher_anim_update_ms">60</integer>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 994a566..6202d13 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -741,6 +741,8 @@
     <string name="quick_settings_done">Done</string>
     <!-- QuickSettings: Control panel: Label for connected device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connected">Connected</string>
+    <!-- QuickSettings: Control panel: Label for connected device, showing remote device battery level. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_connected_battery_level">Connected, battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
     <!-- QuickSettings: Control panel: Label for connecting device. [CHAR LIMIT=NONE] -->
     <string name="quick_settings_connecting">Connecting...</string>
     <!-- QuickSettings: Tethering. [CHAR LIMIT=NONE] -->
@@ -1195,6 +1197,12 @@
         <xliff:g id="application_personal">%3$s</xliff:g>, which can monitor your personal network
         activity.</string>
 
+    <!-- Indication on the keyguard that appears when a trust agents unlocks the device. [CHAR LIMIT=40] -->
+    <string name="keyguard_indication_trust_granted">Unlocked for <xliff:g id="user_name" example="John Doe">%1$s</xliff:g></string>
+
+    <!-- Indication on the keyguard that appears when a trust agent is active and available. [CHAR LIMIT=40] -->
+    <string name="keyguard_indication_trust_managed"><xliff:g id="trust_agent" example="Smart Lock">%1$s</xliff:g> is running</string>
+
     <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
     <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
 
@@ -1442,7 +1450,7 @@
     <string name="notification_header_default_channel">Notifications</string>
 
     <!-- Notification Inline Controls: Shown when a channel's notifications are currently blocked -->
-    <string name="notification_channel_disabled">You won\'t get these notifications anymore.</string>
+    <string name="notification_channel_disabled">You won\'t get these notifications anymore</string>
 
     <!-- Notification: Control panel: Label that shows how many channels are included in this bundle
         of notifications.  Replaces the channel name and only appears when there is more than one channel. -->
@@ -1452,6 +1460,9 @@
         Hints that the user's only option is to block all of the app's notifications. -->
     <string name="notification_default_channel_desc">This app doesn\'t have notification categories</string>
 
+    <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
+    <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string>
+
     <!-- Notification: Control panel: Label that shows how many channels this application has
         defined, describing the current notification channel as "1 out of n notification categories from this app". -->
     <plurals name="notification_num_channels_desc">
@@ -1502,20 +1513,27 @@
     <!-- Notification: Menu row: Content description for the snooze icon. [CHAR LIMIT=NONE] -->
     <string name="notification_menu_snooze_description">notification snooze options</string>
 
-    <!-- Notification: Menu row: Snooze options: 15 minute option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_15_min">15 minutes</string>
-    <!-- Notification: Menu row: Snooze options: 30 minute option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_30_min">30 minutes</string>
-    <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_1_hour">1 hour</string>
-    <!-- Notification: Menu row: Snooze options: 1 hour option. [CHAR LIMIT=50]-->
-    <string name="snooze_option_2_hour">2 hours</string>
-    <!-- Notification: Menu row: Snooze undo button label. [CHAR LIMIT=50]-->
+    <!-- Notification: Snooze panel: Snooze undo button label. [CHAR LIMIT=50]-->
     <string name="snooze_undo">UNDO</string>
 
-    <!-- Notification: Menu row: Snooze: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
+    <!-- Notification: Snooze panel: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
     <string name="snoozed_for_time">Snoozed for <xliff:g id="time_amount" example="15 minutes">%1$s</xliff:g></string>
 
+    <!-- Notification:Snooze panel: Snooze options for hours -->
+    <plurals name="snoozeHourOptions">
+        <item quantity="one">%d hour</item>
+        <item quantity="two">%d hours</item>
+        <item quantity="few">%d hours</item>
+        <item quantity="other">%d hours</item>
+    </plurals>
+
+   <!--  Notification: Snooze panel: Snooze options for minutes -->
+   <plurals name="snoozeMinuteOptions">
+        <item quantity="one">%d minute</item>
+        <item quantity="few">%d minutes</item>
+        <item quantity="other">%d minutes</item>
+    </plurals>
+
     <!-- Title of the battery settings detail panel [CHAR LIMIT=20] -->
     <string name="battery_panel_title">Battery usage</string>
 
@@ -2028,4 +2046,7 @@
         been identified for them as running). [CHAR LIMIT=NONE] -->
     <string name="running_foreground_services_msg">Tap for details on battery and data usage</string>
 
+    <!-- Prompt to turn off data usage [CHAR LIMIT=NONE] -->
+    <string name="data_usage_disable_mobile" msgid="8656552431969276305">Turn off mobile data?</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/strings_car.xml b/packages/SystemUI/res/values/strings_car.xml
index 882773a..658eb4f 100644
--- a/packages/SystemUI/res/values/strings_car.xml
+++ b/packages/SystemUI/res/values/strings_car.xml
@@ -17,13 +17,6 @@
  */
 -->
 <resources>
-    <string name="car_lockscreen_disclaimer_title">Drive safely</string>
-    <string name="car_lockscreen_disclaimer_text">
-        Stay fully aware of driving conditions and always obey applicable laws. Directions may be
-        inaccurate, incomplete, dangerous, not suitable, prohibited, or involve crossing
-        administrative areas. Business information may also be inaccurate or incomplete. Data is
-        not real-time, and location accuracy cannot be guaranteed. Do not handle your mobile device
-        or use apps not intended for Android Auto while driving.
-    </string>
-
+    <string name="unknown_user_label">Unknown</string>
+    <string name="start_driving">Start Driving</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d98b789..aacb4aa 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -27,7 +27,6 @@
         <item name="android:ambientShadowAlpha">0.35</item>
     </style>
 
-
     <!-- Recents theme -->
     <style name="RecentsTheme.Wallpaper">
         <item name="android:windowBackground">@*android:color/transparent</item>
@@ -35,6 +34,13 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowDisablePreview">true</item>
         <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+    </style>
+
+    <style name="RecentsTheme.Wallpaper.Light">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
     </style>
 
     <style name="ClearAllButtonDefaultMargins">
@@ -47,6 +53,8 @@
     <!-- Performance optimized Recents theme (no wallpaper) -->
     <style name="RecentsTheme.NoWallpaper">
         <item name="android:windowBackground">@android:color/black</item>
+        <item name="wallpaperTextColor">@android:color/white</item>
+        <item name="wallpaperTextColorSecondary">@android:color/white</item>
     </style>
 
     <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
@@ -210,6 +218,7 @@
 
     <style name="TextAppearance.QS.Introduction">
         <item name="android:textSize">14sp</item>
+        <item name="android:textColor">@color/zen_introduction</item>
     </style>
 
     <style name="TextAppearance.QS.Warning">
@@ -226,7 +235,7 @@
     </style>
 
     <style name="TextAppearance.QS.DetailButton.White">
-        <item name="android:textColor">@color/qs_detail_button_white</item>
+        <item name="android:textColor">@color/zen_introduction</item>
     </style>
 
     <style name="TextAppearance.QS.DetailEmpty">
@@ -290,11 +299,36 @@
     <style name="Animation.StatusBar">
     </style>
 
-    <style name="systemui_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
         <item name="lightIconTheme">@style/DualToneLightTheme</item>
         <item name="darkIconTheme">@style/DualToneDarkTheme</item>
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+        <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
+        <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
+        <item name="passwordStyle">@style/PasswordTheme</item>
+
+        <!-- Needed for MediaRoute chooser dialog -->
+        <item name="*android:isLightTheme">false</item>
     </style>
-    <style name="qs_theme" parent="systemui_theme">
+
+    <style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+        <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+        <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
+        <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item>
+        <item name="passwordStyle">@style/PasswordTheme.Light</item>
+    </style>
+
+    <style name="LockPatternStyle">
+        <item name="*android:regularColor">?attr/wallpaperTextColor</item>
+        <item name="*android:successColor">?attr/wallpaperTextColor</item>
+        <item name="*android:errorColor">?android:attr/colorError</item>
+    </style>
+
+    <!-- Overlay manager may replace this theme -->
+    <style name="qs_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings" />
+
+    <style name="qs_theme" parent="qs_base">
         <item name="lightIconTheme">@style/QSIconTheme</item>
         <item name="darkIconTheme">@style/QSIconTheme</item>
     </style>
@@ -307,6 +341,8 @@
 
     <style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
 
+    <style name="Theme.SystemUI.Dialog.GlobalActions" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen" />
+
     <style name="QSBorderlessButton">
         <item name="android:padding">12dp</item>
         <item name="android:background">@drawable/qs_btn_borderless_rect</item>
@@ -448,7 +484,7 @@
         <item name="android:paddingEnd">8dp</item>
     </style>
 
-    <style name="edit_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+    <style name="edit_theme" parent="qs_base">
         <item name="android:colorBackground">?android:attr/colorSecondary</item>
     </style>
 
diff --git a/packages/SystemUI/res/values/styles_car.xml b/packages/SystemUI/res/values/styles_car.xml
new file mode 100644
index 0000000..c66792c
--- /dev/null
+++ b/packages/SystemUI/res/values/styles_car.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="CarUserSwitcher.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
+        <item name="android:progressDrawable">@drawable/car_progress_bar</item>
+        <item name="android:min">0</item>
+        <item name="android:max">@integer/car_user_switcher_timeout_ms</item>
+        <item name="android:progress">0</item>
+        <item name="android:interpolator">@android:anim/linear_interpolator</item>
+    </style>
+
+    <style name="CarUserSwitcher.StartDrivingButton" parent="@android:style/Widget.Material.Button">
+        <item name="android:background">@drawable/car_round_button</item>
+        <item name="android:textSize">@dimen/car_start_driving_text_size</item>
+        <item name="android:textColor">@color/car_start_driving_text</item>
+        <item name="android:paddingLeft">@dimen/car_start_driving_padding_side</item>
+        <item name="android:paddingRight">@dimen/car_start_driving_padding_side</item>
+    </style>
+</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 223dafd..32f502b 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -128,7 +128,7 @@
         <com.android.systemui.tuner.TunerSwitch
           android:key="doze_always_on"
           android:title="@string/tuner_doze_always_on"
-          sysui:defValue="false" />
+          sysui:defValue="true" />
 
     </PreferenceScreen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
index 80509a6..6a83c71 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -36,6 +36,9 @@
     @Override
     public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(host, event);
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return;
+        }
         CharSequence text = event.getContentDescription();
         if (!TextUtils.isEmpty(text)) {
             event.setContentDescription(replaceFancyColon(text));
@@ -44,15 +47,22 @@
 
     @Override
     public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
-        CharSequence text = ((TextView) host).getText();
-        if (!TextUtils.isEmpty(text)) {
-            event.getText().add(replaceFancyColon(text));
+        if (TextUtils.isEmpty(mFancyColon)) {
+            super.onPopulateAccessibilityEvent(host, event);
+        } else {
+            CharSequence text = ((TextView) host).getText();
+            if (!TextUtils.isEmpty(text)) {
+                event.getText().add(replaceFancyColon(text));
+            }
         }
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(host, info);
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return;
+        }
         if (!TextUtils.isEmpty(info.getText())) {
             info.setText(replaceFancyColon(info.getText()));
         }
@@ -62,6 +72,13 @@
     }
 
     private CharSequence replaceFancyColon(CharSequence text) {
+        if (TextUtils.isEmpty(mFancyColon)) {
+            return text;
+        }
         return text.toString().replace(mFancyColon, ":");
     }
+
+    public static boolean isNeeded(Context context) {
+        return !TextUtils.isEmpty(context.getString(R.string.keyguard_fancy_colon));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
new file mode 100644
index 0000000..ce3068d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
@@ -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.
+ */
+
+package com.android.keyguard;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+
+/***
+ * This button is used by the device with embedded SIM card to disable current carrier to unlock
+ * the device with no cellular service.
+ */
+class KeyguardEsimArea extends Button implements View.OnClickListener {
+    private static final String ACTION_DISABLE_ESIM = "com.android.keyguard.disable_esim";
+    private static final String TAG = "KeyguardEsimArea";
+    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+
+    private EuiccManager mEuiccManager;
+
+    private BroadcastReceiver mReceiver =
+        new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (ACTION_DISABLE_ESIM.equals(intent.getAction())) {
+                    int resultCode = getResultCode();
+                    if (resultCode != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                        // TODO (b/62680294): Surface more info. to the end users for this failure.
+                        Log.e(TAG, "Error disabling esim, result code = " + resultCode);
+                    }
+                }
+            }
+        };
+
+    public KeyguardEsimArea(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, android.R.style.Widget_Material_Button_Borderless);
+    }
+
+    public KeyguardEsimArea(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setOnClickListener(this);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_DISABLE_ESIM),
+                PERMISSION_SELF, null /* scheduler */);
+    }
+
+    public static boolean isEsimLocked(Context context, int subId) {
+        EuiccManager euiccManager =
+                (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
+        if (!euiccManager.isEnabled()) {
+            return false;
+        }
+        SubscriptionInfo sub = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
+        return  sub != null && sub.isEmbedded();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mContext.unregisterReceiver(mReceiver);
+        super.onDetachedFromWindow();
+    }
+
+    @Override
+    public void onClick(View v) {
+        Intent intent = new Intent(mContext, KeyguardEsimArea.class);
+        intent.setAction(ACTION_DISABLE_ESIM);
+        intent.setPackage(mContext.getPackageName());
+        PendingIntent callbackIntent = PendingIntent.getBroadcast(
+            mContext,
+            0 /* requestCode */,
+            intent,
+            PendingIntent.FLAG_UPDATE_CURRENT);
+        mEuiccManager
+                .switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, callbackIntent);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 616e5b9..27bc599 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -21,6 +21,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
@@ -75,8 +76,7 @@
     }
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
-        super(new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault), attrs,
-                defStyle);
+        super(context, attrs, defStyle);
         mSecurityModel = new KeyguardSecurityModel(context);
         mLockPatternUtils = new LockPatternUtils(context);
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
@@ -471,7 +471,8 @@
         return 0;
     }
 
-    protected int getLayoutIdFor(SecurityMode securityMode) {
+    @VisibleForTesting
+    public int getLayoutIdFor(SecurityMode securityMode) {
         switch (securityMode) {
             case Pattern: return R.layout.keyguard_pattern_view;
             case PIN: return R.layout.keyguard_pin_view;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 16a0e5a..432b406 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -35,8 +35,10 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
@@ -91,10 +93,11 @@
         if (DEBUG) Log.v(TAG, "Resetting state");
         KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
         mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
+        boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
         if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
             int count = TelephonyManager.getDefault().getSimCount();
             Resources rez = getResources();
-            final String msg;
+            String msg;
             int color = Color.WHITE;
             if (count < 2) {
                 msg = rez.getString(R.string.kg_sim_pin_instructions);
@@ -106,9 +109,14 @@
                     color = info.getIconTint();
                 }
             }
+            if (isEsimLocked) {
+                msg = msg + " " + rez.getString(R.string.kg_sim_lock_instructions_esim);
+            }
             mSecurityMessageDisplay.setMessage(msg);
             mSimImageView.setImageTintList(ColorStateList.valueOf(color));
         }
+        KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
+        esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index fddb12d..7f79008 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -29,8 +29,10 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
@@ -136,10 +138,11 @@
             state = ENTER_PUK;
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
+            boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
             if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
                 int count = TelephonyManager.getDefault().getSimCount();
                 Resources rez = getResources();
-                final String msg;
+                String msg;
                 int color = Color.WHITE;
                 if (count < 2) {
                     msg = rez.getString(R.string.kg_puk_enter_puk_hint);
@@ -151,11 +154,18 @@
                         color = info.getIconTint();
                     }
                 }
+                if (isEsimLocked) {
+                    msg = msg + " " + rez.getString(R.string.kg_sim_lock_instructions_esim);
+                }
                 mSecurityMessageDisplay.setMessage(msg);
                 mSimImageView.setImageTintList(ColorStateList.valueOf(color));
             }
+            KeyguardEsimArea esimButton = findViewById(R.id.keyguard_esim_area);
+            esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
             mPasswordEntry.requestFocus();
         }
+
+
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index d214d55..bc2a59d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -19,9 +19,15 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
+import android.support.v4.graphics.ColorUtils;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.AttributeSet;
@@ -44,6 +50,7 @@
 public class KeyguardStatusView extends GridLayout {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final String TAG = "KeyguardStatusView";
+    private static final int MARQUEE_DELAY_MS = 2000;
 
     private final LockPatternUtils mLockPatternUtils;
     private final AlarmManager mAlarmManager;
@@ -54,10 +61,16 @@
     private TextView mOwnerInfo;
     private ViewGroup mClockContainer;
     private ChargingView mBatteryDoze;
+    private View mKeyguardStatusArea;
+    private Runnable mPendingMarqueeStart;
+    private Handler mHandler;
 
     private View[] mVisibleInDoze;
     private boolean mPulsing;
-    private boolean mDark;
+    private float mDarkAmount = 0;
+    private int mTextColor;
+    private int mDateTextColor;
+    private int mAlarmTextColor;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -104,9 +117,29 @@
         super(context, attrs, defStyle);
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mLockPatternUtils = new LockPatternUtils(getContext());
+        mHandler = new Handler(Looper.myLooper());
     }
 
     private void setEnableMarquee(boolean enabled) {
+        if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
+        if (enabled) {
+            if (mPendingMarqueeStart == null) {
+                mPendingMarqueeStart = () -> {
+                    setEnableMarqueeImpl(true);
+                    mPendingMarqueeStart = null;
+                };
+                mHandler.postDelayed(mPendingMarqueeStart, MARQUEE_DELAY_MS);
+            }
+        } else {
+            if (mPendingMarqueeStart != null) {
+                mHandler.removeCallbacks(mPendingMarqueeStart);
+                mPendingMarqueeStart = null;
+            }
+            setEnableMarqueeImpl(false);
+        }
+    }
+
+    private void setEnableMarqueeImpl(boolean enabled) {
         if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
         if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
         if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
@@ -120,10 +153,16 @@
         mDateView = findViewById(R.id.date_view);
         mClockView = findViewById(R.id.clock_view);
         mClockView.setShowCurrentUserTime(true);
-        mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+        if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
+            mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+        }
         mOwnerInfo = findViewById(R.id.owner_info);
         mBatteryDoze = findViewById(R.id.battery_doze);
-        mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
+        mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
+        mVisibleInDoze = new View[]{mBatteryDoze, mClockView, mKeyguardStatusArea};
+        mTextColor = mClockView.getCurrentTextColor();
+        mDateTextColor = mDateView.getCurrentTextColor();
+        mAlarmTextColor = mAlarmStatusView.getCurrentTextColor();
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
         setEnableMarquee(shouldMarquee);
@@ -182,8 +221,11 @@
     }
 
     public int getClockBottom() {
-        return mClockView.getBottom() +
-                ((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin;
+        return mKeyguardStatusArea.getBottom();
+    }
+
+    public float getClockTextSize() {
+        return mClockView.getTextSize();
     }
 
     public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
@@ -278,12 +320,13 @@
         }
     }
 
-    public void setDark(boolean dark) {
-        if (mDark == dark) {
+    public void setDark(float darkAmount) {
+        if (mDarkAmount == darkAmount) {
             return;
         }
-        mDark = dark;
+        mDarkAmount = darkAmount;
 
+        boolean dark = darkAmount == 1;
         final int N = mClockContainer.getChildCount();
         for (int i = 0; i < N; i++) {
             View child = mClockContainer.getChildAt(i);
@@ -292,8 +335,17 @@
             }
             child.setAlpha(dark ? 0 : 1);
         }
+        if (mOwnerInfo != null) {
+            mOwnerInfo.setAlpha(dark ? 0 : 1);
+        }
+
         updateDozeVisibleViews();
         mBatteryDoze.setDark(dark);
+        mClockView.setTextColor(ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount));
+        mDateView.setTextColor(ColorUtils.blendARGB(mDateTextColor, Color.WHITE, darkAmount));
+        int blendedAlarmColor = ColorUtils.blendARGB(mAlarmTextColor, Color.WHITE, darkAmount);
+        mAlarmStatusView.setTextColor(blendedAlarmColor);
+        mAlarmStatusView.setCompoundDrawableTintList(ColorStateList.valueOf(blendedAlarmColor));
     }
 
     public void setPulsing(boolean pulsing) {
@@ -303,7 +355,7 @@
 
     private void updateDozeVisibleViews() {
         for (View child : mVisibleInDoze) {
-            child.setAlpha(mDark && mPulsing ? 0.8f : 1);
+            child.setAlpha(mDarkAmount == 1 && mPulsing ? 0.8f : 1);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ad82840..32775fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -52,7 +52,6 @@
 import android.os.IRemoteCallback;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -62,7 +61,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -74,6 +72,8 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -131,6 +131,8 @@
     private static final int MSG_SCREEN_TURNED_OFF = 332;
     private static final int MSG_DREAMING_STATE_CHANGED = 333;
     private static final int MSG_USER_UNLOCKED = 334;
+    private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
+    private static final int MSG_FINGERPRINT_AUTHENTICATION_CONTINUE = 336;
 
     /** Fingerprint state: Not listening to fingerprint. */
     private static final int FINGERPRINT_STATE_STOPPED = 0;
@@ -170,6 +172,8 @@
     private boolean mBootCompleted;
     private boolean mNeedsSlowUnlockTransition;
     private boolean mHasLockscreenWallpaper;
+    private boolean mAssistantVisible;
+    private boolean mKeyguardOccluded;
 
     // Device provisioning state
     private boolean mDeviceProvisioned;
@@ -197,6 +201,13 @@
     private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
     private LockPatternUtils mLockPatternUtils;
 
+    /**
+     * Short delay before restarting fingerprint authentication after a successful try
+     * This should be slightly longer than the time between onFingerprintAuthenticated and
+     * setKeyguardGoingAway(true).
+     */
+    private static final int FINGERPRINT_CONTINUE_DELAY_MS = 500;
+
     // If FP daemon dies, keyguard should retry after a short delay
     private int mHardwareUnavailableRetryCount = 0;
     private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
@@ -287,6 +298,13 @@
                 case MSG_USER_UNLOCKED:
                     handleUserUnlocked();
                     break;
+                case MSG_ASSISTANT_STACK_CHANGED:
+                    mAssistantVisible = (boolean)msg.obj;
+                    updateFingerprintListeningState();
+                    break;
+                case MSG_FINGERPRINT_AUTHENTICATION_CONTINUE:
+                    updateFingerprintListeningState();
+                    break;
             }
         }
     };
@@ -414,9 +432,22 @@
         mKeyguardGoingAway = goingAway;
     }
 
+    /**
+     * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
+     * @param occluded
+     */
+    public void setKeyguardOccluded(boolean occluded) {
+        mKeyguardOccluded = occluded;
+        updateFingerprintListeningState();
+    }
+
     private void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
         mUserFingerprintAuthenticated.put(userId, true);
+        // Update/refresh trust state only if user can skip bouncer
+        if (getUserCanSkipBouncer(userId)) {
+            mTrustManager.unlockedByFingerprintForUser(userId);
+        }
         // Don't send cancel if authentication succeeds
         mFingerprintCancelSignal = null;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -425,6 +456,13 @@
                 cb.onFingerprintAuthenticated(userId);
             }
         }
+
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE),
+                FINGERPRINT_CONTINUE_DELAY_MS);
+
+        // Only authenticate fingerprint once when assistant is visible
+        mAssistantVisible = false;
+
         Trace.endSection();
     }
 
@@ -1106,10 +1144,16 @@
             mFpm.addLockoutResetCallback(mLockoutResetCallback);
         }
 
+        SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
         mUserManager = context.getSystemService(UserManager.class);
     }
 
     private void updateFingerprintListeningState() {
+        // If this message exists, we should not authenticate again until this message is
+        // consumed by the handler
+        if (mHandler.hasMessages(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE)) {
+            return;
+        }
         mHandler.removeCallbacks(mRetryFingerprintAuthentication);
         boolean shouldListenForFingerprint = shouldListenForFingerprint();
         if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
@@ -1122,8 +1166,10 @@
 
     private boolean shouldListenForFingerprint() {
         return (mKeyguardIsVisible || !mDeviceInteractive ||
-                    (mBouncer && !mKeyguardGoingAway) || mGoingToSleep)
-                && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser());
+                (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
+                (mAssistantVisible && mKeyguardOccluded))
+                && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
+                && !mKeyguardGoingAway;
     }
 
     private void startListeningForFingerprint() {
@@ -1151,8 +1197,10 @@
     private void stopListeningForFingerprint() {
         if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
         if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
-            mFingerprintCancelSignal.cancel();
-            mFingerprintCancelSignal = null;
+            if (mFingerprintCancelSignal != null) {
+                mFingerprintCancelSignal.cancel();
+                mFingerprintCancelSignal = null;
+            }
             setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
         }
         if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
@@ -1651,6 +1699,7 @@
 
     public void clearFingerprintRecognized() {
         mUserFingerprintAuthenticated.clear();
+        mTrustManager.clearAllFingerprints();
     }
 
     public boolean isSimPinVoiceSecure() {
@@ -1674,6 +1723,23 @@
         }
     }
 
+    private final TaskStackListener mTaskStackListener = new TaskStackListener() {
+        @Override
+        public void onTaskStackChangedBackground() {
+            try {
+                ActivityManager.StackInfo info = ActivityManager.getService().getStackInfo(
+                        ActivityManager.StackId.ASSISTANT_STACK_ID);
+                if (info == null) {
+                    return;
+                }
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
+                        info.visible));
+            } catch (RemoteException e) {
+                Log.e(TAG, "unable to check task stack", e);
+            }
+        }
+    };
+
     /**
      * @return true if and only if the state has changed for the specified {@code slotId}
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 14d6b59..5a02178 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -154,13 +154,19 @@
 
     /**
      * Called when the device has started waking up.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedWakingUp() { }
 
     /**
      * Called when the device has started going to sleep.
      * @param why see {@link #onFinishedGoingToSleep(int)}
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedGoingToSleep(int why) { }
 
     /**
@@ -168,17 +174,26 @@
      * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN},
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onFinishedGoingToSleep(int why) { }
 
     /**
      * Called when the screen has been turned on.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOn() { }
 
     /**
      * Called when the screen has been turned off.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOff() { }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index c43820d..12f75bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -23,15 +23,14 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.os.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.InputType;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
@@ -127,13 +126,16 @@
             mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding,
                     getContext().getResources().getDimensionPixelSize(
                             R.dimen.password_char_padding));
+            int textColor = a.getColor(R.styleable.PasswordTextView_android_textColor, Color.WHITE);
+            mDrawPaint.setColor(textColor);
         } finally {
             a.recycle();
         }
         mDrawPaint.setFlags(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
         mDrawPaint.setTextAlign(Paint.Align.CENTER);
-        mDrawPaint.setColor(0xffffffff);
-        mDrawPaint.setTypeface(Typeface.create("sans-serif-light", 0));
+        mDrawPaint.setTypeface(Typeface.create(
+                context.getString(com.android.internal.R.string.config_headlineFontFamilyLight),
+                0));
         mShowPassword = Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
         mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
@@ -248,9 +250,9 @@
             mText = mText.substring(0, length - 1);
             CharState charState = mTextChars.get(length - 1);
             charState.startRemoveAnimation(0, 0);
+            sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
         }
         userActivity();
-        sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
     }
 
     public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
index 810dd8c..01b4254 100644
--- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
@@ -24,59 +24,50 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * Custom {@link FrameLayout} that re-inflates when changes to {@link Configuration} happen.
- * Currently supports changes to density and locale.
+ * Currently supports changes to density, asset path, and locale.
  */
-public class AutoReinflateContainer extends FrameLayout {
+public class AutoReinflateContainer extends FrameLayout implements
+        ConfigurationController.ConfigurationListener {
 
     private final List<InflateListener> mInflateListeners = new ArrayList<>();
     private final int mLayout;
-    private int mDensity;
-    private LocaleList mLocaleList;
 
     public AutoReinflateContainer(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
 
-        mDensity = context.getResources().getConfiguration().densityDpi;
-        mLocaleList = context.getResources().getConfiguration().getLocales();
-
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoReinflateContainer);
         if (!a.hasValue(R.styleable.AutoReinflateContainer_android_layout)) {
             throw new IllegalArgumentException("AutoReinflateContainer must contain a layout");
         }
         mLayout = a.getResourceId(R.styleable.AutoReinflateContainer_android_layout, 0);
+        a.recycle();
         inflateLayout();
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        boolean shouldInflateLayout = false;
-        final int density = newConfig.densityDpi;
-        if (density != mDensity) {
-            mDensity = density;
-            shouldInflateLayout = true;
-        }
-        final LocaleList localeList = newConfig.getLocales();
-        if (localeList != mLocaleList) {
-            mLocaleList = localeList;
-            shouldInflateLayout = true;
-        }
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        Dependency.get(ConfigurationController.class).addCallback(this);
+    }
 
-        if (shouldInflateLayout) {
-            inflateLayout();
-        }
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     protected void inflateLayoutImpl() {
         LayoutInflater.from(getContext()).inflate(mLayout, this);
     }
 
-    protected void inflateLayout() {
+    public void inflateLayout() {
         removeAllViews();
         inflateLayoutImpl();
         final int N = mInflateListeners.size();
@@ -90,6 +81,21 @@
         listener.onInflated(getChildAt(0));
     }
 
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        inflateLayout();
+    }
+
+    @Override
+    public void onOverlayChanged() {
+        inflateLayout();
+    }
+
+    @Override
+    public void onLocaleListChanged() {
+        inflateLayout();
+    }
+
     public interface InflateListener {
         /**
          * Called whenever a new view is inflated.
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 96a7112..c4de63b 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -71,6 +71,7 @@
 
     private int mLightModeBackgroundColor;
     private int mLightModeFillColor;
+    private float mDarkIntensity;
 
     public BatteryMeterView(Context context) {
         this(context, null, 0);
@@ -239,6 +240,7 @@
 
     @Override
     public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+        mDarkIntensity = darkIntensity;
         float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
         int foreground = getColorForDarkIntensity(intensity, mLightModeFillColor,
                 mDarkModeFillColor);
@@ -255,6 +257,14 @@
         }
     }
 
+    public void setFillColor(int color) {
+        if (mLightModeFillColor == color) {
+            return;
+        }
+        mLightModeFillColor = color;
+        onDarkChanged(new Rect(), mDarkIntensity, DarkIconDispatcher.DEFAULT_ICON_TINT);
+    }
+
     private int getColorForDarkIntensity(float darkIntensity, int lightColor, int darkColor) {
         return (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 8ba33c3..ecc2111 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -16,6 +16,7 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.hardware.SensorManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -28,19 +29,25 @@
 import com.android.internal.util.Preconditions;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.PluginManagerImpl;
 import com.android.systemui.plugins.VolumeDialogController;
+import com.android.systemui.power.PowerNotificationWarnings;
+import com.android.systemui.power.PowerUI;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
-import com.android.systemui.statusbar.phone.StatusBarWindowManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarWindowManager;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -77,8 +84,10 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerServiceImpl;
+import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.util.leak.LeakReporter;
@@ -105,6 +114,7 @@
  * services, registered receivers, etc.
  */
 public class Dependency extends SystemUI {
+    private static final String TAG = "Dependency";
 
     /**
      * Key for getting a background Looper for background work.
@@ -150,6 +160,9 @@
         mProviders.put(ActivityStarterDelegate.class, () ->
                 getDependency(ActivityStarter.class));
 
+        mProviders.put(AsyncSensorManager.class, () ->
+                new AsyncSensorManager(mContext.getSystemService(SensorManager.class)));
+
         mProviders.put(BluetoothController.class, () ->
                 new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER)));
 
@@ -244,11 +257,17 @@
         mProviders.put(StatusBarIconController.class, () ->
                 new StatusBarIconControllerImpl(mContext));
 
+        mProviders.put(ScreenLifecycle.class, () ->
+                new ScreenLifecycle());
+
+        mProviders.put(WakefulnessLifecycle.class, () ->
+                new WakefulnessLifecycle());
+
         mProviders.put(FragmentService.class, () ->
                 new FragmentService(mContext));
 
         mProviders.put(ExtensionController.class, () ->
-                new ExtensionControllerImpl());
+                new ExtensionControllerImpl(mContext));
 
         mProviders.put(PluginDependencyProvider.class, () ->
                 new PluginDependencyProvider(get(PluginManager.class)));
@@ -264,11 +283,23 @@
         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());
+
         mProviders.put(ForegroundServiceController.class,
                 () -> new ForegroundServiceControllerImpl(mContext));
 
         mProviders.put(UiOffloadThread.class, UiOffloadThread::new);
 
+        mProviders.put(PluginActivityManager.class,
+                () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));
+
+        mProviders.put(PowerUI.WarningsUI.class, () -> new PowerNotificationWarnings(mContext));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
index c382882..9fe730a 100644
--- a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
@@ -14,56 +14,77 @@
 
 package com.android.systemui;
 
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.IDockedStackListener;
 import android.view.WindowManagerGlobal;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.function.Consumer;
 
 /**
  * Utility wrapper to listen for whether or not a docked stack exists, to be
  * used for things like the different overview icon in that mode.
  */
-public class DockedStackExistsListener extends IDockedStackListener.Stub {
+public class DockedStackExistsListener {
 
     private static final String TAG = "DockedStackExistsListener";
 
-    private final Consumer<Boolean> mCallback;
+    private static ArrayList<WeakReference<Consumer<Boolean>>> sCallbacks = new ArrayList<>();
 
-    private DockedStackExistsListener(Consumer<Boolean> callback) {
-        mCallback = callback;
+    static {
+        try {
+            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
+                    new IDockedStackListener.Stub() {
+                        @Override
+                        public void onDividerVisibilityChanged(boolean b) throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onDockedStackExistsChanged(boolean exists)
+                                throws RemoteException {
+                            DockedStackExistsListener.onDockedStackExistsChanged(exists);
+                        }
+
+                        @Override
+                        public void onDockedStackMinimizedChanged(boolean b, long l, boolean b1)
+                                throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onAdjustedForImeChanged(boolean b, long l)
+                                throws RemoteException {
+
+                        }
+
+                        @Override
+                        public void onDockSideChanged(int i) throws RemoteException {
+
+                        }
+                    });
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed registering docked stack exists listener", e);
+        }
     }
 
-    @Override
-    public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
-    }
 
-    @Override
-    public void onDockedStackExistsChanged(final boolean exists) throws RemoteException {
-        mCallback.accept(exists);
-    }
-
-    @Override
-    public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
-                                              boolean isHomeStackResizable) throws RemoteException {
-    }
-
-    @Override
-    public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
-            throws RemoteException {
-    }
-
-    @Override
-    public void onDockSideChanged(int newDockSide) throws RemoteException {
+    private static void onDockedStackExistsChanged(boolean exists) {
+        synchronized (sCallbacks) {
+            sCallbacks.removeIf(wf -> {
+                Consumer<Boolean> l = wf.get();
+                if (l != null) l.accept(exists);
+                return l == null;
+            });
+        }
     }
 
     public static void register(Consumer<Boolean> callback) {
-        try {
-            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
-                    new DockedStackExistsListener(callback));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed registering docked stack exists listener", e);
+        synchronized (sCallbacks) {
+            sCallbacks.add(new WeakReference<>(callback));
         }
     }
 }
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/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
new file mode 100644
index 0000000..467ec2e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -0,0 +1,118 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+
+import com.android.settingslib.Utils;
+
+public class HardwareBgDrawable extends LayerDrawable {
+
+    private final Paint mPaint = new Paint();
+    private final Drawable[] mLayers;
+    private final boolean mRoundTop;
+    private int mPoint;
+    private boolean mRotatedBackground;
+
+    public HardwareBgDrawable(boolean roundTop, boolean roundEnd, Context context) {
+        this(roundTop, getLayers(context, roundTop, roundEnd));
+    }
+
+    public HardwareBgDrawable(boolean roundTop, Drawable[] layers) {
+        super(layers);
+        if (layers.length != 2) {
+            throw new IllegalArgumentException("Need 2 layers");
+        }
+        mRoundTop = roundTop;
+        mLayers = layers;
+    }
+
+    private static Drawable[] getLayers(Context context, boolean roundTop, boolean roundEnd) {
+        int drawable = roundEnd ? R.drawable.rounded_bg_full : R.drawable.rounded_bg;
+        final Drawable[] layers;
+        if (roundTop) {
+            layers = new Drawable[]{
+                    context.getDrawable(drawable).mutate(),
+                    context.getDrawable(drawable).mutate(),
+            };
+        } else {
+            layers = new Drawable[]{
+                    context.getDrawable(drawable).mutate(),
+                    context.getDrawable(roundEnd ? R.drawable.rounded_full_bg_bottom
+                            : R.drawable.rounded_bg_bottom).mutate(),
+            };
+        }
+        layers[1].setTint(Utils.getColorAttr(context, android.R.attr.colorPrimaryDark));
+        return layers;
+    }
+
+    public void setCutPoint(int point) {
+        mPoint = point;
+        invalidateSelf();
+    }
+
+    public int getCutPoint() {
+        return mPoint;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mPoint >= 0 && !mRotatedBackground) {
+            Rect bounds = getBounds();
+            int top = bounds.top + mPoint;
+            if (top > bounds.bottom) top = bounds.bottom;
+            if (mRoundTop) {
+                mLayers[0].setBounds(bounds.left, bounds.top, bounds.right, top);
+            } else {
+                mLayers[1].setBounds(bounds.left, top, bounds.right, bounds.bottom);
+            }
+            if (mRoundTop) {
+                mLayers[1].draw(canvas);
+                mLayers[0].draw(canvas);
+            } else {
+                mLayers[0].draw(canvas);
+                mLayers[1].draw(canvas);
+            }
+        } else {
+            mLayers[0].draw(canvas);
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+
+    public void setRotatedBackground(boolean rotatedBackground) {
+        mRotatedBackground = rotatedBackground;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
new file mode 100644
index 0000000..ca34345
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -0,0 +1,432 @@
+/*
+ * 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;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.leak.RotationUtils;
+
+import java.util.ArrayList;
+
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
+
+public class HardwareUiLayout extends FrameLayout implements Tunable {
+
+    private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
+    private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
+    private final int[] mTmp2 = new int[2];
+    private View mChild;
+    private int mOldHeight;
+    private boolean mAnimating;
+    private AnimatorSet mAnimation;
+    private View mDivision;
+    private boolean mHasOutsideTouch;
+    private HardwareBgDrawable mBackground;
+    private Animator mAnimator;
+    private boolean mCollapse;
+    private int mEndPoint;
+    private boolean mEdgeBleed;
+    private boolean mRoundedDivider;
+    private int mRotation = ROTATION_NONE;
+    private boolean mRotatedBackground;
+
+    public HardwareUiLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        updateSettings();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateSettings();
+        Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
+        getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        updateSettings();
+    }
+
+    private void updateSettings() {
+        mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
+                EDGE_BLEED, 0) != 0;
+        mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
+                ROUNDED_DIVIDER, 1) != 0;
+        updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+        mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
+        if (mChild != null) {
+            mChild.setBackground(mBackground);
+            requestLayout();
+        }
+    }
+
+    private void updateEdgeMargin(int edge) {
+        if (mChild != null) {
+            MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
+            if (mRotation == ROTATION_LANDSCAPE) {
+                params.topMargin = edge;
+            } else if (mRotation == ROTATION_SEASCAPE) {
+                params.bottomMargin = edge;
+            } else {
+                params.rightMargin = edge;
+            }
+            mChild.setLayoutParams(params);
+        }
+    }
+
+    private int getEdgePadding() {
+        return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mChild == null) {
+            if (getChildCount() != 0) {
+                mChild = getChildAt(0);
+                mChild.setBackground(mBackground);
+                updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+                mOldHeight = mChild.getMeasuredHeight();
+                mChild.addOnLayoutChangeListener(
+                        (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                                updatePosition());
+                updateRotation();
+            } else {
+                return;
+            }
+        }
+        int newHeight = mChild.getMeasuredHeight();
+        if (newHeight != mOldHeight) {
+            animateChild(mOldHeight, newHeight);
+        }
+        post(() -> updatePosition());
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateRotation();
+    }
+
+    private void updateRotation() {
+        int rotation = RotationUtils.getRotation(getContext());
+        if (rotation != mRotation) {
+            rotate(mRotation, rotation);
+            mRotation = rotation;
+        }
+    }
+
+    private void rotate(int from, int to) {
+        if (from != ROTATION_NONE && to != ROTATION_NONE) {
+            // Rather than handling this confusing case, just do 2 rotations.
+            rotate(from, ROTATION_NONE);
+            rotate(ROTATION_NONE, to);
+            return;
+        }
+        if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) {
+            rotateRight();
+        } else {
+            rotateLeft();
+        }
+        if (to != ROTATION_NONE) {
+            if (mChild instanceof LinearLayout) {
+                mRotatedBackground = true;
+                mBackground.setRotatedBackground(true);
+                LinearLayout linearLayout = (LinearLayout) mChild;
+                if (to == ROTATION_SEASCAPE) {
+                    swapOrder(linearLayout);
+                }
+                linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+                swapDimens(this.mChild);
+            }
+        } else {
+            if (mChild instanceof LinearLayout) {
+                mRotatedBackground = false;
+                mBackground.setRotatedBackground(false);
+                LinearLayout linearLayout = (LinearLayout) mChild;
+                if (from == ROTATION_SEASCAPE) {
+                    swapOrder(linearLayout);
+                }
+                linearLayout.setOrientation(LinearLayout.VERTICAL);
+                swapDimens(mChild);
+            }
+        }
+    }
+
+    private void swapOrder(LinearLayout linearLayout) {
+        ArrayList<View> children = new ArrayList<>();
+        for (int i = 0; i < linearLayout.getChildCount(); i++) {
+            children.add(0, linearLayout.getChildAt(0));
+            linearLayout.removeViewAt(0);
+        }
+        children.forEach(v -> linearLayout.addView(v));
+    }
+
+    private void rotateRight() {
+        rotateRight(this);
+        rotateRight(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityRight(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private void swapDimens(View v) {
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        int h = params.width;
+        params.width = params.height;
+        params.height = h;
+        v.setLayoutParams(params);
+    }
+
+    private int rotateGravityRight(int gravity) {
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.BOTTOM;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.TOP;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.LEFT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.RIGHT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void rotateLeft() {
+        rotateLeft(this);
+        rotateLeft(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityLeft(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private int rotateGravityLeft(int gravity) {
+        if (gravity == -1) {
+            gravity = Gravity.TOP | Gravity.START;
+        }
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.TOP;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.BOTTOM;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.RIGHT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.LEFT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void rotateLeft(View v) {
+        v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
+                v.getPaddingLeft());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
+                params.leftMargin);
+        v.setLayoutParams(params);
+    }
+
+    private void rotateRight(View v) {
+        v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
+                v.getPaddingRight());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
+                params.rightMargin);
+        v.setLayoutParams(params);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        post(() -> updatePosition());
+    }
+
+    private void animateChild(int oldHeight, int newHeight) {
+        if (true) return;
+        if (mAnimating) {
+            mAnimation.cancel();
+        }
+        mAnimating = true;
+        mAnimation = new AnimatorSet();
+        mAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnimating = false;
+            }
+        });
+        int fromTop = mChild.getTop();
+        int fromBottom = mChild.getBottom();
+        int toTop = fromTop - ((newHeight - oldHeight) / 2);
+        int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
+        ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
+        top.addUpdateListener(animation -> mBackground.invalidateSelf());
+        mAnimation.playTogether(top,
+                ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
+    }
+
+    public void setDivisionView(View v) {
+        mDivision = v;
+        if (mDivision != null) {
+            mDivision.addOnLayoutChangeListener(
+                    (v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                            updatePosition());
+        }
+        updatePosition();
+    }
+
+    private void updatePosition() {
+        if (mChild == null) return;
+        if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
+            int index = mRotatedBackground ? 0 : 1;
+            mDivision.getLocationOnScreen(mTmp2);
+            float trans = mRotatedBackground ? mDivision.getTranslationX()
+                    : mDivision.getTranslationY();
+            int viewTop = (int) (mTmp2[index] + trans);
+            mChild.getLocationOnScreen(mTmp2);
+            viewTop -= mTmp2[index];
+            setCutPoint(viewTop);
+        } else {
+            setCutPoint(mChild.getMeasuredHeight());
+        }
+    }
+
+    private void setCutPoint(int point) {
+        int curPoint = mBackground.getCutPoint();
+        if (curPoint == point) return;
+        if (getAlpha() == 0 || curPoint == 0) {
+            mBackground.setCutPoint(point);
+            return;
+        }
+        if (mAnimator != null) {
+            if (mEndPoint == point) {
+                return;
+            }
+            mAnimator.cancel();
+        }
+        mEndPoint = point;
+        mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
+        if (mCollapse) {
+            mAnimator.setStartDelay(300);
+            mCollapse = false;
+        }
+        mAnimator.start();
+    }
+
+    @Override
+    public ViewOutlineProvider getOutlineProvider() {
+        return super.getOutlineProvider();
+    }
+
+    public void setOutsideTouchListener(OnClickListener onClickListener) {
+        mHasOutsideTouch = true;
+        requestLayout();
+        setOnClickListener(onClickListener);
+        setClickable(true);
+        setFocusable(true);
+    }
+
+    public void setCollapse() {
+        mCollapse = true;
+    }
+
+    public static HardwareUiLayout get(View v) {
+        if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
+        if (v.getParent() instanceof View) {
+            return get((View) v.getParent());
+        }
+        return null;
+    }
+
+    private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
+        if (mHasOutsideTouch || (mChild == null)) {
+            inoutInfo.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+            return;
+        }
+        inoutInfo.setTouchableInsets(
+                ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
+        inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
+                0, getBottom() - mChild.getBottom());
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 9a4179f..907a79e 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -199,7 +199,7 @@
             // Load background image dimensions, if we haven't saved them yet
             if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
                 // Need to load the image to get dimensions
-                loadWallpaper(forDraw, true /* needsReset */);
+                loadWallpaper(forDraw, false /* needsReset */);
                 if (DEBUG) {
                     Log.d(TAG, "Reloading, redoing updateSurfaceSize later.");
                 }
@@ -405,17 +405,17 @@
                     }
                 } else {
                     drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
+                    if (FIXED_SIZED_SURFACE) {
+                        // If the surface is fixed-size, we should only need to
+                        // draw it once and then we'll let the window manager
+                        // position it appropriately.  As such, we no longer needed
+                        // the loaded bitmap.  Yay!
+                        // hw-accelerated renderer retains bitmap for faster rotation
+                        unloadWallpaper(false /* forgetSize */);
+                    }
                 }
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-                if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) {
-                    // If the surface is fixed-size, we should only need to
-                    // draw it once and then we'll let the window manager
-                    // position it appropriately.  As such, we no longer needed
-                    // the loaded bitmap.  Yay!
-                    // hw-accelerated renderer retains bitmap for faster rotation
-                    unloadWallpaper(false /* forgetSize */);
-                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 3cc81df..4437d31 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -47,6 +47,7 @@
         Key.QS_INVERT_COLORS_ADDED,
         Key.QS_WORK_ADDED,
         Key.QS_NIGHTDISPLAY_ADDED,
+        Key.SEEN_MULTI_USER,
     })
     public @interface Key {
         @Deprecated
@@ -62,12 +63,18 @@
         String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
         String DND_NONE_SELECTED = "DndNoneSelected";
         String DND_FAVORITE_ZEN = "DndFavoriteZen";
-        String QS_HOTSPOT_ADDED = "QsHotspotAdded";
-        String QS_DATA_SAVER_ADDED = "QsDataSaverAdded";
         String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown";
+        @Deprecated
+        String QS_HOTSPOT_ADDED = "QsHotspotAdded";
+        @Deprecated
+        String QS_DATA_SAVER_ADDED = "QsDataSaverAdded";
+        @Deprecated
         String QS_INVERT_COLORS_ADDED = "QsInvertColorsAdded";
+        @Deprecated
         String QS_WORK_ADDED = "QsWorkAdded";
+        @Deprecated
         String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded";
+        String SEEN_MULTI_USER = "HasSeenMultiUser";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
new file mode 100644
index 0000000..f7936b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -0,0 +1,220 @@
+/*
+ * 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;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+
+import android.app.Fragment;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.provider.Settings.Secure;
+import android.support.annotation.VisibleForTesting;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import com.android.systemui.R.id;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class RoundedCorners extends SystemUI implements Tunable {
+    public static final String SIZE = "sysui_rounded_size";
+    public static final String PADDING = "sysui_rounded_content_padding";
+
+    private int mRoundedDefault;
+    private View mOverlay;
+    private View mBottomOverlay;
+    private float mDensity;
+    private TunablePadding mQsPadding;
+    private TunablePadding mStatusBarPadding;
+    private TunablePadding mNavBarPadding;
+
+    @Override
+    public void start() {
+        mRoundedDefault = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius);
+        if (mRoundedDefault != 0) {
+            setupRounding();
+        }
+        int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+        if (padding != 0) {
+            setupPadding(padding);
+        }
+    }
+
+    private void setupRounding() {
+        mOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        mOverlay.setAlpha(0);
+        mOverlay.findViewById(R.id.right).setRotation(90);
+
+        mContext.getSystemService(WindowManager.class)
+                .addView(mOverlay, getWindowLayoutParams());
+        mBottomOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mBottomOverlay.setAlpha(0);
+        mBottomOverlay.findViewById(R.id.right).setRotation(180);
+        mBottomOverlay.findViewById(R.id.left).setRotation(270);
+        WindowManager.LayoutParams layoutParams = getWindowLayoutParams();
+        layoutParams.gravity = Gravity.BOTTOM;
+        mContext.getSystemService(WindowManager.class)
+                .addView(mBottomOverlay, layoutParams);
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+
+        Dependency.get(TunerService.class).addTunable(this, SIZE);
+
+        // Watch color inversion and invert the overlay as needed.
+        SecureSetting setting = new SecureSetting(mContext, Dependency.get(Dependency.MAIN_HANDLER),
+                Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
+            @Override
+            protected void handleValueChanged(int value, boolean observedChange) {
+                int tint = value != 0 ? Color.WHITE : Color.BLACK;
+                ColorStateList tintList = ColorStateList.valueOf(tint);
+                ((ImageView) mOverlay.findViewById(id.left)).setImageTintList(tintList);
+                ((ImageView) mOverlay.findViewById(id.right)).setImageTintList(tintList);
+                ((ImageView) mBottomOverlay.findViewById(id.left)).setImageTintList(tintList);
+                ((ImageView) mBottomOverlay.findViewById(id.right)).setImageTintList(tintList);
+            }
+        };
+        setting.setListening(true);
+        setting.onChange(false);
+
+        mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft,
+                    int oldTop, int oldRight, int oldBottom) {
+                mOverlay.removeOnLayoutChangeListener(this);
+                mOverlay.animate()
+                        .alpha(1)
+                        .setDuration(1000)
+                        .start();
+                mBottomOverlay.animate()
+                        .alpha(1)
+                        .setDuration(1000)
+                        .start();
+            }
+        });
+    }
+
+    private void setupPadding(int padding) {
+        // Add some padding to all the content near the edge of the screen.
+        StatusBar sb = getComponent(StatusBar.class);
+        View statusBar = sb.getStatusBarWindow();
+
+        TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
+                padding, FLAG_END);
+
+        FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
+        fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
+                new TunablePaddingTagListener(padding, R.id.status_bar));
+        fragmentHostManager.addTagListener(QS.TAG,
+                new TunablePaddingTagListener(padding, R.id.header));
+    }
+
+    private WindowManager.LayoutParams getWindowLayoutParams() {
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                0
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_SLIPPERY
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                ,
+                PixelFormat.TRANSLUCENT);
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS
+                | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
+        lp.setTitle("RoundedOverlay");
+        lp.gravity = Gravity.TOP;
+        return lp;
+    }
+
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (mOverlay == null) return;
+        if (SIZE.equals(key)) {
+            int size = mRoundedDefault;
+            try {
+                size = (int) (Integer.parseInt(newValue) * mDensity);
+            } catch (Exception e) {
+            }
+            setSize(mOverlay.findViewById(R.id.left), size);
+            setSize(mOverlay.findViewById(R.id.right), size);
+            setSize(mBottomOverlay.findViewById(R.id.left), size);
+            setSize(mBottomOverlay.findViewById(R.id.right), size);
+        }
+    }
+
+    private void setSize(View view, int pixelSize) {
+        LayoutParams params = view.getLayoutParams();
+        params.width = pixelSize;
+        params.height = pixelSize;
+        view.setLayoutParams(params);
+    }
+
+    @VisibleForTesting
+    static class TunablePaddingTagListener implements FragmentListener {
+
+        private final int mPadding;
+        private final int mId;
+        private TunablePadding mTunablePadding;
+
+        public TunablePaddingTagListener(int padding, int id) {
+            mPadding = padding;
+            mId = id;
+        }
+
+        @Override
+        public void onFragmentViewCreated(String tag, Fragment fragment) {
+            if (mTunablePadding != null) {
+                mTunablePadding.destroy();
+            }
+            View view = fragment.getView();
+            if (mId != 0) {
+                view = view.findViewById(mId);
+            }
+            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
+                    FLAG_START | FLAG_END);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 74b745f..699fdef 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -22,6 +22,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.RectF;
 import android.os.Handler;
 import android.util.Log;
@@ -30,7 +31,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
-
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
@@ -82,6 +82,7 @@
     private float mDensityScale;
     private float mTranslation = 0;
 
+    private boolean mMenuRowIntercepting;
     private boolean mLongPressSent;
     private LongPressListener mLongPressListener;
     private Runnable mWatchLongPress;
@@ -91,6 +92,7 @@
     private int mFalsingThreshold;
     private boolean mTouchAboveFalsingThreshold;
     private boolean mDisableHwLayers;
+    private boolean mFadeDependingOnAmountSwiped;
     private Context mContext;
 
     private HashMap<View, Animator> mDismissPendingMap = new HashMap<>();
@@ -101,12 +103,15 @@
         mHandler = new Handler();
         mSwipeDirection = swipeDirection;
         mVelocityTracker = VelocityTracker.obtain();
-        mDensityScale =  context.getResources().getDisplayMetrics().density;
         mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
 
-        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
-        mFalsingThreshold = context.getResources().getDimensionPixelSize(
-                R.dimen.swipe_helper_falsing_threshold);
+        // Extra long-press!
+        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
+
+        Resources res = context.getResources();
+        mDensityScale =  res.getDisplayMetrics().density;
+        mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
+        mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
         mFalsingManager = FalsingManager.getInstance(context);
         mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
     }
@@ -176,8 +181,7 @@
     }
 
     protected float getSize(View v) {
-        return mSwipeDirection == X ? v.getMeasuredWidth() :
-                v.getMeasuredHeight();
+        return mSwipeDirection == X ? v.getMeasuredWidth() : v.getMeasuredHeight();
     }
 
     public void setMinSwipeProgress(float minSwipeProgress) {
@@ -195,6 +199,11 @@
     }
 
     private float getSwipeAlpha(float progress) {
+        if (mFadeDependingOnAmountSwiped) {
+            // The more progress has been fade, the lower the alpha value so that the view fades.
+            return Math.max(1 - progress, 0);
+        }
+
         return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END));
     }
 
@@ -207,9 +216,8 @@
         float swipeProgress = getSwipeProgressForOffset(animView, translation);
         if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
             if (FADE_OUT_DURING_SWIPE && dismissable) {
-                float alpha = swipeProgress;
                 if (!mDisableHwLayers) {
-                    if (alpha != 0f && alpha != 1f) {
+                    if (swipeProgress != 0f && swipeProgress != 1f) {
                         animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                     } else {
                         animView.setLayerType(View.LAYER_TYPE_NONE, null);
@@ -259,6 +267,10 @@
 
     @Override
     public boolean onInterceptTouchEvent(final MotionEvent ev) {
+        if (mCurrView instanceof ExpandableNotificationRow) {
+            NotificationMenuRowPlugin nmr = ((ExpandableNotificationRow) mCurrView).getProvider();
+            mMenuRowIntercepting = nmr.onInterceptTouchEvent(mCurrView, ev);
+        }
         final int action = ev.getAction();
 
         switch (action) {
@@ -294,7 +306,10 @@
                                             menuItem = ((ExpandableNotificationRow) mCurrView)
                                                     .getProvider().getLongpressMenuItem(mContext);
                                         }
-                                        mLongPressListener.onLongPress(mCurrView, x, y, menuItem);
+                                        if (menuItem != null) {
+                                            mLongPressListener.onLongPress(mCurrView, x, y,
+                                                    menuItem);
+                                        }
                                     }
                                 }
                             };
@@ -324,15 +339,16 @@
 
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                final boolean captured = (mDragging || mLongPressSent);
+                final boolean captured = (mDragging || mLongPressSent || mMenuRowIntercepting);
                 mDragging = false;
                 mCurrView = null;
                 mLongPressSent = false;
+                mMenuRowIntercepting = false;
                 removeLongPressCallback();
                 if (captured) return true;
                 break;
         }
-        return mDragging || mLongPressSent;
+        return mDragging || mLongPressSent || mMenuRowIntercepting;
     }
 
     /**
@@ -551,11 +567,11 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        if (mLongPressSent) {
+        if (mLongPressSent && !mMenuRowIntercepting) {
             return true;
         }
 
-        if (!mDragging) {
+        if (!mDragging && !mMenuRowIntercepting) {
             if (mCallback.getChildAtPosition(ev) != null) {
 
                 // We are dragging directly over a card, make sure that we also catch the gesture
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 0eb469f..9f2dcd9 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui;
 
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.content.BroadcastReceiver;
@@ -39,6 +40,7 @@
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.power.PowerUI;
@@ -87,6 +89,7 @@
             GarbageMonitor.Service.class,
             LatencyTester.class,
             GlobalActionsComponent.class,
+            RoundedCorners.class,
     };
 
     /**
@@ -113,7 +116,7 @@
         // Set the application theme that is inherited by all services. Note that setting the
         // application theme in the manifest does only work for activities. Keep this in sync with
         // the theme set there.
-        setTheme(R.style.systemui_theme);
+        setTheme(R.style.Theme_SystemUI);
 
         SystemUIFactory.createFromConfig(this);
 
@@ -265,4 +268,10 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    @Override
+    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+        if (!mServicesStarted) return null;
+        return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 5237244..0c067ff 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -40,6 +40,8 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.VolumeDialogControllerImpl;
 
+import java.util.function.Consumer;
+
 /**
  * Class factory to provide customizable SystemUI components.
  */
@@ -84,8 +86,10 @@
 
     public ScrimController createScrimController(LightBarController lightBarController,
             ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
-            LockscreenWallpaper lockscreenWallpaper) {
-        return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim);
+            LockscreenWallpaper lockscreenWallpaper,
+            Consumer<Boolean> scrimVisibleListener) {
+        return new ScrimController(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
+                scrimVisibleListener);
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 8506734..e4b405f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -34,8 +34,8 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.analytics.DataCollector;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.AsyncSensorManager;
 
 import java.io.PrintWriter;
 
@@ -76,6 +76,7 @@
     private boolean mSessionActive = false;
     private int mState = StatusBarState.SHADE;
     private boolean mScreenOn;
+    private boolean mShowingAod;
     private Runnable mPendingWtf;
 
     protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@@ -87,7 +88,7 @@
 
     private FalsingManager(Context context) {
         mContext = context;
-        mSensorManager = mContext.getSystemService(SensorManager.class);
+        mSensorManager = Dependency.get(AsyncSensorManager.class);
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mDataCollector = DataCollector.getInstance(mContext);
         mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
@@ -122,7 +123,7 @@
                     .append(" mState=").append(StatusBarState.toShortString(mState))
                     .toString()
             );
-        return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD);
+        return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
     }
 
     private boolean sessionEntrypoint() {
@@ -144,6 +145,14 @@
         }
     }
 
+    public void updateSessionActive() {
+        if (shouldSessionBeActive()) {
+            sessionEntrypoint();
+        } else {
+            sessionExitpoint(false /* force */);
+        }
+    }
+
     private void onSessionStart() {
         if (FalsingLog.ENABLED) {
             FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
@@ -249,6 +258,11 @@
         return mEnforceBouncer;
     }
 
+    public void setShowingAod(boolean showingAod) {
+        mShowingAod = showingAod;
+        updateSessionActive();
+    }
+
     public void setStatusBarState(int state) {
         if (FalsingLog.ENABLED) {
             FalsingLog.i("setStatusBarState", new StringBuilder()
@@ -257,11 +271,7 @@
                     .toString());
         }
         mState = state;
-        if (shouldSessionBeActive()) {
-            sessionEntrypoint();
-        } else {
-            sessionExitpoint(false /* force */);
-        }
+        updateSessionActive();
     }
 
     public void onScreenTurningOn() {
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
new file mode 100644
index 0000000..34c05a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -0,0 +1,194 @@
+/*
+ * 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.colorextraction;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWallpaperVisibilityListener;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.ExtractionType;
+import com.android.internal.colorextraction.types.Tonal;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+/**
+ * ColorExtractor aware of wallpaper visibility
+ */
+public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
+    private static final String TAG = "SysuiColorExtractor";
+    private boolean mWallpaperVisible;
+    // Colors to return when the wallpaper isn't visible
+    private final GradientColors mWpHiddenColors;
+
+    public SysuiColorExtractor(Context context) {
+        this(context, new Tonal(context), true);
+    }
+
+    @VisibleForTesting
+    public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) {
+        super(context, type);
+        mWpHiddenColors = new GradientColors();
+
+        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+        updateDefaultGradients(systemColors);
+
+        if (registerVisibility) {
+            try {
+                IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
+                Handler handler = Handler.getMain();
+                boolean visible = windowManagerService.registerWallpaperVisibilityListener(
+                        new IWallpaperVisibilityListener.Stub() {
+                            @Override
+                            public void onWallpaperVisibilityChanged(boolean newVisibility,
+                                    int displayId) throws RemoteException {
+                                handler.post(() -> setWallpaperVisible(newVisibility));
+                            }
+                        }, Display.DEFAULT_DISPLAY);
+                setWallpaperVisible(visible);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
+            }
+        }
+
+        WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
+        if (wallpaperManager != null) {
+            // Listen to all users instead of only the current one.
+            wallpaperManager.removeOnColorsChangedListener(this);
+            wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+                    UserHandle.USER_ALL);
+        }
+    }
+
+    private void updateDefaultGradients(WallpaperColors colors) {
+        Tonal.applyFallback(colors, mWpHiddenColors);
+    }
+
+    @Override
+    public void onColorsChanged(WallpaperColors colors, int which, int userId) {
+        if (userId != KeyguardUpdateMonitor.getCurrentUser()) {
+            // Colors do not belong to current user, ignoring.
+            return;
+        }
+
+        super.onColorsChanged(colors, which);
+
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            updateDefaultGradients(colors);
+        }
+    }
+
+    @VisibleForTesting
+    GradientColors getFallbackColors() {
+        return mWpHiddenColors;
+    }
+
+    /**
+     * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @return colors
+     */
+    @Override
+    public GradientColors getColors(int which) {
+        return getColors(which, TYPE_DARK);
+    }
+
+    /**
+     * Wallpaper colors when the wallpaper is visible, fallback otherwise.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
+     * @return colors
+     */
+    @Override
+    public GradientColors getColors(int which, int type) {
+        return getColors(which, type, false /* ignoreVisibility */);
+    }
+
+    /**
+     * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility.
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper
+     *                                  isn't visible
+     * @return
+     */
+    public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) {
+        return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility);
+    }
+
+    /**
+     *
+     * @param which FLAG_LOCK or FLAG_SYSTEM
+     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
+     * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning
+     *                                  if it's visible or not
+     * @return colors
+     */
+    public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
+        // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
+        // if we have different lock and system wallpapers.
+        if (which == WallpaperManager.FLAG_LOCK) {
+            ignoreWallpaperVisibility = true;
+        }
+        if (mWallpaperVisible || ignoreWallpaperVisibility) {
+            return super.getColors(which, type);
+        } else {
+            return mWpHiddenColors;
+        }
+    }
+
+    @VisibleForTesting
+    void setWallpaperVisible(boolean visible) {
+        if (mWallpaperVisible != visible) {
+            mWallpaperVisible = visible;
+            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("SysuiColorExtractor:");
+
+        pw.println("  Current wallpaper colors:");
+        pw.println("    system: " + mSystemColors);
+        pw.println("    lock: " + mLockColors);
+
+        GradientColors[] system = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+        GradientColors[] lock = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+        pw.println("  Gradients:");
+        pw.println("    system: " + Arrays.toString(system));
+        pw.println("    lock: " + Arrays.toString(lock));
+        pw.println("  Default scrim: " + mWpHiddenColors);
+
+    }
+}
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 eea09df..d374d68 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -19,12 +19,18 @@
 import android.app.AlarmManager;
 import android.app.Application;
 import android.content.Context;
+import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.os.Handler;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.AsyncSensorManager;
+import com.android.systemui.util.wakelock.DelayedWakeLock;
 import com.android.systemui.util.wakelock.WakeLock;
 
 public class DozeFactory {
@@ -35,33 +41,49 @@
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
     public DozeMachine assembleMachine(DozeService dozeService) {
         Context context = dozeService;
-        SensorManager sensorManager = context.getSystemService(SensorManager.class);
+        SensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
 
         DozeHost host = getHost(dozeService);
         AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
         DozeParameters params = new DozeParameters(context);
         Handler handler = new Handler();
-        WakeLock wakeLock = WakeLock.createPartial(context, "Doze");
+        WakeLock wakeLock = new DelayedWakeLock(handler,
+                WakeLock.createPartial(context, "Doze"));
 
-        DozeMachine machine = new DozeMachine(
-                DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params),
-                config,
-                wakeLock);
+        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[]{
-                createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
-                        machine),
+                new DozePauser(handler, machine, alarmManager),
+                new DozeFalsingManagerAdapter(FalsingManager.getInstance(context)),
+                createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
+                        handler, wakeLock, machine),
                 createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
+                new DozeScreenState(wrappedService, handler),
+                createDozeScreenBrightness(context, wrappedService, sensorManager, host, handler),
         });
 
         return machine;
     }
 
+    private DozeMachine.Part createDozeScreenBrightness(Context context,
+            DozeMachine.Service service, SensorManager sensorManager, DozeHost host,
+            Handler handler) {
+        Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
+                context.getString(R.string.doze_brightness_sensor_type));
+        return new DozeScreenBrightness(context, service, sensorManager, sensor, host, handler);
+    }
+
     private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
-            DozeHost host, AmbientDisplayConfiguration config, DozeParameters params,
-            Handler handler, WakeLock wakeLock, DozeMachine machine) {
+            DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
+            DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine) {
         boolean allowPulseTriggers = true;
-        return new DozeTriggers(context, machine, host, config, params,
+        return new DozeTriggers(context, machine, host, alarmManager, config, params,
                 sensorManager, handler, wakeLock, allowPulseTriggers);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java
new file mode 100644
index 0000000..00ca9a4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.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 com.android.systemui.doze;
+
+import com.android.systemui.classifier.FalsingManager;
+
+/**
+ * Notifies FalsingManager of whether or not AOD is showing.
+ */
+public class DozeFalsingManagerAdapter implements DozeMachine.Part {
+
+    private final FalsingManager mFalsingManager;
+
+    public DozeFalsingManagerAdapter(FalsingManager falsingManager) {
+        mFalsingManager = falsingManager;
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        mFalsingManager.setShowingAod(isAodMode(newState));
+    }
+
+    private boolean isAodMode(DozeMachine.State state) {
+        switch (state) {
+            case DOZE_AOD:
+            case DOZE_AOD_PAUSING:
+            case DOZE_AOD_PAUSED:
+                return true;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 3e424d0..7db118d 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();
@@ -38,6 +40,13 @@
 
     void setAnimateWakeup(boolean animateWakeup);
 
+    void onDoubleTap(float x, float y);
+
+    default void setAodDimmingScrim(float scrimOpacity) {}
+    void setDozeScreenBrightness(int value);
+
+    void onIgnoreTouchWhilePulsing(boolean ignore);
+
     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..79de48a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,7 +35,7 @@
     private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
     static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
-    private static final int PULSE_REASONS = 5;
+    private static final int PULSE_REASONS = 6;
 
     public static final int PULSE_REASON_NONE = -1;
     public static final int PULSE_REASON_INTENT = 0;
@@ -43,6 +43,7 @@
     public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
     public static final int PULSE_REASON_SENSOR_PICKUP = 3;
     public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
+    public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
 
     private static boolean sRegisterKeyguardCallback = true;
 
@@ -163,6 +164,11 @@
         }
     }
 
+    public static void traceState(DozeMachine.State state) {
+        if (!ENABLED) return;
+        log("state " + state);
+    }
+
     public static void traceProximityResult(Context context, boolean near, long millis,
             int pulseReason) {
         if (!ENABLED) return;
@@ -179,6 +185,7 @@
             case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
             case PULSE_REASON_SENSOR_PICKUP: return "pickup";
             case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
+            case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
             default: throw new IllegalArgumentException("bad reason: " + pulseReason);
         }
     }
@@ -231,10 +238,10 @@
                 + state + " blocked=" + blocked);
     }
 
-    public static void tracePulseCanceledByProx(Context context) {
+    public static void tracePulseTouchDisabledByProx(Context context, boolean disabled) {
         if (!ENABLED) return;
         init(context);
-        log("pulseCanceledByProx");
+        log("pulseTouchDisabledByProx " + disabled);
     }
 
     public static void setRegisterKeyguardCallback(boolean registerKeyguardCallback) {
@@ -248,6 +255,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/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 44bb33a..8ec6afc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -17,6 +17,7 @@
 package com.android.systemui.doze;
 
 import android.annotation.MainThread;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.Display;
@@ -60,13 +61,16 @@
         /** Doze is done. DozeService is finished. */
         FINISH,
         /** AOD, but the display is temporarily off. */
-        DOZE_AOD_PAUSED;
+        DOZE_AOD_PAUSED,
+        /** AOD, prox is near, transitions to DOZE_AOD_PAUSED after a timeout. */
+        DOZE_AOD_PAUSING;
 
         boolean canPulse() {
             switch (this) {
                 case DOZE:
                 case DOZE_AOD:
                 case DOZE_AOD_PAUSED:
+                case DOZE_AOD_PAUSING:
                     return true;
                 default:
                     return false;
@@ -88,11 +92,14 @@
                 case UNINITIALIZED:
                 case INITIALIZED:
                 case DOZE:
+                case DOZE_REQUEST_PULSE:
                 case DOZE_AOD_PAUSED:
                     return Display.STATE_OFF;
                 case DOZE_PULSING:
+                    return Display.STATE_ON;
                 case DOZE_AOD:
-                    return Display.STATE_DOZE; // TODO: use STATE_ON if appropriate.
+                case DOZE_AOD_PAUSING:
+                    return Display.STATE_DOZE_SUSPEND;
                 default:
                     return Display.STATE_UNKNOWN;
             }
@@ -219,9 +226,11 @@
         State oldState = mState;
         mState = newState;
 
+        DozeLog.traceState(newState);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "doze_machine_state", newState.ordinal());
+
         updatePulseReason(newState, oldState, pulseReason);
         performTransitionOnComponents(oldState, newState);
-        updateScreenState(newState);
         updateWakeLockState(newState);
 
         resolveIntermediateState(newState);
@@ -283,7 +292,8 @@
         if (mState == State.FINISH) {
             return State.FINISH;
         }
-        if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD || mState == State.DOZE)
+        if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING
+                || mState == State.DOZE_AOD || mState == State.DOZE)
                 && requestedState == State.DOZE_PULSE_DONE) {
             Log.i(TAG, "Dropping pulse done because current state is already done: " + mState);
             return mState;
@@ -306,13 +316,6 @@
         }
     }
 
-    private void updateScreenState(State newState) {
-        int state = newState.screenState();
-        if (state != Display.STATE_UNKNOWN) {
-            mDozeService.setDozeScreenState(state);
-        }
-    }
-
     private void resolveIntermediateState(State state) {
         switch (state) {
             case INITIALIZED:
@@ -359,5 +362,36 @@
 
         /** Request waking up. */
         void requestWakeUp();
+
+        /** Set screen brightness */
+        void setDozeScreenBrightness(int brightness);
+
+        class Delegate implements Service {
+            private final Service mDelegate;
+
+            public Delegate(Service delegate) {
+                mDelegate = delegate;
+            }
+
+            @Override
+            public void finish() {
+                mDelegate.finish();
+            }
+
+            @Override
+            public void setDozeScreenState(int state) {
+                mDelegate.setDozeScreenState(state);
+            }
+
+            @Override
+            public void requestWakeUp() {
+                mDelegate.requestWakeUp();
+            }
+
+            @Override
+            public void setDozeScreenBrightness(int brightness) {
+                mDelegate.setDozeScreenBrightness(brightness);
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java b/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
new file mode 100644
index 0000000..a33b454c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import android.app.AlarmManager;
+import android.os.Handler;
+
+import com.android.systemui.util.AlarmTimeout;
+
+/**
+ * Moves the doze machine from the pausing to the paused state after a timeout.
+ */
+public class DozePauser implements DozeMachine.Part {
+    public static final String TAG = DozePauser.class.getSimpleName();
+    private static final long TIMEOUT = 10 * 1000;
+    private final AlarmTimeout mPauseTimeout;
+    private final DozeMachine mMachine;
+
+    public DozePauser(Handler handler, DozeMachine machine, AlarmManager alarmManager) {
+        mMachine = machine;
+        mPauseTimeout = new AlarmTimeout(alarmManager, this::onTimeout, TAG, handler);
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        switch (newState) {
+            case DOZE_AOD_PAUSING:
+                mPauseTimeout.schedule(TIMEOUT, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+                break;
+            default:
+                mPauseTimeout.cancel();
+                break;
+        }
+    }
+
+    private void onTimeout() {
+        mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSED);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
new file mode 100644
index 0000000..dcb3882
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Interface for class that cares about doze states.
+ */
+public interface DozeReceiver {
+    void setDozing(boolean dozing);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
new file mode 100644
index 0000000..30420529
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -0,0 +1,128 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+
+/**
+ * Controls the screen brightness when dozing.
+ */
+public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListener {
+    private final Context mContext;
+    private final DozeMachine.Service mDozeService;
+    private final DozeHost mDozeHost;
+    private final Handler mHandler;
+    private final SensorManager mSensorManager;
+    private final Sensor mLightSensor;
+    private final int[] mSensorToBrightness;
+    private final int[] mSensorToScrimOpacity;
+    private boolean mRegistered;
+
+    public DozeScreenBrightness(Context context, DozeMachine.Service service,
+            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
+            Handler handler) {
+        mContext = context;
+        mDozeService = service;
+        mSensorManager = sensorManager;
+        mLightSensor = lightSensor;
+        mDozeHost = host;
+        mHandler = handler;
+
+        mSensorToBrightness = context.getResources().getIntArray(
+                R.array.config_doze_brightness_sensor_to_brightness);
+        mSensorToScrimOpacity = context.getResources().getIntArray(
+                R.array.config_doze_brightness_sensor_to_scrim_opacity);
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        switch (newState) {
+            case INITIALIZED:
+                resetBrightnessToDefault();
+                break;
+            case DOZE_AOD:
+            case DOZE_REQUEST_PULSE:
+                setLightSensorEnabled(true);
+                break;
+            case DOZE:
+            case DOZE_AOD_PAUSED:
+                setLightSensorEnabled(false);
+                resetBrightnessToDefault();
+                break;
+            case FINISH:
+                setLightSensorEnabled(false);
+                break;
+        }
+    }
+
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        if (mRegistered) {
+            int sensorValue = (int) event.values[0];
+            int brightness = computeBrightness(sensorValue);
+            if (brightness > 0) {
+                mDozeService.setDozeScreenBrightness(brightness);
+            }
+
+            int scrimOpacity = computeScrimOpacity(sensorValue);
+            if (scrimOpacity >= 0) {
+                mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
+            }
+        }
+    }
+
+    private int computeScrimOpacity(int sensorValue) {
+        if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) {
+            return -1;
+        }
+        return mSensorToScrimOpacity[sensorValue];
+    }
+
+    private int computeBrightness(int sensorValue) {
+        if (sensorValue < 0 || sensorValue >= mSensorToBrightness.length) {
+            return -1;
+        }
+        return mSensorToBrightness[sensorValue];
+    }
+
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    private void resetBrightnessToDefault() {
+        mDozeService.setDozeScreenBrightness(mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_screenBrightnessDoze));
+    }
+
+    private void setLightSensorEnabled(boolean enabled) {
+        if (enabled && !mRegistered && mLightSensor != null) {
+            mRegistered = mSensorManager.registerListener(this, mLightSensor,
+                    SensorManager.SENSOR_DELAY_NORMAL, mHandler);
+        } else if (!enabled && mRegistered) {
+            mSensorManager.unregisterListener(this);
+            mRegistered = false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
new file mode 100644
index 0000000..63f5d97
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import android.os.Handler;
+import android.view.Display;
+
+/**
+ * Controls the screen when dozing.
+ */
+public class DozeScreenState implements DozeMachine.Part {
+    private final DozeMachine.Service mDozeService;
+    private final Handler mHandler;
+    private int mPendingScreenState = Display.STATE_UNKNOWN;
+    private Runnable mApplyPendingScreenState = this::applyPendingScreenState;
+
+    public DozeScreenState(DozeMachine.Service service, Handler handler) {
+        mDozeService = service;
+        mHandler = handler;
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        int screenState = newState.screenState();
+        if (screenState == Display.STATE_UNKNOWN) {
+            // We'll keep it in the existing state
+            return;
+        }
+        boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
+        if (messagePending || oldState == DozeMachine.State.INITIALIZED) {
+            // During initialization, we hide the navigation bar. That is however only applied after
+            // a traversal; setting the screen state here is immediate however, so it can happen
+            // that the screen turns on again before the navigation bar is hidden. To work around
+            // that, wait for a traversal to happen before applying the initial screen state.
+            mPendingScreenState = screenState;
+            if (!messagePending) {
+                mHandler.post(mApplyPendingScreenState);
+            }
+            return;
+        }
+        applyScreenState(screenState);
+    }
+
+    private void applyPendingScreenState() {
+        applyScreenState(mPendingScreenState);
+        mPendingScreenState = Display.STATE_UNKNOWN;
+    }
+
+    private void applyScreenState(int screenState) {
+        if (screenState != Display.STATE_UNKNOWN) {
+            mDozeService.setDozeScreenState(screenState);
+            mPendingScreenState = Display.STATE_UNKNOWN;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
index ad5897a..5d0a9d7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
@@ -24,18 +24,11 @@
 /**
  * Prevents usage of doze screen states on devices that don't support them.
  */
-public class DozeScreenStatePreventingAdapter implements DozeMachine.Service {
-
-    private final DozeMachine.Service mInner;
+public class DozeScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
 
     @VisibleForTesting
     DozeScreenStatePreventingAdapter(DozeMachine.Service inner) {
-        mInner = inner;
-    }
-
-    @Override
-    public void finish() {
-        mInner.finish();
+        super(inner);
     }
 
     @Override
@@ -43,12 +36,7 @@
         if (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND) {
             state = Display.STATE_ON;
         }
-        mInner.setDozeScreenState(state);
-    }
-
-    @Override
-    public void requestWakeUp() {
-        mInner.requestWakeUp();
+        super.setDozeScreenState(state);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 73f5222..566353c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -18,6 +18,7 @@
 
 import android.annotation.AnyThread;
 import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -29,6 +30,7 @@
 import android.hardware.TriggerEventListener;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -38,6 +40,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.AlarmTimeout;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
@@ -51,6 +54,7 @@
     private static final String TAG = "DozeSensors";
 
     private final Context mContext;
+    private final AlarmManager mAlarmManager;
     private final SensorManager mSensorManager;
     private final TriggerSensor[] mSensors;
     private final ContentResolver mResolver;
@@ -65,10 +69,12 @@
     private final ProxSensor mProxSensor;
 
 
-    public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
+    public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
+            DozeParameters dozeParameters,
             AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback,
             Consumer<Boolean> proxCallback) {
         mContext = context;
+        mAlarmManager = alarmManager;
         mSensorManager = sensorManager;
         mDozeParameters = dozeParameters;
         mConfig = config;
@@ -81,17 +87,29 @@
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
                         null /* setting */,
                         dozeParameters.getPulseOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
+                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+                        false /* touchscreen */),
                 mPickupSensor = new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PULSE_ON_PICK_UP,
                         config.pulseOnPickupAvailable(),
-                        DozeLog.PULSE_REASON_SENSOR_PICKUP),
+                        DozeLog.PULSE_REASON_SENSOR_PICKUP, false /* touchCoords */,
+                        false /* touchscreen */),
                 new TriggerSensor(
                         findSensorWithType(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
                         true /* configured */,
-                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
+                        DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP,
+                        dozeParameters.doubleTapReportsTouchCoordinates(),
+                        true /* touchscreen */),
+                new TriggerSensor(
+                        findSensorWithType(config.longPressSensorType()),
+                        Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
+                        false /* settingDef */,
+                        true /* configured */,
+                        DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
+                        true /* reports touch coordinates */,
+                        true /* touchscreen */),
         };
 
         mProxSensor = new ProxSensor();
@@ -99,10 +117,14 @@
     }
 
     private Sensor findSensorWithType(String type) {
+        return findSensorWithType(mSensorManager, type);
+    }
+
+    static Sensor findSensorWithType(SensorManager sensorManager, String type) {
         if (TextUtils.isEmpty(type)) {
             return null;
         }
-        List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
         for (Sensor s : sensorList) {
             if (type.equals(s.getStringType())) {
                 return s;
@@ -123,6 +145,15 @@
         }
     }
 
+    /** Set the listening state of only the sensors that require the touchscreen. */
+    public void setTouchscreenSensorsListening(boolean listening) {
+        for (TriggerSensor sensor : mSensors) {
+            if (sensor.mRequiresTouchscreen) {
+                sensor.setListening(listening);
+            }
+        }
+    }
+
     public void reregisterAllSensors() {
         for (TriggerSensor s : mSensors) {
             s.setListening(false);
@@ -139,7 +170,7 @@
     }
 
     public void setProxListening(boolean listen) {
-        mProxSensor.setRegistered(listen);
+        mProxSensor.setRequested(listen);
     }
 
     private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@@ -163,15 +194,35 @@
         for (TriggerSensor s : mSensors) {
             pw.print("Sensor: "); pw.println(s.toString());
         }
+        pw.print("ProxSensor: "); pw.println(mProxSensor.toString());
+    }
+
+    /**
+     * @return true if prox is currently far, false if near or null if unknown.
+     */
+    public Boolean isProximityCurrentlyFar() {
+        return mProxSensor.mCurrentlyFar;
     }
 
     private class ProxSensor implements SensorEventListener {
 
+        static final long COOLDOWN_TRIGGER = 2 * 1000;
+        static final long COOLDOWN_PERIOD = 5 * 1000;
+
+        boolean mRequested;
         boolean mRegistered;
         Boolean mCurrentlyFar;
+        long mLastNear;
+        final AlarmTimeout mCooldownTimer;
 
-        void setRegistered(boolean register) {
-            if (mRegistered == register) {
+
+        public ProxSensor() {
+            mCooldownTimer = new AlarmTimeout(mAlarmManager, this::updateRegistered,
+                    "prox_cooldown", mHandler);
+        }
+
+        void setRequested(boolean requested) {
+            if (mRequested == requested) {
                 // Send an update even if we don't re-register.
                 mHandler.post(() -> {
                     if (mCurrentlyFar != null) {
@@ -180,6 +231,18 @@
                 });
                 return;
             }
+            mRequested = requested;
+            updateRegistered();
+        }
+
+        private void updateRegistered() {
+            setRegistered(mRequested && !mCooldownTimer.isScheduled());
+        }
+
+        private void setRegistered(boolean register) {
+            if (mRegistered == register) {
+                return;
+            }
             if (register) {
                 mRegistered = mSensorManager.registerListener(this,
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
@@ -195,11 +258,30 @@
         public void onSensorChanged(SensorEvent event) {
             mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange();
             mProxCallback.accept(mCurrentlyFar);
+
+            long now = SystemClock.elapsedRealtime();
+            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
+                // wakeups than we're saving from turning of the screen. Instead, turn it off
+                // for a while.
+                mCooldownTimer.schedule(COOLDOWN_PERIOD, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+                updateRegistered();
+            }
         }
 
         @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 {
@@ -207,16 +289,30 @@
         final boolean mConfigured;
         final int mPulseReason;
         final String mSetting;
+        final boolean mReportsTouchCoordinates;
+        final boolean mSettingDefault;
+        final boolean mRequiresTouchscreen;
 
         private boolean mRequested;
         private boolean mRegistered;
         private boolean mDisabled;
 
-        public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason) {
+        public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
+                boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
+            this(sensor, setting, true /* settingDef */, configured, pulseReason,
+                    reportsTouchCoordinates, requiresTouchscreen);
+        }
+
+        public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
+                boolean configured, int pulseReason, boolean reportsTouchCoordinates,
+                boolean requiresTouchscreen) {
             mSensor = sensor;
             mSetting = setting;
+            mSettingDefault = settingDef;
             mConfigured = configured;
             mPulseReason = pulseReason;
+            mReportsTouchCoordinates = reportsTouchCoordinates;
+            mRequiresTouchscreen = requiresTouchscreen;
         }
 
         public void setListening(boolean listen) {
@@ -247,7 +343,7 @@
             if (TextUtils.isEmpty(mSetting)) {
                 return true;
             }
-            return Settings.Secure.getIntForUser(mResolver, mSetting, 1,
+            return Settings.Secure.getIntForUser(mResolver, mSetting, mSettingDefault ? 1 : 0,
                     UserHandle.USER_CURRENT) != 0;
         }
 
@@ -263,6 +359,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;
@@ -276,7 +373,13 @@
                 }
 
                 mRegistered = false;
-                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck);
+                float screenX = -1;
+                float screenY = -1;
+                if (mReportsTouchCoordinates && event.values.length >= 2) {
+                    screenX = event.values[0];
+                    screenY = event.values[1];
+                }
+                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY);
                 updateListener();  // reregister, this sensor only fires once
             }));
         }
@@ -309,7 +412,12 @@
          * Called when a sensor requests a pulse
          * @param pulseReason Requesting sensor, e.g. {@link DozeLog#PULSE_REASON_SENSOR_PICKUP}
          * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity.
+         * @param screenX the location on the screen where the sensor fired or -1
+         *                if the sensor doesn't support reporting screen locations.
+         * @param screenY the location on the screen where the sensor fired or -1
+         *                if the sensor doesn't support reporting screen locations.
          */
-        void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck);
+        void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck,
+                float screenX, float screenY);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 5241266..98b1106 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,23 +16,27 @@
 
 package com.android.systemui.doze;
 
+import android.content.Context;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.service.dreams.DreamService;
 import android.util.Log;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.PluginManager;
-
+import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
+import com.android.systemui.plugins.PluginListener;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-public class DozeService extends DreamService implements DozeMachine.Service {
+public class DozeService extends DreamService
+        implements DozeMachine.Service, RequestDoze, PluginListener<DozeServicePlugin> {
     private static final String TAG = "DozeService";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private DozeMachine mDozeMachine;
+    private DozeServicePlugin mDozePlugin;
 
     public DozeService() {
         setDebug(DEBUG);
@@ -48,21 +52,42 @@
             finish();
             return;
         }
-
+        Dependency.get(PluginManager.class).addPluginListener(this,
+                DozeServicePlugin.class, false /* Allow multiple */);
         mDozeMachine = new DozeFactory().assembleMachine(this);
     }
 
     @Override
+    public void onPluginConnected(DozeServicePlugin plugin, Context pluginContext) {
+        mDozePlugin = plugin;
+        mDozePlugin.setDozeRequester(this);
+    }
+
+    @Override
+    public void onPluginDisconnected(DozeServicePlugin plugin) {
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStopped();
+            mDozePlugin = null;
+        }
+    }
+
+    @Override
     public void onDreamingStarted() {
         super.onDreamingStarted();
         mDozeMachine.requestState(DozeMachine.State.INITIALIZED);
         startDozing();
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStarted();
+        }
     }
 
     @Override
     public void onDreamingStopped() {
         super.onDreamingStopped();
         mDozeMachine.requestState(DozeMachine.State.FINISH);
+        if (mDozePlugin != null) {
+            mDozePlugin.onDreamingStopped();
+        }
     }
 
     @Override
@@ -77,4 +102,18 @@
         PowerManager pm = getSystemService(PowerManager.class);
         pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
     }
+
+    @Override
+    public void onRequestShowDoze() {
+        if (mDozeMachine != null) {
+            mDozeMachine.requestState(DozeMachine.State.DOZE_AOD);
+        }
+    }
+
+    @Override
+    public void onRequestHideDoze() {
+        if (mDozeMachine != null) {
+            mDozeMachine.requestState(DozeMachine.State.DOZE);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
new file mode 100644
index 0000000..1c6521f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
@@ -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.
+ */
+
+package com.android.systemui.doze;
+
+import android.support.annotation.VisibleForTesting;
+import android.view.Display;
+
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+/**
+ * Prevents usage of doze screen states on devices that don't support them.
+ */
+public class DozeSuspendScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
+
+    @VisibleForTesting
+    DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) {
+        super(inner);
+    }
+
+    @Override
+    public void setDozeScreenState(int state) {
+        if (state == Display.STATE_DOZE_SUSPEND) {
+            state = Display.STATE_DOZE;
+        }
+        super.setDozeScreenState(state);
+    }
+
+    /**
+     * If the device supports the doze display state, return {@code inner}. Otherwise
+     * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}.
+     */
+    public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner,
+            DozeParameters params) {
+        return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner) : inner;
+    }
+
+    private static boolean isNeeded(DozeParameters params) {
+        return !params.getDozeSuspendDisplayStateSupported();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 563b8fe..4583160 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.app.AlarmManager;
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -39,6 +40,7 @@
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
+import java.util.function.IntConsumer;
 
 /**
  * Handles triggers for ambient state changes.
@@ -69,7 +71,7 @@
 
 
     public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
-            AmbientDisplayConfiguration config,
+            AlarmManager alarmManager, AmbientDisplayConfiguration config,
             DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
             WakeLock wakeLock, boolean allowPulseTriggers) {
         mContext = context;
@@ -81,8 +83,8 @@
         mHandler = handler;
         mWakeLock = wakeLock;
         mAllowPulseTriggers = allowPulseTriggers;
-        mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, config,
-                wakeLock, this::onSensor, this::onProximityFar);
+        mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters,
+                config, wakeLock, this::onSensor, this::onProximityFar);
         mUiModeManager = mContext.getSystemService(UiModeManager.class);
     }
 
@@ -98,10 +100,53 @@
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
     }
 
-    private void onSensor(int pulseReason, boolean sensorPerformedProxCheck) {
-        requestPulse(pulseReason, sensorPerformedProxCheck);
+    private void proximityCheckThenCall(IntConsumer callback,
+            boolean alreadyPerformedProxCheck,
+            int pulseReason) {
+        Boolean cachedProxFar = mDozeSensors.isProximityCurrentlyFar();
+        if (alreadyPerformedProxCheck) {
+            callback.accept(ProximityCheck.RESULT_NOT_CHECKED);
+        } else if (cachedProxFar != null) {
+            callback.accept(cachedProxFar ? ProximityCheck.RESULT_FAR : ProximityCheck.RESULT_NEAR);
+        } else {
+            final long start = SystemClock.uptimeMillis();
+            new ProximityCheck() {
+                @Override
+                public void onProximityResult(int result) {
+                    final long end = SystemClock.uptimeMillis();
+                    DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
+                            end - start, pulseReason);
+                    callback.accept(result);
+                }
+            }.check();
+        }
+    }
 
-        if (pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP) {
+    private void onSensor(int pulseReason, boolean sensorPerformedProxCheck,
+            float screenX, float screenY) {
+        boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
+        boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
+        boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
+
+        if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !isLongPress) {
+            proximityCheckThenCall((result) -> {
+                if (result == ProximityCheck.RESULT_NEAR) {
+                    // In pocket, drop event.
+                    return;
+                }
+                if (isDoubleTap) {
+                    mDozeHost.onDoubleTap(screenX, screenY);
+                    mMachine.wakeUp();
+                } else {
+                    mDozeHost.extendPulse();
+                }
+            }, sensorPerformedProxCheck, pulseReason);
+            return;
+        } else {
+            requestPulse(pulseReason, sensorPerformedProxCheck);
+        }
+
+        if (isPickup) {
             final long timeSinceNotification =
                     SystemClock.elapsedRealtime() - mNotificationPulseTime;
             final boolean withinVibrationThreshold =
@@ -112,29 +157,25 @@
 
     private void onProximityFar(boolean far) {
         final boolean near = !far;
-        DozeMachine.State state = mMachine.getState();
-        if (near && state == DozeMachine.State.DOZE_PULSING) {
-            if (DEBUG) Log.i(TAG, "Prox NEAR, ending pulse");
-            DozeLog.tracePulseCanceledByProx(mContext);
-            mMachine.requestState(DozeMachine.State.DOZE_PULSE_DONE);
+        final DozeMachine.State state = mMachine.getState();
+        final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
+        final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
+        final boolean aod = (state == DozeMachine.State.DOZE_AOD);
+
+        if (state == DozeMachine.State.DOZE_PULSING) {
+            boolean ignoreTouch = near;
+            if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+            mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
         }
-        if (far && state == DozeMachine.State.DOZE_AOD_PAUSED) {
+        if (far && (paused || pausing)) {
             if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
             mMachine.requestState(DozeMachine.State.DOZE_AOD);
-        } else if (near && state == DozeMachine.State.DOZE_AOD) {
+        } else if (near && aod) {
             if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD");
-            mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSED);
+            mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
         }
     }
 
-    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) {
@@ -145,14 +186,19 @@
                 break;
             case DOZE:
             case DOZE_AOD:
-            case DOZE_AOD_PAUSED:
                 mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
-                mDozeSensors.setListening(true);
                 if (oldState != DozeMachine.State.INITIALIZED) {
                     mDozeSensors.reregisterAllSensors();
                 }
+                mDozeSensors.setListening(true);
+                break;
+            case DOZE_AOD_PAUSED:
+            case DOZE_AOD_PAUSING:
+                mDozeSensors.setProxListening(true);
+                mDozeSensors.setListening(false);
                 break;
             case DOZE_PULSING:
+                mDozeSensors.setTouchscreenSensorsListening(false);
                 mDozeSensors.setProxListening(true);
                 break;
             case FINISH:
@@ -166,11 +212,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);
         }
     }
 
@@ -186,33 +232,15 @@
         }
 
         mPulsePending = true;
-        if (!mDozeParameters.getProxCheckBeforePulse() || performedProxCheck) {
-            // skip proximity check
-            continuePulseRequest(reason);
-            return;
-        }
-
-        final long start = SystemClock.uptimeMillis();
-        new ProximityCheck() {
-            @Override
-            public void onProximityResult(int result) {
-                final long end = SystemClock.uptimeMillis();
-                DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
-                        end - start, reason);
-                if (performedProxCheck) {
-                    // we already continued
-                    return;
-                }
-                // avoid pulsing in pockets
-                if (result == RESULT_NEAR) {
-                    mPulsePending = false;
-                    return;
-                }
-
-                // not in-pocket, continue pulsing
+        proximityCheckThenCall((result) -> {
+            if (result == ProximityCheck.RESULT_NEAR) {
+                // in pocket, abort pulse
+                mPulsePending = false;
+            } else {
+                // not in pocket, continue pulsing
                 continuePulseRequest(reason);
             }
-        }.check();
+        }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason);
     }
 
     private boolean canPulse() {
@@ -246,6 +274,7 @@
         protected static final int RESULT_UNKNOWN = 0;
         protected static final int RESULT_NEAR = 1;
         protected static final int RESULT_FAR = 2;
+        protected static final int RESULT_NOT_CHECKED = 3;
 
         private boolean mRegistered;
         private boolean mFinished;
@@ -323,7 +352,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();
@@ -359,7 +388,7 @@
         @Override
         public void onPowerSaveChanged(boolean active) {
             if (active) {
-                onPowerSave();
+                mMachine.requestState(DozeMachine.State.FINISH);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index ea33ebf..dc626fb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -23,6 +23,7 @@
 import android.text.format.Formatter;
 import android.util.Log;
 
+import com.android.systemui.util.AlarmTimeout;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.util.Calendar;
@@ -35,26 +36,23 @@
 
     private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
     private final Context mContext;
-    private final AlarmManager mAlarmManager;
     private final DozeHost mHost;
     private final Handler mHandler;
     private final WakeLock mWakeLock;
     private final DozeMachine mMachine;
-    private final AlarmManager.OnAlarmListener mTimeTick;
+    private final AlarmTimeout mTimeTicker;
 
-    private boolean mTimeTickScheduled = false;
     private long mLastTimeTickElapsed = 0;
 
     public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
             WakeLock wakeLock, DozeHost host, Handler handler) {
         mContext = context;
-        mAlarmManager = alarmManager;
         mMachine = machine;
         mWakeLock = wakeLock;
         mHost = host;
         mHandler = handler;
 
-        mTimeTick = this::onTimeTick;
+        mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
     }
 
     private void pulseWhileDozing(int reason) {
@@ -76,6 +74,7 @@
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
             case DOZE_AOD:
+            case DOZE_AOD_PAUSING:
                 scheduleTimeTick();
                 break;
             case DOZE:
@@ -87,6 +86,7 @@
                 break;
             case DOZE_PULSE_DONE:
                 mHost.abortPulsing();
+                break;
             case INITIALIZED:
                 mHost.startDozing();
                 break;
@@ -95,40 +95,41 @@
                 unscheduleTimeTick();
                 break;
         }
-        mHost.setAnimateWakeup(shouldAnimateWakeup(newState));
+        updateAnimateWakeup(newState);
     }
 
-    private boolean shouldAnimateWakeup(DozeMachine.State state) {
+    private void updateAnimateWakeup(DozeMachine.State state) {
         switch (state) {
-            case DOZE_AOD:
             case DOZE_REQUEST_PULSE:
             case DOZE_PULSING:
             case DOZE_PULSE_DONE:
-                return true;
+                mHost.setAnimateWakeup(true);
+                break;
+            case FINISH:
+                // Keep current state.
+                break;
             default:
-                return false;
+                mHost.setAnimateWakeup(false);
+                break;
         }
     }
 
     private void scheduleTimeTick() {
-        if (mTimeTickScheduled) {
+        if (mTimeTicker.isScheduled()) {
             return;
         }
 
         long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis();
-        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
-
-        mTimeTickScheduled = true;
+        mTimeTicker.schedule(delta, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
         mLastTimeTickElapsed = SystemClock.elapsedRealtime();
     }
 
     private void unscheduleTimeTick() {
-        if (!mTimeTickScheduled) {
+        if (!mTimeTicker.isScheduled()) {
             return;
         }
         verifyLastTimeTick();
-        mAlarmManager.cancel(mTimeTick);
+        mTimeTicker.cancel();
     }
 
     private void verifyLastTimeTick() {
@@ -151,10 +152,6 @@
     }
 
     private void onTimeTick() {
-        if (!mTimeTickScheduled) {
-            // Alarm was canceled, but we still got the callback. Ignore.
-            return;
-        }
         verifyLastTimeTick();
 
         mHost.dozeTimeTick();
@@ -162,7 +159,6 @@
         // Keep wakelock until a frame has been pushed.
         mHandler.post(mWakeLock.wrap(() -> {}));
 
-        mTimeTickScheduled = false;
         scheduleTimeTick();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
new file mode 100644
index 0000000..18fb423
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.fragments;
+
+import android.app.Fragment;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.plugins.FragmentBase;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
+
+import java.util.function.Consumer;
+
+/**
+ * Wires up an Extension to a Fragment tag/id so that it always contains the class
+ * selected by the extension.
+ */
+public class ExtensionFragmentListener<T extends FragmentBase> implements Consumer<T> {
+
+    private static final String TAG = "ExtensionFragmentListener";
+
+    private final FragmentHostManager mFragmentHostManager;
+    private final String mTag;
+    private final Extension<T> mExtension;
+    private final int mId;
+    private String mOldClass;
+
+    private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
+        mTag = tag;
+        mFragmentHostManager = FragmentHostManager.get(view);
+        mExtension = extension;
+        mId = id;
+        mFragmentHostManager.getFragmentManager().beginTransaction()
+                .replace(id, (Fragment) mExtension.get(), mTag)
+                .commit();
+        mExtension.clearItem(false);
+    }
+
+    @Override
+    public void accept(T extension) {
+        try {
+            Fragment.class.cast(extension);
+            mFragmentHostManager.getExtensionManager().setCurrentExtension(mId, mTag,
+                    mOldClass, extension.getClass().getName(), mExtension.getContext());
+            mOldClass = extension.getClass().getName();
+        } catch (ClassCastException e) {
+            Log.e(TAG, extension.getClass().getName() + " must be a Fragment", e);
+        }
+        mExtension.clearItem(true);
+    }
+
+    public static <T> void attachExtensonToFragment(View view, String tag, int id,
+            Extension<T> extension) {
+        extension.addCallback(new ExtensionFragmentListener(view, tag, id, extension));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index ee155d9..f8f364d 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 import android.util.ArrayMap;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -52,7 +53,7 @@
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
     private final FragmentService mManager;
-    private final PluginFragmentManager mPlugins = new PluginFragmentManager();
+    private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager();
 
     private FragmentController mFragments;
     private FragmentLifecycleCallbacks mLifecycleCallbacks;
@@ -175,7 +176,7 @@
         return mFragments.getFragmentManager();
     }
 
-    PluginFragmentManager getPluginManager() {
+    ExtensionFragmentManager getExtensionManager() {
         return mPlugins;
     }
 
@@ -262,25 +263,17 @@
         }
     }
 
-    class PluginFragmentManager {
-        private final ArrayMap<String, Context> mPluginLookup = new ArrayMap<>();
+    class ExtensionFragmentManager {
+        private final ArrayMap<String, Context> mExtensionLookup = new ArrayMap<>();
 
-        public void removePlugin(String tag, String currentClass, String defaultClass) {
-            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
-            mPluginLookup.remove(currentClass);
+        public void setCurrentExtension(int id, @NonNull  String tag, @Nullable String oldClass,
+                @NonNull String currentClass, @Nullable Context context) {
+            if (oldClass != null) {
+                mExtensionLookup.remove(oldClass);
+            }
+            mExtensionLookup.put(currentClass, context);
             getFragmentManager().beginTransaction()
-                    .replace(((View) fragment.getView().getParent()).getId(),
-                            instantiate(mContext, defaultClass, null), tag)
-                    .commit();
-            reloadFragments();
-        }
-
-        public void setCurrentPlugin(String tag, String currentClass, Context context) {
-            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
-            mPluginLookup.put(currentClass, context);
-            getFragmentManager().beginTransaction()
-                    .replace(((View) fragment.getView().getParent()).getId(),
-                            instantiate(context, currentClass, null), tag)
+                    .replace(id, instantiate(context, currentClass, null), tag)
                     .commit();
             reloadFragments();
         }
@@ -293,11 +286,11 @@
         }
 
         Fragment instantiate(Context context, String className, Bundle arguments) {
-            Context pluginContext = mPluginLookup.get(className);
-            if (pluginContext != null) {
-                Fragment f = Fragment.instantiate(pluginContext, className, arguments);
+            Context extensionContext = mExtensionLookup.get(className);
+            if (extensionContext != null) {
+                Fragment f = Fragment.instantiate(extensionContext, className, arguments);
                 if (f instanceof Plugin) {
-                    ((Plugin) f).onCreate(mContext, pluginContext);
+                    ((Plugin) f).onCreate(mContext, extensionContext);
                 }
                 return f;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
deleted file mode 100644
index 03bb73d..0000000
--- a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.fragments;
-
-import android.app.Fragment;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.plugins.FragmentBase;
-import com.android.systemui.plugins.Plugin;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
-
-public class PluginFragmentListener implements PluginListener<Plugin> {
-
-    private static final String TAG = "PluginFragmentListener";
-
-    private final FragmentHostManager mFragmentHostManager;
-    private final PluginManager mPluginManager;
-    private final Class<? extends Fragment> mDefaultClass;
-    private final Class<? extends FragmentBase> mExpectedInterface;
-    private final String mTag;
-
-    public PluginFragmentListener(View view, String tag, Class<? extends Fragment> defaultFragment,
-            Class<? extends FragmentBase> expectedInterface) {
-        mTag = tag;
-        mFragmentHostManager = FragmentHostManager.get(view);
-        mPluginManager = Dependency.get(PluginManager.class);
-        mExpectedInterface = expectedInterface;
-        mDefaultClass = defaultFragment;
-    }
-
-    public void startListening() {
-        mPluginManager.addPluginListener(this, mExpectedInterface,
-                false /* Only allow one */);
-    }
-
-    public void stopListening() {
-        mPluginManager.removePluginListener(this);
-    }
-
-    @Override
-    public void onPluginConnected(Plugin plugin, Context pluginContext) {
-        try {
-            mExpectedInterface.cast(plugin);
-            Fragment.class.cast(plugin);
-            mFragmentHostManager.getPluginManager().setCurrentPlugin(mTag,
-                    plugin.getClass().getName(), pluginContext);
-        } catch (ClassCastException e) {
-            Log.e(TAG, plugin.getClass().getName() + " must be a Fragment and implement "
-                    + mExpectedInterface.getName(), e);
-        }
-    }
-
-    @Override
-    public void onPluginDisconnected(Plugin plugin) {
-        mFragmentHostManager.getPluginManager().removePlugin(mTag,
-                plugin.getClass().getName(), mDefaultClass.getName());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index f07027e..09a08f0 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -46,6 +46,11 @@
     }
 
     @Override
+    public void handleShowShutdownUi(boolean isReboot, String reason) {
+        mExtension.get().showShutdownUi(isReboot, reason);
+    }
+
+    @Override
     public void handleShowGlobalActionsMenu() {
         mExtension.get().showGlobalActions(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 206342e..33d5617 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -15,18 +15,29 @@
 package com.android.systemui.globalactions;
 
 import com.android.internal.R;
-import com.android.internal.app.AlertController;
-import com.android.internal.app.AlertController.AlertParams;
+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;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.HardwareUiLayout;
+import com.android.systemui.Interpolators;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
+import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.phone.ScrimController;
+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;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -34,11 +45,11 @@
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
+import android.graphics.Point;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
@@ -56,21 +67,25 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
+import android.util.MathUtils;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
-import android.widget.ListView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -79,7 +94,7 @@
  * may show depending on whether the keyguard is showing, and whether the device
  * is provisioned.
  */
-class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
+class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -127,7 +142,7 @@
      * @param context everything needs a context :(
      */
     public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFuncs) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mWindowManagerFuncs = windowManagerFuncs;
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -162,6 +177,7 @@
 
     /**
      * Show the global actions dialog (creating if necessary)
+     *
      * @param keyguardShowing True if keyguard is showing
      */
     public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
@@ -205,12 +221,12 @@
             mDialog.getWindow().setAttributes(attrs);
             mDialog.show();
             mWindowManagerFuncs.onGlobalActionsShown();
-            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
         }
     }
 
     /**
      * Create the global actions dialog.
+     *
      * @return A new dialog.
      */
     private ActionsDialog createDialog() {
@@ -314,29 +330,21 @@
 
         mAdapter = new MyAdapter();
 
-        AlertParams params = new AlertParams(mContext);
-        params.mAdapter = mAdapter;
-        params.mOnClickListener = this;
-        params.mForceInverseBackground = true;
-
-        ActionsDialog dialog = new ActionsDialog(mContext, params);
+        OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
+            @Override
+            public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
+                    long id) {
+                final Action action = mAdapter.getItem(position);
+                if (action instanceof LongPressAction) {
+                    mDialog.dismiss();
+                    return ((LongPressAction) action).onLongPress();
+                }
+                return false;
+            }
+        };
+        ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
         dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
-
-        dialog.getListView().setItemsCanFocus(true);
-        dialog.getListView().setLongClickable(true);
-        dialog.getListView().setOnItemLongClickListener(
-                new AdapterView.OnItemLongClickListener() {
-                    @Override
-                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
-                            long id) {
-                        final Action action = mAdapter.getItem(position);
-                        if (action instanceof LongPressAction) {
-                            return ((LongPressAction) action).onLongPress();
-                        }
-                        return false;
-                    }
-        });
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        dialog.setKeyguardShowing(mKeyguardShowing);
 
         dialog.setOnDismissListener(this);
 
@@ -346,7 +354,7 @@
     private final class PowerAction extends SinglePressAction implements LongPressAction {
         private PowerAction() {
             super(R.drawable.ic_lock_power_off,
-                R.string.global_action_power_off);
+                    R.string.global_action_power_off);
         }
 
         @Override
@@ -614,7 +622,7 @@
                     SinglePressAction switchToUser = new SinglePressAction(
                             R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
-                            + (isCurrentUser ? " \u2714" : "")) {
+                                    + (isCurrentUser ? " \u2714" : "")) {
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -641,7 +649,6 @@
         refreshSilentMode();
         mAirplaneModeOn.updateState(mAirplaneState);
         mAdapter.notifyDataSetChanged();
-        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
         if (mShowSilentToggle) {
             IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
             mContext.registerReceiver(mRingerModeReceiver, filter);
@@ -652,7 +659,7 @@
         if (!mHasVibrator) {
             final boolean silentModeOn =
                     mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
-            ((ToggleAction)mSilentModeAction).updateState(
+            ((ToggleAction) mSilentModeAction).updateState(
                     silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
         }
     }
@@ -672,16 +679,18 @@
 
     /** {@inheritDoc} */
     public void onClick(DialogInterface dialog, int which) {
-        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
+        Action item = mAdapter.getItem(which);
+        if (!(item instanceof SilentModeTriStateAction)) {
             dialog.dismiss();
         }
-        mAdapter.getItem(which).onPress();
+        item.onPress();
     }
 
     /**
      * The adapter used for the list within the global actions dialog, taking
      * into account whether the keyguard is showing via
-     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether the device is provisioned
+     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
+     * the device is provisioned
      * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
      */
     private class MyAdapter extends BaseAdapter {
@@ -744,7 +753,11 @@
 
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
-            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            if (position == 2) {
+                HardwareUiLayout.get(parent).setDivisionView(view);
+            }
+            return view;
         }
     }
 
@@ -760,7 +773,7 @@
     private interface Action {
         /**
          * @return Text that will be announced when dialog is created.  null
-         *     for none.
+         * for none.
          */
         CharSequence getLabelForAccessibility(Context context);
 
@@ -770,13 +783,13 @@
 
         /**
          * @return whether this action should appear in the dialog when the keygaurd
-         *    is showing.
+         * is showing.
          */
         boolean showDuringKeyguard();
 
         /**
          * @return whether this action should appear in the dialog before the
-         *   device is provisioned.
+         * device is provisioned.
          */
         boolean showBeforeProvisioning();
 
@@ -834,7 +847,8 @@
 
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
-            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
+            View v = inflater.inflate(com.android.systemui.R.layout.global_actions_item, parent,
+                    false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -895,10 +909,10 @@
         protected int mDisabledStatusMessageResId;
 
         /**
-         * @param enabledIconResId The icon for when this action is on.
-         * @param disabledIconResid The icon for when this action is off.
-         * @param message The general information message, e.g 'Silent Mode'
-         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
+         * @param enabledIconResId           The icon for when this action is on.
+         * @param disabledIconResid          The icon for when this action is off.
+         * @param message                    The general information message, e.g 'Silent Mode'
+         * @param enabledStatusMessageResId  The on status message, e.g 'sound disabled'
          * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
          */
         public ToggleAction(int enabledIconResId,
@@ -931,7 +945,7 @@
             willCreate();
 
             View v = inflater.inflate(R
-                            .layout.global_actions_item, parent, false);
+                    .layout.global_actions_item, parent, false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -979,6 +993,7 @@
          * Implementations may override this if their state can be in on of the intermediate
          * states until some notification is received (e.g airplane mode is 'turning off' until
          * we know the wireless connections are back online
+         *
          * @param buttonOn Whether the button was turned on or off
          */
         protected void changeStateFromPress(boolean buttonOn) {
@@ -1020,7 +1035,7 @@
 
     private static class SilentModeTriStateAction implements Action, View.OnClickListener {
 
-        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+        private final int[] ITEM_IDS = {R.id.option1, R.id.option2, R.id.option3};
 
         private final AudioManager mAudioManager;
         private final Handler mHandler;
@@ -1145,19 +1160,19 @@
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MESSAGE_DISMISS:
-                if (mDialog != null) {
-                    mDialog.dismiss();
-                    mDialog = null;
-                }
-                break;
-            case MESSAGE_REFRESH:
-                refreshSilentMode();
-                mAdapter.notifyDataSetChanged();
-                break;
-            case MESSAGE_SHOW:
-                handleShow();
-                break;
+                case MESSAGE_DISMISS:
+                    if (mDialog != null) {
+                        mDialog.dismiss();
+                        mDialog = null;
+                    }
+                    break;
+                case MESSAGE_REFRESH:
+                    refreshSilentMode();
+                    mAdapter.notifyDataSetChanged();
+                    break;
+                case MESSAGE_SHOW:
+                    handleShow();
+                    break;
             }
         }
     };
@@ -1191,40 +1206,123 @@
         }
     }
 
-    private static final class ActionsDialog extends Dialog implements DialogInterface {
-        private final Context mContext;
-        private final AlertController mAlert;
-        private final MyAdapter mAdapter;
+    private static final class ActionsDialog extends Dialog implements DialogInterface,
+            ColorExtractor.OnColorsChangedListener {
 
-        public ActionsDialog(Context context, AlertParams params) {
-            super(context, getDialogTheme(context));
-            mContext = getContext();
-            mAlert = AlertController.create(mContext, this, getWindow());
-            mAdapter = (MyAdapter) params.mAdapter;
-            params.apply(mAlert);
+        private final Context mContext;
+        private final MyAdapter mAdapter;
+        private final LinearLayout mListView;
+        private final HardwareUiLayout mHardwareLayout;
+        private final OnClickListener mClickListener;
+        private final OnItemLongClickListener mLongClickListener;
+        private final GradientDrawable mGradientDrawable;
+        private final ColorExtractor mColorExtractor;
+        private boolean mKeyguardShowing;
+
+        public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
+                OnItemLongClickListener longClickListener) {
+            super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+            mContext = context;
+            mAdapter = adapter;
+            mClickListener = clickListener;
+            mLongClickListener = longClickListener;
+            mGradientDrawable = new GradientDrawable(mContext);
+            mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+
+            // Window initialization
+            Window window = getWindow();
+            window.requestFeature(Window.FEATURE_NO_TITLE);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+            window.addFlags(
+                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+            window.setBackgroundDrawable(mGradientDrawable);
+            window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+
+            setContentView(com.android.systemui.R.layout.global_actions_wrapped);
+            mListView = findViewById(android.R.id.list);
+            mHardwareLayout = HardwareUiLayout.get(mListView);
+            mHardwareLayout.setOutsideTouchListener(view -> dismiss());
         }
 
-        private static int getDialogTheme(Context context) {
-            TypedValue outValue = new TypedValue();
-            context.getTheme().resolveAttribute(R.attr.alertDialogTheme,
-                    outValue, true);
-            return outValue.resourceId;
+        private void updateList() {
+            mListView.removeAllViews();
+            for (int i = 0; i < mAdapter.getCount(); i++) {
+                View v = mAdapter.getView(i, null, mListView);
+                final int pos = i;
+                v.setOnClickListener(view -> mClickListener.onClick(this, pos));
+                v.setOnLongClickListener(view ->
+                        mLongClickListener.onItemLongClick(null, v, pos, 0));
+                mListView.addView(v);
+            }
         }
 
         @Override
         protected void onStart() {
             super.setCanceledOnTouchOutside(true);
             super.onStart();
-        }
+            updateList();
 
-        public ListView getListView() {
-            return mAlert.getListView();
+            Point displaySize = new Point();
+            mContext.getDisplay().getRealSize(displaySize);
+            mColorExtractor.addOnColorsChangedListener(this);
+            mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
+            GradientColors colors = mColorExtractor.getColors(mKeyguardShowing ?
+                    WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
+            mGradientDrawable.setColors(colors, false);
         }
 
         @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mAlert.installContent();
+        protected void onStop() {
+            super.onStop();
+            mColorExtractor.removeOnColorsChangedListener(this);
+        }
+
+        @Override
+        public void show() {
+            super.show();
+            mGradientDrawable.setAlpha(0);
+            mHardwareLayout.setTranslationX(getAnimTranslation());
+            mHardwareLayout.setAlpha(0);
+            mHardwareLayout.animate()
+                    .alpha(1)
+                    .translationX(0)
+                    .setDuration(300)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .setUpdateListener(animation -> {
+                        int alpha = (int) ((Float) animation.getAnimatedValue()
+                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
+                        mGradientDrawable.setAlpha(alpha);
+                    })
+                    .withEndAction(() -> getWindow().getDecorView().requestAccessibilityFocus())
+                    .start();
+        }
+
+        @Override
+        public void dismiss() {
+            mHardwareLayout.setTranslationX(0);
+            mHardwareLayout.setAlpha(1);
+            mHardwareLayout.animate()
+                    .alpha(0)
+                    .translationX(getAnimTranslation())
+                    .setDuration(300)
+                    .withEndAction(() -> super.dismiss())
+                    .setInterpolator(new LogAccelerateInterpolator())
+                    .setUpdateListener(animation -> {
+                        int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
+                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
+                        mGradientDrawable.setAlpha(alpha);
+                    })
+                    .start();
+        }
+
+        private float getAnimTranslation() {
+            return getContext().getResources().getDimension(
+                    com.android.systemui.R.dimen.global_actions_panel_width) / 2;
         }
 
         @Override
@@ -1242,19 +1340,20 @@
         }
 
         @Override
-        public boolean onKeyDown(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyDown(keyCode, event)) {
-                return true;
+        public void onColorsChanged(ColorExtractor extractor, int which) {
+            if (mKeyguardShowing) {
+                if ((WallpaperManager.FLAG_LOCK & which) != 0) {
+                    mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_LOCK));
+                }
+            } else {
+                if ((WallpaperManager.FLAG_SYSTEM & which) != 0) {
+                    mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_SYSTEM));
+                }
             }
-            return super.onKeyDown(keyCode, event);
         }
 
-        @Override
-        public boolean onKeyUp(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyUp(keyCode, event)) {
-                return true;
-            }
-            return super.onKeyUp(keyCode, event);
+        public void setKeyguardShowing(boolean keyguardShowing) {
+            mKeyguardShowing = keyguardShowing;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index c1e51b9..2cf230c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -14,16 +14,33 @@
 
 package com.android.systemui.globalactions;
 
+import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
+import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
-import android.content.Context;
-import android.support.v7.view.ContextThemeWrapper;
-
 public class GlobalActionsImpl implements GlobalActions {
 
+    private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
+
     private final Context mContext;
     private final KeyguardMonitor mKeyguardMonitor;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -38,11 +55,56 @@
     @Override
     public void showGlobalActions(GlobalActionsManager manager) {
         if (mGlobalActions == null) {
-            final ContextThemeWrapper context = new ContextThemeWrapper(mContext,
-                    android.R.style.Theme_Material_Light);
-            mGlobalActions = new GlobalActionsDialog(context, manager);
+            mGlobalActions = new GlobalActionsDialog(mContext, manager);
         }
         mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
                 mDeviceProvisionedController.isDeviceProvisioned());
     }
+
+    @Override
+    public void showShutdownUi(boolean isReboot, String reason) {
+        GradientDrawable background = new GradientDrawable(mContext);
+        background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255));
+
+        Dialog d = new Dialog(mContext,
+                com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
+        // Window initialization
+        Window window = d.getWindow();
+        window.getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT;
+        window.getAttributes().height = ViewGroup.LayoutParams.MATCH_PARENT;
+        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        window.requestFeature(Window.FEATURE_NO_TITLE);
+        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+        window.addFlags(
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+        window.setBackgroundDrawable(background);
+        window.setWindowAnimations(R.style.Animation_Toast);
+
+        d.setContentView(R.layout.shutdown_dialog);
+        d.setCancelable(false);
+
+        int color = Utils.getColorAttr(mContext, com.android.systemui.R.attr.wallpaperTextColor);
+        boolean onKeyguard = mContext.getSystemService(
+                KeyguardManager.class).isKeyguardLocked();
+
+        ProgressBar bar = d.findViewById(R.id.progress);
+        bar.getIndeterminateDrawable().setTint(color);
+        TextView message = d.findViewById(R.id.text1);
+        message.setTextColor(color);
+        if (isReboot) message.setText(R.string.reboot_to_reset_message);
+
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        GradientColors colors = Dependency.get(SysuiColorExtractor.class).getColors(
+                onKeyguard ? WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
+        background.setColors(colors, false);
+        background.setScreenSize(displaySize.x, displaySize.y);
+
+        d.show();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
new file mode 100644
index 0000000..4c98c08
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -0,0 +1,86 @@
+/*
+ * 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.keyguard;
+
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.policy.IKeyguardDrawnCallback;
+
+/**
+ * Dispatches the lifecycles keyguard gets from WindowManager on the main thread.
+ */
+public class KeyguardLifecyclesDispatcher {
+
+    static final int SCREEN_TURNING_ON = 0;
+    static final int SCREEN_TURNED_ON = 1;
+    static final int SCREEN_TURNING_OFF = 2;
+    static final int SCREEN_TURNED_OFF = 3;
+
+    static final int STARTED_WAKING_UP = 4;
+    static final int FINISHED_WAKING_UP = 5;
+    static final int STARTED_GOING_TO_SLEEP = 6;
+    static final int FINISHED_GOING_TO_SLEEP = 7;
+
+    private final ScreenLifecycle mScreenLifecycle;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+
+    public KeyguardLifecyclesDispatcher(ScreenLifecycle screenLifecycle,
+            WakefulnessLifecycle wakefulnessLifecycle) {
+        mScreenLifecycle = screenLifecycle;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+    }
+
+    void dispatch(int what) {
+        mHandler.obtainMessage(what).sendToTarget();
+    }
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SCREEN_TURNING_ON:
+                    mScreenLifecycle.dispatchScreenTurningOn();
+                    break;
+                case SCREEN_TURNED_ON:
+                    mScreenLifecycle.dispatchScreenTurnedOn();
+                    break;
+                case SCREEN_TURNING_OFF:
+                    mScreenLifecycle.dispatchScreenTurningOff();
+                    break;
+                case SCREEN_TURNED_OFF:
+                    mScreenLifecycle.dispatchScreenTurnedOff();
+                    break;
+                case STARTED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchStartedWakingUp();
+                    break;
+                case FINISHED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchFinishedWakingUp();
+                    break;
+                case STARTED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchStartedGoingToSleep();
+                    break;
+                case FINISHED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown message: " + msg);
+            }
+        }
+    };
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 2d5d198..2a5ae0d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -31,6 +31,7 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
 import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIApplication;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -40,12 +41,17 @@
     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
 
     private KeyguardViewMediator mKeyguardViewMediator;
+    private KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
 
     @Override
     public void onCreate() {
         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
         mKeyguardViewMediator =
                 ((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class);
+        mKeyguardLifecyclesDispatcher = new KeyguardLifecyclesDispatcher(
+                Dependency.get(ScreenLifecycle.class),
+                Dependency.get(WakefulnessLifecycle.class));
+
     }
 
     @Override
@@ -111,12 +117,16 @@
         public void onStartedGoingToSleep(int reason) {
             checkPermission();
             mKeyguardViewMediator.onStartedGoingToSleep(reason);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
         public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) {
             checkPermission();
             mKeyguardViewMediator.onFinishedGoingToSleep(reason, cameraGestureTriggered);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
@@ -124,6 +134,15 @@
             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
             checkPermission();
             mKeyguardViewMediator.onStartedWakingUp();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.STARTED_WAKING_UP);
+            Trace.endSection();
+        }
+
+        @Override // Binder interface
+        public void onFinishedWakingUp() {
+            Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
             Trace.endSection();
         }
 
@@ -132,6 +151,7 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurningOn(callback);
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
             Trace.endSection();
         }
 
@@ -140,13 +160,21 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOn();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
             Trace.endSection();
         }
 
         @Override // Binder interface
+        public void onScreenTurningOff() {
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
+        }
+
+        @Override // Binder interface
         public void onScreenTurnedOff() {
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOff();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
         }
 
         @Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1ec52e7..d132e76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -364,7 +364,10 @@
         public void onUserSwitchComplete(int userId) {
             if (userId != UserHandle.USER_SYSTEM) {
                 UserInfo info = UserManager.get(mContext).getUserInfo(userId);
-                if (info != null && (info.isGuest() || info.isDemo())) {
+                // Don't try to dismiss if the user has Pin/Patter/Password set
+                if (info == null || mLockPatternUtils.isSecure(userId)) {
+                    return;
+                } else if (info.isGuest() || info.isDemo()) {
                     // If we just switched to a guest, try to dismiss keyguard.
                     dismiss(null /* callback */);
                 }
@@ -656,7 +659,7 @@
     }
 
     boolean mustNotUnlockCurrentUser() {
-        return (UserManager.isSplitSystemUser() || UserManager.isDeviceInDemoMode(mContext))
+        return UserManager.isSplitSystemUser()
                 && KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM;
     }
 
@@ -808,6 +811,7 @@
         synchronized (this) {
             mDeviceInteractive = false;
             mGoingToSleep = false;
+            mWakeAndUnlocking = false;
 
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
@@ -1173,6 +1177,7 @@
 
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
+                mUpdateMonitor.setKeyguardOccluded(isOccluded);
                 mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
                         && mDeviceInteractive);
                 adjustStatusBarLocked();
@@ -1953,7 +1958,6 @@
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
             mStatusBarKeyguardViewManager.onScreenTurnedOff();
             mDrawnCallback = null;
-            mWakeAndUnlocking = false;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
new file mode 100644
index 0000000..1b20cfb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
@@ -0,0 +1,42 @@
+/*
+ * 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.keyguard;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Base class for lifecycles with observers.
+ */
+public class Lifecycle<T> {
+
+    private ArrayList<T> mObservers = new ArrayList<>();
+
+    public void addObserver(T observer) {
+        mObservers.add(observer);
+    }
+
+    public void removeObserver(T observer) {
+        mObservers.remove(observer);
+    }
+
+    public void dispatch(Consumer<T> consumer) {
+        for (int i = 0; i < mObservers.size(); i++) {
+            consumer.accept(mObservers.get(i));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
new file mode 100644
index 0000000..b6fce44
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.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 com.android.systemui.keyguard;
+
+import android.os.Trace;
+
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the screen lifecycle.
+ */
+public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> implements Dumpable {
+
+    public static final int SCREEN_OFF = 0;
+    public static final int SCREEN_TURNING_ON = 1;
+    public static final int SCREEN_ON = 2;
+    public static final int SCREEN_TURNING_OFF = 3;
+
+    private int mScreenState = SCREEN_OFF;
+
+    public int getScreenState() {
+        return mScreenState;
+    }
+
+    public void dispatchScreenTurningOn() {
+        setScreenState(SCREEN_TURNING_ON);
+        dispatch(Observer::onScreenTurningOn);
+    }
+
+    public void dispatchScreenTurnedOn() {
+        setScreenState(SCREEN_ON);
+        dispatch(Observer::onScreenTurnedOn);
+    }
+
+    public void dispatchScreenTurningOff() {
+        setScreenState(SCREEN_TURNING_OFF);
+        dispatch(Observer::onScreenTurningOff);
+    }
+
+    public void dispatchScreenTurnedOff() {
+        setScreenState(SCREEN_OFF);
+        dispatch(Observer::onScreenTurnedOff);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("ScreenLifecycle:");
+        pw.println("  mScreenState=" + mScreenState);
+    }
+
+    private void setScreenState(int screenState) {
+        mScreenState = screenState;
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "screenState", screenState);
+    }
+
+    public interface Observer {
+        default void onScreenTurningOn() {}
+        default void onScreenTurnedOn() {}
+        default void onScreenTurningOff() {}
+        default void onScreenTurnedOff() {}
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
new file mode 100644
index 0000000..951c0ea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.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 com.android.systemui.keyguard;
+
+import android.os.Trace;
+
+import com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the wakefulness lifecycle.
+ */
+public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
+        Dumpable {
+
+    public static final int WAKEFULNESS_ASLEEP = 0;
+    public static final int WAKEFULNESS_WAKING = 1;
+    public static final int WAKEFULNESS_AWAKE = 2;
+    public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
+
+    private int mWakefulness = WAKEFULNESS_ASLEEP;
+
+    public int getWakefulness() {
+        return mWakefulness;
+    }
+
+    public void dispatchStartedWakingUp() {
+        setWakefulness(WAKEFULNESS_WAKING);
+        dispatch(Observer::onStartedWakingUp);
+    }
+
+    public void dispatchFinishedWakingUp() {
+        setWakefulness(WAKEFULNESS_AWAKE);
+        dispatch(Observer::onFinishedWakingUp);
+    }
+
+    public void dispatchStartedGoingToSleep() {
+        setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
+        dispatch(Observer::onStartedGoingToSleep);
+    }
+
+    public void dispatchFinishedGoingToSleep() {
+        setWakefulness(WAKEFULNESS_ASLEEP);
+        dispatch(Observer::onFinishedGoingToSleep);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("WakefulnessLifecycle:");
+        pw.println("  mWakefulness=" + mWakefulness);
+    }
+
+    private void setWakefulness(int wakefulness) {
+        mWakefulness = wakefulness;
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
+    }
+
+    public interface Observer {
+        default void onStartedWakingUp() {}
+        default void onFinishedWakingUp() {}
+        default void onStartedGoingToSleep() {}
+        default void onFinishedGoingToSleep() {}
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
index 6733421..abc5667 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
@@ -65,7 +65,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = true;
             try {
                 // To be implemented for input handling over Pip windows
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 0373d77..b3f992d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -71,10 +71,6 @@
     TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
         public void onActivityPinned(String packageName, int taskId) {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             mTouchHandler.onActivityPinned();
             mMediaController.onActivityPinned();
             mMenuController.onActivityPinned();
@@ -86,13 +82,10 @@
 
         @Override
         public void onActivityUnpinned() {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext,
                     mActivityManager);
-            mMenuController.hideMenu();
+            mMenuController.onActivityUnpinned(topPipActivity);
+            mTouchHandler.onActivityUnpinned(topPipActivity);
             mNotificationController.onActivityUnpinned(topPipActivity);
 
             SystemServicesProxy.getInstance(mContext).setPipVisibility(topPipActivity != null);
@@ -115,10 +108,6 @@
 
         @Override
         public void onPinnedActivityRestartAttempt(boolean clearedTask) {
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
             mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
index 62ec09b..b3a0794 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
@@ -26,14 +26,18 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
 import android.media.session.PlaybackState;
 import android.os.UserHandle;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.UserInfoController;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -88,13 +92,21 @@
         }
     };
 
-    private MediaController.Callback mPlaybackChangedListener = new MediaController.Callback() {
+    private final MediaController.Callback mPlaybackChangedListener = new MediaController.Callback() {
         @Override
         public void onPlaybackStateChanged(PlaybackState state) {
             notifyActionsChanged();
         }
     };
 
+    private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener =
+            new OnActiveSessionsChangedListener() {
+        @Override
+        public void onActiveSessionsChanged(List<MediaController> controllers) {
+            resolveActiveMediaController(controllers);
+        }
+    };
+
     private ArrayList<ActionListener> mListeners = new ArrayList<>();
 
     public PipMediaController(Context context, IActivityManager activityManager) {
@@ -110,9 +122,11 @@
         createMediaActions();
         mMediaSessionManager =
                 (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        mMediaSessionManager.addOnActiveSessionsChangedListener(controllers -> {
-            resolveActiveMediaController(controllers);
-        }, null);
+
+        // The media session listener needs to be re-registered when switching users
+        UserInfoController userInfoController = Dependency.get(UserInfoController.class);
+        userInfoController.addCallback((String name, Drawable picture, String userAccount) ->
+                registerSessionListenerForCurrentUser());
     }
 
     /**
@@ -120,7 +134,8 @@
      */
     public void onActivityPinned() {
         // Once we enter PiP, try to find the active media controller for the top most activity
-        resolveActiveMediaController(mMediaSessionManager.getActiveSessions(null));
+        resolveActiveMediaController(mMediaSessionManager.getActiveSessionsForUser(null,
+                UserHandle.USER_CURRENT));
     }
 
     /**
@@ -201,6 +216,15 @@
     }
 
     /**
+     * Re-registers the session listener for the current user.
+     */
+    private void registerSessionListenerForCurrentUser() {
+        mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionsChangedListener);
+        mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionsChangedListener, null,
+                UserHandle.USER_CURRENT, null);
+    }
+
+    /**
      * Tries to find and set the active media controller for the top PiP activity.
      */
     private void resolveActiveMediaController(List<MediaController> controllers) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index e310847..c558056 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -22,6 +22,7 @@
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
 import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
@@ -32,6 +33,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.IWindowManager;
@@ -77,6 +79,9 @@
     public static final int MENU_STATE_CLOSE = 1;
     public static final int MENU_STATE_FULL = 2;
 
+    // The duration to wait before we consider the start activity as having timed out
+    private static final long START_ACTIVITY_REQUEST_TIMEOUT_MS = 300;
+
     /**
      * A listener interface to receive notification on changes in PIP.
      */
@@ -125,8 +130,9 @@
 
     private ReferenceCountedTrigger mOnAttachDecrementTrigger;
     private boolean mStartActivityRequested;
+    private long mStartActivityRequestedTime;
     private Messenger mToActivityMessenger;
-    private Messenger mMessenger = new Messenger(new Handler() {
+    private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -161,7 +167,7 @@
                 }
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
-                    mStartActivityRequested = false;
+                    setStartActivityRequested(false);
                     if (mOnAttachDecrementTrigger != null) {
                         mOnAttachDecrementTrigger.decrement();
                         mOnAttachDecrementTrigger = null;
@@ -174,7 +180,17 @@
                 }
             }
         }
-    });
+    };
+    private Messenger mMessenger = new Messenger(mHandler);
+
+    private Runnable mStartActivityRequestedTimeoutRunnable = () -> {
+        setStartActivityRequested(false);
+        if (mOnAttachDecrementTrigger != null) {
+            mOnAttachDecrementTrigger.decrement();
+            mOnAttachDecrementTrigger = null;
+        }
+        Log.e(TAG, "Expected start menu activity request timed out");
+    };
 
     private ActionListener mMediaActionListener = new ActionListener() {
         @Override
@@ -202,6 +218,11 @@
         }
     }
 
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        hideMenu();
+        setStartActivityRequested(false);
+    }
+
     public void onPinnedStackAnimationEnded() {
         // Note: Only active menu activities care about this event
         if (mToActivityMessenger != null) {
@@ -243,7 +264,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Could not notify menu to update dismiss fraction", e);
             }
-        } else if (!mStartActivityRequested) {
+        } else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) {
+            // If we haven't requested the start activity, or if it previously took too long to
+            // start, then start it
             startMenuActivity(MENU_STATE_NONE, null /* stackBounds */,
                     null /* movementBounds */, false /* allowMenuTimeout */);
         }
@@ -273,7 +296,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Could not notify menu to show", e);
             }
-        } else if (!mStartActivityRequested) {
+        } else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) {
+            // If we haven't requested the start activity, or if it previously took too long to
+            // start, then start it
             startMenuActivity(menuState, stackBounds, movementBounds, allowMenuTimeout);
         }
     }
@@ -368,12 +393,12 @@
                         pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
                 options.setTaskOverlay(true, true /* canResume */);
                 mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
-                mStartActivityRequested = true;
+                setStartActivityRequested(true);
             } else {
                 Log.e(TAG, "No PIP tasks found");
             }
         } catch (RemoteException e) {
-            mStartActivityRequested = false;
+            setStartActivityRequested(false);
             Log.e(TAG, "Error showing PIP menu activity", e);
         }
     }
@@ -416,6 +441,14 @@
     }
 
     /**
+     * @return whether the time of the activity request has exceeded the timeout.
+     */
+    private boolean isStartActivityRequestedElapsed() {
+        return (SystemClock.uptimeMillis() - mStartActivityRequestedTime)
+                >= START_ACTIVITY_REQUEST_TIMEOUT_MS;
+    }
+
+    /**
      * Handles changes in menu visibility.
      */
     private void onMenuStateChanged(int menuState, boolean resize) {
@@ -443,12 +476,24 @@
         mMenuState = menuState;
     }
 
+    private void setStartActivityRequested(boolean requested) {
+        mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
+        mStartActivityRequested = requested;
+        mStartActivityRequestedTime = requested ? SystemClock.uptimeMillis() : 0;
+    }
+
     public final void onBusEvent(HidePipMenuEvent event) {
         if (mStartActivityRequested) {
             // If the menu has been start-requested, but not actually started, then we defer the
-            // trigger callback until the menu has started and called back to the controller
+            // trigger callback until the menu has started and called back to the controller.
             mOnAttachDecrementTrigger = event.getAnimationTrigger();
             mOnAttachDecrementTrigger.increment();
+
+            // Fallback for b/63752800, we have started the PipMenuActivity but it has not made any
+            // callbacks. Don't continue to wait for the menu to show past some timeout.
+            mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
+            mHandler.postDelayed(mStartActivityRequestedTimeoutRunnable,
+                    START_ACTIVITY_REQUEST_TIMEOUT_MS);
         }
     }
 
@@ -458,5 +503,7 @@
         pw.println(innerPrefix + "mMenuState=" + mMenuState);
         pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger);
         pw.println(innerPrefix + "mListeners=" + mListeners.size());
+        pw.println(innerPrefix + "mStartActivityRequested=" + mStartActivityRequested);
+        pw.println(innerPrefix + "mStartActivityRequestedTime=" + mStartActivityRequestedTime);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index b8771d7..cebb22f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -241,14 +241,14 @@
     /**
      * Flings the minimized PiP to the closest minimized snap target.
      */
-    Rect flingToMinimizedState(float velocityY, Rect movementBounds) {
+    Rect flingToMinimizedState(float velocityY, Rect movementBounds, Point dragStartPosition) {
         cancelAnimations();
         // We currently only allow flinging the minimized stack up and down, so just lock the
         // movement bounds to the current stack bounds horizontally
         movementBounds = new Rect(mBounds.left, movementBounds.top, mBounds.left,
                 movementBounds.bottom);
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                0 /* velocityX */, velocityY);
+                0 /* velocityX */, velocityY, dragStartPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
@@ -281,10 +281,11 @@
      * Flings the PiP to the closest snap target.
      */
     Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds,
-            AnimatorUpdateListener updateListener, AnimatorListener listener) {
+            AnimatorUpdateListener updateListener, AnimatorListener listener,
+            Point startPosition) {
         cancelAnimations();
         Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                velocityX, velocityY);
+                velocityX, velocityY, startPosition);
         if (!mBounds.equals(toBounds)) {
             mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
             mFlingAnimationUtils.apply(mBoundsAnimator, 0,
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 854696e..9b48320 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -25,10 +25,13 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.IActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 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;
@@ -39,6 +42,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -116,10 +120,11 @@
             };
 
     // Behaviour states
-    private int mMenuState;
+    private int mMenuState = MENU_STATE_NONE;
     private boolean mIsMinimized;
     private boolean mIsImeShowing;
     private int mImeHeight;
+    private int mImeOffset;
     private float mSavedSnapFraction = -1f;
     private boolean mSendingHoverAccessibilityEvents;
     private boolean mMovementWithinMinimize;
@@ -184,14 +189,17 @@
         mDismissViewController = new PipDismissViewController(context);
         mSnapAlgorithm = new PipSnapAlgorithm(mContext);
         mTouchState = new PipTouchState(mViewConfig);
-        mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
+        mFlingAnimationUtils = new FlingAnimationUtils(context, 2.5f);
         mGestures = new PipTouchGesture[] {
                 mDefaultMovementGesture
         };
         mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mMenuController,
                 mSnapAlgorithm, mFlingAnimationUtils);
-        mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
+
+        Resources res = context.getResources();
+        mExpandedShortestEdgeSize = res.getDimensionPixelSize(
                 R.dimen.pip_expanded_shortest_edge_size);
+        mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
 
         // Register the listener for input consumer touch events
         inputConsumerController.setTouchListener(this::handleTouchEvent);
@@ -212,16 +220,17 @@
     }
 
     public void onActivityPinned() {
-        // Reset some states once we are pinned
-        mMenuState = MENU_STATE_NONE;
-
-        if (mIsMinimized) {
-            setMinimizedStateInternal(false);
-        }
-        cleanUpDismissTarget();
+        cleanUp();
         mShowPipMenuOnAnimationEnd = true;
     }
 
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        if (topPipActivity == null) {
+            // Clean up state after the last PiP activity is removed
+            cleanUp();
+        }
+    }
+
     public void onPinnedStackAnimationEnded() {
         // Always synchronize the motion helper bounds once PiP animations finish
         mMotionHelper.synchronizePinnedStackBounds();
@@ -262,7 +271,6 @@
         mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
                 mIsImeShowing ? mImeHeight : 0);
 
-
         // If this is from an IME adjustment, then we should move the PiP so that it is not occluded
         // by the IME
         if (fromImeAdjustement) {
@@ -275,18 +283,22 @@
                         ? expandedMovementBounds
                         : normalMovementBounds;
                 if (mIsImeShowing) {
-                    // IME visible
+                    // IME visible, apply the IME offset if the space allows for it
+                    final int imeOffset = toMovementBounds.bottom - Math.max(toMovementBounds.top,
+                            toMovementBounds.bottom - mImeOffset);
                     if (bounds.top == mMovementBounds.bottom) {
                         // If the PIP is currently resting on top of the IME, then adjust it with
-                        // the hiding IME
-                        bounds.offsetTo(bounds.left, toMovementBounds.bottom);
+                        // the showing IME
+                        bounds.offsetTo(bounds.left, toMovementBounds.bottom - imeOffset);
                     } else {
-                        bounds.offset(0, Math.min(0, toMovementBounds.bottom - bounds.top));
+                        bounds.offset(0, Math.min(0, toMovementBounds.bottom - imeOffset
+                                - bounds.top));
                     }
                 } else {
                     // IME hidden
-                    if (bounds.top == mMovementBounds.bottom) {
-                        // If the PIP is resting on top of the IME, then adjust it with the hiding IME
+                    if (bounds.top >= (mMovementBounds.bottom - mImeOffset)) {
+                        // If the PIP is resting on top of the IME, then adjust it with the hiding
+                        // IME
                         bounds.offsetTo(bounds.left, toMovementBounds.bottom);
                     }
                 }
@@ -376,10 +388,10 @@
                 if (!mSendingHoverAccessibilityEvents) {
                     AccessibilityEvent event = AccessibilityEvent.obtain(
                             AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
-                    AccessibilityNodeInfo info =
-                            PipAccessibilityInteractionConnection.obtainRootAccessibilityNodeInfo();
-                    event.setSource(info);
-                    info.recycle();
+                    event.setImportantForAccessibility(true);
+                    event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+                    event.setWindowId(
+                            AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
                     mAccessibilityManager.sendAccessibilityEvent(event);
                     mSendingHoverAccessibilityEvents = true;
                 }
@@ -389,10 +401,10 @@
                 if (mSendingHoverAccessibilityEvents) {
                     AccessibilityEvent event = AccessibilityEvent.obtain(
                             AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
-                    AccessibilityNodeInfo info =
-                            PipAccessibilityInteractionConnection.obtainRootAccessibilityNodeInfo();
-                    event.setSource(info);
-                    info.recycle();
+                    event.setImportantForAccessibility(true);
+                    event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+                    event.setWindowId(
+                            AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
                     mAccessibilityManager.sendAccessibilityEvent(event);
                     mSendingHoverAccessibilityEvents = false;
                 }
@@ -405,7 +417,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();
@@ -431,7 +443,7 @@
     /**
      * Sets the minimized state.
      */
-    void setMinimizedStateInternal(boolean isMinimized) {
+    private void setMinimizedStateInternal(boolean isMinimized) {
         if (!ENABLE_MINIMIZE) {
             return;
         }
@@ -470,7 +482,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
@@ -538,6 +550,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 final Point mStartPosition = new Point();
+        private final PointF mDelta = new PointF();
 
         @Override
         public void onDown(PipTouchState touchState) {
@@ -545,7 +559,10 @@
                 return;
             }
 
-            mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
+            Rect bounds = mMotionHelper.getBounds();
+            mDelta.set(0f, 0f);
+            mStartPosition.set(bounds.left, bounds.top);
+            mStartedOnLeft = bounds.left < mMovementBounds.centerX();
             mMovementWithinMinimize = true;
             mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
 
@@ -578,10 +595,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));
                 }
@@ -591,6 +609,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);
 
@@ -691,7 +715,8 @@
 
                 if (isFling) {
                     mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds,
-                            mUpdateScrimListener, postAnimationCallback);
+                            mUpdateScrimListener, postAnimationCallback,
+                            mStartPosition);
                 } else {
                     mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener,
                             postAnimationCallback);
@@ -735,6 +760,16 @@
         mDismissViewController.destroyDismissTarget();
     }
 
+    /**
+     * Resets some states related to the touch handling.
+     */
+    private void cleanUp() {
+        if (mIsMinimized) {
+            setMinimizedStateInternal(false);
+        }
+        cleanUpDismissTarget();
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
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..686b3bb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -29,7 +29,7 @@
  */
 public class PipTouchState {
     private static final String TAG = "PipTouchHandler";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private ViewConfiguration mViewConfig;
 
@@ -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/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
new file mode 100644
index 0000000..9becc38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java
@@ -0,0 +1,43 @@
+/*
+ * 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.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+public class PluginActivityManager {
+
+    private final Context mContext;
+    private final PluginManager mPluginManager;
+    private final ArrayMap<String, String> mActionLookup = new ArrayMap<>();
+
+    public PluginActivityManager(Context context, PluginManager pluginManager) {
+        mContext = context;
+        mPluginManager = pluginManager;
+    }
+
+    public void addActivityPlugin(String className, String action) {
+        mActionLookup.put(className, action);
+    }
+
+    public Activity instantiate(ClassLoader cl, String className, Intent intent) {
+        String action = mActionLookup.get(className);
+        if (TextUtils.isEmpty(action)) return null;
+        return mPluginManager.getOneShotPlugin(action, PluginActivity.class);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
index 493d244..a968399 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
@@ -42,7 +42,6 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper;
-import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
 import dalvik.system.PathClassLoader;
@@ -120,14 +119,21 @@
         }
         PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null,
                 false, mLooper, cls, this);
+        PluginListener<Plugin> listener = new PluginListener<Plugin>() {
+            @Override
+            public void onPluginConnected(Plugin plugin, Context pluginContext) { }
+        };
+        mPluginMap.put(listener, p);
         mPluginPrefs.addAction(action);
-        PluginInfo<T> info = p.getPlugin();
+        PluginInstanceManager.PluginInfo<T> info = p.getPlugin();
         if (info != null) {
             mOneShotPackages.add(info.mPackage);
             mHasOneShot = true;
             startListening();
+            mPluginMap.remove(listener);
             return info.mPlugin;
         }
+        mPluginMap.remove(listener);
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 6b3daa3..b007f92 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -104,10 +104,9 @@
     private SystemUIDialog mHighTempDialog;
     private SystemUIDialog mThermalShutdownDialog;
 
-    public PowerNotificationWarnings(Context context, NotificationManager notificationManager,
-            StatusBar statusBar) {
+    public PowerNotificationWarnings(Context context) {
         mContext = context;
-        mNoMan = notificationManager;
+        mNoMan = mContext.getSystemService(NotificationManager.class);
         mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mReceiver.init();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a642077..beb7712 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,12 +16,13 @@
 
 package com.android.systemui.power;
 
-import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.BatteryManager;
@@ -31,14 +32,17 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.phone.StatusBar;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -56,6 +60,7 @@
     private PowerManager mPowerManager;
     private HardwarePropertiesManager mHardwarePropertiesManager;
     private WarningsUI mWarnings;
+    private final Configuration mLastConfiguration = new Configuration();
     private int mBatteryLevel = 100;
     private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
     private int mPlugType = 0;
@@ -71,15 +76,18 @@
     private int mNumTemps;
     private long mNextLogTime;
 
+    // We create a method reference here so that we are guaranteed that we can remove a callback
+    // by using the same instance (method references are not guaranteed to be the same object
+    // each time they are created).
+    private final Runnable mUpdateTempCallback = this::updateTemperatureWarning;
+
     public void start() {
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mHardwarePropertiesManager = (HardwarePropertiesManager)
                 mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE);
         mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
-        mWarnings = new PowerNotificationWarnings(
-                mContext,
-                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE),
-                getComponent(StatusBar.class));
+        mWarnings = Dependency.get(WarningsUI.class);
+        mLastConfiguration.setTo(mContext.getResources().getConfiguration());
 
         ContentObserver obs = new ContentObserver(mHandler) {
             @Override
@@ -101,6 +109,16 @@
         initTemperatureWarning();
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        final int mask = ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC;
+
+        // Safe to modify mLastConfiguration here as it's only updated by the main thread (here).
+        if ((mLastConfiguration.updateFrom(newConfig) & mask) != 0) {
+            mHandler.post(this::initTemperatureWarning);
+        }
+    }
+
     void updateBatteryWarningLevels() {
         int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -247,16 +265,23 @@
             // Get the throttling temperature. No need to check if we're not throttling.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
-                    HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+                    HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
             if (throttlingTemps == null
                     || throttlingTemps.length == 0
                     || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
                 return;
             }
-            mThresholdTemp = throttlingTemps[0];
+            mThresholdTemp = throttlingTemps[0] -
+                    resources.getInteger(R.integer.config_warningTemperatureTolerance);
         }
+
         setNextLogTime();
 
+        // This initialization method may be called on a configuration change. Only one set of
+        // ongoing callbacks should be occurring, so remove any now. updateTemperatureWarning will
+        // schedule an ongoing callback.
+        mHandler.removeCallbacks(mUpdateTempCallback);
+
         // We have passed all of the checks, start checking the temp
         updateTemperatureWarning();
     }
@@ -268,7 +293,8 @@
         }
     }
 
-    private void updateTemperatureWarning() {
+    @VisibleForTesting
+    protected void updateTemperatureWarning() {
         float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
                 HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
                 HardwarePropertiesManager.TEMPERATURE_CURRENT);
@@ -288,7 +314,7 @@
 
         logTemperatureStats();
 
-        mHandler.postDelayed(this::updateTemperatureWarning, TEMPERATURE_INTERVAL);
+        mHandler.postDelayed(mUpdateTempCallback, TEMPERATURE_INTERVAL);
     }
 
     private void logAtTemperatureThreshold(float temp) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
new file mode 100644
index 0000000..f960dc5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
@@ -0,0 +1,98 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.statusbar.phone.AutoTileManager.HOTSPOT;
+import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION;
+import static com.android.systemui.statusbar.phone.AutoTileManager.NIGHT;
+import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER;
+import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public class AutoAddTracker {
+
+    private static final String[][] CONVERT_PREFS = {
+            {Key.QS_HOTSPOT_ADDED, HOTSPOT},
+            {Key.QS_DATA_SAVER_ADDED, SAVER},
+            {Key.QS_INVERT_COLORS_ADDED, INVERSION},
+            {Key.QS_WORK_ADDED, WORK},
+            {Key.QS_NIGHTDISPLAY_ADDED, NIGHT},
+    };
+
+    private final ArraySet<String> mAutoAdded;
+    private final Context mContext;
+
+    public AutoAddTracker(Context context) {
+        mContext = context;
+        mAutoAdded = new ArraySet<>(getAdded());
+        for (String[] convertPref : CONVERT_PREFS) {
+            if (Prefs.getBoolean(context, convertPref[0], false)) {
+                setTileAdded(convertPref[1]);
+                Prefs.putBoolean(context, convertPref[0], false);
+            }
+        }
+        mContext.getContentResolver().registerContentObserver(
+                Secure.getUriFor(Secure.QS_AUTO_ADDED_TILES), false, mObserver);
+    }
+
+    public boolean isAdded(String tile) {
+        return mAutoAdded.contains(tile);
+    }
+
+    public void setTileAdded(String tile) {
+        if (mAutoAdded.add(tile)) {
+            saveTiles();
+        }
+    }
+
+    public void destroy() {
+        mContext.getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    private void saveTiles() {
+        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES,
+                TextUtils.join(",", mAutoAdded));
+    }
+
+    private Collection<String> getAdded() {
+        String current = Secure.getString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES);
+        if (current == null) {
+            return Collections.emptyList();
+        }
+        return Arrays.asList(current.split(","));
+    }
+
+    @VisibleForTesting
+    protected final ContentObserver mObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            mAutoAdded.addAll(getAdded());
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
index 5b3ec08..3d8f9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
@@ -16,12 +16,14 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.service.quicksettings.Tile;
 import android.widget.ImageView;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile.Icon;
 import com.android.systemui.plugins.qs.QSTile.State;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.SignalDrawable;
 
 import java.util.Objects;
@@ -35,7 +37,8 @@
     public CellTileView(Context context) {
         super(context);
         mSignalDrawable = new SignalDrawable(mContext);
-        mSignalDrawable.setDarkIntensity(isDark(mContext));
+        mSignalDrawable.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
+                QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
         mSignalDrawable.setIntrinsicSize(context.getResources().getDimensionPixelSize(
                 R.dimen.qs_tile_icon_size));
     }
@@ -48,10 +51,6 @@
         }
     }
 
-    private static int isDark(Context context) {
-        return Utils.getColorAttr(context, android.R.attr.colorForeground) == 0xff000000 ? 1 : 0;
-    }
-
     public static class SignalIcon extends Icon {
 
         private final int mState;
@@ -68,7 +67,8 @@
         public Drawable getDrawable(Context context) {
             //TODO: Not the optimal solution to create this drawable
             SignalDrawable d = new SignalDrawable(context);
-            d.setDarkIntensity(isDark(context));
+            d.setColors(QSTileImpl.getColorForState(context, Tile.STATE_UNAVAILABLE),
+                    QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
             d.setLevel(getState());
             return d;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 0d74b7a..ed57c04 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -39,8 +39,6 @@
     protected float mQsExpansion;
     private QSCustomizer mQSCustomizer;
     private QSFooter mQSFooter;
-    private int mGutterHeight;
-    private View mBackground;
     private float mFullElevation;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -55,8 +53,6 @@
         mHeader = findViewById(R.id.header);
         mQSCustomizer = findViewById(R.id.qs_customize);
         mQSFooter = findViewById(R.id.qs_footer);
-        mBackground = findViewById(R.id.qs_background);
-        mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
         mFullElevation = mQSPanel.getElevation();
 
         setClickable(true);
@@ -110,18 +106,10 @@
 
     public void updateExpansion() {
         int height = calculateContainerHeight();
-        int gutterHeight = Math.round(mQsExpansion * mGutterHeight);
-        setBottom(getTop() + height + gutterHeight);
+        setBottom(getTop() + height);
         mQSDetail.setBottom(getTop() + height);
-        mBackground.setBottom(getTop() + height);
         // Pin QS Footer to the bottom of the panel.
         mQSFooter.setTranslationY(height - mQSFooter.getHeight());
-
-        float elevation = mQsExpansion * mFullElevation;
-        mQSDetail.setElevation(elevation);
-        mBackground.setElevation(elevation);
-        mQSFooter.setElevation(elevation);
-        mQSPanel.setElevation(elevation);
     }
 
     protected int calculateContainerHeight() {
@@ -135,17 +123,4 @@
         mQsExpansion = expansion;
         updateExpansion();
     }
-
-    public void setGutterEnabled(boolean gutterEnabled) {
-        if (gutterEnabled == (mGutterHeight != 0)) {
-            return;
-        }
-        if (gutterEnabled) {
-            mGutterHeight = getContext().getResources().getDimensionPixelSize(
-                    R.dimen.qs_gutter_height);
-        } else {
-            mGutterHeight = 0;
-        }
-        updateExpansion();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 697db5f..10514a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -287,11 +287,17 @@
         mScanState = state;
         final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
         if (state) {
-            mQsDetailHeaderProgress.animate().alpha(1f);
-            anim.start();
+            mQsDetailHeaderProgress.animate().cancel();
+            mQsDetailHeaderProgress.animate()
+                    .alpha(1)
+                    .withEndAction(anim::start)
+                    .start();
         } else {
-            mQsDetailHeaderProgress.animate().alpha(0f);
-            anim.stop();
+            mQsDetailHeaderProgress.animate().cancel();
+            mQsDetailHeaderProgress.animate()
+                    .alpha(0f)
+                    .withEndAction(anim::stop)
+                    .start();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
index a318efc..c454048 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailClipper.java
@@ -100,4 +100,8 @@
             mAnimator = null;
         };
     };
+
+    public void showBackground() {
+        mBackground.showSecondLayer();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index cef7c8a..f47ef1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -175,8 +175,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/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 39ef6c5..dc81772 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -63,7 +63,6 @@
     private QSContainerImpl mContainer;
     private int mLayoutDirection;
     private QSFooter mFooter;
-    private int mGutterHeight;
 
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -80,7 +79,6 @@
         mHeader = view.findViewById(R.id.header);
         mFooter = view.findViewById(R.id.qs_footer);
         mContainer = view.findViewById(id.quick_settings_container);
-        mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
 
         mQSDetail.setQsPanel(mQSPanel, mHeader, mFooter);
 
@@ -96,6 +94,13 @@
         if (savedInstanceState != null) {
             setExpanded(savedInstanceState.getBoolean(EXTRA_EXPANDED));
             setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
+            int[] loc = new int[2];
+            View edit = view.findViewById(android.R.id.edit);
+            edit.getLocationInWindow(loc);
+            int x = loc[0] + edit.getWidth() / 2;
+            int y = loc[1] + edit.getHeight() / 2;
+            mQSCustomizer.setEditLocation(x, y);
+            mQSCustomizer.restoreInstanceState(savedInstanceState);
         }
     }
 
@@ -112,6 +117,7 @@
         super.onSaveInstanceState(outState);
         outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
         outState.putBoolean(EXTRA_LISTENING, mListening);
+        mQSCustomizer.saveInstanceState(outState);
     }
 
     @VisibleForTesting
@@ -131,7 +137,6 @@
 
     @Override
     public void setHasNotifications(boolean hasNotifications) {
-        mContainer.setGutterEnabled(hasNotifications);
     }
 
     public void setPanelView(HeightListener panelView) {
@@ -250,7 +255,7 @@
         mContainer.setExpansion(expansion);
         final float translationScaleY = expansion - 1;
         if (!mHeaderAnimating) {
-            int height = mHeader.getHeight() + mGutterHeight;
+            int height = mHeader.getHeight();
             getView().setTranslationY(mKeyguardShowing ? (translationScaleY * height)
                     : headerTranslation);
         }
@@ -334,15 +339,15 @@
             LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
             int panelHeight = layoutParams.topMargin + layoutParams.bottomMargin +
                     + mQSPanel.getMeasuredHeight();
-            return panelHeight + getView().getPaddingBottom() + mGutterHeight;
+            return panelHeight + getView().getPaddingBottom();
         } else {
-            return getView().getMeasuredHeight() + mGutterHeight;
+            return getView().getMeasuredHeight();
         }
     }
 
     @Override
     public void setHeightOverride(int desiredHeight) {
-        mContainer.setHeightOverride(desiredHeight - mGutterHeight);
+        mContainer.setHeightOverride(desiredHeight);
     }
 
     public int getQsMinExpansionHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index c4d88ae..8f41084 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -46,6 +46,7 @@
 import com.android.systemui.settings.BrightnessController;
 import com.android.systemui.settings.ToggleSliderView;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -53,7 +54,7 @@
 import java.util.Collection;
 
 /** View that represents the quick settings tile panel. **/
-public class QSPanel extends LinearLayout implements Tunable, Callback {
+public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener {
 
     public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
 
@@ -152,6 +153,9 @@
         if (mHost != null) {
             setTiles(mHost.getTiles());
         }
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.addCallback(this);
+        }
     }
 
     @Override
@@ -163,6 +167,9 @@
         for (TileRecord record : mRecords) {
             record.tile.removeCallbacks();
         }
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.removeCallback(this);
+        }
         super.onDetachedFromWindow();
     }
 
@@ -194,12 +201,19 @@
     }
 
     public void setBrightnessMirror(BrightnessMirrorController c) {
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.removeCallback(this);
+        }
         mBrightnessMirrorController = c;
-        ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
-        ToggleSliderView mirror = c.getMirror().findViewById(
-                R.id.brightness_slider);
-        brightnessSlider.setMirror(mirror);
-        brightnessSlider.setMirrorController(c);
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.addCallback(this);
+        }
+        updateBrightnessMirror();
+    }
+
+    @Override
+    public void onBrightnessMirrorReinflated(View brightnessMirror) {
+        updateBrightnessMirror();
     }
 
     View getBrightnessView() {
@@ -246,9 +260,16 @@
         super.onConfigurationChanged(newConfig);
         mFooter.onConfigurationChanged();
 
+        updateBrightnessMirror();
+    }
+
+    public void updateBrightnessMirror() {
         if (mBrightnessMirrorController != null) {
-            // Reload the mirror in case it got reinflated but we didn't.
-            setBrightnessMirror(mBrightnessMirrorController);
+            ToggleSliderView brightnessSlider = findViewById(R.id.brightness_slider);
+            ToggleSliderView mirrorSlider = mBrightnessMirrorController.getMirror()
+                    .findViewById(R.id.brightness_slider);
+            brightnessSlider.setMirror(mirrorSlider);
+            brightnessSlider.setMirrorController(mBrightnessMirrorController);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index d434f2f..3ce1465c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -15,18 +15,22 @@
  */
 package com.android.systemui.qs;
 
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.SpannableStringBuilder;
 import android.text.method.LinkMovementMethod;
 import android.text.style.ClickableSpan;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -58,6 +62,8 @@
     private final Handler mMainHandler;
     private final View mDivider;
 
+    private final UserManager mUm;
+
     private AlertDialog mDialog;
     private QSTileHost mHost;
     protected H mHandler;
@@ -80,6 +86,7 @@
         mSecurityController = Dependency.get(SecurityController.class);
         mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
         mDivider = qsPanel == null ? null : qsPanel.getDivider();
+        mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
     }
 
     public void setHostEnvironment(QSTileHost host) {
@@ -127,6 +134,9 @@
 
     private void handleRefreshState() {
         final boolean isDeviceManaged = mSecurityController.isDeviceManaged();
+        final UserInfo currentUser = mUm.getUserInfo(ActivityManager.getCurrentUser());
+        final boolean isDemoDevice = UserManager.isDeviceInDemoMode(mContext) && currentUser != null
+                && currentUser.isDemo();
         final boolean hasWorkProfile = mSecurityController.hasWorkProfile();
         final boolean hasCACerts = mSecurityController.hasCACertInCurrentUser();
         final boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile();
@@ -136,7 +146,7 @@
         final CharSequence organizationName = mSecurityController.getDeviceOwnerOrganizationName();
         final CharSequence workProfileName = mSecurityController.getWorkProfileOrganizationName();
         // Update visibility of footer
-        mIsVisible = isDeviceManaged || hasCACerts || hasCACertsInWorkProfile ||
+        mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile ||
             vpnName != null || vpnNameWorkProfile != null;
         // Update the string
         mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile,
@@ -244,8 +254,9 @@
 
         mDialog = new SystemUIDialog(mContext);
         mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
-        View dialogView = LayoutInflater.from(mContext)
-               .inflate(R.layout.quick_settings_footer_dialog, null, false);
+        View dialogView = LayoutInflater.from(
+                new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog))
+                .inflate(R.layout.quick_settings_footer_dialog, null, false);
         mDialog.setView(dialogView);
         mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index ad98013..b300e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -27,6 +27,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
 import com.android.systemui.qs.tileimpl.QSIconViewImpl;
+import com.android.systemui.qs.tileimpl.SlashImageView;
 
 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/
 public class SignalTileView extends QSIconViewImpl {
@@ -62,7 +63,7 @@
     @Override
     protected View createIcon() {
         mIconFrame = new FrameLayout(mContext);
-        mSignal = new ImageView(mContext);
+        mSignal = new SlashImageView(mContext);
         mIconFrame.addView(mSignal);
         mOverlay = new ImageView(mContext);
         mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
new file mode 100644
index 0000000..c356148
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
@@ -0,0 +1,228 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.annotation.ColorInt;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.util.FloatProperty;
+
+public class SlashDrawable extends Drawable {
+
+    public static final float CORNER_RADIUS = 1f;
+
+    private final Path mPath = new Path();
+    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    // These values are derived in un-rotated (vertical) orientation
+    private static final float SLASH_WIDTH = 1.8384776f;
+    private static final float SLASH_HEIGHT = 28f;
+    private static final float CENTER_X = 10.65f;
+    private static final float CENTER_Y = 11.869239f;
+    private static final float SCALE = 24f;
+
+    // Bottom is derived during animation
+    private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE;
+    private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE;
+    private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE;
+    // Draw the slash washington-monument style; rotate to no-u-turn style
+    private static final float DEFAULT_ROTATION = -45f;
+
+    private Drawable mDrawable;
+    private final RectF mSlashRect = new RectF(0, 0, 0, 0);
+    private float mRotation;
+    private boolean mSlashed;
+    private Mode mTintMode;
+    private ColorStateList mTintList;
+    private boolean mAnimationEnabled = true;
+
+    public SlashDrawable(Drawable d) {
+        mDrawable = d;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mDrawable != null ? mDrawable.getIntrinsicHeight(): 0;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mDrawable != null ? mDrawable.getIntrinsicWidth(): 0;
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mDrawable.setBounds(bounds);
+    }
+
+    public void setDrawable(Drawable d) {
+        mDrawable = d;
+        mDrawable.setCallback(getCallback());
+        mDrawable.setBounds(getBounds());
+        if (mTintMode != null) mDrawable.setTintMode(mTintMode);
+        if (mTintList != null) mDrawable.setTintList(mTintList);
+        invalidateSelf();
+    }
+
+    public void setRotation(float rotation) {
+        if (mRotation == rotation) return;
+        mRotation = rotation;
+        invalidateSelf();
+    }
+
+    public void setAnimationEnabled(boolean enabled) {
+        mAnimationEnabled = enabled;
+    }
+
+    // Animate this value on change
+    private float mCurrentSlashLength;
+    private final FloatProperty mSlashLengthProp = new FloatProperty<SlashDrawable>("slashLength") {
+        @Override
+        public void setValue(SlashDrawable object, float value) {
+            object.mCurrentSlashLength = value;
+        }
+
+        @Override
+        public Float get(SlashDrawable object) {
+            return object.mCurrentSlashLength;
+        }
+    };
+
+    public void setSlashed(boolean slashed) {
+        if (mSlashed == slashed) return;
+
+        mSlashed = slashed;
+
+        final float end = mSlashed ? SLASH_HEIGHT / SCALE : 0f;
+        final float start = mSlashed ? 0f : SLASH_HEIGHT / SCALE;
+
+        if (mAnimationEnabled) {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end);
+            anim.addUpdateListener((ValueAnimator valueAnimator) -> invalidateSelf());
+            anim.setDuration(QS_ANIM_LENGTH);
+            anim.start();
+        } else {
+            mCurrentSlashLength = end;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        canvas.save();
+        Matrix m = new Matrix();
+        final int width = getBounds().width();
+        final int height = getBounds().height();
+        final float radiusX = scale(CORNER_RADIUS, width);
+        final float radiusY = scale(CORNER_RADIUS, height);
+        updateRect(
+                scale(LEFT, width),
+                scale(TOP, height),
+                scale(RIGHT, width),
+                scale(TOP + mCurrentSlashLength, height)
+        );
+
+        mPath.reset();
+        // Draw the slash vertically
+        mPath.addRoundRect(mSlashRect, radiusX, radiusY, Direction.CW);
+        // Rotate -45 + desired rotation
+        m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+        canvas.drawPath(mPath, mPaint);
+
+        // Rotate back to vertical
+        m.setRotate(-mRotation - DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+
+        // Draw another rect right next to the first, for clipping
+        m.setTranslate(mSlashRect.width(), 0);
+        mPath.transform(m);
+        mPath.addRoundRect(mSlashRect, 1.0f * width, 1.0f * height, Direction.CW);
+        m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2);
+        mPath.transform(m);
+        canvas.clipOutPath(mPath);
+
+        mDrawable.draw(canvas);
+        canvas.restore();
+    }
+
+    private float scale(float frac, int width) {
+        return frac * width;
+    }
+
+    private void updateRect(float left, float top, float right, float bottom) {
+        mSlashRect.left = left;
+        mSlashRect.top = top;
+        mSlashRect.right = right;
+        mSlashRect.bottom = bottom;
+    }
+
+    @Override
+    public void setTint(@ColorInt int tintColor) {
+        super.setTint(tintColor);
+        mDrawable.setTint(tintColor);
+        mPaint.setColor(tintColor);
+    }
+
+    @Override
+    public void setTintList(@Nullable ColorStateList tint) {
+        mTintList = tint;
+        super.setTintList(tint);
+        mDrawable.setTintList(tint);
+        mPaint.setColor(tint.getDefaultColor());
+        invalidateSelf();
+    }
+
+    @Override
+    public void setTintMode(@NonNull Mode tintMode) {
+        mTintMode = tintMode;
+        super.setTintMode(tintMode);
+        mDrawable.setTintMode(tintMode);
+    }
+
+    @Override
+    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
+        mDrawable.setAlpha(alpha);
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
+        mDrawable.setColorFilter(colorFilter);
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return 255;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 30053e3..6c95a80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -20,6 +20,9 @@
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.v7.widget.DefaultItemAnimator;
@@ -42,6 +45,7 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSContainerImpl;
 import com.android.systemui.qs.QSDetailClipper;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
@@ -60,6 +64,7 @@
 public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener {
 
     private static final int MENU_RESET = Menu.FIRST;
+    private static final String EXTRA_QS_CUSTOMIZING = "qs_customizing";
 
     private final QSDetailClipper mClipper;
 
@@ -109,11 +114,16 @@
         DefaultItemAnimator animator = new DefaultItemAnimator();
         animator.setMoveDuration(TileAdapter.MOVE_DURATION);
         mRecyclerView.setItemAnimator(animator);
+        updateNavBackDrop(getResources().getConfiguration());
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
+        updateNavBackDrop(newConfig);
+    }
+
+    private void updateNavBackDrop(Configuration newConfig) {
         View navBackdrop = findViewById(R.id.nav_bar_background);
         if (navBackdrop != null) {
             boolean shouldShow = newConfig.smallestScreenWidthDp >= 600
@@ -154,6 +164,21 @@
         }
     }
 
+
+    public void showImmediately() {
+        if (!isShown) {
+            setVisibility(VISIBLE);
+            mClipper.showBackground();
+            isShown = true;
+            setTileSpecs();
+            setCustomizing(true);
+            queryTiles();
+            mNotifQsContainer.setCustomizerAnimating(false);
+            mNotifQsContainer.setCustomizerShowing(true);
+            Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback);
+        }
+    }
+
     private void queryTiles() {
         mFinishedFetchingTiles = false;
         Runnable tileQueryFetchCompletion = () -> {
@@ -227,6 +252,35 @@
         }
     }
 
+
+    public void saveInstanceState(Bundle outState) {
+        if (isShown) {
+            Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback);
+        }
+        outState.putBoolean(EXTRA_QS_CUSTOMIZING, mCustomizing);
+    }
+
+    public void restoreInstanceState(Bundle savedInstanceState) {
+        boolean customizing = savedInstanceState.getBoolean(EXTRA_QS_CUSTOMIZING);
+        if (customizing) {
+            setVisibility(VISIBLE);
+            addOnLayoutChangeListener(new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft,
+                        int oldTop, int oldRight, int oldBottom) {
+                    removeOnLayoutChangeListener(this);
+                    showImmediately();
+                }
+            });
+        }
+    }
+
+    public void setEditLocation(int x, int y) {
+        mX = x;
+        mY = y;
+    }
+
     private final Callback mKeyguardCallback = () -> {
         if (!isAttachedToWindow()) return;
         if (Dependency.get(KeyguardMonitor.class).isShowing() && !mOpening) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 17a0d33..77c3bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -16,7 +16,9 @@
 
 import android.content.Context;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 
+import com.android.systemui.R;
 import com.android.systemui.plugins.qs.*;
 import com.android.systemui.plugins.qs.QSTileView;
 import com.android.systemui.qs.external.CustomTile;
@@ -78,7 +80,7 @@
 
     @Override
     public QSTileView createTileView(QSTile tile, boolean collapsedView) {
-        Context context = mHost.getContext();
+        Context context = new ContextThemeWrapper(mHost.getContext(), R.style.qs_theme);
         QSIconView icon = tile.createTileView(context);
         if (collapsedView) {
             return new QSTileBaseView(context, icon, collapsedView);
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 661c921..8074cb9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -21,7 +21,6 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
-import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.Animatable2.AnimationCallback;
 import android.graphics.drawable.Drawable;
@@ -38,6 +37,8 @@
 
 public class QSIconViewImpl extends QSIconView {
 
+    public static final long QS_ANIM_LENGTH = 350;
+
     protected final View mIcon;
     protected final int mIconSizePx;
     protected final int mTilePaddingBelowIconPx;
@@ -85,7 +86,8 @@
     }
 
     protected void updateIcon(ImageView iv, State state) {
-        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))
+                || !Objects.equals(state.slash, iv.getTag(R.id.qs_slash_tag))) {
             boolean shouldAnimate = iv.isShown() && mAnimationEnabled
                     && iv.getDrawable() != null;
             Drawable d = state.icon != null
@@ -94,9 +96,18 @@
             int padding = state.icon != null ? state.icon.getPadding() : 0;
             if (d != null) {
                 d.setAutoMirrored(false);
+                d.setLayoutDirection(getLayoutDirection());
             }
-            iv.setImageDrawable(d);
+
+            if (iv instanceof SlashImageView) {
+                ((SlashImageView) iv).setAnimationEnabled(shouldAnimate);
+                ((SlashImageView) iv).setState(state.slash, d);
+            } else {
+                iv.setImageDrawable(d);
+            }
+
             iv.setTag(R.id.qs_icon_tag, state.icon);
+            iv.setTag(R.id.qs_slash_tag, state.slash);
             iv.setPadding(0, padding, 0, padding);
             if (d instanceof Animatable2) {
                 Animatable2 a = (Animatable2) d;
@@ -138,22 +149,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(350);
+            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) {
@@ -166,7 +181,7 @@
     }
 
     protected View createIcon() {
-        final ImageView icon = new ImageView(mContext);
+        final ImageView icon = new SlashImageView(mContext);
         icon.setId(android.R.id.icon);
         icon.setScaleType(ScaleType.FIT_CENTER);
         return icon;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
new file mode 100644
index 0000000..13912fe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
@@ -0,0 +1,77 @@
+/*
+ * 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.qs.tileimpl;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.widget.ImageView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.plugins.qs.QSTile.SlashState;
+import com.android.systemui.qs.SlashDrawable;
+
+public class SlashImageView extends ImageView {
+
+    @VisibleForTesting
+    protected SlashDrawable mSlash;
+    private boolean mAnimationEnabled = true;
+
+    public SlashImageView(Context context) {
+        super(context);
+    }
+
+    private void ensureSlashDrawable() {
+        if (mSlash == null) {
+            mSlash = new SlashDrawable(getDrawable());
+            mSlash.setAnimationEnabled(mAnimationEnabled);
+            super.setImageDrawable(mSlash);
+        }
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        if (drawable == null) {
+            mSlash = null;
+            super.setImageDrawable(null);
+        } else if (mSlash == null) {
+            super.setImageDrawable(drawable);
+        } else {
+            mSlash.setAnimationEnabled(mAnimationEnabled);
+            mSlash.setDrawable(drawable);
+        }
+    }
+
+    public void setAnimationEnabled(boolean enabled) {
+        mAnimationEnabled = enabled;
+    }
+
+    private void setSlashState(@NonNull SlashState slashState) {
+        ensureSlashDrawable();
+        mSlash.setRotation(slashState.rotation);
+        mSlash.setSlashed(slashState.isSlashed);
+    }
+
+    public void setState(@Nullable SlashState state, @Nullable Drawable drawable) {
+        if (state != null) {
+            setImageDrawable(drawable);
+            setSlashState(state);
+        } else {
+            mSlash = null;
+            setImageDrawable(drawable);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c5f798e..2e7012e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,19 +29,15 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation,
-                    R.drawable.ic_signal_airplane_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_disable_animation,
-                    R.drawable.ic_signal_airplane_enable);
+    private final Icon mIcon =
+            ResourceIcon.get(R.drawable.ic_signal_airplane);
     private final GlobalSetting mSetting;
 
     private boolean mListening;
@@ -90,11 +86,11 @@
         final boolean airplaneMode = value != 0;
         state.value = airplaneMode;
         state.label = mContext.getString(R.string.airplane_mode);
-        if (airplaneMode) {
-            state.icon = mEnable;
-        } else {
-            state.icon = mDisable;
+        state.icon = mIcon;
+        if (state.slash == null) {
+            state.slash = new SlashState();
         }
+        state.slash.isSlashed = !airplaneMode;
         state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.contentDescription = state.label;
         state.expandedAccessibilityClassName = Switch.class.getName();
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 74cc0ec..3f419a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -15,32 +15,15 @@
  */
 package com.android.systemui.qs.tiles;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.service.quicksettings.Tile;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Checkable;
-import android.widget.ImageView;
 import android.widget.Switch;
-import android.widget.TextView;
-
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.BatteryInfo;
 import com.android.settingslib.graph.BatteryMeterDrawableBase;
-import com.android.settingslib.graph.UsageView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -50,12 +33,10 @@
         BatteryController.BatteryStateChangeCallback {
 
     private final BatteryController mBatteryController;
-    private final BatteryDetail mBatteryDetail = new BatteryDetail();
 
     private int mLevel;
     private boolean mPowerSave;
     private boolean mCharging;
-    private boolean mDetailShown;
     private boolean mPluggedIn;
 
     public BatterySaverTile(QSHost host) {
@@ -83,14 +64,6 @@
     }
 
     @Override
-    public void setDetailListening(boolean listening) {
-        super.setDetailListening(listening);
-        if (!listening) {
-            mBatteryDetail.mCurrentView = null;
-        }
-    }
-
-    @Override
     public Intent getLongClickIntent() {
         return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
     }
@@ -107,9 +80,11 @@
 
     @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;
-        state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
+        BatterySaverIcon bsi = new BatterySaverIcon();
+        bsi.mState = state.state;
+        state.icon = bsi;
         state.label = mContext.getString(R.string.battery_detail_switch_title);
         state.contentDescription = state.label;
         state.value = mPowerSave;
@@ -122,160 +97,48 @@
         mPluggedIn = pluggedIn;
         mCharging = charging;
         refreshState(level);
-        if (mDetailShown) {
-            mBatteryDetail.postBindView();
-        }
     }
 
     @Override
     public void onPowerSaveChanged(boolean isPowerSave) {
         mPowerSave = isPowerSave;
         refreshState(null);
-        if (mDetailShown) {
-            mBatteryDetail.postBindView();
+    }
+
+    public static class BatterySaverIcon extends Icon {
+        private int mState;
+
+        @Override
+        public Drawable getDrawable(Context context) {
+            BatterySaverDrawable b = new BatterySaverDrawable(context, 0);
+            b.mState = mState;
+            final int pad = context.getResources()
+                    .getDimensionPixelSize(R.dimen.qs_tile_divider_height);
+            b.setPadding(pad, pad, pad, pad);
+            return b;
         }
     }
 
-    private final class BatteryDetail implements DetailAdapter, OnClickListener,
-            OnAttachStateChangeListener {
-        private final BatteryMeterDrawableBase mDrawable
-                = new BatteryMeterDrawableBase(
-                        mHost.getContext(),
-                        mHost.getContext().getColor(R.color.meter_background_color));
-        private View mCurrentView;
+    private static class BatterySaverDrawable extends BatteryMeterDrawableBase {
+        private int mState;
+        private static final int MAX_BATTERY = 100;
 
-        @Override
-        public CharSequence getTitle() {
-            return mContext.getString(R.string.battery_panel_title, mLevel);
+        BatterySaverDrawable(Context context, int frameColor) {
+            super(context, frameColor);
+            // Show as full so it's always uniform color
+            super.setBatteryLevel(MAX_BATTERY);
+            setPowerSave(true);
+            setCharging(false);
         }
 
         @Override
-        public Boolean getToggleState() {
-            return null;
+        protected int batteryColorForLevel(int level) {
+            return QSTileImpl.getColorForState(mContext, mState);
         }
 
         @Override
-        public View createDetailView(Context context, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = LayoutInflater.from(mContext).inflate(R.layout.battery_detail, parent,
-                        false);
-            }
-            mCurrentView = convertView;
-            mCurrentView.addOnAttachStateChangeListener(this);
-            bindView();
-            return convertView;
+        public void setBatteryLevel(int val) {
+            // Don't change the actual level, otherwise this won't draw correctly
         }
-
-        private void postBindView() {
-            if (mCurrentView == null) return;
-            mCurrentView.post(new Runnable() {
-                @Override
-                public void run() {
-                    bindView();
-                }
-            });
-        }
-
-        private void bindView() {
-            if (mCurrentView == null) {
-                return;
-            }
-            mDrawable.setBatteryLevel(100);
-            mDrawable.setCharging(false);
-            mDrawable.setPowerSave(true);
-            mDrawable.setShowPercent(false);
-            ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
-            Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
-            checkbox.setChecked(mPowerSave);
-            BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
-                @Override
-                public void onBatteryInfoLoaded(BatteryInfo info) {
-                    if (mCurrentView != null) {
-                        bindBatteryInfo(info);
-                    }
-                }
-            });
-            final TextView batterySaverTitle =
-                    (TextView) mCurrentView.findViewById(android.R.id.title);
-            final TextView batterySaverSummary =
-                    (TextView) mCurrentView.findViewById(android.R.id.summary);
-            if (mCharging) {
-                mCurrentView.findViewById(R.id.switch_container).setAlpha(.7f);
-                batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
-                batterySaverTitle.setText(R.string.battery_detail_charging_summary);
-                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.GONE);
-                mCurrentView.findViewById(R.id.switch_container).setClickable(false);
-            } else {
-                mCurrentView.findViewById(R.id.switch_container).setAlpha(1);
-                batterySaverTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
-                batterySaverTitle.setText(R.string.battery_detail_switch_title);
-                batterySaverSummary.setText(R.string.battery_detail_switch_summary);
-                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.VISIBLE);
-                mCurrentView.findViewById(R.id.switch_container).setClickable(true);
-                mCurrentView.findViewById(R.id.switch_container).setOnClickListener(this);
-            }
-        }
-
-        private void bindBatteryInfo(BatteryInfo info) {
-            SpannableStringBuilder builder = new SpannableStringBuilder();
-            builder.append(info.batteryPercentString, new RelativeSizeSpan(2.6f),
-                    Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
-            if (info.remainingLabel != null) {
-                if (mContext.getResources().getBoolean(R.bool.quick_settings_wide)) {
-                    builder.append(' ');
-                } else {
-                    builder.append('\n');
-                }
-                builder.append(info.remainingLabel);
-            }
-            ((TextView) mCurrentView.findViewById(R.id.charge_and_estimation)).setText(builder);
-
-            info.bindHistory((UsageView) mCurrentView.findViewById(R.id.battery_usage));
-        }
-
-        @Override
-        public void onClick(View v) {
-            mBatteryController.setPowerSaveMode(!mPowerSave);
-        }
-
-        @Override
-        public Intent getSettingsIntent() {
-            return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
-        }
-
-        @Override
-        public void setToggleState(boolean state) {
-            // No toggle state.
-        }
-
-        @Override
-        public int getMetricsCategory() {
-            return MetricsEvent.QS_BATTERY_DETAIL;
-        }
-
-        @Override
-        public void onViewAttachedToWindow(View v) {
-            if (!mDetailShown) {
-                mDetailShown = true;
-                v.getContext().registerReceiver(mReceiver,
-                        new IntentFilter(Intent.ACTION_TIME_TICK), null,
-                        Dependency.get(Dependency.TIME_TICK_HANDLER));
-            }
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            if (mDetailShown) {
-                mDetailShown = false;
-                v.getContext().unregisterReceiver(mReceiver);
-            }
-        }
-
-        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                postBindView();
-            }
-        };
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 79fb5b3..12fccda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -30,6 +30,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -82,7 +83,7 @@
     @Override
     protected void handleClick() {
         // Secondary clicks are header clicks, just toggle.
-        final boolean isEnabled = (Boolean)mState.value;
+        final boolean isEnabled = mState.value;
         mController.setBluetoothEnabled(!isEnabled);
     }
 
@@ -99,6 +100,9 @@
             return;
         }
         showDetail(true);
+        if (!mState.value) {
+            mController.setBluetoothEnabled(true);
+        }
     }
 
     @Override
@@ -114,6 +118,10 @@
                 || mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
         state.dualTarget = true;
         state.value = enabled;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+        state.slash.isSlashed = !enabled;
         if (enabled) {
             state.label = null;
             if (connected) {
@@ -137,7 +145,7 @@
             }
             state.state = Tile.STATE_ACTIVE;
         } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
             state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_bluetooth_off);
@@ -174,6 +182,7 @@
             refreshState();
             if (isShowingDetail()) {
                 mDetailAdapter.updateItems();
+                fireToggleStateChanged(mDetailAdapter.getToggleState());
             }
         }
 
@@ -264,10 +273,17 @@
                     item.icon = R.drawable.ic_qs_bluetooth_on;
                     item.line1 = device.getName();
                     item.tag = device;
-                    int state = mController.getMaxConnectionState(device);
+                    int state = device.getMaxConnectionState();
                     if (state == BluetoothProfile.STATE_CONNECTED) {
                         item.icon = R.drawable.ic_qs_bluetooth_connected;
-                        item.line2 = mContext.getString(R.string.quick_settings_connected);
+                        int batteryLevel = device.getBatteryLevel();
+                        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+                            item.line2 = mContext.getString(
+                                    R.string.quick_settings_connected_battery_level,
+                                    Utils.formatPercentage(batteryLevel));
+                        } else {
+                            item.line2 = mContext.getString(R.string.quick_settings_connected);
+                        }
                         item.canDisconnect = true;
                         items.add(connectedDevices, item);
                         connectedDevices++;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index f0d7d6c..2fc9fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -34,6 +34,7 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.widget.Button;
 
 import com.android.internal.app.MediaRouteChooserDialog;
@@ -50,6 +51,7 @@
 import com.android.systemui.qs.QSDetailItems.Item;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -139,25 +141,15 @@
                         Dependency.get(ActivityStarter.class)
                                 .postStartActivityDismissingKeyguard(getLongClickIntent(), 0);
                     });
-            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+            mDialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+            SystemUIDialog.setShowForAllUsers(mDialog, true);
+            SystemUIDialog.registerDismissListener(mDialog);
+            SystemUIDialog.setWindowOnTop(mDialog);
             mUiHandler.post(() -> mDialog.show());
-            registerReceiver();
             mHost.collapsePanels();
         });
     }
 
-    private void registerReceiver() {
-        mContext.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
-                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
-        mRegistered = true;
-        mDialog.setOnDismissListener(dialog -> {
-            if (mRegistered) {
-                mContext.unregisterReceiver(mReceiver);
-                mRegistered = false;
-            }
-        });
-    }
-
     @Override
     public CharSequence getTileLabel() {
         return mContext.getString(R.string.quick_settings_cast_title);
@@ -223,15 +215,6 @@
         }
     };
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mDialog != null) {
-                mDialog.dismiss();
-            }
-        }
-    };
-
     private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
         private final LinkedHashMap<String, CastDevice> mVisibleOrder = new LinkedHashMap<>();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index fbcdf1a..4afafb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,6 +26,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager.LayoutParams;
 import android.widget.Switch;
 
 import com.android.internal.logging.MetricsLogger;
@@ -31,6 +34,7 @@
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.R.string;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSIconView;
@@ -38,8 +42,9 @@
 import com.android.systemui.qs.CellTileView;
 import com.android.systemui.qs.CellTileView.SignalIcon;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -55,11 +60,13 @@
 
     private final CellSignalCallback mSignalCallback = new CellSignalCallback();
     private final ActivityStarter mActivityStarter;
+    private final KeyguardMonitor mKeyguardMonitor;
 
     public CellularTile(QSHost host) {
         super(host);
         mController = Dependency.get(NetworkController.class);
         mActivityStarter = Dependency.get(ActivityStarter.class);
+        mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDataController = mController.getMobileDataController();
         mDetailAdapter = new CellularDetailAdapter();
     }
@@ -95,7 +102,31 @@
 
     @Override
     protected void handleClick() {
-        mDataController.setMobileDataEnabled(!mDataController.isMobileDataEnabled());
+        if (mDataController.isMobileDataEnabled()) {
+            if (mKeyguardMonitor.isSecure() && !mKeyguardMonitor.canSkipBouncer()) {
+                mActivityStarter.postQSRunnableDismissingKeyguard(this::showDisableDialog);
+            } else {
+                mUiHandler.post(this::showDisableDialog);
+            }
+        } else {
+            mDataController.setMobileDataEnabled(true);
+        }
+    }
+
+    private void showDisableDialog() {
+        mHost.collapsePanels();
+        AlertDialog dialog = new Builder(mContext)
+                .setMessage(string.data_usage_disable_mobile)
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(
+                        com.android.internal.R.string.alert_windows_notification_turn_off_action,
+                        (d, w) -> mDataController.setMobileDataEnabled(false))
+                .create();
+        dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
+        SystemUIDialog.setShowForAllUsers(dialog, true);
+        SystemUIDialog.registerDismissListener(dialog);
+        SystemUIDialog.setWindowOnTop(dialog);
+        dialog.show();
     }
 
     @Override
@@ -139,6 +170,7 @@
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
+
         state.icon = new SignalIcon(cb.mobileSignalIconId);
         if (cb.airplaneModeEnabled) {
             state.state = Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5b374b1..40fe484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -33,12 +34,7 @@
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_invert_colors_enable_animation,
-            R.drawable.ic_invert_colors_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation,
-            R.drawable.ic_invert_colors_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors);
     private final SecureSetting mSetting;
 
     private boolean mListening;
@@ -96,10 +92,14 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.value = enabled;
+        state.slash.isSlashed = !state.value;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.icon = enabled ? mEnable : mDisable;
+        state.icon = mIcon;
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 9557262..5938749 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -27,13 +27,13 @@
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.net.Uri;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ZenRule;
 import android.service.quicksettings.Tile;
+import android.util.Log;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -55,6 +55,7 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
 import com.android.systemui.volume.ZenModePanel;
 
 /** Quick settings tile: Do not disturb **/
@@ -72,13 +73,6 @@
     private static final QSTile.Icon TOTAL_SILENCE =
             ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
 
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_dnd_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
-    private final AnimationIcon mDisableTotalSilence =
-            new AnimationIcon(R.drawable.ic_dnd_total_silence_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
-
     private final ZenModeController mController;
     private final DndDetailAdapter mDetailAdapter;
 
@@ -155,7 +149,22 @@
                     Toast.LENGTH_LONG).show();
             return;
         }
-        showDetail(true);
+        if (!mState.value) {
+            // Because of the complexity of the zen panel, it needs to be shown after
+            // we turn on zen below.
+            mController.addCallback(new ZenModeController.Callback() {
+                @Override
+                public void onZenChanged(int zen) {
+                    mController.removeCallback(this);
+                    showDetail(true);
+                }
+            });
+            int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN,
+                    Global.ZEN_MODE_ALARMS);
+            mController.setZen(zen, null, TAG);
+        } else {
+            showDetail(true);
+        }
     }
 
     @Override
@@ -168,9 +177,11 @@
         final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
         final boolean newValue = zen != ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
+        if (state.slash == null) state.slash = new SlashState();
         state.dualTarget = true;
         state.value = newValue;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.slash.isSlashed = !state.value;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
@@ -192,7 +203,7 @@
                         R.string.accessibility_quick_settings_dnd_alarms_on);
                 break;
             default:
-                state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
+                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
                 state.label = mContext.getString(R.string.quick_settings_dnd_label);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_dnd);
@@ -322,7 +333,7 @@
                 mZenPanel.init(mController);
                 mZenPanel.addOnAttachStateChangeListener(this);
                 mZenPanel.setCallback(mZenModePanelCallback);
-                mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_off, R.string.dnd_is_off);
+                mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_detail_empty, R.string.dnd_is_off);
             }
             updatePanel();
             return mZenPanel;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 6d2aa90..e6ac908 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -23,12 +23,11 @@
 import android.service.quicksettings.Tile;
 import android.widget.Switch;
 
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 
@@ -36,12 +35,7 @@
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation,
-            R.drawable.ic_signal_flashlight_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation,
-            R.drawable.ic_signal_flashlight_enable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight);
     private final FlashlightController mFlashlightController;
 
     public FlashlightTile(QSHost host) {
@@ -104,11 +98,13 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (!mFlashlightController.isAvailable()) {
-            Drawable icon = mHost.getContext().getDrawable(R.drawable.ic_signal_flashlight_enable)
-                    .mutate();
-            state.icon = new DrawableIcon(icon);
+            state.icon = mIcon;
+            state.slash.isSlashed = true;
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_flashlight_unavailable);
             state.state = Tile.STATE_UNAVAILABLE;
@@ -123,8 +119,8 @@
         } else {
             state.value = mFlashlightController.isEnabled();
         }
-        final AnimationIcon icon = state.value ? mEnable : mDisable;
-        state.icon = icon;
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 40f2c4b..c17573d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -39,14 +39,7 @@
     static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
              "com.android.settings", "com.android.settings.TetherSettings"));
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
-                    R.drawable.ic_hotspot_disable);
-    private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
-                    R.drawable.ic_hotspot_enable);
-    private final Icon mDisableNoAnimation = ResourceIcon.get(R.drawable.ic_hotspot_enable);
+    private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot);
     private final Icon mUnavailable = ResourceIcon.get(R.drawable.ic_hotspot_unavailable);
 
     private final HotspotController mController;
@@ -116,6 +109,9 @@
 
     @Override
     protected void handleUpdateState(AirplaneBooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
@@ -124,18 +120,12 @@
         } else {
             state.value = mController.isHotspotEnabled();
         }
-        state.icon = !state.value ? mDisable
-                : state.isTransient ? mEnabledStatic
-                : mEnable;
-        boolean wasAirplane = state.isAirplaneMode;
+        state.icon = mEnabledStatic;
         state.isAirplaneMode = mAirplaneMode.getValue() != 0;
         state.isTransient = mController.isHotspotTransient();
+        state.slash.isSlashed = !state.value && !state.isTransient;
         if (state.isTransient) {
             state.icon = ResourceIcon.get(R.drawable.ic_hotspot_transient_animation);
-        } else if (state.isAirplaneMode) {
-            state.icon = mUnavailable;
-        } else if (wasAirplane) {
-            state.icon = mDisableNoAnimation;
         }
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 6522e10..5e66334 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -36,12 +37,7 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_location_enable_animation,
-                    R.drawable.ic_signal_location_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_location_disable_animation,
-                    R.drawable.ic_signal_location_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_signal_location);
 
     private final LocationController mController;
     private final KeyguardMonitor mKeyguard;
@@ -95,6 +91,9 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         final boolean locationEnabled =  mController.isLocationEnabled();
 
         // Work around for bug 15916487: don't show location tile on top of lock screen. After the
@@ -102,13 +101,13 @@
         // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
         state.value = locationEnabled;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         if (locationEnabled) {
-            state.icon = mEnable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_on);
         } else {
-            state.icon = mDisable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 8aa1e43..2a12769 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -79,8 +79,7 @@
         state.value = isActivated;
         state.label = state.contentDescription =
                 mContext.getString(R.string.quick_settings_night_display_label);
-        state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_night_display_on
-                : R.drawable.ic_qs_night_display_off);
+        state.icon = ResourceIcon.get(R.drawable.ic_qs_night_display_on);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index f26afcc..136cf21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -127,6 +127,9 @@
             return;
         }
         showDetail(true);
+        if (!mState.value) {
+            mController.setWifiEnabled(true);
+        }
     }
 
     @Override
@@ -149,6 +152,12 @@
             mDetailAdapter.setItemsVisible(cb.enabled);
             fireToggleStateChanged(cb.enabled);
         }
+        if (state.slash == null) {
+            state.slash = new SlashState();
+            state.slash.rotation = 6;
+        }
+        state.slash.isSlashed = false;
+        state.state = Tile.STATE_ACTIVE;
         state.dualTarget = true;
         state.value = cb.enabled;
         state.activityIn = cb.enabled && cb.activityIn;
@@ -159,6 +168,8 @@
             state.icon = ResourceIcon.get(R.drawable.ic_signal_wifi_transient_animation);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (!state.value) {
+            state.slash.isSlashed = true;
+            state.state = Tile.STATE_INACTIVE;
             state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (wifiConnected) {
@@ -183,7 +194,6 @@
         state.dualLabelContentDescription = r.getString(
                 R.string.accessibility_quick_settings_open_settings, getTileLabel());
         state.expandedAccessibilityClassName = Switch.class.getName();
-        state.state = Tile.STATE_ACTIVE;
     }
 
     @Override
@@ -304,12 +314,10 @@
         public View createDetailView(Context context, View convertView, ViewGroup parent) {
             if (DEBUG) Log.d(TAG, "createDetailView convertView=" + (convertView != null));
             mAccessPoints = null;
-            mWifiController.scanForAccessPoints();
-            fireScanStateChanged(true);
             mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
             mItems.setTagSuffix("Wifi");
             mItems.setCallback(this);
-            updateItems();
+            mWifiController.scanForAccessPoints(); // updates APs and items
             setItemsVisible(mState.value);
             return mItems;
         }
@@ -317,9 +325,24 @@
         @Override
         public void onAccessPointsChanged(final List<AccessPoint> accessPoints) {
             mAccessPoints = accessPoints.toArray(new AccessPoint[accessPoints.size()]);
+            filterUnreachableAPs();
+
             updateItems();
-            if (accessPoints != null && accessPoints.size() > 0) {
-                fireScanStateChanged(false);
+        }
+
+        /** Filter unreachable APs from mAccessPoints */
+        private void filterUnreachableAPs() {
+            int numReachable = 0;
+            for (AccessPoint ap : mAccessPoints) {
+                if (ap.isReachable()) numReachable++;
+            }
+            if (numReachable != mAccessPoints.length) {
+                AccessPoint[] unfiltered = mAccessPoints;
+                mAccessPoints = new AccessPoint[numReachable];
+                int i = 0;
+                for (AccessPoint ap : unfiltered) {
+                    if (ap.isReachable()) mAccessPoints[i++] = ap;
+                }
             }
         }
 
@@ -352,6 +375,12 @@
 
         private void updateItems() {
             if (mItems == null) return;
+            if ((mAccessPoints != null && mAccessPoints.length > 0)
+                    || !mSignalCallback.mInfo.enabled) {
+                fireScanStateChanged(false);
+            } else {
+                fireScanStateChanged(true);
+            }
 
             // Wi-Fi is off
             if (!mSignalCallback.mInfo.enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 6c89241..38821f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -33,12 +33,7 @@
 /** Quick settings tile: Work profile on/off */
 public class WorkModeTile extends QSTileImpl<BooleanState> implements
         ManagedProfileController.Callback {
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_workmode_enable_animation,
-                    R.drawable.ic_signal_workmode_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_workmode_disable_animation,
-                    R.drawable.ic_signal_workmode_enable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_workmode_disable);
 
     private final ManagedProfileController mProfileController;
 
@@ -93,6 +88,10 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+
         if (arg instanceof Boolean) {
             state.value = (Boolean) arg;
         } else {
@@ -100,12 +99,13 @@
         }
 
         state.label = mContext.getString(R.string.quick_settings_work_mode_label);
+        state.icon = mIcon;
         if (state.value) {
-            state.icon = mEnable;
+            state.slash.isSlashed = false;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_work_mode_on);
         } else {
-            state.icon = mDisable;
+            state.slash.isSlashed = true;
             state.contentDescription =  mContext.getString(
                     R.string.accessibility_quick_settings_work_mode_off);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
index 1240e05..cc7798e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
@@ -31,4 +31,5 @@
     void sendRecentsDrawnEvent();
     void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
     void sendLaunchRecentsEvent();
+    void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 9ba32b3..86dde54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -43,17 +43,22 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.PluginActivity;
+import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.component.ShowUserToastEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -234,6 +239,8 @@
             registerWithSystemUser();
         }
         putComponent(Recents.class, this);
+        Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY,
+                PluginActivity.ACTION_RECENTS);
     }
 
     @Override
@@ -607,6 +614,14 @@
                 }
             });
         }
+
+        // This will catch the cases when a user launches from recents to another app
+        // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
+        // would not reset the wait for transition flag. This will catch it and make sure that the
+        // flag is reset.
+        if (!event.visible) {
+            mImpl.setWaitingForTransitionStart(false);
+        }
     }
 
     /**
@@ -679,6 +694,11 @@
         }
     }
 
+    public final void onBusEvent(LaunchTaskFailedEvent event) {
+        // Reset the transition when tasks fail to launch
+        mImpl.setWaitingForTransitionStart(false);
+    }
+
     public final void onBusEvent(ConfigurationChangedEvent event) {
         // Update the configuration for the Recents component when the activity configuration
         // changes as well
@@ -706,6 +726,25 @@
         }
     }
 
+    public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
+            mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
+        } else {
+            postToSystemUser(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
+                                event.waitingForTransitionStart);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Callback failed", e);
+                    }
+                }
+            });
+        }
+    }
+
     /**
      * Attempts to register with the system user.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ba3bcc7..387527f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -20,6 +20,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
+import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -40,12 +41,15 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.Interpolators;
 import com.android.keyguard.LatencyTracker;
+import com.android.systemui.DejankUtils;
+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.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
@@ -65,6 +69,7 @@
 import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
 import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
@@ -72,6 +77,7 @@
 import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
 import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
+import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
 import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
@@ -98,7 +104,8 @@
 /**
  * The main Recents activity that is started from RecentsComponent.
  */
-public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
+public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener,
+        ColorExtractor.OnColorsChangedListener {
 
     private final static String TAG = "RecentsActivity";
     private final static boolean DEBUG = false;
@@ -109,11 +116,10 @@
     private RecentsPackageMonitor mPackageMonitor;
     private Handler mHandler = new Handler();
     private long mLastTabKeyEventTime;
-    private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private int mLastDisplayDensity;
     private boolean mFinishedOnStartup;
     private boolean mIgnoreAltTabRelease;
     private boolean mIsVisible;
+    private Configuration mLastConfig;
 
     // Top level views
     private RecentsView mRecentsView;
@@ -128,6 +134,10 @@
     private DozeTrigger mIterateTrigger;
     private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
 
+    // Theme and colors
+    private SysuiColorExtractor mColorExtractor;
+    private boolean mUsingDarkText;
+
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
      * last activity launch state. Generally we always launch home when we exit Recents rather than
@@ -328,20 +338,23 @@
         mPackageMonitor = new RecentsPackageMonitor();
         mPackageMonitor.register(this);
 
+        // Select theme based on wallpaper colors
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+        mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
+                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+        setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+                : R.style.RecentsTheme_Wallpaper);
+
         // Set the Recents layout
         setContentView(R.layout.recents);
         takeKeyEvents(true);
         mRecentsView = findViewById(R.id.recents_view);
-        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
-                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
-                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
         mScrimViews = new SystemBarScrimViews(this);
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
-        Configuration appConfiguration = Utilities.getAppConfiguration(this);
-        mLastDeviceOrientation = appConfiguration.orientation;
-        mLastDisplayDensity = appConfiguration.densityDpi;
+        mLastConfig = new Configuration(Utilities.getAppConfiguration(this));
         mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
         mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
             @Override
@@ -379,11 +392,37 @@
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
         MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
 
+        // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
+        ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
+                ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
+        // We don't want to interpolate colors because we're defining the initial state.
+        // Gradient should be set/ready when you open "Recents".
+        mRecentsView.setScrimColors(systemColors, false);
+
         // Notify of the next draw
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
     }
 
     @Override
+    public void onColorsChanged(ColorExtractor colorExtractor, int which) {
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            // Recents doesn't care about the wallpaper being visible or not, it always
+            // wants to scrim with wallpaper colors
+            ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                    WallpaperManager.FLAG_SYSTEM,
+                    ColorExtractor.TYPE_DARK, true /* ignoreVis */);
+            boolean darkText = colors.supportsDarkText();
+            if (darkText != mUsingDarkText) {
+                mUsingDarkText = darkText;
+                setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+                        : R.style.RecentsTheme_Wallpaper);
+                mRecentsView.reevaluateStyles();
+            }
+            mRecentsView.setScrimColors(colors, true /* animated */);
+        }
+    }
+
+    @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
 
@@ -418,8 +457,7 @@
         loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
         loader.loadTasks(this, loadPlan, loadOpts);
         TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
-        mRecentsView.updateStack(stack, true /* setStackViewTasks */);
+        mRecentsView.onReload(stack, mIsVisible);
 
         // Update the nav bar scrim, but defer the animation until the enter-window event
         boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
@@ -465,6 +503,11 @@
     public void onEnterAnimationComplete() {
         super.onEnterAnimationComplete();
         EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+
+        // Workaround for b/64694148: The animation started callback is not made (see
+        // RecentsImpl.getThumbnailTransitionActivityOptions) so reset the transition-waiting state
+        // once the enter animation has completed.
+        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
     }
 
     @Override
@@ -483,10 +526,10 @@
         Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
         int numStackTasks = mRecentsView.getStack().getStackTaskCount();
         EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
-                mLastDeviceOrientation != newDeviceConfiguration.orientation,
-                mLastDisplayDensity != newDeviceConfiguration.densityDpi, numStackTasks > 0));
-        mLastDeviceOrientation = newDeviceConfiguration.orientation;
-        mLastDisplayDensity = newDeviceConfiguration.densityDpi;
+                mLastConfig.orientation != newDeviceConfiguration.orientation,
+                mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0));
+
+        mLastConfig.updateFrom(newDeviceConfiguration);
     }
 
     @Override
@@ -750,6 +793,10 @@
         ssp.removeTask(event.task.key.id);
     }
 
+    public final void onBusEvent(TaskViewDismissedEvent event) {
+        mRecentsView.updateScrimOpacity();
+    }
+
     public final void onBusEvent(AllTaskViewsDismissedEvent event) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.hasDockedTask()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 42e8921..86e93fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -24,12 +24,11 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityOptions;
+import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -208,6 +207,20 @@
     protected static RecentsTaskLoadPlan sInstanceLoadPlan;
     // Stores the last pinned task time
     protected static long sLastPipTime = -1;
+    // Stores whether we are waiting for a transition to/from recents to start. During this time,
+    // we disallow the user from manually toggling recents until the transition has started.
+    private static boolean mWaitingForTransitionStart = false;
+    // Stores whether or not the user toggled while we were waiting for a transition to/from
+    // recents. In this case, we defer the toggle state until then and apply it immediately after.
+    private static boolean mToggleFollowingTransitionStart = true;
+
+    private ActivityOptions.OnAnimationStartedListener mResetToggleFlagListener =
+            new OnAnimationStartedListener() {
+                @Override
+                public void onAnimationStarted() {
+                    setWaitingForTransitionStart(false);
+                }
+            };
 
     protected Context mContext;
     protected Handler mHandler;
@@ -365,6 +378,11 @@
             return;
         }
 
+        if (mWaitingForTransitionStart) {
+            mToggleFollowingTransitionStart = true;
+            return;
+        }
+
         mDraggingInRecents = false;
         mLaunchedWhileDocking = false;
         mTriggeredFromAltTab = false;
@@ -638,6 +656,18 @@
         }
     }
 
+    public void setWaitingForTransitionStart(boolean waitingForTransitionStart) {
+        if (mWaitingForTransitionStart == waitingForTransitionStart) {
+            return;
+        }
+
+        mWaitingForTransitionStart = waitingForTransitionStart;
+        if (!waitingForTransitionStart && mToggleFollowingTransitionStart) {
+            toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET);
+        }
+        mToggleFollowingTransitionStart = false;
+    }
+
     /**
      * Returns the preloaded load plan and invalidates it.
      */
@@ -865,8 +895,9 @@
             }
             AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
             specs.toArray(specsArray);
+
             return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    specsArray, mHandler, null, this), null);
+                    specsArray, mHandler, mResetToggleFlagListener, this), null);
         } else {
             // Update the destination rect
             Task toTask = new Task();
@@ -884,8 +915,10 @@
                         return Lists.newArrayList(new AppTransitionAnimationSpec(
                                 toTask.key.id, thumbnail, rect));
                     });
+
             return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
-                    mHandler, future.getFuture(), null, false /* scaleUp */), future);
+                    mHandler, future.getFuture(), mResetToggleFlagListener, false /* scaleUp */),
+                    future);
         }
     }
 
@@ -919,11 +952,11 @@
     private GraphicBuffer drawThumbnailTransitionBitmap(Task toTask,
             TaskViewTransform toTransform) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (toTransform != null && toTask.key != null) {
+        int width = (int) toTransform.rect.width();
+        int height = (int) toTransform.rect.height();
+        if (toTransform != null && toTask.key != null && width > 0 && height > 0) {
             synchronized (mHeaderBarLock) {
                 boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
-                int width = (int) toTransform.rect.width();
-                int height = (int) toTransform.rect.height();
                 mHeaderBar.onTaskViewSizeChanged(width, height);
                 if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
                     return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
@@ -991,6 +1024,10 @@
         launchState.launchedToTaskId = runningTaskId;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
 
+        // Disable toggling of recents between starting the activity and it is visible and the app
+        // has started its transition into recents.
+        setWaitingForTransitionStart(useThumbnailTransition);
+
         // Preload the icon (this will be a null-op if we have preloaded the icon already in
         // preloadRecents())
         preloadIcon(runningTaskId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index 3921a20..1285626 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -29,6 +29,7 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.ForegroundThread;
 
@@ -105,4 +106,10 @@
     public void sendLaunchRecentsEvent() throws RemoteException {
         EventBus.getDefault().post(new RecentsActivityStartingEvent());
     }
+
+    @Override
+    public void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+        EventBus.getDefault().post(new SetWaitingForTransitionStartEvent(
+                waitingForTransitionStart));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 521157d..d74970f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -43,14 +43,14 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.util.leak.RotationUtils;
 
 import java.util.ArrayList;
 
-public class ScreenPinningRequest implements View.OnClickListener {
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
+import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
 
-    private static final int ROTATION_NONE = 0;
-    private static final int ROTATION_LANDSCAPE = 1;
-    private static final int ROTATION_SEASCAPE = 2;
+public class ScreenPinningRequest implements View.OnClickListener {
 
     private final Context mContext;
 
@@ -160,7 +160,7 @@
             DisplayMetrics metrics = new DisplayMetrics();
             mWindowManager.getDefaultDisplay().getMetrics(metrics);
             float density = metrics.density;
-            int rotation = getRotation(mContext);
+            int rotation = RotationUtils.getRotation(mContext);
 
             inflateView(rotation);
             int bgColor = mContext.getColor(
@@ -202,19 +202,6 @@
             mContext.registerReceiver(mReceiver, filter);
         }
 
-        private int getRotation(Context context) {
-            Configuration config = mContext.getResources().getConfiguration();
-            int rot = context.getDisplay().getRotation();
-            if (config.smallestScreenWidthDp < 600) {
-                if (rot == Surface.ROTATION_90) {
-                    return ROTATION_LANDSCAPE;
-                } else if (rot == Surface.ROTATION_270) {
-                    return ROTATION_SEASCAPE;
-                }
-            }
-            return ROTATION_NONE;
-        }
-
         private void inflateView(int rotation) {
             // We only want this landscape orientation on <600dp, so rather than handle
             // resource overlay for -land and -sw600dp-land, just inflate this
@@ -287,14 +274,14 @@
 
         protected void onConfigurationChanged() {
             removeAllViews();
-            inflateView(getRotation(mContext));
+            inflateView(RotationUtils.getRotation(mContext));
         }
 
         private final Runnable mUpdateLayoutRunnable = new Runnable() {
             @Override
             public void run() {
                 if (mLayout != null && mLayout.getParent() != null) {
-                    mLayout.setLayoutParams(getRequestLayoutParams(getRotation(mContext)));
+                    mLayout.setLayoutParams(getRequestLayoutParams(RotationUtils.getRotation(mContext)));
                 }
             }
         };
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
new file mode 100644
index 0000000..d9cf5fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
@@ -0,0 +1,31 @@
+/*
+ * 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.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when we are setting/resetting the flag to wait for the transition to start.
+ */
+public class SetWaitingForTransitionStartEvent extends EventBus.Event {
+
+    public final boolean waitingForTransitionStart;
+
+    public SetWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+        this.waitingForTransitionStart = waitingForTransitionStart;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 21dfe8c..67685b8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -54,6 +54,7 @@
 import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
@@ -117,31 +118,58 @@
             final Rect windowRect = Recents.getSystemServices().getWindowRect();
             transitionFuture = getAppTransitionFuture(
                     () -> composeAnimationSpecs(task, stackView, destinationStack, windowRect));
-            animStartedListener = () -> {
-                // If we are launching into another task, cancel the previous task's
-                // window transition
-                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                stackView.cancelAllTaskViewAnimations();
+            animStartedListener = new OnAnimationStartedListener() {
+                private boolean mHandled;
 
-                if (screenPinningRequested) {
-                    // Request screen pinning after the animation runs
-                    mStartScreenPinningRunnable.taskId = task.key.id;
-                    mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+                @Override
+                public void onAnimationStarted() {
+                    if (mHandled) {
+                        return;
+                    }
+                    mHandled = true;
+
+                    // If we are launching into another task, cancel the previous task's
+                    // window transition
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
+
+                    if (screenPinningRequested) {
+                        // Request screen pinning after the animation runs
+                        mStartScreenPinningRunnable.taskId = task.key.id;
+                        mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+                    }
+
+                    // Reset the state where we are waiting for the transition to start
+                    EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
                 }
             };
         } else {
             // This is only the case if the task is not on screen (scrolled offscreen for example)
             transitionFuture = null;
-            animStartedListener = () -> {
-                // If we are launching into another task, cancel the previous task's
-                // window transition
-                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                stackView.cancelAllTaskViewAnimations();
+            animStartedListener = new OnAnimationStartedListener() {
+                private boolean mHandled;
+
+                @Override
+                public void onAnimationStarted() {
+                    if (mHandled) {
+                        return;
+                    }
+                    mHandled = true;
+
+                    // If we are launching into another task, cancel the previous task's
+                    // window transition
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                    stackView.cancelAllTaskViewAnimations();
+
+                    // Reset the state where we are waiting for the transition to start
+                    EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
+                }
             };
         }
 
+        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(true));
         final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
                 mHandler, transitionFuture != null ? transitionFuture.future : null,
                 animStartedListener, true /* scaleUp */);
@@ -400,8 +428,8 @@
             view.draw(c);
         }
         node.end(c);
-        return ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight)
-                .createGraphicBufferHandle();
+        Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight);
+        return hwBitmap.createGraphicBufferHandle();
     }
 
     /**
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 a0ad782..8e09481 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -22,13 +22,15 @@
 import android.animation.ObjectAnimator;
 import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -39,8 +41,11 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -75,6 +80,7 @@
 import com.android.systemui.recents.views.RecentsTransitionHelper.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.phone.ScrimController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -89,15 +95,18 @@
     private static final String TAG = "RecentsView";
 
     private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
-    private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
-    private static final float GRID_LAYOUT_SCRIM_ALPHA = 0.45f;
 
     private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
     private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
 
+    private static final int BUSY_RECENTS_TASK_COUNT = 3;
+
     private TaskStackView mTaskStackView;
     private TextView mStackActionButton;
     private TextView mEmptyView;
+    private final float mStackButtonShadowRadius;
+    private final PointF mStackButtonShadowDistance;
+    private final int mStackButtonShadowColor;
 
     private boolean mAwaitingFirstLayout = true;
     private boolean mLastTaskLaunchedWasFreeform;
@@ -106,8 +115,8 @@
     Rect mSystemInsets = new Rect();
     private int mDividerSize;
 
-    private final float mScrimAlpha;
-    private final Drawable mBackgroundScrim;
+    private float mBusynessFactor;
+    private GradientDrawable mBackgroundScrim;
     private Animator mBackgroundScrimAnimator;
 
     private RecentsTransitionHelper mTransitionHelper;
@@ -136,33 +145,72 @@
         mDividerSize = ssp.getDockedDividerSize(context);
         mTouchHandler = new RecentsViewTouchHandler(this);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
-        mScrimAlpha = Recents.getConfiguration().isGridEnabled
-                ? GRID_LAYOUT_SCRIM_ALPHA : DEFAULT_SCRIM_ALPHA;
-        mBackgroundScrim = new ColorDrawable(
-                Color.argb((int) (mScrimAlpha * 255), 0, 0, 0)).mutate();
+        mBackgroundScrim = new GradientDrawable(context);
+        mBackgroundScrim.setCallback(this);
+
+        boolean usingDarkText = Color.luminance(
+                Utils.getColorAttr(mContext, R.attr.wallpaperTextColor)) < 0.5f;
 
         LayoutInflater inflater = LayoutInflater.from(context);
-        if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
-                    this, false);
-            mStackActionButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    EventBus.getDefault().send(new DismissAllTaskViewsEvent());
-                }
-            });
-            addView(mStackActionButton);
-        }
         mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
         addView(mEmptyView);
+
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            if (mStackActionButton != null) {
+                removeView(mStackActionButton);
+            }
+            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
+                    this, false);
+            mStackActionButton.setOnClickListener(
+                    v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent()));
+
+            mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
+            mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
+                    mStackActionButton.getShadowDy());
+            mStackButtonShadowColor = mStackActionButton.getShadowColor();
+            addView(mStackActionButton);
+        }
+
+        reevaluateStyles();
+    }
+
+    public void reevaluateStyles() {
+        int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor);
+        boolean usingDarkText = Color.luminance(textColor) < 0.5f;
+
+        mEmptyView.setTextColor(textColor);
+        mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{
+                {android.R.attr.state_enabled}}, new int[]{textColor}));
+
+        if (mStackActionButton != null) {
+            mStackActionButton.setTextColor(textColor);
+            // Enable/disable shadow if text color is already dark.
+            if (usingDarkText) {
+                mStackActionButton.setShadowLayer(0, 0, 0, 0);
+            } else {
+                mStackActionButton.setShadowLayer(mStackButtonShadowRadius,
+                        mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
+                        mStackButtonShadowColor);
+            }
+        }
+
+        // Let's also require dark status and nav bars if the text is dark
+        int systemBarsStyle = usingDarkText ? View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
+                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0;
+
+        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+                systemBarsStyle);
     }
 
     /**
      * Called from RecentsActivity when it is relaunched.
      */
-    public void onReload(boolean isResumingFromVisible, boolean isTaskStackEmpty) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
+    public void onReload(TaskStack stack, boolean isResumingFromVisible) {
+        final RecentsConfiguration config = Recents.getConfiguration();
+        final RecentsActivityLaunchState launchState = config.getLaunchState();
+        final boolean isTaskStackEmpty = stack.getTaskCount() == 0;
 
         if (mTaskStackView == null) {
             isResumingFromVisible = false;
@@ -177,17 +225,19 @@
 
         // Update the stack
         mTaskStackView.onReload(isResumingFromVisible);
+        updateStack(stack, true /* setStackViewTasks */);
+        updateBusyness();
 
         if (isResumingFromVisible) {
             // If we are already visible, then restore the background scrim
-            animateBackgroundScrim(1f, DEFAULT_UPDATE_SCRIM_DURATION);
+            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
         } else {
             // If we are already occluded by the app, then set the final background scrim alpha now.
             // Otherwise, defer until the enter animation completes to animate the scrim alpha with
             // the tasks for the home animation.
             if (launchState.launchedViaDockGesture || launchState.launchedFromApp
                     || isTaskStackEmpty) {
-                mBackgroundScrim.setAlpha(255);
+                mBackgroundScrim.setAlpha((int) (getOpaqueScrimAlpha() * 255));
             } else {
                 mBackgroundScrim.setAlpha(0);
             }
@@ -211,13 +261,40 @@
     }
 
     /**
+     * Animates the scrim opacity based on how many tasks are visible.
+     * Called from {@link RecentsActivity} when tasks are dismissed.
+     */
+    public void updateScrimOpacity() {
+        if (updateBusyness()) {
+            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
+        }
+    }
+
+    /**
+     * Updates the busyness factor.
+     *
+     * @return True if it changed.
+     */
+    private boolean updateBusyness() {
+        final int taskCount = mTaskStackView.getStack().getStackTaskCount();
+        final float busyness = Math.min(taskCount, BUSY_RECENTS_TASK_COUNT)
+                / (float) BUSY_RECENTS_TASK_COUNT;
+        if (mBusynessFactor == busyness) {
+            return false;
+        } else {
+            mBusynessFactor = busyness;
+            return true;
+        }
+    }
+
+    /**
      * Returns the current TaskStack.
      */
     public TaskStack getStack() {
         return mTaskStackView.getStack();
     }
 
-    /*
+    /**
      * Returns the window background scrim.
      */
     public Drawable getBackgroundScrim() {
@@ -313,6 +390,16 @@
         }
     }
 
+    /**
+     * Set the color of the scrim.
+     *
+     * @param scrimColors Colors to use.
+     * @param animated Interpolate colors if true.
+     */
+    public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) {
+        mBackgroundScrim.setColors(scrimColors, animated);
+    }
+
     @Override
     protected void onAttachedToWindow() {
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -378,6 +465,11 @@
             mEmptyView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
         }
 
+        // Needs to know the screen size since the gradient never scales up or down
+        // even when bounds change.
+        mBackgroundScrim.setScreenSize(right - left, bottom - top);
+        mBackgroundScrim.setBounds(left, top, right, bottom);
+
         if (RecentsDebugFlags.Static.EnableStackActionButton) {
             // Layout the stack action button such that its drawable is start-aligned with the
             // stack, vertically centered in the available space above the stack
@@ -606,7 +698,7 @@
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
                 && getStack().getTaskCount() > 0) {
-            animateBackgroundScrim(1f,
+            animateBackgroundScrim(getOpaqueScrimAlpha(),
                     TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
         }
     }
@@ -766,13 +858,25 @@
     }
 
     /**
+     * Scrim alpha based on how busy recents is:
+     * Scrim will be {@link ScrimController#GRADIENT_SCRIM_ALPHA} when the stack is empty,
+     * and {@link ScrimController#GRADIENT_SCRIM_ALPHA_BUSY} when it's full.
+     *
+     * @return Alpha from 0 to 1.
+     */
+    private float getOpaqueScrimAlpha() {
+        return MathUtils.map(0, 1, ScrimController.GRADIENT_SCRIM_ALPHA,
+                ScrimController.GRADIENT_SCRIM_ALPHA_BUSY, mBusynessFactor);
+    }
+
+    /**
      * Animates the background scrim to the given {@param alpha}.
      */
     private void animateBackgroundScrim(float alpha, int duration) {
         Utilities.cancelAnimationWithoutCallbacks(mBackgroundScrimAnimator);
         // Calculate the absolute alpha to animate from
-        int fromAlpha = (int) ((mBackgroundScrim.getAlpha() / (mScrimAlpha * 255)) * 255);
-        int toAlpha = (int) (alpha * 255);
+        final int fromAlpha = mBackgroundScrim.getAlpha();
+        final int toAlpha = (int) (alpha * 255);
         mBackgroundScrimAnimator = ObjectAnimator.ofInt(mBackgroundScrim, Utilities.DRAWABLE_ALPHA,
                 fromAlpha, toAlpha);
         mBackgroundScrimAnimator.setDuration(duration);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 8135034..9c14d48 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -23,6 +23,7 @@
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.MutableFloat;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -481,6 +482,13 @@
         int height = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
         mTaskRect.set(mStackRect.left, mStackRect.top, mStackRect.right, mStackRect.top + height);
 
+        if (mTaskRect.width() <= 0 || mTaskRect.height() <= 0) {
+            // Logging for b/36654830
+            Log.e(TAG, "Invalid task rect: taskRect=" + mTaskRect + " stackRect=" + mStackRect
+                    + " displayRect=" + displayRect + " windowRect=" + windowRect
+                    + " taskStackBounds=" + taskStackBounds);
+        }
+
         // Short circuit here if the stack rects haven't changed so we don't do all the work below
         if (!lastStackRect.equals(mStackRect)) {
             // Reinitialize the focused and unfocused curves
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 2d47c7b..a2409d1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -50,6 +50,7 @@
 import android.os.UserHandle;
 import android.provider.MediaStore;
 import android.util.DisplayMetrics;
+import android.util.Slog;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -100,6 +101,7 @@
  * An AsyncTask that saves an image to the media store in the background.
  */
 class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
+    private static final String TAG = "SaveImageInBackgroundTask";
 
     private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
     private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
@@ -303,6 +305,7 @@
         } catch (Exception e) {
             // IOException/UnsupportedOperationException may be thrown if external storage is not
             // mounted
+            Slog.e(TAG, "unable to save screenshot", e);
             mParams.clearImage();
             mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
         }
@@ -379,8 +382,6 @@
  * An AsyncTask that deletes an image from the media store in the background.
  */
 class DeleteImageInBackgroundTask extends AsyncTask<Uri, Void, Void> {
-    private static final String TAG = "DeleteImageInBackgroundTask";
-
     private Context mContext;
 
     DeleteImageInBackgroundTask(Context context) {
@@ -578,7 +579,8 @@
         if (requiresRotation) {
             // Rotate the screenshot to the current orientation
             Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,
-                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
+                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888,
+                    mScreenBitmap.hasAlpha(), mScreenBitmap.getColorSpace());
             Canvas c = new Canvas(ss);
             c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
             c.rotate(degrees);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 0232911..da0a435 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -82,6 +82,7 @@
     private void addDivider(Configuration configuration) {
         mView = (DividerView)
                 LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
+        mView.injectDependencies(mWindowManager, mDividerState);
         mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
         mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
         final int size = mContext.getResources().getDimensionPixelSize(
@@ -90,7 +91,6 @@
         final int width = landscape ? size : MATCH_PARENT;
         final int height = landscape ? MATCH_PARENT : size;
         mWindowManager.add(mView, width, height);
-        mView.injectDependencies(mWindowManager, mDividerState);
     }
 
     private void removeDivider() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
index 353a974..3a5c61e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
@@ -22,4 +22,5 @@
 public class DividerState {
     public boolean animateAfterRecentsDrawn;
     public boolean growAfterRecentsDrawn;
+    public float mRatioPositionBeforeMinimized;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 7691652..45835d5 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -372,6 +372,17 @@
     public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState) {
         mWindowManager = windowManager;
         mState = dividerState;
+
+        // Set the previous position ratio before minimized state after attaching this divider
+        if (mStableInsets.isEmpty()) {
+            SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+        }
+        int position = (int) (mState.mRatioPositionBeforeMinimized *
+                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
+        mSnapAlgorithm = null;
+        initializeSnapAlgorithm();
+        mDividerPositionBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position)
+                .position;
     }
 
     public WindowManagerProxy getWindowManagerProxy() {
@@ -727,19 +738,12 @@
             mHandle.setAlpha(minimized ? 0f : 1f);
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
-            if (mStableInsets.isEmpty()) {
-                SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
-            }
             mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
             initializeSnapAlgorithm();
             if (mIsInMinimizeInteraction != minimized) {
                 if (minimized) {
                     mIsInMinimizeInteraction = true;
-                    mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
-                            isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
-                            mDividerSize);
-
                     int position = mMinimizedSnapAlgorithm.getMiddleTarget().position;
                     resizeStack(position, position, mMinimizedSnapAlgorithm.getMiddleTarget());
                 } else {
@@ -784,7 +788,7 @@
             mIsInMinimizeInteraction = true;
             if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())
                     && (mDividerPositionBeforeMinimized <= 0 || !mAdjustedForIme)) {
-                mDividerPositionBeforeMinimized = getCurrentPosition();
+                savePositionBeforeMinimized();
             }
             mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
@@ -844,10 +848,16 @@
         // Only get new position if home stack is resizable, ime is open and not minimized
         // (including the animation)
         if (mHomeStackResizable && adjustedForIme && !mIsInMinimizeInteraction) {
-            mDividerPositionBeforeMinimized = getCurrentPosition();
+            savePositionBeforeMinimized();
         }
     }
 
+    private void savePositionBeforeMinimized() {
+        mDividerPositionBeforeMinimized = getCurrentPosition();
+        mState.mRatioPositionBeforeMinimized = (float) mDividerPositionBeforeMinimized /
+                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth);
+    }
+
     private void resetBackground() {
         mBackground.setPivotX(mBackground.getWidth() / 2);
         mBackground.setPivotY(mBackground.getHeight() / 2);
@@ -1210,14 +1220,6 @@
                 mDockSide, mDividerSize);
         mEntranceAnimationRunning = true;
 
-        // Insets might not have been fetched yet, so fetch manually if needed.
-        if (mStableInsets.isEmpty()) {
-            SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
-            mSnapAlgorithm = null;
-            mMinimizedSnapAlgorithm = null;
-            initializeSnapAlgorithm();
-        }
-
         resizeStack(position, mSnapAlgorithm.getMiddleTarget().position,
                 mSnapAlgorithm.getMiddleTarget());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index eec818b..29b720c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -943,6 +943,10 @@
         }
     }
 
+    public boolean isDrawingAppearAnimation() {
+        return mDrawingAppearAnimation;
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
         if (mDrawingAppearAnimation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index ae665c7..ba92c45 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 = true;
 
     // 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/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index bf89b01..2f4cd0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -77,8 +77,9 @@
     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
-    private static final int MSG_HANDLE_SYSNAV_KEY             = 33 << MSG_SHIFT;
+    private static final int MSG_HANDLE_SYSTEM_KEY             = 33 << MSG_SHIFT;
     private static final int MSG_SHOW_GLOBAL_ACTIONS           = 34 << MSG_SHIFT;
+    private static final int MSG_SHOW_SHUTDOWN_UI              = 35 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -134,8 +135,9 @@
         default void remQsTile(ComponentName tile) { }
         default void clickTile(ComponentName tile) { }
 
-        default void handleSystemNavigationKey(int arg1) { }
+        default void handleSystemKey(int arg1) { }
         default void handleShowGlobalActionsMenu() { }
+        default void handleShowShutdownUi(boolean isReboot, String reason) { }
     }
 
     @VisibleForTesting
@@ -415,9 +417,9 @@
     }
 
     @Override
-    public void handleSystemNavigationKey(int key) {
+    public void handleSystemKey(int key) {
         synchronized (mLock) {
-            mHandler.obtainMessage(MSG_HANDLE_SYSNAV_KEY, key, 0).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_SYSTEM_KEY, key, 0).sendToTarget();
         }
     }
 
@@ -429,6 +431,15 @@
         }
     }
 
+    @Override
+    public void showShutdownUi(boolean isReboot, String reason) {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_SHOW_SHUTDOWN_UI);
+            mHandler.obtainMessage(MSG_SHOW_SHUTDOWN_UI, isReboot ? 1 : 0, 0, reason)
+                    .sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         private H(Looper l) {
             super(l);
@@ -600,9 +611,9 @@
                         mCallbacks.get(i).toggleSplitScreen();
                     }
                     break;
-                case MSG_HANDLE_SYSNAV_KEY:
+                case MSG_HANDLE_SYSTEM_KEY:
                     for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).handleSystemNavigationKey(msg.arg1);
+                        mCallbacks.get(i).handleSystemKey(msg.arg1);
                     }
                     break;
                 case MSG_SHOW_GLOBAL_ACTIONS:
@@ -610,6 +621,11 @@
                         mCallbacks.get(i).handleShowGlobalActionsMenu();
                     }
                     break;
+                case MSG_SHOW_SHUTDOWN_UI:
+                    for (int i = 0; i < mCallbacks.size(); i++) {
+                        mCallbacks.get(i).handleShowShutdownUi(msg.arg1 != 0, (String) msg.obj);
+                    }
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 5436664..d7c6443 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
@@ -46,6 +47,10 @@
         mDismissButton = (DismissViewButton) findContentView();
     }
 
+    public void setTextColor(@ColorInt int color) {
+        mDismissButton.setTextColor(color);
+    }
+
     public void setOnButtonClickListener(OnClickListener listener) {
         mContent.setOnClickListener(listener);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 92b0890..58adde2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.util.AttributeSet;
@@ -45,6 +46,10 @@
         return findViewById(R.id.no_notifications);
     }
 
+    public void setTextColor(@ColorInt int color) {
+        mEmptyText.setTextColor(color);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 1c1be98..22c0b736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -63,6 +63,8 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.statusbar.NotificationGuts.GutsContent;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.HybridNotificationView;
 import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -162,6 +164,7 @@
     private boolean mIsSystemChildExpanded;
     private boolean mIsPinned;
     private FalsingManager mFalsingManager;
+    private AboveShelfChangedListener mAboveShelfChangedListener;
     private HeadsUpManager mHeadsUpManager;
 
     private boolean mJustClicked;
@@ -171,6 +174,18 @@
     private OnExpandClickListener mOnExpandClickListener;
     private boolean mGroupExpansionChanging;
 
+    /**
+     * Whether or not a notification that is not part of a group of notifications can be manually
+     * expanded by the user.
+     */
+    private boolean mEnableNonGroupedNotificationExpand;
+
+    /**
+     * Whether or not to update the background of the header of the notification when its expanded.
+     * If {@code true}, the header background will disappear when expanded.
+     */
+    private boolean mShowGroupBackgroundWhenExpanded;
+
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -183,7 +198,7 @@
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
                 onExpansionChanged(true /* userAction */, wasExpanded);
-            } else {
+            } else if (mEnableNonGroupedNotificationExpand) {
                 if (v.isAccessibilityFocused()) {
                     mPrivateLayout.setFocusOnVisibilityChange();
                 }
@@ -337,7 +352,7 @@
         mShowingPublicInitialized = false;
         updateNotificationColor();
         if (mMenuRow != null) {
-            mMenuRow.onNotificationUpdated();
+            mMenuRow.onNotificationUpdated(mStatusBarNotification);
         }
         if (mIsSummaryWithChildren) {
             mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
@@ -376,6 +391,10 @@
         expandedIcon.setStaticDrawableColor(color);
     }
 
+    public void setAboveShelfChangedListener(AboveShelfChangedListener aboveShelfChangedListener) {
+        mAboveShelfChangedListener = aboveShelfChangedListener;
+    }
+
     @Override
     public boolean isDimmable() {
         if (!getShowingLayout().isDimmable()) {
@@ -430,6 +449,7 @@
     }
 
     public void setHeadsUp(boolean isHeadsUp) {
+        boolean wasAboveShelf = isAboveShelf();
         int intrinsicBefore = getIntrinsicHeight();
         mIsHeadsUp = isHeadsUp;
         mPrivateLayout.setHeadsUp(isHeadsUp);
@@ -442,6 +462,8 @@
         }
         if (isHeadsUp) {
             setAboveShelf(true);
+        } else if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
         }
     }
 
@@ -622,6 +644,7 @@
      */
     public void setPinned(boolean pinned) {
         int intrinsicHeight = getIntrinsicHeight();
+        boolean wasAboveShelf = isAboveShelf();
         mIsPinned = pinned;
         if (intrinsicHeight != getIntrinsicHeight()) {
             notifyHeightChanged(false /* needsAnimation */);
@@ -633,6 +656,9 @@
             setUserExpanded(true);
         }
         setChronometerRunning(mLastChronometerRunning);
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     public boolean isPinned() {
@@ -730,6 +756,19 @@
         return getShowingLayout().getVisibleNotificationHeader();
     }
 
+
+    /**
+     * @return the contracted notification header. This can be different from
+     * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only
+     * returns the contracted version.
+     */
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mIsSummaryWithChildren) {
+            return mChildrenContainer.getHeaderView();
+        }
+        return mPrivateLayout.getContractedNotificationHeader();
+    }
+
     public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
         mOnExpandClickListener = onExpandClickListener;
     }
@@ -805,7 +844,7 @@
 
     public NotificationMenuRowPlugin createMenu() {
         if (mMenuRow.getMenuView() == null) {
-            mMenuRow.createMenu(this);
+            mMenuRow.createMenu(this, mStatusBarNotification);
             mMenuRow.setAppName(mAppName);
             FrameLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
                     LayoutParams.MATCH_PARENT);
@@ -818,7 +857,9 @@
         return mMenuRow;
     }
 
+    @Override
     public void onDensityOrFontScaleChanged() {
+        super.onDensityOrFontScaleChanged();
         initDimens();
         // Let's update our childrencontainer. This is intentionally not guarded with
         // mIsSummaryWithChildren since we might have had children but not anymore.
@@ -838,7 +879,7 @@
         if (oldMenu != null) {
             int menuIndex = indexOfChild(oldMenu);
             removeView(oldMenu);
-            mMenuRow.createMenu(ExpandableNotificationRow.this);
+            mMenuRow.createMenu(ExpandableNotificationRow.this, mStatusBarNotification);
             mMenuRow.setAppName(mAppName);
             addView(mMenuRow.getMenuView(), menuIndex);
         }
@@ -979,8 +1020,12 @@
     }
 
     public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        boolean wasAboveShelf = isAboveShelf();
         mHeadsupDisappearRunning = headsUpAnimatingAway;
         mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     /**
@@ -1173,7 +1218,7 @@
     }
 
     public interface ExpansionLogger {
-        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
+        void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
@@ -1196,10 +1241,16 @@
         mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
         mMaxHeadsUpHeightIncreased = getFontScaledHeight(
                 R.dimen.notification_max_heads_up_height_increased);
-        mIncreasedPaddingBetweenElements = getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mIconTransformContentShiftNoIcon = getResources().getDimensionPixelSize(
+
+        Resources res = getResources();
+        mIncreasedPaddingBetweenElements = res.getDimensionPixelSize(
+                R.dimen.notification_divider_height_increased);
+        mIconTransformContentShiftNoIcon = res.getDimensionPixelSize(
                 R.dimen.notification_icon_transform_content_shift);
+        mEnableNonGroupedNotificationExpand =
+                res.getBoolean(R.bool.config_enableNonGroupedNotificationExpand);
+        mShowGroupBackgroundWhenExpanded =
+                res.getBoolean(R.bool.config_showGroupNotificationBgWhenExpanded);
     }
 
     /**
@@ -1252,30 +1303,39 @@
                 mChildrenContainer.setIsLowPriority(mIsLowPriority);
                 mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
                 mChildrenContainer.onNotificationUpdated();
-                mTranslateableViews.add(mChildrenContainer);
+
+                if (mShouldTranslateContents) {
+                    mTranslateableViews.add(mChildrenContainer);
+                }
             }
         });
 
-        // Add the views that we translate to reveal the menu
-        mTranslateableViews = new ArrayList<View>();
-        for (int i = 0; i < getChildCount(); i++) {
-            mTranslateableViews.add(getChildAt(i));
+        if (mShouldTranslateContents) {
+            // Add the views that we translate to reveal the menu
+            mTranslateableViews = new ArrayList<>();
+            for (int i = 0; i < getChildCount(); i++) {
+                mTranslateableViews.add(getChildAt(i));
+            }
+            // Remove views that don't translate
+            mTranslateableViews.remove(mChildrenContainerStub);
+            mTranslateableViews.remove(mGutsStub);
         }
-        // Remove views that don't translate
-        mTranslateableViews.remove(mChildrenContainerStub);
-        mTranslateableViews.remove(mGutsStub);
     }
 
     public void resetTranslation() {
         if (mTranslateAnim != null) {
             mTranslateAnim.cancel();
         }
-        if (mTranslateableViews != null) {
+
+        if (!mShouldTranslateContents) {
+            setTranslationX(0);
+        } else if (mTranslateableViews != null) {
             for (int i = 0; i < mTranslateableViews.size(); i++) {
                 mTranslateableViews.get(i).setTranslationX(0);
             }
+            invalidateOutline();
         }
-        invalidateOutline();
+
         mMenuRow.resetMenu();
     }
 
@@ -1295,13 +1355,17 @@
             // Don't translate if guts are showing.
             return;
         }
-        // Translate the group of views
-        for (int i = 0; i < mTranslateableViews.size(); i++) {
-            if (mTranslateableViews.get(i) != null) {
-                mTranslateableViews.get(i).setTranslationX(translationX);
+        if (!mShouldTranslateContents) {
+            setTranslationX(translationX);
+        } else if (mTranslateableViews != null) {
+            // Translate the group of views
+            for (int i = 0; i < mTranslateableViews.size(); i++) {
+                if (mTranslateableViews.get(i) != null) {
+                    mTranslateableViews.get(i).setTranslationX(translationX);
+                }
             }
+            invalidateOutline();
         }
-        invalidateOutline();
         if (mMenuRow.getMenuView() != null) {
             mMenuRow.onTranslationUpdate(translationX);
         }
@@ -1309,10 +1373,15 @@
 
     @Override
     public float getTranslation() {
+        if (!mShouldTranslateContents) {
+            return getTranslationX();
+        }
+
         if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
             // All of the views in the list should have same translation, just use first one.
             return mTranslateableViews.get(0).getTranslationX();
         }
+
         return 0;
     }
 
@@ -1402,7 +1471,7 @@
         if (mIsSummaryWithChildren && !mShowingPublic) {
             return !mChildrenExpanded;
         }
-        return mExpandable;
+        return mEnableNonGroupedNotificationExpand && mExpandable;
     }
 
     public void setExpandable(boolean expandable) {
@@ -1456,6 +1525,10 @@
         mHasUserChangedExpansion = true;
         mUserExpanded = userExpanded;
         onExpansionChanged(true /* userAction */, wasExpanded);
+        if (!wasExpanded && isExpanded()
+                && getActualHeight() != getIntrinsicHeight()) {
+            notifyHeightChanged(true /* needsAnimation */);
+        }
     }
 
     public void resetUserExpansion() {
@@ -1514,6 +1587,7 @@
      */
     public void setOnKeyguard(boolean onKeyguard) {
         if (onKeyguard != mOnKeyguard) {
+            boolean wasAboveShelf = isAboveShelf();
             final boolean wasExpanded = isExpanded();
             mOnKeyguard = onKeyguard;
             onExpansionChanged(false /* userAction */, wasExpanded);
@@ -1523,6 +1597,9 @@
                 }
                 notifyHeightChanged(false /* needsAnimation */);
             }
+            if (isAboveShelf() != wasAboveShelf) {
+                mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+            }
         }
     }
 
@@ -1896,6 +1973,9 @@
         if (mGuts != null) {
             mGuts.setActualHeight(height);
         }
+        if (mMenuRow.getMenuView() != null) {
+            mMenuRow.onHeightUpdate();
+        }
     }
 
     @Override
@@ -2001,7 +2081,8 @@
     public void updateBackgroundForGroupState() {
         if (mIsSummaryWithChildren) {
             // Only when the group has finished expanding do we hide its background.
-            mShowNoBackground = isGroupExpanded() && !isGroupExpansionChanging() && !isUserLocked();
+            mShowNoBackground = !mShowGroupBackgroundWhenExpanded && isGroupExpanded()
+                    && !isGroupExpansionChanging() && !isUserLocked();
             mChildrenContainer.updateHeaderForExpansion(mShowNoBackground);
             List<ExpandableNotificationRow> children = mChildrenContainer.getNotificationChildren();
             for (int i = 0; i < children.size(); i++) {
@@ -2010,10 +2091,10 @@
         } else if (isChildInGroup()) {
             final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
             // Only show a background if the group is expanded OR if it is expanding / collapsing
-            // and has a custom background color
+            // and has a custom background color.
             final boolean showBackground = isGroupExpanded()
                     || ((mNotificationParent.isGroupExpansionChanging()
-                            || mNotificationParent.isUserLocked()) && childColor != 0);
+                    || mNotificationParent.isUserLocked()) && childColor != 0);
             mShowNoBackground = !showBackground;
         } else {
             // Only children or parents ever need no background.
@@ -2066,8 +2147,12 @@
         float x = event.getX();
         float y = event.getY();
         NotificationHeaderView header = getVisibleNotificationHeader();
-        if (header != null) {
-            return header.isInTouchRect(x - getTranslation(), y);
+        if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
+            return true;
+        }
+        if ((!mIsSummaryWithChildren || mShowingPublic)
+                && getShowingLayout().disallowSingleClick(x, y)) {
+            return true;
         }
         return super.disallowSingleClick(event);
     }
@@ -2168,7 +2253,11 @@
     }
 
     public void setAboveShelf(boolean aboveShelf) {
+        boolean wasAboveShelf = isAboveShelf();
         mAboveShelf = aboveShelf;
+        if (isAboveShelf() != wasAboveShelf) {
+            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
+        }
     }
 
     public static class NotificationViewState extends ExpandableViewState {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 91abc87..2556890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -17,12 +17,14 @@
 package com.android.systemui.statusbar;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
+import com.android.systemui.R;
 
 /**
  * Like {@link ExpandableView}, but setting an outline for the height and clipping.
@@ -32,18 +34,26 @@
     private final Rect mOutlineRect = new Rect();
     private boolean mCustomOutline;
     private float mOutlineAlpha = -1f;
+    private float mOutlineRadius;
 
-    ViewOutlineProvider mProvider = new ViewOutlineProvider() {
+    /**
+     * {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
+     * it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
+     */
+    protected boolean mShouldTranslateContents;
+
+    private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
         @Override
         public void getOutline(View view, Outline outline) {
-            int translation = (int) getTranslation();
+            int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
             if (!mCustomOutline) {
-                outline.setRect(translation,
+                outline.setRoundRect(translation,
                         mClipTopAmount,
                         getWidth() + translation,
-                        Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount));
+                        Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount),
+                        mOutlineRadius);
             } else {
-                outline.setRect(mOutlineRect);
+                outline.setRoundRect(mOutlineRect, mOutlineRadius);
             }
             outline.setAlpha(mOutlineAlpha);
         }
@@ -52,6 +62,20 @@
     public ExpandableOutlineView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setOutlineProvider(mProvider);
+        initDimens();
+    }
+
+    private void initDimens() {
+        Resources res = getResources();
+        mShouldTranslateContents =
+                res.getBoolean(R.bool.config_translateNotificationContentsOnSwipe);
+        mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
+        setClipToOutline(res.getBoolean(R.bool.config_clipNotificationsToOutline));
+    }
+
+    public void onDensityOrFontScaleChanged() {
+        initDimens();
+        invalidateOutline();
     }
 
     @Override
@@ -108,8 +132,8 @@
     }
 
     /**
-     * @return whether the view currently needs an outline. This is usually false in case it doesn't
-     * have a background.
+     * @return Whether the view currently needs an outline. This is usually {@code false} in case
+     * it doesn't have a background.
      */
     protected boolean needsOutline() {
         if (isChildInGroup()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 6a1f470..efe5e0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -24,8 +24,8 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.ExpandableViewState;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackScrollState;
 
 import java.util.ArrayList;
@@ -355,7 +355,7 @@
         if (mClipToActualHeight) {
             int top = getClipTopAmount();
             mClipRect.set(0, top, getWidth(), Math.max(getActualHeight() + getExtraBottomPadding()
-                                - mClipBottomAmount, top));
+                    - mClipBottomAmount, top));
             setClipBounds(mClipRect);
         } else {
             setClipBounds(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index b15f090..e12b574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -23,6 +23,7 @@
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.CanvasProperty;
 import android.graphics.Color;
@@ -55,7 +56,7 @@
 
     private final int mMinBackgroundRadius;
     private final Paint mCirclePaint;
-    private final int mInverseColor;
+    private final int mDarkIconColor;
     private final int mNormalColor;
     private final ArgbEvaluator mColorInterpolator;
     private final FlingAnimationUtils mFlingAnimationUtils;
@@ -126,17 +127,21 @@
     public KeyguardAffordanceView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        TypedArray a = context.obtainStyledAttributes(attrs, android.R.styleable.ImageView);
+
         mCirclePaint = new Paint();
         mCirclePaint.setAntiAlias(true);
         mCircleColor = 0xffffffff;
         mCirclePaint.setColor(mCircleColor);
 
-        mNormalColor = 0xffffffff;
-        mInverseColor = 0xff000000;
+        mNormalColor = a.getColor(android.R.styleable.ImageView_tint, 0xffffffff);
+        mDarkIconColor = 0xff000000;
         mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_affordance_min_background_radius);
         mColorInterpolator = new ArgbEvaluator();
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
+
+        a.recycle();
     }
 
     public void setImageDrawable(@Nullable Drawable drawable, boolean tint) {
@@ -177,7 +182,7 @@
         Drawable drawable = getDrawable().mutate();
         float alpha = mCircleRadius / mMinBackgroundRadius;
         alpha = Math.min(1.0f, alpha);
-        int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mInverseColor);
+        int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mDarkIconColor);
         drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 1691e135..74737c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -66,21 +65,22 @@
     private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
 
     private final Context mContext;
-    private final ViewGroup mIndicationArea;
-    private final KeyguardIndicationTextView mTextView;
-    private final KeyguardIndicationTextView mDisclosure;
+    private ViewGroup mIndicationArea;
+    private KeyguardIndicationTextView mTextView;
+    private KeyguardIndicationTextView mDisclosure;
     private final UserManager mUserManager;
     private final IBatteryStats mBatteryInfo;
     private final SettableWakeLock mWakeLock;
 
     private final int mSlowThreshold;
     private final int mFastThreshold;
-    private final LockIcon mLockIcon;
+    private LockIcon mLockIcon;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     private String mRestingIndication;
     private String mTransientIndication;
     private int mTransientTextColor;
+    private int mInitialTextColor;
     private boolean mVisible;
 
     private boolean mPowerPluggedIn;
@@ -89,7 +89,7 @@
     private int mChargingWattage;
     private String mMessageToShowOnScreenOn;
 
-    private KeyguardUpdateMonitorCallback mUpdateMonitor;
+    private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
     private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
@@ -115,6 +115,7 @@
         mIndicationArea = indicationArea;
         mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
                 R.id.keyguard_indication_text);
+        mInitialTextColor = mTextView != null ? mTextView.getCurrentTextColor() : Color.WHITE;
         mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mLockIcon = lockIcon;
@@ -153,10 +154,10 @@
      * same instance.
      */
     protected KeyguardUpdateMonitorCallback getKeyguardCallback() {
-        if (mUpdateMonitor == null) {
-            mUpdateMonitor = new BaseKeyguardCallback();
+        if (mUpdateMonitorCallback == null) {
+            mUpdateMonitorCallback = new BaseKeyguardCallback();
         }
-        return mUpdateMonitor;
+        return mUpdateMonitorCallback;
     }
 
     private void updateDisclosure() {
@@ -203,6 +204,24 @@
     }
 
     /**
+     * Returns the indication text indicating that trust has been granted.
+     *
+     * @return {@code null} or an empty string if a trust indication text should not be shown.
+     */
+    protected String getTrustGrantedIndication() {
+        return null;
+    }
+
+    /**
+     * Returns the indication text indicating that trust is currently being managed.
+     *
+     * @return {@code null} or an empty string if a trust managed text should not be shown.
+     */
+    protected String getTrustManagedIndication() {
+        return null;
+    }
+
+    /**
      * Hides transient indication in {@param delayMs}.
      */
     public void hideTransientIndicationDelayed(long delayMs) {
@@ -221,7 +240,7 @@
      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
      */
     public void showTransientIndication(String transientIndication) {
-        showTransientIndication(transientIndication, Color.WHITE);
+        showTransientIndication(transientIndication, mInitialTextColor);
     }
 
     /**
@@ -250,45 +269,56 @@
         }
     }
 
-    private void updateIndication() {
+    protected final void updateIndication() {
         if (TextUtils.isEmpty(mTransientIndication)) {
             mWakeLock.setAcquired(false);
         }
 
         if (mVisible) {
-            // Walk down a precedence-ordered list of what should indication
+            // Walk down a precedence-ordered list of what indication
             // should be shown based on user or device state
             if (mDozing) {
                 // If we're dozing, never show a persistent indication.
                 if (!TextUtils.isEmpty(mTransientIndication)) {
+                    // When dozing we ignore any text color and use white instead, because
+                    // colors can be hard to read in low brightness.
+                    mTextView.setTextColor(Color.WHITE);
                     mTextView.switchIndication(mTransientIndication);
-                    mTextView.setTextColor(mTransientTextColor);
-
                 } else {
                     mTextView.switchIndication(null);
                 }
                 return;
             }
 
-            if (!mUserManager.isUserUnlocked(KeyguardUpdateMonitor.getCurrentUser())) {
+            KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+            int userId = KeyguardUpdateMonitor.getCurrentUser();
+            String trustGrantedIndication = getTrustGrantedIndication();
+            String trustManagedIndication = getTrustManagedIndication();
+            if (!mUserManager.isUserUnlocked(userId)) {
                 mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
-                mTextView.setTextColor(Color.WHITE);
-
+                mTextView.setTextColor(mInitialTextColor);
             } else if (!TextUtils.isEmpty(mTransientIndication)) {
                 mTextView.switchIndication(mTransientIndication);
                 mTextView.setTextColor(mTransientTextColor);
-
+            } else if (!TextUtils.isEmpty(trustGrantedIndication)
+                    && updateMonitor.getUserHasTrust(userId)) {
+                mTextView.switchIndication(trustGrantedIndication);
+                mTextView.setTextColor(mInitialTextColor);
             } else if (mPowerPluggedIn) {
                 String indication = computePowerIndication();
                 if (DEBUG_CHARGING_SPEED) {
                     indication += ",  " + (mChargingWattage / 1000) + " mW";
                 }
                 mTextView.switchIndication(indication);
-                mTextView.setTextColor(Color.WHITE);
-
+                mTextView.setTextColor(mInitialTextColor);
+            } else if (!TextUtils.isEmpty(trustManagedIndication)
+                    && updateMonitor.getUserTrustIsManaged(userId)
+                    && !updateMonitor.getUserHasTrust(userId)) {
+                mTextView.switchIndication(trustManagedIndication);
+                mTextView.setTextColor(mInitialTextColor);
             } else {
                 mTextView.switchIndication(mRestingIndication);
-                mTextView.setTextColor(Color.WHITE);
+                mTextView.setTextColor(mInitialTextColor);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index c432ea8..9e059c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -1308,6 +1308,14 @@
         return header;
     }
 
+
+    public NotificationHeaderView getContractedNotificationHeader() {
+        if (mContractedChild != null) {
+            return mContractedWrapper.getNotificationHeader();
+        }
+        return null;
+    }
+
     public NotificationHeaderView getVisibleNotificationHeader() {
         NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
         return wrapper == null ? null : wrapper.getNotificationHeader();
@@ -1440,4 +1448,15 @@
         }
         return true;
     }
+
+    /**
+     * Should a single click be disallowed on this view when on the keyguard?
+     */
+    public boolean disallowSingleClick(float x, float y) {
+        NotificationViewWrapper visibleWrapper = getVisibleWrapper(getVisibleType());
+        if (visibleWrapper != null) {
+            return visibleWrapper.disallowSingleClick(x, y);
+        }
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index e5b1afe..ef4f419 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -89,6 +89,7 @@
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
         private InflationTask mRunningTask = null;
+        private Throwable mDebugThrowable;
 
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
@@ -249,6 +250,19 @@
         public InflationTask getRunningTask() {
             return mRunningTask;
         }
+
+        /**
+         * Set a throwable that is used for debugging
+         *
+         * @param debugThrowable the throwable to save
+         */
+        public void setDebugThrowable(Throwable debugThrowable) {
+            mDebugThrowable = debugThrowable;
+        }
+
+        public Throwable getDebugThrowable() {
+            return mDebugThrowable;
+        }
     }
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 23a67e2..54d622b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -329,4 +329,8 @@
     public boolean isExposed() {
         return mExposed;
     }
+
+    public boolean isLeavebehind() {
+        return mGutsContent != null && mGutsContent.isLeavebehind();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 7f95d48..4301817 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -267,9 +267,10 @@
             if (!mApply) {
                 return;
             }
-            NotificationHeaderView header = row.getNotificationHeader();
+            NotificationHeaderView header = row.getContractedNotificationHeader();
             if (header == null) {
-                mApply = false;
+                // No header found. We still consider this to be the same to avoid weird flickering
+                // when for example showing an undo notification
                 return;
             }
             Object childData = mExtractor == null ? null : mExtractor.extractData(row);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 427708b..1ffb3b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -154,9 +154,32 @@
             }
         }
 
+        boolean nonBlockable = false;
+        try {
+            final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
+            if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) {
+                final int numChannels = mNotificationChannels.size();
+                for (int i = 0; i < numChannels; i++) {
+                    final NotificationChannel notificationChannel = mNotificationChannels.get(i);
+                    // If any of the system channels is not blockable, the bundle is nonblockable
+                    if (!notificationChannel.isBlockableSystem()) {
+                        nonBlockable = true;
+                        break;
+                    }
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // unlikely.
+        }
+        if (nonBlockablePkgs != null) {
+            nonBlockable |= nonBlockablePkgs.contains(pkg);
+        }
+
         String channelsDescText;
         mNumChannelsView = findViewById(R.id.num_channels_desc);
-        if (mIsSingleDefaultChannel) {
+        if (nonBlockable) {
+            channelsDescText = mContext.getString(R.string.notification_unblockable_desc);
+        } else if (mIsSingleDefaultChannel) {
             channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
         } else {
             switch (mNotificationChannels.size()) {
@@ -188,8 +211,9 @@
             // Multiple channels don't use a channel name for the title.
             channelNameText = mContext.getString(R.string.notification_num_channels,
                     mNotificationChannels.size());
-        } else if (mIsSingleDefaultChannel) {
-            // If this is the default channel, don't use our channel-specific text.
+        } else if (mIsSingleDefaultChannel || nonBlockable) {
+            // If this is the default channel or the app is unblockable,
+            // don't use our channel-specific text.
             channelNameText = mContext.getString(R.string.notification_header_default_channel);
         } else {
             channelNameText = mSingleNotificationChannel.getName();
@@ -218,19 +242,6 @@
             groupDividerView.setVisibility(View.GONE);
         }
 
-        boolean nonBlockable = false;
-        try {
-            final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
-            nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo)
-                    && (mSingleNotificationChannel == null
-                    || !mSingleNotificationChannel.isBlockableSystem());
-        } catch (PackageManager.NameNotFoundException e) {
-            // unlikely.
-        }
-        if (nonBlockablePkgs != null) {
-            nonBlockable |= nonBlockablePkgs.contains(pkg);
-        }
-
         bindButtons(nonBlockable);
 
         // Top-level importance group
@@ -246,12 +257,11 @@
                     (View view) -> {
                         onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
                     });
-            if (numTotalChannels > 1) {
-                settingsButton.setText(R.string.notification_all_categories);
-            } else {
+            if (numTotalChannels <= 1 || nonBlockable) {
                 settingsButton.setText(R.string.notification_more_settings);
+            } else {
+                settingsButton.setText(R.string.notification_all_categories);
             }
-
         } else {
             settingsButton.setVisibility(View.GONE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index c09da21..99b4b07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -100,6 +100,7 @@
     private boolean mShouldShowMenu;
 
     private NotificationSwipeActionHelper mSwipeHelper;
+    private boolean mIsUserTouching;
 
     public NotificationMenuRow(Context context) {
         mContext = context;
@@ -129,7 +130,7 @@
     }
 
     @Override
-    public void createMenu(ViewGroup parent) {
+    public void createMenu(ViewGroup parent, StatusBarNotification sbn) {
         mParent = (ExpandableNotificationRow) parent;
         createMenuViews(true /* resetState */);
     }
@@ -150,7 +151,7 @@
     }
 
     @Override
-    public void onNotificationUpdated() {
+    public void onNotificationUpdated(StatusBarNotification sbn) {
         if (mMenuContainer == null) {
             // Menu hasn't been created yet, no need to do anything.
             return;
@@ -202,8 +203,11 @@
         } else {
             mIconsPlaced = false;
             setMenuLocation();
-            // If the # of items showing changed we need to update the snap position
-            showMenu(mParent, mOnLeft ? getSpaceForMenu() : -getSpaceForMenu(), 0 /* velocity */);
+            if (!mIsUserTouching) {
+                // If the # of items showing changed we need to update the snap position
+                showMenu(mParent, mOnLeft ? getSpaceForMenu() : -getSpaceForMenu(),
+                        0 /* velocity */);
+            }
         }
     }
 
@@ -233,6 +237,7 @@
                 mHandler.removeCallbacks(mCheckForDrag);
                 mCheckForDrag = null;
                 mPrevX = ev.getRawX();
+                mIsUserTouching = true;
                 break;
 
             case MotionEvent.ACTION_MOVE:
@@ -265,7 +270,12 @@
                 break;
 
             case MotionEvent.ACTION_UP:
+                mIsUserTouching = false;
                 return handleUpEvent(ev, view, velocity);
+            case MotionEvent.ACTION_CANCEL:
+                mIsUserTouching = false;
+                cancelDrag();
+                return false;
         }
         return false;
     }
@@ -354,23 +364,24 @@
     }
 
     private void snapBack(View animView, float velocity) {
-        if (mFadeAnimator != null) {
-            mFadeAnimator.cancel();
-        }
-        mHandler.removeCallbacks(mCheckForDrag);
+        cancelDrag();
         mMenuSnappedTo = false;
         mSnapping = true;
         mSwipeHelper.snap(animView, 0 /* leftTarget */, velocity);
     }
 
     private void dismiss(View animView, float velocity) {
+        cancelDrag();
+        mMenuSnappedTo = false;
+        mDismissing = true;
+        mSwipeHelper.dismiss(animView, velocity);
+    }
+
+    private void cancelDrag() {
         if (mFadeAnimator != null) {
             mFadeAnimator.cancel();
         }
         mHandler.removeCallbacks(mCheckForDrag);
-        mMenuSnappedTo = false;
-        mDismissing = true;
-        mSwipeHelper.dismiss(animView, velocity);
     }
 
     /**
@@ -417,10 +428,10 @@
 
     @Override
     public void onHeightUpdate() {
-        if (mParent == null || mMenuItems.size() == 0) {
+        if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
             return;
         }
-        int parentHeight = mParent.getCollapsedHeight();
+        int parentHeight = mParent.getActualHeight();
         float translationY;
         if (parentHeight < mVertSpaceForIcons) {
             translationY = (parentHeight / 2) - (mHorizSpaceForIcon / 2);
@@ -477,7 +488,7 @@
 
     private void setMenuLocation() {
         boolean showOnLeft = mTranslation > 0;
-        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+        if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
                 || !mMenuContainer.isAttachedToWindow()) {
             // Do nothing
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 1a99636..30cdb9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,8 +16,12 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT;
+
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.view.View;
@@ -66,6 +70,7 @@
     private boolean mHasItemsInStableShelf;
     private NotificationIconContainer mCollapsedIcons;
     private int mScrollFastThreshold;
+    private int mIconSize;
     private int mStatusBarState;
     private float mMaxShelfEnd;
     private int mRelativeOffset;
@@ -73,6 +78,7 @@
     private float mOpenedAmount;
     private boolean mNoAnimationsInThisFrame;
     private boolean mAnimationsEnabled = true;
+    private boolean mShowNotificationShelf;
 
     public NotificationShelf(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -101,21 +107,25 @@
     }
 
     private void initDimens() {
-        mIconAppearTopPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_icon_appear_padding);
-        mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
-        mStatusBarPaddingStart = getResources().getDimensionPixelOffset(
-                R.dimen.status_bar_padding_start);
-        mPaddingBetweenElements = getResources().getDimensionPixelSize(
-                R.dimen.notification_divider_height);
+        Resources res = getResources();
+        mIconAppearTopPadding = res.getDimensionPixelSize(R.dimen.notification_icon_appear_padding);
+        mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
+        mStatusBarPaddingStart = res.getDimensionPixelOffset(R.dimen.status_bar_padding_start);
+        mPaddingBetweenElements = res.getDimensionPixelSize(R.dimen.notification_divider_height);
+
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
-        layoutParams.height = getResources().getDimensionPixelOffset(
-                R.dimen.notification_shelf_height);
+        layoutParams.height = res.getDimensionPixelOffset(R.dimen.notification_shelf_height);
         setLayoutParams(layoutParams);
-        int padding = getResources().getDimensionPixelOffset(R.dimen.shelf_icon_container_padding);
+
+        int padding = res.getDimensionPixelOffset(R.dimen.shelf_icon_container_padding);
         mShelfIcons.setPadding(padding, 0, padding, 0);
-        mScrollFastThreshold = getResources().getDimensionPixelOffset(
-                R.dimen.scroll_fast_threshold);
+        mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
+        mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
+        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+
+        if (!mShowNotificationShelf) {
+            setVisibility(GONE);
+        }
     }
 
     @Override
@@ -150,7 +160,7 @@
     public void updateState(StackScrollState resultState,
             AmbientState ambientState) {
         View lastView = ambientState.getLastVisibleBackgroundChild();
-        if (lastView != null) {
+        if (mShowNotificationShelf && lastView != null) {
             float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
             ExpandableViewState lastViewState = resultState.getViewStateForView(lastView);
@@ -174,7 +184,8 @@
                 mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
             }
             mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
-            mShelfState.hidden = !mAmbientState.isShadeExpanded();
+            mShelfState.hidden = !mAmbientState.isShadeExpanded()
+                    || mAmbientState.isQsCustomizerShowing();
             mShelfState.maxShelfEnd = maxShelfEnd;
         } else {
             mShelfState.hidden = true;
@@ -188,6 +199,11 @@
      * the icons from the notification area into the shelf.
      */
     public void updateAppearance() {
+        // If the shelf should not be shown, then there is no need to update anything.
+        if (!mShowNotificationShelf) {
+            return;
+        }
+
         mShelfIcons.resetViewStates();
         float shelfStart = getTranslationY();
         float numViewsInShelf = 0.0f;
@@ -230,7 +246,7 @@
             boolean aboveShelf = ViewState.getFinalTranslationZ(row) > baseZHeight;
             boolean isLastChild = child == lastChild;
             float rowTranslationY = row.getTranslationY();
-            if (isLastChild || aboveShelf || backgroundForceHidden) {
+            if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) {
                 notificationClipEnd = shelfStart + getIntrinsicHeight();
             } else {
                 notificationClipEnd = shelfStart - mPaddingBetweenElements;
@@ -284,7 +300,8 @@
     private void updateNotificationClipHeight(ExpandableNotificationRow row,
             float notificationClipEnd) {
         float viewEnd = row.getTranslationY() + row.getActualHeight();
-        boolean isPinned = row.isPinned() || row.isHeadsUpAnimatingAway();
+        boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway())
+                && !mAmbientState.isDozingAndNotPulsing(row);
         if (viewEnd > notificationClipEnd
                 && (mAmbientState.isShadeExpanded() || !isPinned)) {
             int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
@@ -304,26 +321,65 @@
     private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount,
             boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
             boolean isLastChild) {
+        StatusBarIconView icon = row.getEntry().expandedIcon;
+        NotificationIconContainer.IconState iconState = getIconState(icon);
+        if (iconState == null) {
+            return 0.0f;
+        }
+
         // Let calculate how much the view is in the shelf
         float viewStart = row.getTranslationY();
         int fullHeight = row.getActualHeight() + mPaddingBetweenElements;
         float iconTransformDistance = getIntrinsicHeight() * 1.5f;
         iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
+        iconTransformDistance = Math.min(iconTransformDistance, fullHeight);
         if (isLastChild) {
             fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight());
             iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight()
                     - getIntrinsicHeight());
         }
         float viewEnd = viewStart + fullHeight;
+        if (expandingAnimated && mAmbientState.getScrollY() == 0
+                && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
+            // We are expanding animated. Because we switch to a linear interpolation in this case,
+            // the last icon may be stuck in between the shelf position and the notification
+            // position, which looks pretty bad. We therefore optimize this case by applying a
+            // shorter transition such that the icon is either fully in the notification or we clamp
+            // it into the shelf if it's close enough.
+            // We need to persist this, since after the expansion, the behavior should still be the
+            // same.
+            float position = mAmbientState.getIntrinsicPadding()
+                    + mHostLayout.getPositionInLinearLayout(row);
+            int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
+            if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart
+                    && row.getTranslationY() < position) {
+                iconState.isLastExpandIcon = true;
+                iconState.customTransformHeight = NO_VALUE;
+                // Let's check if we're close enough to snap into the shelf
+                boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
+                        < getIntrinsicHeight();
+                if (!forceInShelf) {
+                    // We are overlapping the shelf but not enough, so the icon needs to be
+                    // repositioned
+                    iconState.customTransformHeight = (int) (mMaxLayoutHeight
+                            - getIntrinsicHeight() - position);
+                }
+            }
+        }
         float fullTransitionAmount;
         float iconTransitionAmount;
         float shelfStart = getTranslationY();
+        if (iconState.hasCustomTransformHeight()) {
+            fullHeight = iconState.customTransformHeight;
+            iconTransformDistance = iconState.customTransformHeight;
+        }
+        boolean fullyInOrOut = true;
         if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf())
                 && (mAmbientState.isShadeExpanded()
                         || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) {
             if (viewStart < shelfStart) {
-
                 float fullAmount = (shelfStart - viewStart) / fullHeight;
+                fullAmount = Math.min(1.0f, fullAmount);
                 float interpolatedAmount =  Interpolators.ACCELERATE_DECELERATE.getInterpolation(
                         fullAmount);
                 interpolatedAmount = NotificationUtils.interpolate(
@@ -333,7 +389,7 @@
                 iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance;
                 iconTransitionAmount = Math.min(1.0f, iconTransitionAmount);
                 iconTransitionAmount = 1.0f - iconTransitionAmount;
-
+                fullyInOrOut = false;
             } else {
                 fullTransitionAmount = 1.0f;
                 iconTransitionAmount = 1.0f;
@@ -342,6 +398,10 @@
             fullTransitionAmount = 0.0f;
             iconTransitionAmount = 0.0f;
         }
+        if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
+            iconState.isLastExpandIcon = false;
+            iconState.customTransformHeight = NO_VALUE;
+        }
         updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount,
                 iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
         return fullTransitionAmount;
@@ -355,9 +415,10 @@
         if (iconState == null) {
             return;
         }
+        boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
         float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f;
         if (clampedAmount == fullTransitionAmount) {
-            iconState.noAnimations = scrollingFast || expandingAnimated;
+            iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
             iconState.useFullTransitionAmount = iconState.noAnimations
                 || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling);
             iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
@@ -365,12 +426,18 @@
             iconState.translateContent = mMaxLayoutHeight - getTranslationY()
                     - getIntrinsicHeight() > 0;
         }
-        if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount
-                && !ViewState.isAnimatingY(icon))) {
+        if (!forceInShelf && (scrollingFast || (expandingAnimated
+                && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
             iconState.cancelAnimations(icon);
             iconState.useFullTransitionAmount = true;
             iconState.noAnimations = true;
         }
+        if (iconState.hasCustomTransformHeight()) {
+            iconState.useFullTransitionAmount = true;
+        }
+        if (iconState.isLastExpandIcon) {
+            iconState.translateContent = false;
+        }
         float transitionAmount;
         if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
                 || iconState.useLinearTransitionAmount) {
@@ -386,7 +453,7 @@
                 ? fullTransitionAmount
                 : transitionAmount;
         iconState.clampedAppearAmount = clampedAmount;
-        float contentTransformationAmount = !row.isAboveShelf()
+        float contentTransformationAmount = !mAmbientState.isAboveShelf(row)
                     && (isLastChild || iconState.translateContent)
                 ? iconTransitionAmount
                 : 0.0f;
@@ -421,12 +488,12 @@
         }
         notificationIconPosition += iconTopPadding;
         float shelfIconPosition = getTranslationY() + icon.getTop();
-        shelfIconPosition += ((1.0f - icon.getIconScale()) * icon.getHeight()) / 2.0f;
+        shelfIconPosition += (icon.getHeight() - icon.getIconScale() * mIconSize) / 2.0f;
         float iconYTranslation = NotificationUtils.interpolate(
                 notificationIconPosition - shelfIconPosition,
                 0,
                 transitionAmount);
-        float shelfIconSize = icon.getHeight() * icon.getIconScale();
+        float shelfIconSize = mIconSize * icon.getIconScale();
         float alpha = 1.0f;
         boolean noIcon = !row.isShowingIcon();
         if (noIcon) {
@@ -438,9 +505,14 @@
         float newSize = NotificationUtils.interpolate(notificationIconSize, shelfIconSize,
                 transitionAmount);
         if (iconState != null) {
-            iconState.scaleX = newSize / icon.getHeight() / icon.getIconScale();
+            iconState.scaleX = newSize / shelfIconSize;
             iconState.scaleY = iconState.scaleX;
             iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
+            boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
+            if (isAppearing) {
+                iconState.hidden = true;
+                iconState.iconAppearAmount = 0.0f;
+            }
             iconState.alpha = alpha;
             iconState.yTranslation = iconYTranslation;
             if (stayingInShelf) {
@@ -450,7 +522,7 @@
                 iconState.scaleY = 1.0f;
                 iconState.hidden = false;
             }
-            if (row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
+            if (mAmbientState.isAboveShelf(row) || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
                     || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
                 iconState.hidden = true;
             }
@@ -537,8 +609,7 @@
         if (!hasOverflow) {
             // we have to ensure that adding the low priority notification won't lead to an
             // overflow
-            collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT)
-                    * mCollapsedIcons.getIconSize();
+            collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize();
         }
         float padding = NotificationUtils.interpolate(collapsedPadding,
                 mShelfIcons.getPaddingEnd(),
@@ -640,6 +711,10 @@
         updateRelativeOffset();
     }
 
+    public void setDarkOffsetX(int offsetX) {
+        mShelfIcons.setDarkOffsetX(offsetX);
+    }
+
     private class ShelfState extends ExpandableViewState {
         private float openedAmount;
         private boolean hasItemsInStableShelf;
@@ -647,6 +722,10 @@
 
         @Override
         public void applyToView(View view) {
+            if (!mShowNotificationShelf) {
+                return;
+            }
+
             super.applyToView(view);
             setMaxShelfEnd(maxShelfEnd);
             setOpenedAmount(openedAmount);
@@ -657,6 +736,10 @@
 
         @Override
         public void animateTo(View child, AnimationProperties properties) {
+            if (!mShowNotificationShelf) {
+                return;
+            }
+
             super.animateTo(child, properties);
             setMaxShelfEnd(maxShelfEnd);
             setOpenedAmount(openedAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 8af1628..c45ca54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -21,11 +21,14 @@
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.os.Bundle;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.text.SpannableString;
@@ -35,6 +38,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -45,6 +51,10 @@
 public class NotificationSnooze extends LinearLayout
         implements NotificationGuts.GutsContent, View.OnClickListener {
 
+    /**
+     * If this changes more number increases, more assistant action resId's should be defined for
+     * accessibility purposes, see {@link #setSnoozeOptions(List)}
+     */
     private static final int MAX_ASSISTANT_SUGGESTIONS = 1;
     private NotificationGuts mGutsContainer;
     private NotificationSwipeActionHelper mSnoozeListener;
@@ -79,16 +89,60 @@
         mDivider = findViewById(R.id.divider);
         mDivider.setAlpha(0f);
         mSnoozeOptionContainer = (ViewGroup) findViewById(R.id.snooze_options);
+        mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
         mSnoozeOptionContainer.setAlpha(0f);
 
         // Create the different options based on list
         mSnoozeOptions = getDefaultSnoozeOptions();
         createOptionViews();
 
-        // Default to first option in list
         setSelected(mDefaultOption);
     }
 
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (mGutsContainer != null && mGutsContainer.isExposed()) {
+            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+                event.getText().add(mSelectedOptionText.getText());
+            }
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.addAction(new AccessibilityAction(R.id.action_snooze_undo,
+                getResources().getString(R.string.snooze_undo)));
+        int count = mSnoozeOptions.size();
+        for (int i = 0; i < count; i++) {
+            AccessibilityAction action = mSnoozeOptions.get(i).getAccessibilityAction();
+            if (action != null) {
+                info.addAction(action);
+            }
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (super.performAccessibilityActionInternal(action, arguments)) {
+            return true;
+        }
+        if (action == R.id.action_snooze_undo) {
+            undoSnooze(mUndoButton);
+            return true;
+        }
+        for (int i = 0; i < mSnoozeOptions.size(); i++) {
+            SnoozeOption so = mSnoozeOptions.get(i);
+            if (so.getAccessibilityAction() != null
+                    && so.getAccessibilityAction().getId() == action) {
+                setSelected(so);
+                return true;
+            }
+        }
+        return false;
+    }
+
     public void setSnoozeOptions(final List<SnoozeCriterion> snoozeList) {
         if (snoozeList == null) {
             return;
@@ -98,7 +152,10 @@
         final int count = Math.min(MAX_ASSISTANT_SUGGESTIONS, snoozeList.size());
         for (int i = 0; i < count; i++) {
             SnoozeCriterion sc = snoozeList.get(i);
-            mSnoozeOptions.add(new SnoozeOption(sc, 0, sc.getExplanation(), sc.getConfirmation()));
+            AccessibilityAction action = new AccessibilityAction(
+                    R.id.action_snooze_assistant_suggestion_1, sc.getExplanation());
+            mSnoozeOptions.add(new NotificationSnoozeOption(sc, 0, sc.getExplanation(),
+                    sc.getConfirmation(), action));
         }
         createOptionViews();
     }
@@ -117,22 +174,30 @@
 
     private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
         ArrayList<SnoozeOption> options = new ArrayList<>();
-        options.add(createOption(R.string.snooze_option_15_min, 15));
-        options.add(createOption(R.string.snooze_option_30_min, 30));
-        mDefaultOption = createOption(R.string.snooze_option_1_hour, 60);
+
+        options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min));
+        options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min));
+        mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour);
         options.add(mDefaultOption);
-        options.add(createOption(R.string.snooze_option_2_hour, 60 * 2));
+        options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours));
         return options;
     }
 
-    private SnoozeOption createOption(int descriptionResId, int minutes) {
+    private SnoozeOption createOption(int minutes, int accessibilityActionId) {
         Resources res = getResources();
-        final String description = res.getString(descriptionResId);
+        boolean showInHours = minutes >= 60;
+        int pluralResId = showInHours
+                ? R.plurals.snoozeHourOptions
+                : R.plurals.snoozeMinuteOptions;
+        int count = showInHours ? (minutes / 60) : minutes;
+        String description = res.getQuantityString(pluralResId, count, count);
         String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
         SpannableString string = new SpannableString(resultText);
         string.setSpan(new StyleSpan(Typeface.BOLD),
                 resultText.length() - description.length(), resultText.length(), 0 /* flags */);
-        return new SnoozeOption(null, minutes, res.getString(descriptionResId), string);
+        AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
+        return new NotificationSnoozeOption(null, minutes, description, string,
+                action);
     }
 
     private void createOptionViews() {
@@ -144,7 +209,7 @@
             TextView tv = (TextView) inflater.inflate(R.layout.notification_snooze_option,
                     mSnoozeOptionContainer, false);
             mSnoozeOptionContainer.addView(tv);
-            tv.setText(option.description);
+            tv.setText(option.getDescription());
             tv.setTag(option);
             tv.setOnClickListener(this);
         }
@@ -179,18 +244,36 @@
                 mDivider.getAlpha(), show ? 1f : 0f);
         ObjectAnimator optionAnim = ObjectAnimator.ofFloat(mSnoozeOptionContainer, View.ALPHA,
                 mSnoozeOptionContainer.getAlpha(), show ? 1f : 0f);
+        mSnoozeOptionContainer.setVisibility(View.VISIBLE);
         mExpandAnimation = new AnimatorSet();
         mExpandAnimation.playTogether(dividerAnim, optionAnim);
         mExpandAnimation.setDuration(150);
         mExpandAnimation.setInterpolator(show ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+        mExpandAnimation.addListener(new AnimatorListenerAdapter() {
+            boolean cancelled = false;
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                cancelled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!show && !cancelled) {
+                    mSnoozeOptionContainer.setVisibility(View.INVISIBLE);
+                    mSnoozeOptionContainer.setAlpha(0f);
+                }
+            }
+        });
         mExpandAnimation.start();
     }
 
     private void setSelected(SnoozeOption option) {
         mSelectedOption = option;
-        mSelectedOptionText.setText(option.confirmation);
+        mSelectedOptionText.setText(option.getConfirmation());
         showSnoozeOptions(false);
         hideSelectedOption();
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
     @Override
@@ -207,20 +290,24 @@
             showSnoozeOptions(!mExpanded);
         } else {
             // Undo snooze was selected
-            mSelectedOption = null;
-            int[] parentLoc = new int[2];
-            int[] targetLoc = new int[2];
-            mGutsContainer.getLocationOnScreen(parentLoc);
-            v.getLocationOnScreen(targetLoc);
-            final int centerX = v.getWidth() / 2;
-            final int centerY = v.getHeight() / 2;
-            final int x = targetLoc[0] - parentLoc[0] + centerX;
-            final int y = targetLoc[1] - parentLoc[1] + centerY;
-            showSnoozeOptions(false);
-            mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+            undoSnooze(v);
         }
     }
 
+    private void undoSnooze(View v) {
+        mSelectedOption = null;
+        int[] parentLoc = new int[2];
+        int[] targetLoc = new int[2];
+        mGutsContainer.getLocationOnScreen(parentLoc);
+        v.getLocationOnScreen(targetLoc);
+        final int centerX = v.getWidth() / 2;
+        final int centerY = v.getHeight() / 2;
+        final int x = targetLoc[0] - parentLoc[0] + centerX;
+        final int y = targetLoc[1] - parentLoc[1] + centerY;
+        showSnoozeOptions(false);
+        mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
+    }
+
     @Override
     public int getActualHeight() {
         return mExpanded ? getHeight() : mCollapsedHeight;
@@ -265,4 +352,48 @@
     public boolean isLeavebehind() {
         return true;
     }
+
+    public class NotificationSnoozeOption implements SnoozeOption {
+        private SnoozeCriterion mCriterion;
+        private int mMinutesToSnoozeFor;
+        private CharSequence mDescription;
+        private CharSequence mConfirmation;
+        private AccessibilityAction mAction;
+
+        public NotificationSnoozeOption(SnoozeCriterion sc, int minToSnoozeFor,
+                CharSequence description,
+                CharSequence confirmation, AccessibilityAction action) {
+            mCriterion = sc;
+            mMinutesToSnoozeFor = minToSnoozeFor;
+            mDescription = description;
+            mConfirmation = confirmation;
+            mAction = action;
+        }
+
+        @Override
+        public SnoozeCriterion getSnoozeCriterion() {
+            return mCriterion;
+        }
+
+        @Override
+        public CharSequence getDescription() {
+            return mDescription;
+        }
+
+        @Override
+        public CharSequence getConfirmation() {
+            return mConfirmation;
+        }
+
+        @Override
+        public int getMinutesToSnoozeFor() {
+            return mMinutesToSnoozeFor;
+        }
+
+        @Override
+        public AccessibilityAction getAccessibilityAction() {
+            return mAction;
+        }
+
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index f9d0cd6..a53e348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -19,39 +19,51 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.annotation.NonNull;
 import android.content.Context;
-import android.content.res.TypedArray;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Display;
 import android.view.View;
+import android.view.WindowManager;
 import android.view.animation.Interpolator;
-import com.android.systemui.R;
+
+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;
 
 /**
  * A view which can draw a scrim
  */
-public class ScrimView extends View
-{
-    private final Paint mPaint = new Paint();
-    private int mScrimColor;
-    private boolean mIsEmpty = true;
+public class ScrimView extends View implements ConfigurationController.ConfigurationListener {
+    private static final String TAG = "ScrimView";
+    private final ColorExtractor.GradientColors mColors;
     private boolean mDrawAsSrc;
     private float mViewAlpha = 1.0f;
     private ValueAnimator mAlphaAnimator;
     private Rect mExcludedRect = new Rect();
     private boolean mHasExcludedArea;
-    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
-            = new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mViewAlpha = (float) animation.getAnimatedValue();
-            invalidate();
+    private Drawable mDrawable;
+    private PorterDuffColorFilter mColorFilter;
+    private int mTintColor;
+    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener = animation -> {
+        if (mDrawable == null) {
+            Log.w(TAG, "Trying to animate null drawable");
+            return;
         }
+        mDrawable.setAlpha((int) (255 * (float) animation.getAnimatedValue()));
     };
     private AnimatorListenerAdapter mClearAnimatorListener = new AnimatorListenerAdapter() {
         @Override
@@ -76,72 +88,163 @@
     public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ScrimView);
+        mDrawable = new GradientDrawable(context);
+        mDrawable.setCallback(this);
+        mColors = new ColorExtractor.GradientColors();
+        updateScreenSize();
+        updateColorWithTint(false);
+    }
 
-        try {
-            mScrimColor = ta.getColor(R.styleable.ScrimView_scrimColor, Color.BLACK);
-        } finally {
-            ta.recycle();
-        }
+    @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.
+        ConfigurationController config = Dependency.get(ConfigurationController.class);
+        config.addCallback(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        ConfigurationController config = Dependency.get(ConfigurationController.class);
+        config.removeCallback(this);
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
-            PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
-            int color = getScrimColorWithAlpha();
+        if (mDrawAsSrc || mDrawable.getAlpha() > 0) {
             if (!mHasExcludedArea) {
-                canvas.drawColor(color, mode);
+                mDrawable.draw(canvas);
             } else {
-                mPaint.setColor(color);
                 if (mExcludedRect.top > 0) {
-                    canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, 0, getWidth(), mExcludedRect.top);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.left > 0) {
-                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left, mExcludedRect.bottom,
-                            mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, mExcludedRect.top, mExcludedRect.left,
+                            mExcludedRect.bottom);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.right < getWidth()) {
-                    canvas.drawRect(mExcludedRect.right,
-                            mExcludedRect.top,
-                            getWidth(),
-                            mExcludedRect.bottom,
-                            mPaint);
+                    canvas.save();
+                    canvas.clipRect(mExcludedRect.right, mExcludedRect.top, getWidth(),
+                            mExcludedRect.bottom);
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
                 if (mExcludedRect.bottom < getHeight()) {
-                    canvas.drawRect(0,  mExcludedRect.bottom, getWidth(), getHeight(), mPaint);
+                    canvas.save();
+                    canvas.clipRect(0, mExcludedRect.bottom, getWidth(), getHeight());
+                    mDrawable.draw(canvas);
+                    canvas.restore();
                 }
             }
         }
     }
 
-    public int getScrimColorWithAlpha() {
-        int color = mScrimColor;
-        color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
-                Color.green(color), Color.blue(color));
-        return color;
+    public void setDrawable(Drawable drawable) {
+        mDrawable = drawable;
+        mDrawable.setCallback(this);
+        mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
+        mDrawable.setAlpha((int) (255 * mViewAlpha));
+        setDrawAsSrc(mDrawAsSrc);
+        updateScreenSize();
+        invalidate();
+    }
+
+    @Override
+    public void invalidateDrawable(@NonNull Drawable drawable) {
+        super.invalidateDrawable(drawable);
+        if (drawable == mDrawable) {
+            invalidate();
+        }
     }
 
     public void setDrawAsSrc(boolean asSrc) {
         mDrawAsSrc = asSrc;
-        mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC
-                : PorterDuff.Mode.SRC_OVER));
-        invalidate();
+        PorterDuff.Mode mode = asSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
+        mDrawable.setXfermode(new PorterDuffXfermode(mode));
     }
 
-    public void setScrimColor(int color) {
-        if (color != mScrimColor) {
-            mIsEmpty = Color.alpha(color) == 0;
-            mScrimColor = color;
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (changed) {
+            mDrawable.setBounds(left, top, right, bottom);
             invalidate();
-            if (mChangeRunnable != null) {
-                mChangeRunnable.run();
-            }
         }
     }
 
-    public int getScrimColor() {
-        return mScrimColor;
+    public void setColors(@NonNull ColorExtractor.GradientColors colors) {
+        setColors(colors, false);
+    }
+
+    public void setColors(@NonNull ColorExtractor.GradientColors colors, boolean animated) {
+        if (colors == null) {
+            throw new IllegalArgumentException("Colors cannot be null");
+        }
+        if (mColors.equals(colors)) {
+            return;
+        }
+        mColors.set(colors);
+        updateColorWithTint(animated);
+    }
+
+    @VisibleForTesting
+    Drawable getDrawable() {
+        return mDrawable;
+    }
+
+    public ColorExtractor.GradientColors getColors() {
+        return mColors;
+    }
+
+    public void setTint(int color) {
+        setTint(color, false);
+    }
+
+    public void setTint(int color, boolean animated) {
+        if (mTintColor == color) {
+            return;
+        }
+        mTintColor = color;
+        updateColorWithTint(animated);
+    }
+
+    private void updateColorWithTint(boolean animated) {
+        if (mDrawable instanceof GradientDrawable) {
+            // Optimization to blend colors and avoid a color filter
+            GradientDrawable drawable = (GradientDrawable) mDrawable;
+            float tintAmount = Color.alpha(mTintColor) / 255f;
+            int mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor,
+                    tintAmount);
+            int secondaryTinted = ColorUtils.blendARGB(mColors.getSecondaryColor(), mTintColor,
+                    tintAmount);
+            drawable.setColors(mainTinted, secondaryTinted, animated);
+        } else {
+            if (mColorFilter == null) {
+                mColorFilter = new PorterDuffColorFilter(mTintColor, PorterDuff.Mode.SRC_OVER);
+            } else {
+                mColorFilter.setColor(mTintColor);
+            }
+            mDrawable.setColorFilter(Color.alpha(mTintColor) == 0 ? null : mColorFilter);
+            mDrawable.invalidateSelf();
+        }
+
+        if (mChangeRunnable != null) {
+            mChangeRunnable.run();
+        }
+    }
+
+    public int getTint() {
+        return mTintColor;
     }
 
     @Override
@@ -150,23 +253,29 @@
     }
 
     public void setViewAlpha(float alpha) {
-        if (mAlphaAnimator != null) {
-            mAlphaAnimator.cancel();
-        }
         if (alpha != mViewAlpha) {
             mViewAlpha = alpha;
-            invalidate();
+
+            if (mAlphaAnimator != null) {
+                mAlphaAnimator.cancel();
+            }
+
+            mDrawable.setAlpha((int) (255 * alpha));
             if (mChangeRunnable != null) {
                 mChangeRunnable.run();
             }
         }
     }
 
+    public float getViewAlpha() {
+        return mViewAlpha;
+    }
+
     public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) {
         if (mAlphaAnimator != null) {
             mAlphaAnimator.cancel();
         }
-        mAlphaAnimator = ValueAnimator.ofFloat(mViewAlpha, alpha);
+        mAlphaAnimator = ValueAnimator.ofFloat(getViewAlpha(), alpha);
         mAlphaAnimator.addUpdateListener(mAlphaUpdateListener);
         mAlphaAnimator.addListener(mClearAnimatorListener);
         mAlphaAnimator.setInterpolator(interpolator);
@@ -193,4 +302,25 @@
     public void setChangeRunnable(Runnable changeRunnable) {
         mChangeRunnable = changeRunnable;
     }
+
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        updateScreenSize();
+    }
+
+    private void updateScreenSize() {
+        if (mDrawable instanceof GradientDrawable) {
+            WindowManager wm = mContext.getSystemService(WindowManager.class);
+            if (wm == null) {
+                Log.w(TAG, "Can't resize gradient drawable to fit the screen");
+                return;
+            }
+            Display display = wm.getDefaultDisplay();
+            if (display != null) {
+                Point size = new Point();
+                display.getRealSize(size);
+                ((GradientDrawable) mDrawable).setScreenSize(size.x, size.y);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 6d2a023..25f3e25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -16,18 +16,15 @@
 
 package com.android.systemui.statusbar;
 
-import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Animatable;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
 import android.telephony.SubscriptionInfo;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -79,10 +76,8 @@
     private boolean mEthernetVisible = false;
     private int mEthernetIconId = 0;
     private int mLastEthernetIconId = -1;
-    private int mWifiBadgeId = -1;
     private boolean mWifiVisible = false;
     private int mWifiStrengthId = 0;
-    private int mLastWifiBadgeId = -1;
     private int mLastWifiStrengthId = -1;
     private boolean mWifiIn;
     private boolean mWifiOut;
@@ -290,7 +285,6 @@
             boolean activityIn, boolean activityOut, String description, boolean isTransient) {
         mWifiVisible = statusIcon.visible && !mBlockWifi;
         mWifiStrengthId = statusIcon.icon;
-        mWifiBadgeId = statusIcon.iconOverlay;
         mWifiDescription = statusIcon.contentDescription;
         mWifiIn = activityIn && mActivityEnabled && mWifiVisible;
         mWifiOut = activityOut && mActivityEnabled && mWifiVisible;
@@ -427,7 +421,6 @@
             mWifi.setImageDrawable(null);
             mWifiDark.setImageDrawable(null);
             mLastWifiStrengthId = -1;
-            mLastWifiBadgeId = -1;
         }
 
         for (PhoneState state : mPhoneStates) {
@@ -483,16 +476,10 @@
                     (mEthernetVisible ? "VISIBLE" : "GONE")));
 
         if (mWifiVisible) {
-            if (mWifiStrengthId != mLastWifiStrengthId || mWifiBadgeId != mLastWifiBadgeId) {
-                if (mWifiBadgeId == -1) {
-                    setIconForView(mWifi, mWifiStrengthId);
-                    setIconForView(mWifiDark, mWifiStrengthId);
-                } else {
-                    setBadgedWifiIconForView(mWifi, mWifiStrengthId, mWifiBadgeId);
-                    setBadgedWifiIconForView(mWifiDark, mWifiStrengthId, mWifiBadgeId);
-                }
+            if (mWifiStrengthId != mLastWifiStrengthId) {
+                setIconForView(mWifi, mWifiStrengthId);
+                setIconForView(mWifiDark, mWifiStrengthId);
                 mLastWifiStrengthId = mWifiStrengthId;
-                mLastWifiBadgeId = mWifiBadgeId;
             }
             mWifiGroup.setContentDescription(mWifiDescription);
             mWifiGroup.setVisibility(View.VISIBLE);
@@ -557,10 +544,6 @@
         // Using the imageView's context to retrieve the Drawable so that theme is preserved.
         Drawable icon = imageView.getContext().getDrawable(iconId);
 
-        setScaledIcon(imageView, icon);
-    }
-
-    private void setScaledIcon(ImageView imageView, Drawable icon) {
         if (mIconScaleFactor == 1.f) {
             imageView.setImageDrawable(icon);
         } else {
@@ -568,32 +551,6 @@
         }
     }
 
-    /**
-     * Creates and sets a LayerDrawable from the given ids on the given view.
-     *
-     * <p>This method will also scale the icon by {@link #mIconScaleFactor} if appropriate.
-     */
-    private void setBadgedWifiIconForView(ImageView imageView, @DrawableRes int wifiPieId,
-            @DrawableRes int badgeId) {
-        // Using the imageView's context to retrieve the Drawable so that theme is preserved.;
-        LayerDrawable icon = new LayerDrawable(new Drawable[] {
-                imageView.getContext().getDrawable(wifiPieId),
-                imageView.getContext().getDrawable(badgeId)});
-
-        // The LayerDrawable shares an underlying state so we must mutate the object to change the
-        // color between the light and dark themes.
-        icon.mutate().setTint(getColorAttr(imageView.getContext(), R.attr.singleToneColor));
-
-        setScaledIcon(imageView, icon);
-    }
-
-    /** Returns the given color attribute value, or white if not defined. */
-    @ColorInt private static int getColorAttr(Context context, int attr) {
-        TypedArray ta = context.obtainStyledAttributes(new int[] {attr});
-        @ColorInt int colorAccent = ta.getColor(0, Color.WHITE);
-        ta.recycle();
-        return colorAccent;
-    }
 
     @Override
     public void onDarkChanged(Rect tintArea, float darkIntensity, int tint) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 89694b33..27fe33e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -23,11 +23,12 @@
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -54,9 +55,16 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.text.NumberFormat;
+import java.util.Arrays;
 
 public class StatusBarIconView extends AnimatedImageView {
     public static final int NO_COLOR = 0;
+
+    /**
+     * Multiply alpha values with (1+DARK_ALPHA_BOOST) when dozing. The chosen value boosts
+     * everything above 30% to 50%, making it appear on 1bit color depths.
+     */
+    private static final float DARK_ALPHA_BOOST = 0.67f;
     private final int ANIMATION_DURATION_FAST = 100;
 
     public static final int STATE_ICON = 0;
@@ -131,6 +139,8 @@
     private final NotificationIconDozeHelper mDozer;
     private int mContrastedDrawableColor;
     private int mCachedContrastBackgroundColor = NO_COLOR;
+    private float[] mMatrix;
+    private ColorMatrixColorFilter mMatrixColorFilter;
 
     public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
         this(context, slot, sbn, false);
@@ -544,14 +554,33 @@
 
     private void updateIconColor() {
         if (mCurrentSetColor != NO_COLOR) {
-            setImageTintList(ColorStateList.valueOf(NotificationUtils.interpolateColors(
-                    mCurrentSetColor, Color.WHITE, mDarkAmount)));
+            if (mMatrixColorFilter == null) {
+                mMatrix = new float[4 * 5];
+                mMatrixColorFilter = new ColorMatrixColorFilter(mMatrix);
+            }
+            int color = NotificationUtils.interpolateColors(
+                    mCurrentSetColor, Color.WHITE, mDarkAmount);
+            updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDarkAmount);
+            mMatrixColorFilter.setColorMatrixArray(mMatrix);
+            setColorFilter(mMatrixColorFilter);
+            invalidate();  // setColorFilter only invalidates if the filter instance changed.
         } else {
-            setImageTintList(null);
             mDozer.updateGrayscale(this, mDarkAmount);
         }
     }
 
+    /**
+     * Updates {@param array} such that it represents a matrix that changes RGB to {@param color}
+     * and multiplies the alpha channel with the color's alpha+{@param alphaBoost}.
+     */
+    private static void updateTintMatrix(float[] array, int color, float alphaBoost) {
+        Arrays.fill(array, 0);
+        array[4] = Color.red(color);
+        array[9] = Color.green(color);
+        array[14] = Color.blue(color);
+        array[18] = Color.alpha(color) / 255f + alphaBoost;
+    }
+
     public void setIconColor(int iconColor, boolean animate) {
         if (mIconColor != iconColor) {
             mIconColor = iconColor;
@@ -756,9 +785,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/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 7162b31..76177a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -23,9 +23,11 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -33,6 +35,7 @@
 import android.view.ViewStub;
 import android.view.WindowManager;
 import android.widget.LinearLayout;
+
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -41,6 +44,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarView;
@@ -62,6 +66,7 @@
 
     private CarBatteryController mCarBatteryController;
     private BatteryMeterView mBatteryMeterView;
+    private Drawable mNotificationPanelBackground;
 
     private ConnectedDeviceSignalController mConnectedDeviceSignalController;
     private CarNavigationBarView mNavigationBarView;
@@ -91,17 +96,18 @@
     protected void makeStatusBarView() {
         super.makeStatusBarView();
 
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+
         FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
         manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
-            mBatteryMeterView = ((BatteryMeterView) fragment.getView().findViewById(
-                    R.id.battery));
+            mBatteryMeterView = fragment.getView().findViewById(R.id.battery);
 
             // By default, the BatteryMeterView should not be visible. It will be toggled
             // when a device has connected by bluetooth.
             mBatteryMeterView.setVisibility(View.GONE);
 
-            ViewStub stub = (ViewStub) fragment.getView().findViewById(
-                    R.id.connected_device_signals_stub);
+            ViewStub stub = fragment.getView().findViewById(R.id.connected_device_signals_stub);
             View signalsView = stub.inflate();
 
             // When a ViewStub if inflated, it does not respect the margins on the
@@ -256,7 +262,7 @@
         if (userSwitcherController.useFullscreenUserSwitcher()) {
             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
                     userSwitcherController,
-                    (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
+                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
         } else {
             super.createUserSwitcher();
         }
@@ -314,13 +320,46 @@
         return startActivityWithOptions(intent, options.toBundle());
     }
 
+    @Override
+    protected boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn) {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by not pinning any
+        // notification if the shade is already opened.
+        if (mPanelExpanded) {
+            return false;
+        }
+
+        return super.shouldPeek(entry, sbn);
+    }
+
+    @Override
+    public void animateExpandNotificationsPanel() {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by removing all heads-
+        // up notifications.
+        mHeadsUpManager.removeAllHeadsUpEntries();
+        super.animateExpandNotificationsPanel();
+    }
+
     /**
      * Ensures that relevant child views are appropriately recreated when the device's density
      * changes.
      */
     @Override
-    protected void onDensityOrFontScaleChanged() {
+    public void onDensityOrFontScaleChanged() {
         super.onDensityOrFontScaleChanged();
         mController.onDensityOrFontScaleChanged();
+
+        // Need to update the background on density changed in case the change was due to night
+        // mode.
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+    }
+
+    /**
+     * Returns the {@link Drawable} that represents the wallpaper that the user has currently set.
+     */
+    private Drawable getDefaultWallpaper() {
+        return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index f8b6dee..9338887 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -16,8 +16,13 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.res.Resources;
+import android.os.CountDownTimer;
 import android.view.View;
 import android.view.ViewStub;
+import android.widget.ProgressBar;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -27,30 +32,132 @@
  * Manages the fullscreen user switcher.
  */
 public class FullscreenUserSwitcher {
+    private final View mContainer;
+    private final View mParent;
+    private final UserGridView mUserGridView;
+    private final UserSwitcherController mUserSwitcherController;
+    private final ProgressBar mProgressBar;
+    private final ProgressBar mSwitchingUsers;
+    private final int mLoginTimeoutMs;
+    private final int mAnimUpdateIntervalMs;
+    private final int mShortAnimDuration;
 
-    private View mContainer;
-    private UserGridView mUserGridView;
-    private UserSwitcherController mUserSwitcherController;
+    private boolean mShowing;
+
+    private CountDownTimer mTimer;
 
     public FullscreenUserSwitcher(StatusBar statusBar,
             UserSwitcherController userSwitcherController,
             ViewStub containerStub) {
         mUserSwitcherController = userSwitcherController;
-        mContainer = containerStub.inflate();
-        mUserGridView = (UserGridView) mContainer.findViewById(R.id.user_grid);
+        mParent = containerStub.inflate();
+        mContainer = mParent.findViewById(R.id.container);
+        mUserGridView = mContainer.findViewById(R.id.user_grid);
         mUserGridView.init(statusBar, mUserSwitcherController);
+        mUserGridView.setUserSelectionListener(record -> {
+            if (!record.isCurrent) {
+                toggleSwitchInProgress(true);
+            }
+        });
+
+        PageIndicator pageIndicator = mContainer.findViewById(R.id.user_switcher_page_indicator);
+        pageIndicator.setupWithViewPager(mUserGridView);
+
+        mProgressBar = mContainer.findViewById(R.id.countdown_progress);
+        Resources res = mContainer.getResources();
+        mLoginTimeoutMs = res.getInteger(R.integer.car_user_switcher_timeout_ms);
+        mAnimUpdateIntervalMs = res.getInteger(R.integer.car_user_switcher_anim_update_ms);
+        mShortAnimDuration = res.getInteger(android.R.integer.config_shortAnimTime);
+
+        mContainer.findViewById(R.id.start_driving).setOnClickListener(v -> {
+            cancelTimer();
+            automaticallySelectUser();
+        });
+
+        mSwitchingUsers = mParent.findViewById(R.id.switching_users);
     }
 
     public void onUserSwitched(int newUserId) {
         mUserGridView.onUserSwitched(newUserId);
     }
 
+    private void toggleSwitchInProgress(boolean inProgress) {
+        if (inProgress) {
+            crossFade(mSwitchingUsers, mContainer);
+        } else {
+            crossFade(mContainer, mSwitchingUsers);
+        }
+    }
+
+    private void crossFade(View incoming, View outgoing) {
+        incoming.animate()
+            .alpha(1.0f)
+            .setDuration(mShortAnimDuration)
+            .setListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+                    incoming.setAlpha(0.0f);
+                    incoming.setVisibility(View.VISIBLE);
+                }
+            });
+
+        outgoing.animate()
+            .alpha(0.0f)
+            .setDuration(mShortAnimDuration)
+            .setListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    outgoing.setVisibility(View.GONE);
+                }
+            });
+    }
+
     public void show() {
-        mContainer.setVisibility(View.VISIBLE);
+        if (mShowing) {
+            return;
+        }
+        mShowing = true;
+        mParent.setVisibility(View.VISIBLE);
+        cancelTimer();
+
+        // This would be the case if we were in the middle of a switch.
+        if (mProgressBar.getVisibility() != View.VISIBLE) {
+            return;
+        }
+
+        mTimer = new CountDownTimer(mLoginTimeoutMs, mAnimUpdateIntervalMs) {
+            @Override
+            public void onTick(long msUntilFinished) {
+                int elapsed = mLoginTimeoutMs - (int) msUntilFinished;
+                mProgressBar.setProgress((int) elapsed, true /* animate */);
+            }
+
+            @Override
+            public void onFinish() {
+                mProgressBar.setProgress(mLoginTimeoutMs, true /* animate */);
+                automaticallySelectUser();
+            }
+        };
+        mTimer.start();
     }
 
     public void hide() {
-        mContainer.setVisibility(View.GONE);
+        mShowing = false;
+        cancelTimer();
+        toggleSwitchInProgress(false);
+        mParent.setVisibility(View.GONE);
+    }
+
+    private void cancelTimer() {
+        if (mTimer != null) {
+            mTimer.cancel();
+            mTimer = null;
+        }
+    }
+
+    private void automaticallySelectUser() {
+        // TODO: Switch according to some policy. This implementation just tries to drop the
+        //       keyguard for the current user.
+        mUserGridView.showOfflineAuthUi();
     }
 }
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
new file mode 100644
index 0000000..f7d0906
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/PageIndicator.java
@@ -0,0 +1,193 @@
+/*
+ * 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.statusbar.car;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+import com.android.systemui.R;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Displays the dots underneath the ViewPager on the lock screen. This is really just a simplified
+ * version of PagerTitleStrip. We don't inherit from there because it's impossible to bypass some
+ * of the overriden logic in that class.
+ */
+public class PageIndicator extends View {
+    private static final String TAG = "PageIndicator";
+    // These can be made a styleable attribute in the future if necessary.
+    private static final int SELECTED_COLOR = 0xFFF5F5F5;  // grey 100
+    private static final int UNSELECTED_COLOR = 0xFFBDBDBD;  // grey 400
+    private final PageListener mPageListener = new PageListener();
+
+    private ViewPager mPager;
+    private WeakReference<PagerAdapter> mWatchingAdapter;
+
+    private int mPageCount;
+    private int mCurrentPosition;
+    private Paint mPaint;
+    private int mRadius;
+    private int mStep;
+
+    public PageIndicator(Context context) {
+        super(context);
+        init();
+    }
+
+    public PageIndicator(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setStyle(Paint.Style.FILL);
+        mRadius = getResources().getDimensionPixelSize(R.dimen.car_page_indicator_dot_diameter) / 2;
+        mStep = mRadius * 3;
+    }
+
+    public void setupWithViewPager(ViewPager pager) {
+        mPager = pager;
+
+        final PagerAdapter adapter = (PagerAdapter) pager.getAdapter();
+        pager.addOnPageChangeListener(mPageListener);
+        pager.addOnAdapterChangeListener(mPageListener);
+        updateAdapter(mWatchingAdapter != null ? mWatchingAdapter.get() : null, adapter);
+        invalidate();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mPager != null) {
+            updateAdapter(mPager.getAdapter(), null);
+            mPager.removeOnPageChangeListener(mPageListener);
+            mPager.removeOnAdapterChangeListener(mPageListener);
+            mPager = null;
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        int x = canvas.getWidth() / 2 - (mPageCount / 2) * mStep;
+        int y = canvas.getHeight() / 2;
+
+        for (int i = 0; i < mPageCount; i++) {
+            if (i == mCurrentPosition) {
+                mPaint.setColor(SELECTED_COLOR);
+            } else {
+                mPaint.setColor(UNSELECTED_COLOR);
+            }
+
+            canvas.drawCircle(x, y, mRadius, mPaint);
+            x += mStep;
+        }
+    }
+
+    void updateAdapter(PagerAdapter oldAdapter, PagerAdapter newAdapter) {
+        if (oldAdapter != null) {
+            oldAdapter.unregisterDataSetObserver(mPageListener);
+            mWatchingAdapter = null;
+        }
+
+        if (newAdapter != null) {
+            newAdapter.registerDataSetObserver(mPageListener);
+            mWatchingAdapter = new WeakReference<>(newAdapter);
+        }
+
+        updateDots();
+
+        if (mPager != null) {
+            requestLayout();
+        }
+    }
+
+    private <T> T getRef(WeakReference<T> weakRef) {
+        if (weakRef == null) {
+            return null;
+        }
+        return weakRef.get();
+    }
+
+    private void updateDots() {
+        PagerAdapter adapter = getRef(mWatchingAdapter);
+        if (adapter == null) {
+            return;
+        }
+
+        int count = adapter.getCount();
+        if (mPageCount == count) {
+            // Nothing to be done.
+            return;
+        }
+
+        mPageCount = count;
+        mCurrentPosition = 0;
+        invalidate();
+    }
+
+    private class PageListener extends DataSetObserver implements ViewPager.OnPageChangeListener,
+            ViewPager.OnAdapterChangeListener {
+
+        @Override
+        public void onPageScrolled(int unused1, float unused2, int unused3) { }
+
+        @Override
+        public void onPageSelected(int position) {
+            if (mCurrentPosition == position) {
+                return;
+            }
+
+            if (mPageCount <= position) {
+                Log.e(TAG, "Position out of bounds, position=" + position + " size=" + mPageCount);
+                return;
+            }
+
+            mCurrentPosition = position;
+            invalidate();
+        }
+
+        @Override
+        public void onPageScrollStateChanged(int state) { }
+
+        @Override
+        public void onAdapterChanged(ViewPager viewPager, PagerAdapter oldAdapter,
+                PagerAdapter newAdapter) {
+            updateAdapter(oldAdapter, newAdapter);
+        }
+
+        @Override
+        public void onChanged() {
+            updateDots();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
index 137b5cf..cfa9864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
@@ -17,27 +17,35 @@
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.GridView;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.util.UserIcons;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.UserUtil;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
-public class UserGridView extends GridView {
-
+/**
+ * Displays a ViewPager with icons for the users in the system to allow switching between users.
+ * One of the uses of this is for the lock screen in auto.
+ */
+public class UserGridView extends ViewPager {
     private StatusBar mStatusBar;
     private UserSwitcherController mUserSwitcherController;
     private Adapter mAdapter;
-    private int mPendingUserId = UserHandle.USER_NULL;
+    private UserSelectionListener mUserSelectionListener;
 
     public UserGridView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -47,116 +55,184 @@
         mStatusBar = statusBar;
         mUserSwitcherController = userSwitcherController;
         mAdapter = new Adapter(mUserSwitcherController);
+        addOnLayoutChangeListener(mAdapter);
         setAdapter(mAdapter);
-
-        setOnItemClickListener(new OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                mPendingUserId = UserHandle.USER_NULL;
-                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
-                if (record == null) {
-                    return;
-                }
-
-                if (record.isGuest || record.isAddUser) {
-                    mUserSwitcherController.switchTo(record);
-                    return;
-                }
-
-                if (record.isCurrent) {
-                    showOfflineAuthUi();
-                } else {
-                    mPendingUserId = record.info.id;
-                    mUserSwitcherController.switchTo(record);
-                }
-            }
-        });
-
-        setOnItemLongClickListener(new OnItemLongClickListener() {
-            @Override
-            public boolean onItemLongClick(AdapterView<?> parent,
-                    View view, int position, long id) {
-                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
-                if (record == null || record.isAddUser) {
-                    return false;
-                }
-                if (record.isGuest) {
-                    if (record.isCurrent) {
-                        mUserSwitcherController.switchTo(record);
-                    }
-                    return true;
-                }
-
-                UserUtil.deleteUserWithPrompt(getContext(), record.info.id,
-                        mUserSwitcherController);
-                return true;
-            }
-        });
     }
 
     public void onUserSwitched(int newUserId) {
-        if (mPendingUserId == newUserId) {
-            // Bring up security view after user switch is completed.
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    showOfflineAuthUi();
-                }
-            });
-        }
-        mPendingUserId = UserHandle.USER_NULL;
+        // Bring up security view after user switch is completed.
+        post(this::showOfflineAuthUi);
     }
 
-    private void showOfflineAuthUi() {
+    public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
+        mUserSelectionListener = userSelectionListener;
+    }
+
+    void showOfflineAuthUi() {
         // TODO: Show keyguard UI in-place.
         mStatusBar.executeRunnableDismissingKeyguard(null, null, true, true, true);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        if (widthMode == MeasureSpec.UNSPECIFIED) {
-            setNumColumns(AUTO_FIT);
-        } else {
-            int columnWidth = Math.max(1, getRequestedColumnWidth());
-            int itemCount = getAdapter() == null ? 0 : getAdapter().getCount();
-            int numColumns = Math.max(1, Math.min(itemCount, widthSize / columnWidth));
-            setNumColumns(numColumns);
+        // Wrap content doesn't work in ViewPagers, so simulate the behavior in code.
+        int height = 0;
+        for(int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            child.measure(widthMeasureSpec,
+                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+            height = Math.max(child.getMeasuredHeight(), height);
         }
+        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
-    private final class Adapter extends UserSwitcherController.BaseUserAdapter {
+    /**
+     * This is a ViewPager.PagerAdapter which deletegates the work to a
+     * UserSwitcherController.BaseUserAdapter. Java doesn't support multiple inheritance so we have
+     * to use composition instead to achieve the same goal since both the base classes are abstract
+     * classes and not interfaces.
+     */
+    private final class Adapter extends PagerAdapter implements View.OnLayoutChangeListener {
+        private final int mPodWidth;
+        private final int mPodMargin;
+
+        private final WrappedBaseUserAdapter mUserAdapter;
+        private int mContainerWidth;
+
         public Adapter(UserSwitcherController controller) {
-            super(controller);
+            super();
+            mUserAdapter = new WrappedBaseUserAdapter(controller, this);
+            mPodWidth = getResources().getDimensionPixelSize(
+                    R.dimen.car_fullscreen_user_pod_image_avatar_width);
+            mPodMargin = getResources().getDimensionPixelSize(
+                    R.dimen.car_fullscreen_user_pod_margin_side);
         }
 
         @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
-                        (Context.LAYOUT_INFLATER_SERVICE);
-                convertView = inflater.inflate(R.layout.car_fullscreen_user_pod, null);
-            }
-            UserSwitcherController.UserRecord record = getItem(position);
+        public void destroyItem(ViewGroup container, int position, Object object) {
+            container.removeView((View) object);
+        }
 
-            TextView nameView = (TextView) convertView.findViewById(R.id.user_name);
+        private int getIconsPerPage() {
+            // We need to know how many pods we need in this page. Each pod has its own width and
+            // margins on both sides. We can then divide the measured width of the parent by the
+            // sum of pod width and margin to get the number of pods that will completely fit.
+            return mContainerWidth / (mPodWidth + mPodMargin * 2);
+        }
+
+        @Override
+        public Object instantiateItem(ViewGroup container, int position) {
+            Context context = getContext();
+            LayoutInflater inflater = LayoutInflater.from(context);
+
+            ViewGroup pods = (ViewGroup) inflater.inflate(
+                    R.layout.car_fullscreen_user_pod_container, null);
+
+            int iconsPerPage = getIconsPerPage();
+            int limit = Math.min(mUserAdapter.getCount(), (position + 1) * iconsPerPage);
+            for (int i = position * iconsPerPage; i < limit; i++) {
+                pods.addView(makeUserPod(inflater, context, i, pods));
+            }
+            container.addView(pods);
+            return pods;
+        }
+
+        private Drawable getUserIcon(Context context, UserSwitcherController.UserRecord record) {
+            if (record.isAddUser) {
+                Drawable icon = context.getDrawable(R.drawable.ic_add_circle_qs);
+                icon.setTint(Color.WHITE);
+                return icon;
+            }
+            return UserIcons.getDefaultUserIcon(record.resolveId(), /* light= */ true);
+        }
+
+        private View makeUserPod(LayoutInflater inflater, Context context,
+                int position, ViewGroup parent) {
+            final UserSwitcherController.UserRecord record = mUserAdapter.getItem(position);
+            View view = inflater.inflate(R.layout.car_fullscreen_user_pod, parent, false);
+
+            TextView nameView = view.findViewById(R.id.user_name);
             if (record != null) {
-                nameView.setText(getName(getContext(), record));
-                convertView.setActivated(record.isCurrent);
+                nameView.setText(mUserAdapter.getName(context, record));
+                view.setActivated(record.isCurrent);
             } else {
-                nameView.setText("Unknown");
+                nameView.setText(context.getString(R.string.unknown_user_label));
             }
 
-            ImageView iconView = (ImageView) convertView.findViewById(R.id.user_avatar);
+            ImageView iconView = (ImageView) view.findViewById(R.id.user_avatar);
             if (record == null || record.picture == null) {
-                iconView.setImageDrawable(getDrawable(getContext(), record));
+                iconView.setImageDrawable(getUserIcon(context, record));
             } else {
                 iconView.setImageBitmap(record.picture);
             }
 
-            return convertView;
+            iconView.setOnClickListener(v -> {
+                if (record == null) {
+                    return;
+                }
+
+                if (mUserSelectionListener != null) {
+                    mUserSelectionListener.onUserSelected(record);
+                }
+
+                if (record.isCurrent) {
+                    showOfflineAuthUi();
+                } else {
+                    mUserSwitcherController.switchTo(record);
+                }
+            });
+
+            return view;
+        }
+
+        @Override
+        public int getCount() {
+            int iconsPerPage = getIconsPerPage();
+            if (iconsPerPage == 0) {
+                return 0;
+            }
+            return (int) Math.ceil((double) mUserAdapter.getCount() / getIconsPerPage());
+        }
+
+        public void refresh() {
+            mUserAdapter.refresh();
+        }
+
+        @Override
+        public boolean isViewFromObject(View view, Object object) {
+            return view == object;
+        }
+
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                int oldLeft, int oldTop, int oldRight, int oldBottom) {
+            mContainerWidth = Math.max(left - right, right - left);
+            notifyDataSetChanged();
         }
     }
+
+    private final class WrappedBaseUserAdapter extends UserSwitcherController.BaseUserAdapter {
+        private Adapter mContainer;
+
+        public WrappedBaseUserAdapter(UserSwitcherController controller, Adapter container) {
+            super(controller);
+            mContainer = container;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            throw new UnsupportedOperationException("unused");
+        }
+
+        @Override
+        public void notifyDataSetChanged() {
+            super.notifyDataSetChanged();
+            mContainer.notifyDataSetChanged();
+        }
+    }
+
+    interface UserSelectionListener {
+        void onUserSelected(UserSwitcherController.UserRecord record);
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java
new file mode 100644
index 0000000..07baedc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfChangedListener.java
@@ -0,0 +1,28 @@
+/*
+ * 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.statusbar.notification;
+
+/**
+ * A listener for when the above shelf state of notification changes
+ */
+public interface AboveShelfChangedListener {
+
+    /**
+     * Notifies a listener that the above shelf state changed
+     */
+    void onAboveShelfStateChanged(boolean aboveShelf);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java
new file mode 100644
index 0000000..f10d2d7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AboveShelfObserver.java
@@ -0,0 +1,73 @@
+/*
+ * 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.statusbar.notification;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+
+/**
+ * An observer that listens to the above shelf state and can notify listeners
+ */
+public class AboveShelfObserver implements AboveShelfChangedListener {
+
+    private final ViewGroup mHostLayout;
+    private boolean mHasViewsAboveShelf = false;
+    private HasViewAboveShelfChangedListener mListener;
+
+    public AboveShelfObserver(ViewGroup hostLayout) {
+        mHostLayout = hostLayout;
+    }
+
+    public void setListener(HasViewAboveShelfChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void onAboveShelfStateChanged(boolean aboveShelf) {
+        boolean hasViewsAboveShelf = aboveShelf;
+        if (!hasViewsAboveShelf && mHostLayout != null) {
+            int n = mHostLayout.getChildCount();
+            for (int i = 0; i < n; i++) {
+                View child = mHostLayout.getChildAt(i);
+                if (child instanceof ExpandableNotificationRow) {
+                    if (((ExpandableNotificationRow) child).isAboveShelf()) {
+                        hasViewsAboveShelf = true;
+                        break;
+                    }
+                }
+            }
+        }
+        if (mHasViewsAboveShelf != hasViewsAboveShelf) {
+            mHasViewsAboveShelf = hasViewsAboveShelf;
+            if (mListener != null) {
+                mListener.onHasViewsAboveShelfChanged(hasViewsAboveShelf);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    boolean hasViewsAboveShelf() {
+        return mHasViewsAboveShelf;
+    }
+
+    public interface HasViewAboveShelfChangedListener {
+        void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index e6b3fb8..92f26d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -48,10 +48,13 @@
 
     @Override
     protected boolean sameAs(TransformState otherState) {
+        if (super.sameAs(otherState)) {
+            return true;
+        }
         if (otherState instanceof ImageTransformState) {
             return mIcon != null && mIcon.sameAs(((ImageTransformState) otherState).getIcon());
         }
-        return super.sameAs(otherState);
+        return false;
     }
 
     @Override
@@ -113,7 +116,7 @@
     }
 
     @Override
-    protected boolean transformScale() {
+    protected boolean transformScale(TransformState otherState) {
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 15cca5f..fcc982ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -31,6 +31,7 @@
 
 import com.android.internal.widget.NotificationExpandButton;
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
@@ -61,9 +62,12 @@
     private ImageView mWorkProfileImage;
     private boolean mIsLowPriority;
     private boolean mTransformLowPriorityTitle;
+    private boolean mShowExpandButtonAtEnd;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(ctx, view, row);
+        mShowExpandButtonAtEnd = ctx.getResources().getBoolean(
+                R.bool.config_showNotificationExpandButtonAtEnd);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
@@ -114,6 +118,7 @@
         mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
         mColor = resolveColor(mExpandButton);
         mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
+        mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
         getDozer().setColor(mColor);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index abb4cf6..bb979eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.widget.ImageView;
@@ -41,6 +42,8 @@
     private TextView mTitle;
     private TextView mText;
     private View mActionsContainer;
+    private View mReplyAction;
+    private Rect mTmpRect = new Rect();
 
     private int mContentHeight;
     private int mMinHeightHint;
@@ -130,6 +133,29 @@
             mProgressBar = null;
         }
         mActionsContainer = mView.findViewById(com.android.internal.R.id.actions_container);
+        mReplyAction = mView.findViewById(com.android.internal.R.id.reply_icon_action);
+    }
+
+    @Override
+    public boolean disallowSingleClick(float x, float y) {
+        if (mReplyAction != null && mReplyAction.getVisibility() == View.VISIBLE) {
+            if (isOnView(mReplyAction, x, y) || isOnView(mPicture, x, y)) {
+                return true;
+            }
+        }
+        return super.disallowSingleClick(x, y);
+    }
+
+    private boolean isOnView(View view, float x, float y) {
+        View searchView = (View) view.getParent();
+        while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
+            searchView.getHitRect(mTmpRect);
+            x -= mTmpRect.left;
+            y -= mTmpRect.top;
+            searchView = (View) searchView.getParent();
+        }
+        view.getHitRect(mTmpRect);
+        return mTmpRect.contains((int) x,(int) y);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 4b73613..5200d69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -186,4 +186,8 @@
     public boolean isDimmable() {
         return true;
     }
+
+    public boolean disallowSingleClick(float x, float y) {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
index 6fe5756..c4aabe4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification;
 
 import android.text.Layout;
+import android.text.Spanned;
 import android.text.TextUtils;
 import android.util.Pools;
 import android.view.View;
@@ -41,16 +42,76 @@
 
     @Override
     protected boolean sameAs(TransformState otherState) {
+        if (super.sameAs(otherState)) {
+            return true;
+        }
         if (otherState instanceof TextViewTransformState) {
             TextViewTransformState otherTvs = (TextViewTransformState) otherState;
             if(TextUtils.equals(otherTvs.mText.getText(), mText.getText())) {
                 int ownEllipsized = getEllipsisCount();
                 int otherEllipsized = otherTvs.getEllipsisCount();
                 return ownEllipsized == otherEllipsized
-                        && getInnerHeight(mText) == getInnerHeight(otherTvs.mText);
+                        && mText.getLineCount() == otherTvs.mText.getLineCount()
+                        && hasSameSpans(otherTvs);
             }
         }
-        return super.sameAs(otherState);
+        return false;
+    }
+
+    private boolean hasSameSpans(TextViewTransformState otherTvs) {
+        boolean hasSpans = mText instanceof Spanned;
+        boolean otherHasSpans = otherTvs.mText instanceof Spanned;
+        if (hasSpans != otherHasSpans) {
+            return false;
+        } else if (!hasSpans) {
+            return true;
+        }
+        // Actually both have spans, let's try to compare them
+        Spanned ownSpanned = (Spanned) mText;
+        Object[] spans = ownSpanned.getSpans(0, ownSpanned.length(), Object.class);
+        Spanned otherSpanned = (Spanned) otherTvs.mText;
+        Object[] otherSpans = otherSpanned.getSpans(0, otherSpanned.length(), Object.class);
+        if (spans.length != otherSpans.length) {
+            return false;
+        }
+        for (int i = 0; i < spans.length; i++) {
+            Object span = spans[i];
+            Object otherSpan = otherSpans[i];
+            if (!span.getClass().equals(otherSpan.getClass())) {
+                return false;
+            }
+            if (ownSpanned.getSpanStart(span) != otherSpanned.getSpanStart(otherSpan)
+                    || ownSpanned.getSpanEnd(span) != otherSpanned.getSpanEnd(otherSpan)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected boolean transformScale(TransformState otherState) {
+        if (!(otherState instanceof TextViewTransformState)) {
+            return false;
+        }
+        TextViewTransformState otherTvs = (TextViewTransformState) otherState;
+        int lineCount = mText.getLineCount();
+        return lineCount == 1 && lineCount == otherTvs.mText.getLineCount()
+                && getEllipsisCount() == otherTvs.getEllipsisCount()
+                && getViewHeight() != otherTvs.getViewHeight();
+    }
+
+    @Override
+    protected int getViewWidth() {
+        Layout l = mText.getLayout();
+        if (l != null) {
+            return (int) l.getLineWidth(0);
+        }
+        return super.getViewWidth();
+    }
+
+    @Override
+    protected int getViewHeight() {
+        return mText.getLineHeight();
     }
 
     private int getInnerHeight(TextView text) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index c3f1cb1..bafedff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -54,6 +54,7 @@
 
     protected View mTransformedView;
     private int[] mOwnPosition = new int[2];
+    private boolean mSameAsAny;
     private float mTransformationEndY = UNDEFINED;
     private float mTransformationEndX = UNDEFINED;
 
@@ -107,7 +108,7 @@
         final View transformedView = mTransformedView;
         boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
         boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
-        boolean transformScale = transformScale();
+        boolean transformScale = transformScale(otherState);
         // lets animate the positions correctly
         if (transformationAmount == 0.0f
                 || transformX && getTransformationStartX() == UNDEFINED
@@ -131,16 +132,16 @@
                 }
                 // we also want to animate the scale if we're the same
                 View otherView = otherState.getTransformedView();
-                if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
-                    setTransformationStartScaleX(otherView.getWidth() * otherView.getScaleX()
-                            / (float) transformedView.getWidth());
+                if (transformScale && otherState.getViewWidth() != getViewWidth()) {
+                    setTransformationStartScaleX(otherState.getViewWidth() * otherView.getScaleX()
+                            / (float) getViewWidth());
                     transformedView.setPivotX(0);
                 } else {
                     setTransformationStartScaleX(UNDEFINED);
                 }
-                if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
-                    setTransformationStartScaleY(otherView.getHeight() * otherView.getScaleY()
-                            / (float) transformedView.getHeight());
+                if (transformScale && otherState.getViewHeight() != getViewHeight()) {
+                    setTransformationStartScaleY(otherState.getViewHeight() * otherView.getScaleY()
+                            / (float) getViewHeight());
                     transformedView.setPivotY(0);
                 } else {
                     setTransformationStartScaleY(UNDEFINED);
@@ -204,7 +205,15 @@
         }
     }
 
-    protected boolean transformScale() {
+    protected int getViewWidth() {
+        return mTransformedView.getWidth();
+    }
+
+    protected int getViewHeight() {
+        return mTransformedView.getHeight();
+    }
+
+    protected boolean transformScale(TransformState otherState) {
         return false;
     }
 
@@ -258,7 +267,7 @@
         final View transformedView = mTransformedView;
         boolean transformX = (transformationFlags & TRANSFORM_X) != 0;
         boolean transformY = (transformationFlags & TRANSFORM_Y) != 0;
-        boolean transformScale = transformScale();
+        boolean transformScale = transformScale(otherState);
         // lets animate the positions correctly
         if (transformationAmount == 0.0f) {
             if (transformX) {
@@ -274,13 +283,13 @@
                 setTransformationStartY(start);
             }
             View otherView = otherState.getTransformedView();
-            if (transformScale && otherView.getWidth() != transformedView.getWidth()) {
+            if (transformScale && otherState.getViewWidth() != getViewWidth()) {
                 setTransformationStartScaleX(transformedView.getScaleX());
                 transformedView.setPivotX(0);
             } else {
                 setTransformationStartScaleX(UNDEFINED);
             }
-            if (transformScale && otherView.getHeight() != transformedView.getHeight()) {
+            if (transformScale && otherState.getViewHeight() != getViewHeight()) {
                 setTransformationStartScaleY(transformedView.getScaleY());
                 transformedView.setPivotY(0);
             } else {
@@ -332,14 +341,14 @@
             if (transformationStartScaleX != UNDEFINED) {
                 transformedView.setScaleX(
                         NotificationUtils.interpolate(transformationStartScaleX,
-                                (otherView.getWidth() / (float) transformedView.getWidth()),
+                                (otherState.getViewWidth() / (float) getViewWidth()),
                                 interpolatedValue));
             }
             float transformationStartScaleY = getTransformationStartScaleY();
             if (transformationStartScaleY != UNDEFINED) {
                 transformedView.setScaleY(
                         NotificationUtils.interpolate(transformationStartScaleY,
-                                (otherView.getHeight() / (float) transformedView.getHeight()),
+                                (otherState.getViewHeight() / (float) getViewHeight()),
                                 interpolatedValue));
             }
         }
@@ -418,7 +427,7 @@
     }
 
     protected boolean sameAs(TransformState otherState) {
-        return false;
+        return mSameAsAny;
     }
 
     public void appear(float transformationAmount, TransformableView otherView) {
@@ -449,6 +458,9 @@
         if (view instanceof ImageView) {
             ImageTransformState result = ImageTransformState.obtain();
             result.initFrom(view);
+            if (view.getId() == com.android.internal.R.id.reply_icon_action) {
+                ((TransformState) result).setIsSameAsAnyView(true);
+            }
             return result;
         }
         if (view instanceof ProgressBar) {
@@ -461,6 +473,10 @@
         return result;
     }
 
+    private void setIsSameAsAnyView(boolean sameAsAny) {
+        mSameAsAny = sameAsAny;
+    }
+
     public void recycle() {
         reset();
         if (getClass() == TransformState.class) {
@@ -514,6 +530,7 @@
 
     protected void reset() {
         mTransformedView = null;
+        mSameAsAny = false;
         mTransformationEndX = UNDEFINED;
         mTransformationEndY = UNDEFINED;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 7512efa..1bd90fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -24,6 +24,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
+import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.SecureSetting;
 import com.android.systemui.statusbar.policy.DataSaverController;
@@ -36,39 +37,47 @@
  */
 public class AutoTileManager {
 
+    public static final String HOTSPOT = "hotspot";
+    public static final String SAVER = "saver";
+    public static final String INVERSION = "inversion";
+    public static final String WORK = "work";
+    public static final String NIGHT = "night";
     private final Context mContext;
     private final QSTileHost mHost;
     private final Handler mHandler;
+    private final AutoAddTracker mAutoTracker;
 
     public AutoTileManager(Context context, QSTileHost host) {
+        mAutoTracker = new AutoAddTracker(context);
         mContext = context;
         mHost = host;
         mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
-        if (!Prefs.getBoolean(context, Key.QS_HOTSPOT_ADDED, false)) {
+        if (!mAutoTracker.isAdded(HOTSPOT)) {
             Dependency.get(HotspotController.class).addCallback(mHotspotCallback);
         }
-        if (!Prefs.getBoolean(context, Key.QS_DATA_SAVER_ADDED, false)) {
+        if (!mAutoTracker.isAdded(SAVER)) {
             Dependency.get(DataSaverController.class).addCallback(mDataSaverListener);
         }
-        if (!Prefs.getBoolean(context, Key.QS_INVERT_COLORS_ADDED, false)) {
+        if (!mAutoTracker.isAdded(INVERSION)) {
             mColorsSetting = new SecureSetting(mContext, mHandler,
                     Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
                 @Override
                 protected void handleValueChanged(int value, boolean observedChange) {
+                    if (mAutoTracker.isAdded(INVERSION)) return;
                     if (value != 0) {
-                        mHost.addTile("inversion");
-                        Prefs.putBoolean(mContext, Key.QS_INVERT_COLORS_ADDED, true);
+                        mHost.addTile(INVERSION);
+                        mAutoTracker.setTileAdded(INVERSION);
                         mHandler.post(() -> mColorsSetting.setListening(false));
                     }
                 }
             };
             mColorsSetting.setListening(true);
         }
-        if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) {
+        if (!mAutoTracker.isAdded(WORK)) {
             Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
         }
 
-        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false)
+        if (!mAutoTracker.isAdded(NIGHT)
                 && NightDisplayController.isAvailable(mContext)) {
             Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);
         }
@@ -76,6 +85,7 @@
 
     public void destroy() {
         mColorsSetting.setListening(false);
+        mAutoTracker.destroy();
         Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
@@ -86,9 +96,10 @@
             new ManagedProfileController.Callback() {
                 @Override
                 public void onManagedProfileChanged() {
+                    if (mAutoTracker.isAdded(WORK)) return;
                     if (Dependency.get(ManagedProfileController.class).hasActiveProfile()) {
-                        mHost.addTile("work");
-                        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
+                        mHost.addTile(WORK);
+                        mAutoTracker.setTileAdded(WORK);
                         mHandler.post(() -> Dependency.get(ManagedProfileController.class)
                                 .removeCallback(mProfileCallback));
                     }
@@ -104,9 +115,10 @@
     private final DataSaverController.Listener mDataSaverListener = new Listener() {
         @Override
         public void onDataSaverChanged(boolean isDataSaving) {
+            if (mAutoTracker.isAdded(SAVER)) return;
             if (isDataSaving) {
-                mHost.addTile("saver");
-                Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
+                mHost.addTile(SAVER);
+                mAutoTracker.setTileAdded(SAVER);
                 mHandler.post(() -> Dependency.get(DataSaverController.class).removeCallback(
                         mDataSaverListener));
             }
@@ -116,9 +128,10 @@
     private final HotspotController.Callback mHotspotCallback = new Callback() {
         @Override
         public void onHotspotChanged(boolean enabled) {
+            if (mAutoTracker.isAdded(HOTSPOT)) return;
             if (enabled) {
-                mHost.addTile("hotspot");
-                Prefs.putBoolean(mContext, Key.QS_HOTSPOT_ADDED, true);
+                mHost.addTile(HOTSPOT);
+                mAutoTracker.setTileAdded(HOTSPOT);
                 mHandler.post(() -> Dependency.get(HotspotController.class)
                         .removeCallback(mHotspotCallback));
             }
@@ -144,8 +157,9 @@
         }
 
         private void addNightTile() {
-            mHost.addTile("night");
-            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true);
+            if (mAutoTracker.isAdded(NIGHT)) return;
+            mHost.addTile(NIGHT);
+            mAutoTracker.setTileAdded(NIGHT);
             mHandler.post(() -> Dependency.get(NightDisplayController.class)
                     .setListener(null));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
index 020dc25..37554c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
@@ -15,36 +15,76 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.os.LocaleList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
 
 import com.android.systemui.ConfigurationChangedReceiver;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 public class ConfigurationControllerImpl implements ConfigurationController,
         ConfigurationChangedReceiver {
 
     private final ArrayList<ConfigurationListener> mListeners = new ArrayList<>();
+    private final Configuration mLastConfig = new Configuration();
     private int mDensity;
     private float mFontScale;
+    private LocaleList mLocaleList;
 
     public ConfigurationControllerImpl(Context context) {
         Configuration currentConfig = context.getResources().getConfiguration();
         mFontScale = currentConfig.fontScale;
         mDensity = currentConfig.densityDpi;
+        mLocaleList = currentConfig.getLocales();
     }
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        mListeners.forEach(l -> l.onConfigChanged(newConfig));
+        // Avoid concurrent modification exception
+        ArrayList<ConfigurationListener> listeners = new ArrayList<>(mListeners);
+
+        listeners.forEach(l -> {
+            if (mListeners.contains(l)) {
+                l.onConfigChanged(newConfig);
+            }
+        });
         final float fontScale = newConfig.fontScale;
         final int density = newConfig.densityDpi;
         if (density != mDensity || mFontScale != fontScale) {
-            mListeners.forEach(l -> l.onDensityOrFontScaleChanged());
+            listeners.forEach(l -> {
+                if (mListeners.contains(l)) {
+                    l.onDensityOrFontScaleChanged();
+                }
+            });
             mDensity = density;
             mFontScale = fontScale;
         }
+
+        final LocaleList localeList = newConfig.getLocales();
+        if (!localeList.equals(mLocaleList)) {
+            mLocaleList = localeList;
+            listeners.forEach(l -> {
+                if (mListeners.contains(l)) {
+                    l.onLocaleListChanged();
+                }
+            });
+        }
+
+        if ((mLastConfig.updateFrom(newConfig) & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
+                listeners.forEach(l -> {
+                    if (mListeners.contains(l)) {
+                        l.onOverlayChanged();
+                    }
+                });
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index e1ca929..6b7397b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -77,6 +77,10 @@
         return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
     }
 
+    public boolean getDozeSuspendDisplayStateSupported() {
+        return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported);
+    }
+
     public int getPulseDuration(boolean pickup) {
         return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
     }
@@ -153,6 +157,10 @@
         return 2 * getPulseVisibleDuration();
     }
 
+    public boolean doubleTapReportsTouchCoordinates() {
+        return mContext.getResources().getBoolean(R.bool.doze_double_tap_reports_touch_coordinates);
+    }
+
 
     /**
      * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
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..c45c05e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -23,14 +23,11 @@
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
-import android.view.View;
 import android.view.animation.Interpolator;
 
-import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.Interpolators;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
-import com.android.systemui.doze.DozeTriggers;
 
 /**
  * Controller which handles all the doze animations of the scrims.
@@ -54,6 +51,9 @@
     private float mBehindTarget;
     private boolean mDozingAborted;
     private boolean mWakeAndUnlocking;
+    private boolean mFullyPulsing;
+
+    private float mAodFrontScrimOpacity = 0;
 
     public DozeScrimController(ScrimController scrimController, Context context) {
         mContext = context;
@@ -69,7 +69,8 @@
             mDozingAborted = false;
             abortAnimations();
             mScrimController.setDozeBehindAlpha(1f);
-            mScrimController.setDozeInFrontAlpha(mDozeParameters.getAlwaysOn() ? 0f : 1f);
+            mScrimController.setDozeInFrontAlpha(
+                    mDozeParameters.getAlwaysOn() ? mAodFrontScrimOpacity : 1f);
         } else {
             cancelPulsing();
             if (animate) {
@@ -87,6 +88,19 @@
         }
     }
 
+    /**
+     * Set the opacity of the front scrim when showing AOD1
+     *
+     * Used to emulate lower brightness values than the hardware supports natively.
+     */
+    public void setAodDimmingScrim(float scrimOpacity) {
+        mAodFrontScrimOpacity = scrimOpacity;
+        if (mDozing && !isPulsing() && !mDozingAborted && !mWakeAndUnlocking
+                && mDozeParameters.getAlwaysOn()) {
+            mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+        }
+    }
+
     public void setWakeAndUnlocking() {
         // Immediately abort the doze scrims in case of wake-and-unlock
         // for pulsing so the Keyguard fade-out animation scrim can take over.
@@ -113,6 +127,7 @@
         // be invoked when we're done so that the caller can drop the pulse wakelock.
         mPulseCallback = callback;
         mPulseReason = reason;
+        mScrimController.setDozeInFrontAlpha(1f);
         mHandler.post(mPulseIn);
     }
 
@@ -124,7 +139,8 @@
         if (mDozing && !mWakeAndUnlocking) {
             mScrimController.setDozeBehindAlpha(1f);
             mScrimController.setDozeInFrontAlpha(
-                    mDozeParameters.getAlwaysOn() && !mDozingAborted ? 0f : 1f);
+                    mDozeParameters.getAlwaysOn() && !mDozingAborted ?
+                            mAodFrontScrimOpacity : 1f);
         }
     }
 
@@ -136,6 +152,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 +185,7 @@
         if (DEBUG) Log.d(TAG, "Cancel pulsing");
 
         if (mPulseCallback != null) {
+            mFullyPulsing = false;
             mHandler.removeCallbacks(mPulseIn);
             mHandler.removeCallbacks(mPulseOut);
             mHandler.removeCallbacks(mPulseOutExtended);
@@ -282,10 +305,6 @@
 
             // Signal that the pulse is ready to turn the screen on and draw.
             pulseStarted();
-
-            if (mDozeParameters.getAlwaysOn()) {
-                mHandler.post(DozeScrimController.this::onScreenTurnedOn);
-            }
         }
     };
 
@@ -297,6 +316,7 @@
             mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
             mHandler.postDelayed(mPulseOutExtended,
                     mDozeParameters.getPulseVisibleDurationExtended());
+            mFullyPulsing = true;
         }
     };
 
@@ -311,23 +331,41 @@
     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;
-            startScrimAnimation(true /* inFront */, mDozeParameters.getAlwaysOn() ? 0 : 1,
+            startScrimAnimation(true /* inFront */, 1,
                     mDozeParameters.getPulseOutDuration(),
-                    Interpolators.ALPHA_IN, mPulseOutFinished);
+                    Interpolators.ALPHA_IN, mPulseOutFinishing);
+        }
+    };
+
+    private final Runnable mPulseOutFinishing = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG) Log.d(TAG, "Pulse out finished");
+            DozeLog.tracePulseFinish();
+            if (mDozeParameters.getAlwaysOn() && mDozing) {
+                // Setting power states can block rendering. For AOD, delay finishing the pulse and
+                // setting the power state until the fully black scrim had time to hit the
+                // framebuffer.
+                mHandler.postDelayed(mPulseOutFinished, 30);
+            } else {
+                mPulseOutFinished.run();
+            }
         }
     };
 
     private final Runnable mPulseOutFinished = new Runnable() {
         @Override
         public void run() {
-            if (DEBUG) Log.d(TAG, "Pulse out finished");
-            DozeLog.tracePulseFinish();
-
             // Signal that the pulse is all finished so we can turn the screen off now.
-            pulseFinished();
+            DozeScrimController.this.pulseFinished();
+            if (mDozeParameters.getAlwaysOn()) {
+                mScrimController.setDozeInFrontAlpha(mAodFrontScrimOpacity);
+            }
         }
     };
 }
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..cb96dea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -29,6 +29,8 @@
 import com.android.keyguard.LatencyTracker;
 import com.android.systemui.Dependency;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 
 /**
  * Controller which coordinates all the fingerprint unlocking actions with the UI.
@@ -99,6 +101,8 @@
     private final UnlockMethodCache mUnlockMethodCache;
     private final Context mContext;
     private int mPendingAuthenticatedUserId = -1;
+    private boolean mPendingShowBouncer;
+    private boolean mHasScreenTurnedOnSinceAuthenticating;
 
     public FingerprintUnlockController(Context context,
             DozeScrimController dozeScrimController,
@@ -110,6 +114,8 @@
         mPowerManager = context.getSystemService(PowerManager.class);
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
         mUpdateMonitor.registerCallback(this);
+        Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
+        Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
         mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
         mDozeScrimController = dozeScrimController;
         mKeyguardViewMediator = keyguardViewMediator;
@@ -163,18 +169,16 @@
             }
             mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
                     FINGERPRINT_WAKELOCK_TIMEOUT_MS);
-            if (mDozeScrimController.isPulsing()) {
-
-                // 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
-                // until the clock and the notifications are faded out.
-                mStatusBarWindowManager.setForceDozeBrightness(true);
-            }
         }
         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");
@@ -183,8 +187,20 @@
             Trace.endSection();
             return;
         }
+        startWakeAndUnlock(calculateMode());
+    }
+
+    public void startWakeAndUnlock(int mode) {
         boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
-        mMode = calculateMode();
+        mMode = mode;
+        mHasScreenTurnedOnSinceAuthenticating = false;
+        if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && 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
+            // until the clock and the notifications are faded out.
+            mStatusBarWindowManager.setForceDozeBrightness(true);
+        }
         if (!wasDeviceInteractive) {
             if (DEBUG_FP_WAKELOCK) {
                 Log.i(TAG, "fp wakelock: Authenticated, waking up...");
@@ -206,9 +222,10 @@
                 Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
                 if (!wasDeviceInteractive) {
                     mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+                    mPendingShowBouncer = true;
+                } else {
+                    showBouncer();
                 }
-                mStatusBarKeyguardViewManager.animateCollapsePanels(
-                        FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
                 Trace.endSection();
                 break;
             case MODE_WAKE_AND_UNLOCK_PULSING:
@@ -219,6 +236,7 @@
                             true /* allowEnterAnimation */);
                 } else {
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
+
                     mDozeScrimController.abortDoze();
                 }
                 mStatusBarWindowManager.setStatusBarFocusable(false);
@@ -234,13 +252,16 @@
             case MODE_NONE:
                 break;
         }
-        if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
-            mStatusBarWindowManager.setForceDozeBrightness(false);
-        }
         mStatusBar.notifyFpAuthModeChanged();
         Trace.endSection();
     }
 
+    private void showBouncer() {
+        mStatusBarKeyguardViewManager.animateCollapsePanels(
+                FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+        mPendingShowBouncer = false;
+    }
+
     @Override
     public void onStartedGoingToSleep(int why) {
         mPendingAuthenticatedUserId = -1;
@@ -263,12 +284,19 @@
         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;
@@ -325,4 +353,26 @@
         }
         mStatusBar.notifyFpAuthModeChanged();
     }
+
+    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
+            new WakefulnessLifecycle.Observer() {
+        @Override
+        public void onFinishedWakingUp() {
+            if (mPendingShowBouncer) {
+                FingerprintUnlockController.this.showBouncer();
+            }
+        }
+    };
+
+    private final ScreenLifecycle.Observer mScreenObserver =
+            new ScreenLifecycle.Observer() {
+                @Override
+                public void onScreenTurnedOn() {
+                    mHasScreenTurnedOnSinceAuthenticating = true;
+                }
+            };
+
+    public boolean hasScreenTurnedOnSinceAuthenticating() {
+        return mHasScreenTurnedOnSinceAuthenticating;
+    }
 }
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 6fe8827..6cfa838 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -100,6 +100,7 @@
     public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
     public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
     public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
+    public static final String CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = "lift_to_launch_ml";
 
     public static final String EXTRA_CAMERA_LAUNCH_SOURCE
             = "com.android.systemui.camera_launch_source";
@@ -125,6 +126,7 @@
     private TextView mEnterpriseDisclosure;
     private TextView mIndicationText;
     private ViewGroup mPreviewContainer;
+    private ViewGroup mOverlayContainer;
 
     private View mLeftPreview;
     private View mCameraPreview;
@@ -228,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);
@@ -235,10 +238,12 @@
         mEnterpriseDisclosure = findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mIndicationText = findViewById(R.id.keyguard_indication_text);
-        watchForCameraPolicyChanges();
         updateCameraVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
+        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+        mLockIcon.setScreenOn(updateMonitor.isScreenOn());
+        mLockIcon.setDeviceInteractive(updateMonitor.isDeviceInteractive());
         mLockIcon.update();
         setClipChildren(false);
         setClipToPadding(false);
@@ -253,6 +258,7 @@
         mFlashlightController = Dependency.get(FlashlightController.class);
         mAccessibilityController = Dependency.get(AccessibilityController.class);
         mAssistManager = Dependency.get(AssistManager.class);
+        mLockIcon.setAccessibilityController(mAccessibilityController);
         updateLeftAffordance();
     }
 
@@ -274,6 +280,11 @@
                 .withDefault(() -> new DefaultLeftButton())
                 .withCallback(button -> setLeftButton(button))
                 .build();
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+        getContext().registerReceiverAsUser(mDevicePolicyReceiver,
+                UserHandle.ALL, filter, null, null);
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
     }
 
     @Override
@@ -282,6 +293,8 @@
         mAccessibilityController.removeStateChangedCallback(this);
         mRightExtension.destroy();
         mLeftExtension.destroy();
+        getContext().unregisterReceiver(mDevicePolicyReceiver);
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
     }
 
     private void initAccessibility() {
@@ -319,6 +332,7 @@
         lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
         lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
         mLockIcon.setLayoutParams(lp);
+        mLockIcon.setContentDescription(getContext().getText(R.string.accessibility_unlock_button));
         mLockIcon.update(true /* force */);
 
         lp = mLeftAffordanceView.getLayoutParams();
@@ -397,32 +411,6 @@
                 && pm.resolveActivity(PHONE_INTENT, 0) != null;
     }
 
-    private boolean isCameraDisabledByDpm() {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (dpm != null && mStatusBar != null) {
-            try {
-                final int userId = ActivityManager.getService().getCurrentUser().id;
-                final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
-                final  boolean disabledBecauseKeyguardSecure =
-                        (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
-                                && mStatusBar.isKeyguardSecure();
-                return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Can't get userId", e);
-            }
-        }
-        return false;
-    }
-
-    private void watchForCameraPolicyChanges() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        getContext().registerReceiverAsUser(mDevicePolicyReceiver,
-                UserHandle.ALL, filter, null, null);
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
-    }
-
     @Override
     public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) {
         mRightAffordanceView.setClickable(touchExplorationEnabled);
@@ -819,8 +807,10 @@
 
         if (dozing) {
             mLockIcon.setVisibility(INVISIBLE);
+            mOverlayContainer.setVisibility(INVISIBLE);
         } else {
             mLockIcon.setVisibility(VISIBLE);
+            mOverlayContainer.setVisibility(VISIBLE);
             if (animate) {
                 startFinishDozeAnimation();
             }
@@ -865,7 +855,8 @@
         @Override
         public IconState getIcon() {
             ResolveInfo resolved = resolveCameraIntent();
-            mIconState.isVisible = !isCameraDisabledByDpm() && resolved != null
+            boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
+            mIconState.isVisible = !isCameraDisabled && resolved != null
                     && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                     && mUserSetupComplete;
             mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 95f32bb..fd95cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -234,8 +234,11 @@
     }
 
     protected void ensureView() {
-        mHandler.removeCallbacks(mRemoveViewRunnable);
-        if (mRoot == null) {
+        // Removal of the view might be deferred to reduce unlock latency,
+        // in this case we need to force the removal, otherwise we'll
+        // end up in an unpredictable state.
+        boolean forceRemoval = mHandler.hasCallbacks(mRemoveViewRunnable);
+        if (mRoot == null || forceRemoval) {
             inflateView();
         }
     }
@@ -249,6 +252,7 @@
         mKeyguardView.setViewMediatorCallback(mCallback);
         mContainer.addView(mRoot, mContainer.getChildCount());
         mRoot.setVisibility(View.INVISIBLE);
+        mRoot.dispatchApplyWindowInsets(mRoot.getRootWindowInsets());
     }
 
     protected void removeView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 7370c03..e65bab6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -16,13 +16,14 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
+
 import android.content.res.Resources;
 import android.graphics.Path;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.NotificationUtils;
 
 /**
  * Utility class to calculate the clock position and top padding of notifications on Keyguard.
@@ -40,6 +41,10 @@
     private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f;
     private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f;
 
+    private static final long MILLIS_PER_MINUTES = 1000 * 60;
+    private static final float BURN_IN_PREVENTION_PERIOD_Y = 521;
+    private static final float BURN_IN_PREVENTION_PERIOD_X = 83;
+
     private int mClockNotificationsMarginMin;
     private int mClockNotificationsMarginMax;
     private float mClockYFractionMin;
@@ -52,6 +57,8 @@
     private int mKeyguardStatusHeight;
     private float mEmptyDragAmount;
     private float mDensity;
+    private int mBurnInPreventionOffsetX;
+    private int mBurnInPreventionOffsetY;
 
     /**
      * The number (fractional) of notifications the "more" card counts when calculating how many
@@ -71,6 +78,7 @@
     private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
     private int mClockBottom;
     private float mDarkAmount;
+    private int mDozingStackPadding;
 
     /**
      * Refreshes the dimension values.
@@ -86,6 +94,11 @@
                 (float) res.getDimensionPixelSize(R.dimen.notification_shelf_height) /
                         res.getDimensionPixelSize(R.dimen.notification_min_height);
         mDensity = res.getDisplayMetrics().density;
+        mBurnInPreventionOffsetX = res.getDimensionPixelSize(
+                R.dimen.burn_in_prevention_offset_x);
+        mBurnInPreventionOffsetY = res.getDimensionPixelSize(
+                R.dimen.burn_in_prevention_offset_y);
+        mDozingStackPadding = res.getDimensionPixelSize(R.dimen.dozing_stack_padding);
     }
 
     public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
@@ -122,10 +135,12 @@
                 y + getClockNotificationsPadding() + mKeyguardStatusHeight);
         result.clockAlpha = getClockAlpha(result.clockScale);
 
-        result.stackScrollerPadding = (int) NotificationUtils.interpolate(
+        result.stackScrollerPadding = (int) interpolate(
                 result.stackScrollerPadding,
-                mClockBottom + y,
+                mClockBottom + y + mDozingStackPadding,
                 mDarkAmount);
+
+        result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
     }
 
     private float getClockScale(int notificationPadding, int clockY, int startPadding) {
@@ -154,9 +169,39 @@
     private int getClockY() {
         // Dark: Align the bottom edge of the clock at one third:
         // clockBottomEdge = result - mKeyguardStatusHeight / 2 + mClockBottom
-        float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom);
+        float clockYDark = (0.33f * mHeight + (float) mKeyguardStatusHeight / 2 - mClockBottom)
+                + burnInPreventionOffsetY();
         float clockYRegular = getClockYFraction() * mHeight;
-        return (int) NotificationUtils.interpolate(clockYRegular, clockYDark, mDarkAmount);
+        return (int) interpolate(clockYRegular, clockYDark, mDarkAmount);
+    }
+
+    private float burnInPreventionOffsetY() {
+        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+                mBurnInPreventionOffsetY * 2,
+                BURN_IN_PREVENTION_PERIOD_Y)
+                - mBurnInPreventionOffsetY;
+    }
+
+    private float burnInPreventionOffsetX() {
+        return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
+                mBurnInPreventionOffsetX * 2,
+                BURN_IN_PREVENTION_PERIOD_X)
+                - mBurnInPreventionOffsetX;
+    }
+
+    /**
+     * Implements a continuous, piecewise linear, periodic zig-zag function
+     *
+     * Can be thought of as a linear approximation of abs(sin(x)))
+     *
+     * @param period period of the function, ie. zigzag(x + period) == zigzag(x)
+     * @param amplitude maximum value of the function
+     * @return a value between 0 and amplitude
+     */
+    private float zigzag(float x, float amplitude, float period) {
+        float xprime = (x % period) / (period / 2);
+        float interpolationAmount = (xprime <= 1) ? xprime : (2 - xprime);
+        return interpolate(0, amplitude, interpolationAmount);
     }
 
     private float getClockYExpansionAdjustment() {
@@ -230,5 +275,8 @@
          * the padding, but not the overall panel size.
          */
         public int stackScrollerPaddingAdjustment;
+
+        /** The x translation of the clock. */
+        public int clockX;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 42b09df..a6691b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,35 +16,48 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
+import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
+import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
+import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 
 /**
  * The header group on Keyguard.
  */
 public class KeyguardStatusBarView extends RelativeLayout
-        implements BatteryStateChangeCallback, OnUserInfoChangedListener {
+        implements BatteryStateChangeCallback, OnUserInfoChangedListener, ConfigurationListener {
 
     private boolean mBatteryCharging;
     private boolean mKeyguardUserSwitcherShowing;
@@ -63,6 +76,7 @@
     private int mSystemIconsSwitcherHiddenExpandedMargin;
     private int mSystemIconsBaseMargin;
     private View mSystemIconsContainer;
+    private TintedIconManager mIconManager;
 
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -203,12 +217,18 @@
         mUserSwitcherController = Dependency.get(UserSwitcherController.class);
         mMultiUserSwitch.setUserSwitcherController(mUserSwitcherController);
         userInfoController.reloadUserInfo();
+        Dependency.get(ConfigurationController.class).addCallback(this);
+        mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
+        Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
+        onOverlayChanged();
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         Dependency.get(UserInfoController.class).removeCallback(this);
+        Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     @Override
@@ -312,4 +332,30 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    public void onOverlayChanged() {
+        @ColorInt int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor);
+        @ColorInt int iconColor = Utils.getDefaultColor(mContext, Color.luminance(textColor) < 0.5 ?
+                R.color.dark_mode_icon_color_single_tone :
+                R.color.light_mode_icon_color_single_tone);
+        float intensity = textColor == Color.WHITE ? 0 : 1;
+        mCarrierLabel.setTextColor(iconColor);
+        mBatteryView.setFillColor(iconColor);
+        mIconManager.setTint(iconColor);
+        Rect tintArea = new Rect(0, 0, 0, 0);
+
+        applyDarkness(R.id.signal_cluster, tintArea, intensity, iconColor);
+        applyDarkness(R.id.battery, tintArea, intensity, iconColor);
+        applyDarkness(R.id.clock, tintArea, intensity, iconColor);
+        // Reload user avatar
+        ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
+                .onDensityOrFontScaleChanged();
+    }
+
+    private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
+        View v = findViewById(id);
+        if (v instanceof DarkReceiver) {
+            ((DarkReceiver) v).onDarkChanged(tintArea, intensity, color);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 9d699cf..917a56f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.WallpaperColors;
+import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.view.View;
 
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 
@@ -49,6 +54,7 @@
     private boolean mDockedLight;
     private int mLastStatusBarMode;
     private int mLastNavigationBarMode;
+    private final Color mDarkModeColor;
 
     /**
      * Whether the navigation bar should be light factoring in already how much alpha the scrim has
@@ -61,12 +67,14 @@
      */
     private boolean mHasLightNavigationBar;
     private boolean mScrimAlphaBelowThreshold;
+    private boolean mInvertLightNavBarWithScrim;
     private float mScrimAlpha;
 
     private final Rect mLastFullscreenBounds = new Rect();
     private final Rect mLastDockedBounds = new Rect();
 
-    public LightBarController() {
+    public LightBarController(Context ctx) {
+        mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone));
         mStatusBarIconController = Dependency.get(DarkIconDispatcher.class);
         mBatteryController = Dependency.get(BatteryController.class);
         mBatteryController.addCallback(this);
@@ -74,6 +82,7 @@
 
     public void setNavigationBar(LightBarTransitionsController navigationBar) {
         mNavigationBarController = navigationBar;
+        updateNavigation();
     }
 
     public void setFingerprintUnlockController(
@@ -119,7 +128,8 @@
             boolean last = mNavigationLight;
             mHasLightNavigationBar = isLight(vis, navigationBarMode,
                     View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
-            mNavigationLight = mHasLightNavigationBar && mScrimAlphaBelowThreshold;
+            mNavigationLight = mHasLightNavigationBar
+                    && (mScrimAlphaBelowThreshold || !mInvertLightNavBarWithScrim);
             if (mNavigationLight != last) {
                 updateNavigation();
             }
@@ -145,6 +155,15 @@
         }
     }
 
+    public void setScrimColor(GradientColors colors) {
+        boolean invertLightNavBarWithScrimBefore = mInvertLightNavBarWithScrim;
+        mInvertLightNavBarWithScrim = !colors.supportsDarkText();
+        if (mHasLightNavigationBar
+                && invertLightNavBarWithScrimBefore != mInvertLightNavBarWithScrim) {
+            reevaluate();
+        }
+    }
+
     private boolean isLight(int vis, int barMode, int flag) {
         boolean isTransparentBar = (barMode == MODE_TRANSPARENT
                 || barMode == MODE_LIGHTS_OUT_TRANSPARENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 6bd959f..b0ac6ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -23,8 +23,8 @@
 import android.os.SystemClock;
 import android.util.TimeUtils;
 
-import com.android.systemui.Dumpable;
 import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
 import com.android.systemui.Interpolators;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.statusbar.CommandQueue;
@@ -55,7 +55,6 @@
     private ValueAnimator mTintAnimator;
     private float mDarkIntensity;
     private float mNextDarkIntensity;
-
     private final Runnable mTransitionDeferringDoneRunnable = new Runnable() {
         @Override
         public void run() {
@@ -130,6 +129,7 @@
     public void setIconsDark(boolean dark, boolean animate) {
         if (!animate) {
             setIconTintInternal(dark ? 1.0f : 0.0f);
+            mNextDarkIntensity = dark ? 1.0f : 0.0f;
         } else if (mTransitionPending) {
             deferIconTintChange(dark ? 1.0f : 0.0f);
         } else if (mTransitionDeferring) {
@@ -155,19 +155,19 @@
 
     private void animateIconTint(float targetDarkIntensity, long delay,
             long duration) {
+        if (mNextDarkIntensity == targetDarkIntensity) {
+            return;
+        }
         if (mTintAnimator != null) {
             mTintAnimator.cancel();
         }
-        if (mDarkIntensity == targetDarkIntensity) {
-            return;
-        }
         mNextDarkIntensity = targetDarkIntensity;
         mTintAnimator = ValueAnimator.ofFloat(mDarkIntensity, targetDarkIntensity);
         mTintAnimator.addUpdateListener(
                 animation -> setIconTintInternal((Float) animation.getAnimatedValue()));
         mTintAnimator.setDuration(duration);
         mTintAnimator.setStartDelay(delay);
-        mTintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mTintAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         mTintAnimator.start();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index bccc5d5..c241290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -178,7 +178,7 @@
                     : 0);
             setRestingAlpha(
                     anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
-            setImageDrawable(icon);
+            setImageDrawable(icon, false);
             mHasFingerPrintIcon = anyFingerprintIcon;
             if (animation != null && isAnim) {
                 animation.forceAnimationOnUI();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 99b3aa8..87f5ca7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -36,6 +36,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.app.WallpaperColors;
 import android.util.Log;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -156,6 +157,11 @@
         postUpdateWallpaper();
     }
 
+    @Override
+    public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) {
+
+    }
+
     private void postUpdateWallpaper() {
         mH.removeCallbacks(this);
         mH.post(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index c30bb9a..f393dcd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -30,6 +30,8 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
@@ -74,7 +76,8 @@
         if (mUserListener == null) {
             return false;
         }
-        return mUserListener.getUserCount() != 0;
+        return mUserListener.getUserCount() != 0
+                && Prefs.getBoolean(getContext(), Key.SEEN_MULTI_USER, false);
     }
 
     public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index d047fa9..fbad937 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -45,7 +45,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
-import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -94,7 +93,7 @@
  */
 public class NavigationBarFragment extends Fragment implements Callbacks {
 
-    private static final String TAG = "NavigationBar";
+    public static final String TAG = "NavigationBar";
     private static final boolean DEBUG = false;
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
 
@@ -202,8 +201,7 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_SCREEN_ON);
         getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-        PowerManager pm = getContext().getSystemService(PowerManager.class);
-        notifyNavigationBarScreenOn(pm.isScreenOn());
+        notifyNavigationBarScreenOn();
     }
 
     @Override
@@ -378,8 +376,8 @@
                 ((View) mNavigationBarView.getParent()).getLayoutParams());
     }
 
-    private void notifyNavigationBarScreenOn(boolean screenOn) {
-        mNavigationBarView.notifyScreenOn(screenOn);
+    private void notifyNavigationBarScreenOn() {
+        mNavigationBarView.notifyScreenOn();
     }
 
     private void prepareNavigationBarView() {
@@ -604,10 +602,6 @@
         return mNavigationBarMode == MODE_SEMI_TRANSPARENT;
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-        mNavigationBarView.onKeyguardOccludedChanged(keyguardOccluded);
-    }
-
     public void disableAnimationsDuringHide(long delay) {
         mNavigationBarView.setLayoutTransitionsEnabled(false);
         mNavigationBarView.postDelayed(() -> mNavigationBarView.setLayoutTransitionsEnabled(true),
@@ -663,10 +657,9 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                notifyNavigationBarScreenOn(false);
-            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
-                notifyNavigationBarScreenOn(true);
+            if (Intent.ACTION_SCREEN_OFF.equals(action)
+                    || Intent.ACTION_SCREEN_ON.equals(action)) {
+                notifyNavigationBarScreenOn();
             }
         }
     };
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 720ca14..aaa31b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -19,9 +19,11 @@
 import android.content.res.Configuration;
 import android.graphics.drawable.Icon;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Display.Mode;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -35,6 +37,7 @@
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -43,6 +46,8 @@
 import java.util.List;
 import java.util.Objects;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 public class NavigationBarInflaterView extends FrameLayout
         implements Tunable, PluginListener<NavBarButtonProvider> {
 
@@ -71,6 +76,8 @@
     public static final String KEY_CODE_START = "(";
     public static final String KEY_IMAGE_DELIM = ":";
     public static final String KEY_CODE_END = ")";
+    private static final String WEIGHT_SUFFIX = "W";
+    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
 
     private final List<NavBarButtonProvider> mPlugins = new ArrayList<>();
 
@@ -219,26 +226,27 @@
         String[] center = sets[1].split(BUTTON_SEPARATOR);
         String[] end = sets[2].split(BUTTON_SEPARATOR);
         // Inflate these in start to end order or accessibility traversal will be messed up.
-        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(start, mRot0.findViewById(R.id.ends_group), isRot0Landscape, true);
+        inflateButtons(start, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, true);
 
-        inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), isRot0Landscape);
-        inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), !isRot0Landscape);
+        inflateButtons(center, mRot0.findViewById(R.id.center_group), isRot0Landscape, false);
+        inflateButtons(center, mRot90.findViewById(R.id.center_group), !isRot0Landscape, false);
 
-        addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
-        addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot0.findViewById(R.id.ends_group));
+        addGravitySpacer(mRot90.findViewById(R.id.ends_group));
 
-        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), isRot0Landscape);
-        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), !isRot0Landscape);
+        inflateButtons(end, mRot0.findViewById(R.id.ends_group), isRot0Landscape, false);
+        inflateButtons(end, mRot90.findViewById(R.id.ends_group), !isRot0Landscape, false);
     }
 
     private void addGravitySpacer(LinearLayout layout) {
         layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
     }
 
-    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
+    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
+            boolean start) {
         for (int i = 0; i < buttons.length; i++) {
-            inflateButton(buttons[i], parent, landscape);
+            inflateButton(buttons[i], parent, landscape, start);
         }
     }
 
@@ -251,40 +259,66 @@
     }
 
     @Nullable
-    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) {
+    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+            boolean start) {
         LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
-        float size = extractSize(buttonSpec);
-        View v = createView(buttonSpec, parent, inflater, landscape);
+        View v = createView(buttonSpec, parent, inflater);
         if (v == null) return null;
 
-        if (size != 0) {
-            ViewGroup.LayoutParams params = v.getLayoutParams();
-            params.width = (int) (params.width * size);
-        }
+        v = applySize(v, buttonSpec, landscape, start);
         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;
     }
 
-    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater,
-            boolean landscape) {
+    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
+        String sizeStr = extractSize(buttonSpec);
+        if (sizeStr == null) return v;
+
+        if (sizeStr.contains(WEIGHT_SUFFIX)) {
+            float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
+            FrameLayout frame = new ReverseFrameLayout(mContext);
+            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
+            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
+                childParams.gravity = Gravity.CENTER;
+            } else {
+                childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
+                        : (start ? Gravity.START : Gravity.END);
+            }
+            frame.addView(v, childParams);
+            frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+            frame.setClipChildren(false);
+            frame.setClipToPadding(false);
+            return frame;
+        }
+        float size = Float.parseFloat(sizeStr);
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        params.width = (int) (params.width * size);
+        return v;
+    }
+
+    private View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
         View v = null;
         String button = extractButton(buttonSpec);
         if (LEFT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
+            button = extractButton(s);
         } else if (RIGHT.equals(button)) {
-            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
-            button = extractButton(buttonSpec);
+            String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
+            button = extractButton(s);
         }
         // Let plugins go first so they can override a standard view if they want.
         for (NavBarButtonProvider provider : mPlugins) {
@@ -340,13 +374,12 @@
         return Integer.parseInt(subStr);
     }
 
-    public static float extractSize(String buttonSpec) {
+    public static String extractSize(String buttonSpec) {
         if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return 1;
+            return null;
         }
         final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
-        String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
-        return Float.parseFloat(sizeStr);
+        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
     }
 
     public static String extractButton(String buttonSpec) {
@@ -379,8 +412,8 @@
                 mButtonDispatchers.valueAt(i).clear();
             }
         }
-        clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons));
-        clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot0.findViewById(R.id.nav_buttons));
+        clearAllChildren(mRot90.findViewById(R.id.nav_buttons));
     }
 
     private void clearAllChildren(ViewGroup group) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 0557cb1..d116bbf3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -59,6 +59,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
     final static boolean DEBUG = false;
@@ -74,7 +75,6 @@
     View[] mRotatedViews = new View[4];
 
     boolean mVertical;
-    boolean mScreenOn;
     private int mCurrentRotation = -1;
 
     boolean mShowMenu;
@@ -317,7 +317,8 @@
             mDockedIcon = getDrawable(ctx,
                     R.drawable.ic_sysbar_docked, R.drawable.ic_sysbar_docked_dark);
         }
-        if (oldConfig.densityDpi != newConfig.densityDpi) {
+        if (oldConfig.densityDpi != newConfig.densityDpi
+                || oldConfig.getLayoutDirection() != newConfig.getLayoutDirection()) {
             mBackIcon = getDrawable(ctx, R.drawable.ic_sysbar_back, R.drawable.ic_sysbar_back_dark);
             mBackLandIcon = mBackIcon;
             mBackAltIcon = getDrawable(ctx,
@@ -364,8 +365,7 @@
         super.setLayoutDirection(layoutDirection);
     }
 
-    public void notifyScreenOn(boolean screenOn) {
-        mScreenOn = screenOn;
+    public void notifyScreenOn() {
         setDisabledFlags(mDisabledFlags, true);
     }
 
@@ -565,10 +565,7 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        DockedStackExistsListener.register(exists -> mHandler.post(() -> {
-            mDockedStackExists = exists;
-            updateRecentsIcon();
-        }));
+        DockedStackExistsListener.register(mDockedListener);
     }
 
     void updateRotatedViews() {
@@ -630,9 +627,6 @@
         getHomeButton().setVertical(mVertical);
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-    }
-
     private void updateTaskSwitchHelper() {
         if (mGestureHelper == null) return;
         boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
@@ -669,7 +663,8 @@
         updateTaskSwitchHelper();
         updateIcons(getContext(), mConfiguration, newConfig);
         updateRecentsIcon();
-        if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi) {
+        if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi
+                || mConfiguration.getLayoutDirection() != newConfig.getLayoutDirection()) {
             // If car mode or density changes, we need to reset the icons.
             setNavigationIconHints(mNavigationIconHints, true);
         }
@@ -836,4 +831,8 @@
         void onVerticalChanged(boolean isVertical);
     }
 
+    private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+        mDockedStackExists = exists;
+        updateRecentsIcon();
+    });
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
new file mode 100644
index 0000000..004a604
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
@@ -0,0 +1,115 @@
+/*
+ * 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.statusbar.phone;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+/**
+ * Redirects touches that aren't handled by any child view to the nearest
+ * clickable child. Only takes effect on <sw600dp.
+ */
+public class NearestTouchFrame extends FrameLayout {
+
+    private final ArrayList<View> mClickableChildren = new ArrayList<>();
+    private final boolean mIsActive;
+    private final int[] mTmpInt = new int[2];
+    private final int[] mOffset = new int[2];
+    private View mTouchingChild;
+
+    public NearestTouchFrame(Context context, AttributeSet attrs) {
+        this(context, attrs, context.getResources().getConfiguration());
+    }
+
+    @VisibleForTesting
+    NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
+        super(context, attrs);
+        mIsActive = c.smallestScreenWidthDp < 600;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        mClickableChildren.clear();
+        addClickableChildren(this);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        getLocationInWindow(mOffset);
+    }
+
+    private void addClickableChildren(ViewGroup group) {
+        final int N = group.getChildCount();
+        for (int i = 0; i < N; i++) {
+            View child = group.getChildAt(i);
+            if (child.isClickable()) {
+                mClickableChildren.add(child);
+            } else if (child instanceof ViewGroup) {
+                addClickableChildren((ViewGroup) child);
+            }
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mIsActive) {
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                mTouchingChild = findNearestChild(event);
+            }
+            if (mTouchingChild != null) {
+                event.offsetLocation(mTouchingChild.getWidth() / 2 - event.getX(),
+                        mTouchingChild.getHeight() / 2 - event.getY());
+                return mTouchingChild.dispatchTouchEvent(event);
+            }
+        }
+        return super.onTouchEvent(event);
+    }
+
+    private View findNearestChild(MotionEvent event) {
+        return mClickableChildren.stream().map(v -> new Pair<>(distance(v, event), v))
+                .min(Comparator.comparingInt(f -> f.first)).get().second;
+    }
+
+    private int distance(View v, MotionEvent event) {
+        v.getLocationInWindow(mTmpInt);
+        int left = mTmpInt[0] - mOffset[0];
+        int top = mTmpInt[1] - mOffset[1];
+        int right = left + v.getWidth();
+        int bottom = top + v.getHeight();
+
+        int x = Math.min(Math.abs(left - (int) event.getX()),
+                Math.abs((int) event.getX() - right));
+        int y = Math.min(Math.abs(top - (int) event.getY()),
+                Math.abs((int) event.getY() - bottom));
+
+        return Math.max(x, y);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index dd84dea..b75c7e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -18,6 +18,7 @@
 
 import android.service.notification.StatusBarNotification;
 import android.support.annotation.Nullable;
+import android.util.Log;
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
@@ -29,7 +30,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -38,6 +38,7 @@
  */
 public class NotificationGroupManager implements OnHeadsUpChangedListener {
 
+    private static final String TAG = "NotificationGroupManager";
     private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
     private OnGroupChangeListener mListener;
     private int mBarState = -1;
@@ -96,7 +97,7 @@
             return;
         }
         if (isGroupChild(sbn)) {
-            group.children.remove(removed);
+            group.children.remove(removed.key);
         } else {
             group.summary = null;
         }
@@ -109,6 +110,9 @@
     }
 
     public void onEntryAdded(final NotificationData.Entry added) {
+        if (added.row.isRemoved()) {
+            added.setDebugThrowable(new Throwable());
+        }
         final StatusBarNotification sbn = added.notification;
         boolean isGroupChild = isGroupChild(sbn);
         String groupKey = getGroupKey(sbn);
@@ -118,15 +122,25 @@
             mGroupMap.put(groupKey, group);
         }
         if (isGroupChild) {
-            group.children.add(added);
+            NotificationData.Entry existing = group.children.get(added.key);
+            if (existing != null && existing != added) {
+                Throwable existingThrowable = existing.getDebugThrowable();
+                Log.wtf(TAG, "Inconsistent entries found with the same key " + added.key
+                        + "existing removed: " + existing.row.isRemoved()
+                        + (existingThrowable != null
+                                ? Log.getStackTraceString(existingThrowable) + "\n": "")
+                        + " added removed" + added.row.isRemoved()
+                        , new Throwable());
+            }
+            group.children.put(added.key, added);
             updateSuppression(group);
         } else {
             group.summary = added;
             group.expanded = added.row.areChildrenExpanded();
             updateSuppression(group);
             if (!group.children.isEmpty()) {
-                HashSet<NotificationData.Entry> childrenCopy =
-                        (HashSet<NotificationData.Entry>) group.children.clone();
+                ArrayList<NotificationData.Entry> childrenCopy
+                        = new ArrayList<>(group.children.values());
                 for (NotificationData.Entry child : childrenCopy) {
                     onEntryBecomingChild(child);
                 }
@@ -410,7 +424,8 @@
         // The parent of a suppressed group got huned, lets hun the child!
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
         if (notificationGroup != null) {
-            Iterator<NotificationData.Entry> iterator = notificationGroup.children.iterator();
+            Iterator<NotificationData.Entry> iterator
+                    = notificationGroup.children.values().iterator();
             NotificationData.Entry child = iterator.hasNext() ? iterator.next() : null;
             if (child == null) {
                 child = getIsolatedChild(sbn.getGroupKey());
@@ -463,7 +478,7 @@
     }
 
     public static class NotificationGroup {
-        public final HashSet<NotificationData.Entry> children = new HashSet<>();
+        public final HashMap<String, NotificationData.Entry> children = new HashMap<>();
         public NotificationData.Entry summary;
         public boolean expanded;
         /**
@@ -474,10 +489,16 @@
         @Override
         public String toString() {
             String result = "    summary:\n      "
-                    + (summary != null ? summary.notification : "null");
+                    + (summary != null ? summary.notification : "null")
+                    + (summary != null && summary.getDebugThrowable() != null
+                            ? Log.getStackTraceString(summary.getDebugThrowable())
+                            : "");
             result += "\n    children size: " + children.size();
-            for (NotificationData.Entry child : children) {
-                result += "\n      " + child.notification;
+            for (NotificationData.Entry child : children.values()) {
+                result += "\n      " + child.notification
+                + (child.getDebugThrowable() != null
+                        ? Log.getStackTraceString(child.getDebugThrowable())
+                        : "");
             }
             return result;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 5bfdd1f..41a69b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -280,4 +280,9 @@
             v.setDecorColor(mIconTint);
         }
     }
+
+    public void setDark(boolean dark) {
+        mNotificationIcons.setDark(dark, false, 0);
+        mShelfIcons.setDark(dark, false, 0);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index a4fadc4..6f5ad96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -123,6 +123,7 @@
     private boolean mDisallowNextAnimation;
     private boolean mAnimationsEnabled = true;
     private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
+    private int mDarkOffsetX;
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -389,6 +390,14 @@
                 iconState.xTranslation = getWidth() - iconState.xTranslation - view.getWidth();
             }
         }
+
+        if (mDark && mDarkOffsetX != 0) {
+            for (int i = 0; i < childCount; i++) {
+                View view = getChildAt(i);
+                IconState iconState = mIconStates.get(view);
+                iconState.xTranslation += mDarkOffsetX;
+            }
+        }
     }
 
     private float getLayoutEnd() {
@@ -512,7 +521,12 @@
         mReplacingIcons = replacingIcons;
     }
 
+    public void setDarkOffsetX(int offsetX) {
+        mDarkOffsetX = offsetX;
+    }
+
     public class IconState extends ViewState {
+        public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
@@ -525,6 +539,8 @@
         public boolean justUndarkened;
         public int iconColor = StatusBarIconView.NO_COLOR;
         public boolean noAnimations;
+        public boolean isLastExpandIcon;
+        public int customTransformHeight = NO_VALUE;
 
         @Override
         public void applyToView(View view) {
@@ -602,6 +618,10 @@
             justUndarkened = false;
         }
 
+        public boolean hasCustomTransformHeight() {
+            return isLastExpandIcon && customTransformHeight != NO_VALUE;
+        }
+
         @Override
         public void initFrom(View view) {
             super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
new file mode 100644
index 0000000..9ff907b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java
@@ -0,0 +1,152 @@
+/*
+ * 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.statusbar.phone;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.plugins.NotificationListenerController;
+import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
+import java.util.ArrayList;
+
+/**
+ * A version of NotificationListenerService that passes all info to
+ * any plugins connected. Also allows those plugins the chance to cancel
+ * any incoming callbacks or to trigger new ones.
+ */
+public class NotificationListenerWithPlugins extends NotificationListenerService implements
+        PluginListener<NotificationListenerController> {
+
+    private ArrayList<NotificationListenerController> mPlugins = new ArrayList<>();
+    private boolean mConnected;
+
+    @Override
+    public void registerAsSystemService(Context context, ComponentName componentName,
+            int currentUser) throws RemoteException {
+        super.registerAsSystemService(context, componentName, currentUser);
+        Dependency.get(PluginManager.class).addPluginListener(this,
+                NotificationListenerController.class);
+    }
+
+    @Override
+    public void unregisterAsSystemService() throws RemoteException {
+        super.unregisterAsSystemService();
+        Dependency.get(PluginManager.class).removePluginListener(this);
+    }
+
+    @Override
+    public StatusBarNotification[] getActiveNotifications() {
+        StatusBarNotification[] activeNotifications = super.getActiveNotifications();
+        for (NotificationListenerController plugin : mPlugins) {
+            activeNotifications = plugin.getActiveNotifications(activeNotifications);
+        }
+        return activeNotifications;
+    }
+
+    @Override
+    public RankingMap getCurrentRanking() {
+        RankingMap currentRanking = super.getCurrentRanking();
+        for (NotificationListenerController plugin : mPlugins) {
+            currentRanking = plugin.getCurrentRanking(currentRanking);
+        }
+        return currentRanking;
+    }
+
+    public void onPluginConnected() {
+        mConnected = true;
+        mPlugins.forEach(p -> p.onListenerConnected(getProvider()));
+    }
+
+    /**
+     * Called when listener receives a onNotificationPosted.
+     * Returns true to indicate this callback should be skipped.
+     */
+    public boolean onPluginNotificationPosted(StatusBarNotification sbn,
+            final RankingMap rankingMap) {
+        for (NotificationListenerController plugin : mPlugins) {
+            if (plugin.onNotificationPosted(sbn, rankingMap)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called when listener receives a onNotificationRemoved.
+     * Returns true to indicate this callback should be skipped.
+     */
+    public boolean onPluginNotificationRemoved(StatusBarNotification sbn,
+            final RankingMap rankingMap) {
+        for (NotificationListenerController plugin : mPlugins) {
+            if (plugin.onNotificationRemoved(sbn, rankingMap)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public RankingMap onPluginRankingUpdate(RankingMap rankingMap) {
+        return getCurrentRanking();
+    }
+
+    @Override
+    public void onPluginConnected(NotificationListenerController plugin, Context pluginContext) {
+        mPlugins.add(plugin);
+        if (mConnected) {
+            plugin.onListenerConnected(getProvider());
+        }
+    }
+
+    @Override
+    public void onPluginDisconnected(NotificationListenerController plugin) {
+        mPlugins.remove(plugin);
+    }
+
+    private NotificationProvider getProvider() {
+        return new NotificationProvider() {
+            @Override
+            public StatusBarNotification[] getActiveNotifications() {
+                return NotificationListenerWithPlugins.super.getActiveNotifications();
+            }
+
+            @Override
+            public RankingMap getRankingMap() {
+                return NotificationListenerWithPlugins.super.getCurrentRanking();
+            }
+
+            @Override
+            public void addNotification(StatusBarNotification sbn) {
+                onNotificationPosted(sbn, getRankingMap());
+            }
+
+            @Override
+            public void removeNotification(StatusBarNotification sbn) {
+                onNotificationRemoved(sbn, getRankingMap());
+            }
+
+            @Override
+            public void updateRanking() {
+                onNotificationRankingUpdate(getRankingMap());
+            }
+        };
+    }
+}
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 6aab8e1..cca6ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
@@ -26,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -33,6 +35,7 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.MathUtils;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -41,7 +44,6 @@
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
-import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -58,7 +60,9 @@
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -111,7 +115,6 @@
     private QS mQs;
     private FrameLayout mQsFrame;
     private KeyguardStatusView mKeyguardStatusView;
-    private TextView mClockView;
     private View mReserveNotificationSpace;
     private View mQsNavbarScrim;
     protected NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -163,8 +166,9 @@
     private int mUnlockMoveDistance;
     private float mEmptyDragAmount;
 
-    private ObjectAnimator mClockAnimator;
-    private int mClockAnimationTarget = -1;
+    private Animator mClockAnimator;
+    private int mClockAnimationTargetX = Integer.MIN_VALUE;
+    private int mClockAnimationTargetY = Integer.MIN_VALUE;
     private int mTopPaddingAdjustment;
     private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
@@ -198,6 +202,7 @@
     private int mQsFalsingThreshold;
 
     private float mKeyguardStatusBarAnimateAlpha = 1f;
+    private float mQsClockAlphaOverride = 1f;
     private int mOldLayoutDirection;
     private HeadsUpTouchHelper mHeadsUpTouchHelper;
     private boolean mIsExpansionFromHeadsUp;
@@ -224,11 +229,15 @@
     private NotificationGroupManager mGroupManager;
     private boolean mShowIconsWhenExpanded;
     private int mIndicationBottomPadding;
+    private int mAmbientIndicationBottomPadding;
     private boolean mIsFullWidth;
     private float mDarkAmount;
+    private float mDarkAmountTarget;
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private boolean mNoVisibleNotifications = true;
     private ValueAnimator mDarkAnimator;
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private boolean mUserSetupComplete;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -240,6 +249,7 @@
 
     public void setStatusBar(StatusBar bar) {
         mStatusBar = bar;
+        mKeyguardBottomArea.setStatusBar(mStatusBar);
     }
 
     @Override
@@ -247,7 +257,6 @@
         super.onFinishInflate();
         mKeyguardStatusBar = findViewById(R.id.keyguard_header);
         mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
-        mClockView = findViewById(R.id.clock_view);
 
         mNotificationContainerParent = (NotificationsQuickSettingsContainer)
                 findViewById(R.id.notification_container_parent);
@@ -258,10 +267,10 @@
         mNotificationStackScroller.setOnEmptySpaceClickListener(this);
         mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
         mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
-        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
-        mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
         mLastOrientation = getResources().getConfiguration().orientation;
 
+        initBottomArea();
+
         mQsFrame = findViewById(R.id.qs_frame);
     }
 
@@ -301,16 +310,18 @@
     }
 
     public void updateResources() {
-        int panelWidth = getResources().getDimensionPixelSize(R.dimen.notification_panel_width);
+        Resources res = getResources();
+        int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width);
         int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mQsFrame.getLayoutParams();
-        if (lp.width != panelWidth || lp.gravity != panelGravity) {
-            lp.width = panelWidth;
+        if (lp.width != qsWidth || lp.gravity != panelGravity) {
+            lp.width = qsWidth;
             lp.gravity = panelGravity;
             mQsFrame.setLayoutParams(lp);
         }
 
+        int panelWidth = res.getDimensionPixelSize(R.dimen.notification_panel_width);
         lp = (FrameLayout.LayoutParams) mNotificationStackScroller.getLayoutParams();
         if (lp.width != panelWidth || lp.gravity != panelGravity) {
             lp.width = panelWidth;
@@ -319,6 +330,42 @@
         }
     }
 
+    public void onOverlayChanged() {
+        // Re-inflate the status view group.
+        int index = indexOfChild(mKeyguardStatusView);
+        removeView(mKeyguardStatusView);
+        mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_status_view,
+                this,
+                false);
+        addView(mKeyguardStatusView, index);
+
+        // Update keyguard bottom area
+        index = indexOfChild(mKeyguardBottomArea);
+        removeView(mKeyguardBottomArea);
+        mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_bottom_area,
+                this,
+                false);
+        addView(mKeyguardBottomArea, index);
+        initBottomArea();
+        setDarkAmount(mDarkAmount);
+
+        setKeyguardStatusViewVisibility(mStatusBarState, false, false);
+        setKeyguardBottomAreaVisibility(mStatusBarState, false);
+    }
+
+    private void initBottomArea() {
+        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
+        mKeyguardBottomArea.setStatusBar(mStatusBar);
+        mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
+    }
+
+    public void setKeyguardIndicationController(KeyguardIndicationController indicationController) {
+        mKeyguardBottomArea.setKeyguardIndicationController(indicationController);
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
@@ -326,7 +373,8 @@
 
         // Update Clock Pivot
         mKeyguardStatusView.setPivotX(getWidth() / 2);
-        mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize());
+        mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f *
+                mKeyguardStatusView.getClockTextSize());
 
         // Calculate quick setting heights.
         int oldMaxHeight = mQsMaxExpansionHeight;
@@ -415,8 +463,9 @@
                     mDarkAmount);
             mClockPositionAlgorithm.run(mClockPositionResult);
             if (animate || mClockAnimator != null) {
-                startClockAnimation(mClockPositionResult.clockY);
+                startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY);
             } else {
+                mKeyguardStatusView.setX(mClockPositionResult.clockX);
                 mKeyguardStatusView.setY(mClockPositionResult.clockY);
             }
             updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
@@ -424,6 +473,7 @@
             mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
         }
         mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
+        mNotificationStackScroller.setDarkShelfOffsetX(mClockPositionResult.clockX);
         requestScrollerTopPaddingUpdate(animate);
     }
 
@@ -436,10 +486,11 @@
                 mKeyguardStatusView.getHeight());
         int notificationPadding = Math.max(1, getResources().getDimensionPixelSize(
                 R.dimen.notification_divider_height));
-        float shelfSize = mNotificationStackScroller.getNotificationShelf().getIntrinsicHeight()
-                + notificationPadding;
+        NotificationShelf shelf = mNotificationStackScroller.getNotificationShelf();
+        float shelfSize = shelf.getVisibility() == GONE ? 0
+                : shelf.getIntrinsicHeight() + notificationPadding;
         float availableSpace = mNotificationStackScroller.getHeight() - minPadding - shelfSize
-                - mIndicationBottomPadding;
+                - Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
         int count = 0;
         for (int i = 0; i < mNotificationStackScroller.getChildCount(); i++) {
             ExpandableView child = (ExpandableView) mNotificationStackScroller.getChildAt(i);
@@ -478,11 +529,12 @@
         return count;
     }
 
-    private void startClockAnimation(int y) {
-        if (mClockAnimationTarget == y) {
+    private void startClockAnimation(int x, int y) {
+        if (mClockAnimationTargetX == x && mClockAnimationTargetY == y) {
             return;
         }
-        mClockAnimationTarget = y;
+        mClockAnimationTargetX = x;
+        mClockAnimationTargetY = y;
         getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             @Override
             public boolean onPreDraw() {
@@ -491,15 +543,20 @@
                     mClockAnimator.removeAllListeners();
                     mClockAnimator.cancel();
                 }
-                mClockAnimator = ObjectAnimator
-                        .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
+                AnimatorSet set = new AnimatorSet();
+                set.play(ObjectAnimator.ofFloat(
+                        mKeyguardStatusView, View.Y, mClockAnimationTargetY))
+                        .with(ObjectAnimator.ofFloat(
+                                mKeyguardStatusView, View.X, mClockAnimationTargetX));
+                mClockAnimator = set;
                 mClockAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
                 mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                 mClockAnimator.addListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         mClockAnimator = null;
-                        mClockAnimationTarget = -1;
+                        mClockAnimationTargetX = Integer.MIN_VALUE;
+                        mClockAnimationTargetY = Integer.MIN_VALUE;
                     }
                 });
                 mClockAnimator.start();
@@ -510,7 +567,7 @@
 
     private void updateClock(float alpha, float scale) {
         if (!mKeyguardStatusViewAnimating) {
-            mKeyguardStatusView.setAlpha(alpha);
+            mKeyguardStatusView.setAlpha(alpha * mQsClockAlphaOverride);
         }
         mKeyguardStatusView.setScaleX(scale);
         mKeyguardStatusView.setScaleY(scale);
@@ -1262,6 +1319,15 @@
             mQsNavbarScrim.setAlpha(getQsExpansionFraction());
         }
 
+        // Fade clock when QS is on top of it
+        float newClockAlpha = (height - mKeyguardStatusView.getY()) /
+                mKeyguardStatusView.getHeight();
+        newClockAlpha = 1 - MathUtils.constrain(newClockAlpha, 0, 1);
+        if (newClockAlpha != mQsClockAlphaOverride) {
+            mQsClockAlphaOverride = Interpolators.ALPHA_OUT.getInterpolation(newClockAlpha);
+            updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
+        }
+
         // Upon initialisation when we are not layouted yet we don't want to announce that we are
         // fully expanded, hence the != 0.0f check.
         if (height != 0.0f && mQsFullyExpanded && !mLastAnnouncementWasQuickSettings) {
@@ -1657,6 +1723,10 @@
         mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        View ambientIndicationContainer = mStatusBar.getAmbientIndicationContainer();
+        if (ambientIndicationContainer != null) {
+            ambientIndicationContainer.setAlpha(alpha);
+        }
     }
 
     private float getNotificationsTopY() {
@@ -2375,6 +2445,8 @@
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
         } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
+        } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) {
+            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER;
         } else {
 
             // Default.
@@ -2440,6 +2512,10 @@
      * @param keyguardIsShowing whether keyguard is being shown
      */
     public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) {
+        if (!mStatusBar.isCameraAllowedByAdmin()) {
+            return false;
+        }
+
         ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
         String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
                 ? null : resolveInfo.activityInfo.packageName;
@@ -2505,7 +2581,7 @@
     public void setTouchDisabled(boolean disabled) {
         super.setTouchDisabled(disabled);
         if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) {
-            mAffordanceHelper.resetImmediately();
+            mAffordanceHelper.reset(false /* animate */);
         }
     }
 
@@ -2515,8 +2591,13 @@
             return;
         }
         if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
-            mDarkAnimator.cancel();
+            if (animate && mDarkAmountTarget == darkAmount) {
+                return;
+            } else {
+                mDarkAnimator.cancel();
+            }
         }
+        mDarkAmountTarget = darkAmount;
         if (animate) {
             mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
             mDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
@@ -2529,7 +2610,7 @@
 
     private void setDarkAmount(float amount) {
         mDarkAmount = amount;
-        mKeyguardStatusView.setDark(amount == 1);
+        mKeyguardStatusView.setDark(mDarkAmount);
         positionClockAndNotifications();
     }
 
@@ -2543,4 +2624,41 @@
     public void setPulsing(boolean pulsing) {
         mKeyguardStatusView.setPulsing(pulsing);
     }
+
+    public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
+        if (mAmbientIndicationBottomPadding != ambientIndicationBottomPadding) {
+            mAmbientIndicationBottomPadding = ambientIndicationBottomPadding;
+            mStatusBar.updateKeyguardMaxNotifications();
+        }
+    }
+
+    public void refreshTime() {
+        mKeyguardStatusView.refreshTime();
+        if (mDarkAmount > 0) {
+            positionClockAndNotifications();
+        }
+    }
+
+    public void setStatusAccessibilityImportance(int mode) {
+         mKeyguardStatusView.setImportantForAccessibility(mode);
+    }
+
+    /**
+     * TODO: this should be removed.
+     * It's not correct to pass this view forward because other classes will end up adding
+     * children to it. Theme will be out of sync.
+     * @return bottom area view
+     */
+    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+        return mKeyguardBottomArea;
+    }
+
+    public void setUserSetupComplete(boolean userSetupComplete) {
+        mUserSetupComplete = userSetupComplete;
+        mKeyguardBottomArea.setUserSetupComplete(userSetupComplete);
+    }
+
+    public LockIcon getLockIcon() {
+        return mKeyguardBottomArea.getLockIcon();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 646f3d8..76cc0ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
+import android.support.annotation.DimenRes;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewStub;
@@ -32,20 +33,20 @@
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.NotificationData.Entry;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 /**
  * The container with notification stack scroller and quick settings inside.
  */
 public class NotificationsQuickSettingsContainer extends FrameLayout
-        implements OnInflateListener, FragmentListener, OnHeadsUpChangedListener {
+        implements OnInflateListener, FragmentListener,
+        AboveShelfObserver.HasViewAboveShelfChangedListener {
 
     private FrameLayout mQsFrame;
     private View mUserSwitcher;
-    private View mStackScroller;
+    private NotificationStackScrollLayout mStackScroller;
     private View mKeyguardStatusBar;
     private boolean mInflated;
     private boolean mQsExpanded;
@@ -53,8 +54,7 @@
 
     private int mBottomPadding;
     private int mStackScrollerMargin;
-    private boolean mHeadsUp;
-    private HeadsUpManager mHeadsUpManager;
+    private boolean mHasViewsAboveShelf;
 
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -76,29 +76,27 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         FragmentHostManager.get(this).addTagListener(QS.TAG, this);
-        mHeadsUpManager = SysUiServiceProvider.getComponent(getContext(), StatusBar.class)
-                .mHeadsUpManager;
-        mHeadsUpManager.addListener(this);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         FragmentHostManager.get(this).removeTagListener(QS.TAG, this);
-        mHeadsUpManager.removeListener(this);
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        reloadWidth(mQsFrame);
-        reloadWidth(mStackScroller);
+        reloadWidth(mQsFrame, R.dimen.qs_panel_width);
+        reloadWidth(mStackScroller, R.dimen.notification_panel_width);
     }
 
-    private void reloadWidth(View view) {
+    /**
+     * Loads the given width resource and sets it on the given View.
+     */
+    private void reloadWidth(View view, @DimenRes int width) {
         LayoutParams params = (LayoutParams) view.getLayoutParams();
-        params.width = getContext().getResources().getDimensionPixelSize(
-                R.dimen.notification_panel_width);
+        params.width = getResources().getDimensionPixelSize(width);
         view.setLayoutParams(params);
     }
 
@@ -114,7 +112,7 @@
         boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
         boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
 
-        final boolean qsBottom = mHeadsUp;
+        final boolean qsBottom = mHasViewsAboveShelf;
         View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
         View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
         // Invert the order of the scroll view and user switcher such that the notifications receive
@@ -181,7 +179,7 @@
             setPadding(0, 0, 0, mBottomPadding);
             setBottomMargin(mStackScroller, mStackScrollerMargin);
         }
-
+        mStackScroller.setQsCustomizerShowing(isShowing);
     }
 
     private void setBottomMargin(View v, int bottomMargin) {
@@ -191,12 +189,8 @@
     }
 
     @Override
-    public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
-        boolean hasHeadsUp = mHeadsUpManager.getAllEntries().size() != 0;
-        if (mHeadsUp == hasHeadsUp) {
-            return;
-        }
-        mHeadsUp = hasHeadsUp;
+    public void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf) {
+        mHasViewsAboveShelf = hasViewsAboveShelf;
         invalidate();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 1ef784e..16d85be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.view.InputDevice;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
 import android.view.animation.Interpolator;
@@ -1092,21 +1093,25 @@
         });
         animator.start();
         setAnimator(animator);
-        mKeyguardBottomArea.getIndicationArea().animate()
-                .translationY(-mHintDistance)
-                .setDuration(250)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .withEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        mKeyguardBottomArea.getIndicationArea().animate()
-                                .translationY(0)
-                                .setDuration(450)
-                                .setInterpolator(mBounceInterpolator)
-                                .start();
-                    }
-                })
-                .start();
+
+        View[] viewsToAnimate = {
+                mKeyguardBottomArea.getIndicationArea(),
+                mStatusBar.getAmbientIndicationContainer()};
+        for (View v : viewsToAnimate) {
+            if (v == null) {
+                continue;
+            }
+            v.animate()
+                    .translationY(-mHintDistance)
+                    .setDuration(250)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .withEndAction(() -> v.animate()
+                            .translationY(0)
+                            .setDuration(450)
+                            .setInterpolator(mBounceInterpolator)
+                            .start())
+                    .start();
+        }
     }
 
     private void setAnimator(ValueAnimator animator) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index f3ba5aa..d1ef035 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -196,8 +196,7 @@
         }
 
         // TTY status
-        mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
-        mIconController.setIconVisibility(mSlotTty, false);
+        updateTTY();
 
         // bluetooth status
         updateBluetooth();
@@ -419,9 +418,17 @@
         mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
     }
 
-    private final void updateTTY(Intent intent) {
-        int currentTtyMode = intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
-                TelecomManager.TTY_MODE_OFF);
+    private final void updateTTY() {
+        TelecomManager telecomManager =
+                (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+        if (telecomManager == null) {
+            updateTTY(TelecomManager.TTY_MODE_OFF);
+        } else {
+            updateTTY(telecomManager.getCurrentTtyMode());
+        }
+    }
+
+    private final void updateTTY(int currentTtyMode) {
         boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
 
         if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
@@ -754,7 +761,8 @@
             } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
                 updateSimState(intent);
             } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                updateTTY(intent);
+                updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
+                        TelecomManager.TTY_MODE_OFF));
             } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
                     action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
                     action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index f45967a..bcbc345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -16,10 +16,10 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
 import java.util.ArrayList;
@@ -48,7 +48,7 @@
 
     @Override
     public void addView(View child) {
-        reversParams(child.getLayoutParams());
+        reverseParams(child.getLayoutParams(), child);
         if (mIsLayoutReverse) {
             super.addView(child, 0);
         } else {
@@ -58,7 +58,7 @@
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
-        reversParams(params);
+        reverseParams(params, child);
         if (mIsLayoutReverse) {
             super.addView(child, 0, params);
         } else {
@@ -100,7 +100,15 @@
         }
     }
 
-    private void reversParams(ViewGroup.LayoutParams params) {
+    private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+        if (child instanceof Reversable) {
+            ((Reversable) child).reverse();
+        }
+        if (child.getPaddingLeft() == child.getPaddingRight()
+                && child.getPaddingTop() == child.getPaddingBottom()) {
+            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
+                    child.getPaddingTop(), child.getPaddingLeft());
+        }
         if (params == null) {
             return;
         }
@@ -109,4 +117,23 @@
         params.height = width;
     }
 
+    public interface Reversable {
+        void reverse();
+    }
+
+    public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+
+        public ReverseFrameLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void reverse() {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                reverseParams(child.getLayoutParams(), child);
+            }
+        }
+    }
+
 }
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 67d5b6a..1d64480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -20,39 +20,56 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.app.WallpaperManager;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Rect;
-import android.support.v4.graphics.ColorUtils;
-import android.util.TypedValue;
+import android.graphics.drawable.Drawable;
+import android.os.Trace;
+import android.util.MathUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 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.internal.graphics.ColorUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.stack.ViewState;
 
+import java.util.function.Consumer;
+
 /**
  * Controls both the scrim behind the notifications and in front of the notifications (when a
  * security method gets shown).
  */
 public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
-        OnHeadsUpChangedListener {
+        OnHeadsUpChangedListener, OnColorsChangedListener {
     public static final long ANIMATION_DURATION = 220;
     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
             = new PathInterpolator(0f, 0, 0.7f, 1f);
     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
             = new PathInterpolator(0.3f, 0f, 0.8f, 1f);
-    protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
+    // Default alpha value for most scrims, if unsure use this constant
+    public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
+    // A scrim varies its opacity based on a busyness factor, for example
+    // how many notifications are currently visible.
+    public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
+    protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
-    private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
-    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = 0.85f;
+    private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
+    private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
     private static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -61,12 +78,18 @@
 
     private final LightBarController mLightBarController;
     protected final ScrimView mScrimBehind;
-    private final ScrimView mScrimInFront;
+    protected final ScrimView mScrimInFront;
     private final UnlockMethodCache mUnlockMethodCache;
     private final View mHeadsUpScrim;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
+    private final SysuiColorExtractor mColorExtractor;
+    private GradientColors mLockColors;
+    private GradientColors mSystemColors;
+    private boolean mNeedsDrawableColorUpdate;
+
     protected float mScrimBehindAlpha;
+    protected float mScrimBehindAlphaResValue;
     protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
     protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
 
@@ -84,6 +107,7 @@
     protected long mDurationOverride = -1;
     private long mAnimationDelay;
     private Runnable mOnAnimationFinished;
+    private boolean mDeferFinishedListener;
     private final Interpolator mInterpolator = new DecelerateInterpolator();
     private boolean mDozing;
     private float mDozeInFrontAlpha;
@@ -98,18 +122,40 @@
     private boolean mSkipFirstFrame;
     private boolean mDontAnimateBouncerChanges;
     private boolean mKeyguardFadingOutInProgress;
+    private boolean mAnimatingDozeUnlock;
     private ValueAnimator mKeyguardFadeoutAnimation;
+    /** Wake up from AOD transition is starting; need fully opaque front scrim */
+    private boolean mWakingUpFromAodStarting;
+    /** Wake up from AOD transition is in progress; need black tint */
+    private boolean mWakingUpFromAodInProgress;
+    /** Wake up from AOD transition is animating; need to reset when animation finishes */
+    private boolean mWakingUpFromAodAnimationRunning;
+    private boolean mScrimsVisble;
+    private final Consumer<Boolean> mScrimVisibleListener;
 
     public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
-            ScrimView scrimInFront, View headsUpScrim) {
+            ScrimView scrimInFront, View headsUpScrim,
+            Consumer<Boolean> scrimVisibleListener) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
         mHeadsUpScrim = headsUpScrim;
+        mScrimVisibleListener = scrimVisibleListener;
         final Context context = scrimBehind.getContext();
         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
         mLightBarController = lightBarController;
-        mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+        mScrimBehindAlphaResValue = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+        // Scrim alpha is initially set to the value on the resource but might be changed
+        // to make sure that text on top of it is legible.
+        mScrimBehindAlpha = mScrimBehindAlphaResValue;
+
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+        mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+        mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+        mNeedsDrawableColorUpdate = true;
 
         updateHeadsUpScrim(false);
         updateScrims();
@@ -117,6 +163,9 @@
 
     public void setKeyguardShowing(boolean showing) {
         mKeyguardShowing = showing;
+
+        // Showing/hiding the keyguard means that scrim colors have to be switched
+        mNeedsDrawableColorUpdate = true;
         scheduleUpdate();
     }
 
@@ -151,12 +200,43 @@
 
     public void setBouncerShowing(boolean showing) {
         mBouncerShowing = showing;
-        mAnimateChange = !mTracking && !mDontAnimateBouncerChanges;
+        mAnimateChange = !mTracking && !mDontAnimateBouncerChanges && !mKeyguardFadingOutInProgress;
         scheduleUpdate();
     }
 
+    /** Prepares the wakeUpFromAod animation (while turning on screen); Forces black scrims. */
+    public void prepareWakeUpFromAod() {
+        if (mWakingUpFromAodInProgress) {
+            return;
+        }
+        mWakingUpFromAodInProgress = true;
+        mWakingUpFromAodStarting = true;
+        mAnimateChange = false;
+        scheduleUpdate();
+        onPreDraw();
+    }
+
+    /** Starts the wakeUpFromAod animation (once screen is on); animate to transparent scrims. */
+    public void wakeUpFromAod() {
+        if (mWakeAndUnlocking || mAnimateKeyguardFadingOut) {
+            // Wake and unlocking has a separate transition that must not be interfered with.
+            mWakingUpFromAodStarting = false;
+            mWakingUpFromAodInProgress = false;
+            return;
+        }
+        if (mWakingUpFromAodStarting) {
+            mWakingUpFromAodInProgress = true;
+            mWakingUpFromAodStarting = false;
+            mAnimateChange = true;
+            scheduleUpdate();
+        }
+    }
+
     public void setWakeAndUnlocking() {
         mWakeAndUnlocking = true;
+        mAnimatingDozeUnlock = true;
+        mWakingUpFromAodStarting = false;
+        mWakingUpFromAodInProgress = false;
         scheduleUpdate();
     }
 
@@ -192,7 +272,7 @@
 
     public void animateKeyguardUnoccluding(long duration) {
         mAnimateChange = false;
-        setScrimBehindColor(0f);
+        setScrimBehindAlpha(0f);
         mAnimateChange = true;
         scheduleUpdate();
         mDurationOverride = duration;
@@ -230,12 +310,33 @@
         return mDozeInFrontAlpha;
     }
 
+    public void setNotificationCount(int notificationCount) {
+        final float maxNotificationDensity = 3;
+        float notificationDensity = Math.min(notificationCount / maxNotificationDensity, 1f);
+        float newAlpha = MathUtils.map(0, 1,
+                GRADIENT_SCRIM_ALPHA, GRADIENT_SCRIM_ALPHA_BUSY,
+                notificationDensity);
+        if (mScrimBehindAlphaKeyguard != newAlpha) {
+            mScrimBehindAlphaKeyguard = newAlpha;
+            mAnimateChange = true;
+            scheduleUpdate();
+        }
+    }
+
     private float getScrimInFrontAlpha() {
         return mKeyguardUpdateMonitor.needsSlowUnlockTransition()
                 ? SCRIM_IN_FRONT_ALPHA_LOCKED
                 : SCRIM_IN_FRONT_ALPHA;
     }
 
+    /**
+     * Sets the given drawable as the background of the scrim that shows up behind the
+     * notifications.
+     */
+    public void setScrimBehindDrawable(Drawable drawable) {
+        mScrimBehind.setDrawable(drawable);
+    }
+
     protected void scheduleUpdate() {
         if (mUpdatePending) return;
 
@@ -246,27 +347,65 @@
     }
 
     protected void updateScrims() {
-        if (mAnimateKeyguardFadingOut || mForceHideScrims) {
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(0f);
-        } else if (mWakeAndUnlocking) {
-
-            // During wake and unlock, we first hide everything behind a black scrim, which then
-            // gets faded out from animateKeyguardFadingOut.
-            if (mDozing) {
-                setScrimInFrontColor(0f);
-                setScrimBehindColor(1f);
+        // Make sure we have the right gradients and their opacities will satisfy GAR.
+        if (mNeedsDrawableColorUpdate) {
+            mNeedsDrawableColorUpdate = false;
+            final GradientColors currentScrimColors;
+            if (mKeyguardShowing) {
+                // Always animate color changes if we're seeing the keyguard
+                mScrimInFront.setColors(mLockColors, true /* animated */);
+                mScrimBehind.setColors(mLockColors, true /* animated */);
+                currentScrimColors = mLockColors;
             } else {
-                setScrimInFrontColor(1f);
-                setScrimBehindColor(0f);
+                // Only animate scrim color if the scrim view is actually visible
+                boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
+                boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
+                mScrimInFront.setColors(mSystemColors, animateScrimInFront);
+                mScrimBehind.setColors(mSystemColors, animateScrimBehind);
+                currentScrimColors = mSystemColors;
             }
-        } else if (!mKeyguardShowing && !mBouncerShowing) {
+
+            // Calculate minimum scrim opacity for white or black text.
+            int textColor = currentScrimColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
+            int mainColor = currentScrimColors.getMainColor();
+            float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
+                    4.5f /* minimumContrast */) / 255f;
+            mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
+            mLightBarController.setScrimColor(mScrimInFront.getColors());
+        }
+
+        if (mAnimateKeyguardFadingOut || mForceHideScrims) {
+            setScrimInFrontAlpha(0f);
+            setScrimBehindAlpha(0f);
+        } else if (mWakeAndUnlocking) {
+            // During wake and unlock, we first hide everything behind a black scrim, which then
+            // gets faded out from animateKeyguardFadingOut. This must never be animated.
+            mAnimateChange = false;
+            if (mDozing) {
+                setScrimInFrontAlpha(0f);
+                setScrimBehindAlpha(1f);
+            } else {
+                setScrimInFrontAlpha(1f);
+                setScrimBehindAlpha(0f);
+            }
+        } else if (!mKeyguardShowing && !mBouncerShowing && !mWakingUpFromAodStarting) {
             updateScrimNormal();
-            setScrimInFrontColor(0);
+            setScrimInFrontAlpha(0);
         } else {
             updateScrimKeyguard();
         }
         mAnimateChange = false;
+        dispatchScrimsVisible();
+    }
+
+    private void dispatchScrimsVisible() {
+        boolean scrimsVisible = mScrimBehind.getViewAlpha() > 0 || mScrimInFront.getViewAlpha() > 0;
+
+        if (mScrimsVisble != scrimsVisible) {
+            mScrimsVisble = scrimsVisible;
+
+            mScrimVisibleListener.accept(scrimsVisible);
+        }
     }
 
     private void updateScrimKeyguard() {
@@ -275,18 +414,22 @@
             float fraction = 1 - behindFraction;
             fraction = (float) Math.pow(fraction, 0.8f);
             behindFraction = (float) Math.pow(behindFraction, 0.8f);
-            setScrimInFrontColor(fraction * getScrimInFrontAlpha());
-            setScrimBehindColor(behindFraction * mScrimBehindAlphaKeyguard);
+            setScrimInFrontAlpha(fraction * getScrimInFrontAlpha());
+            setScrimBehindAlpha(behindFraction * mScrimBehindAlphaKeyguard);
         } else if (mBouncerShowing && !mBouncerIsKeyguard) {
-            setScrimInFrontColor(getScrimInFrontAlpha());
+            setScrimInFrontAlpha(getScrimInFrontAlpha());
             updateScrimNormal();
         } else if (mBouncerShowing) {
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(mScrimBehindAlpha);
+            setScrimInFrontAlpha(0f);
+            setScrimBehindAlpha(mScrimBehindAlpha);
         } else {
             float fraction = Math.max(0, Math.min(mFraction, 1));
-            setScrimInFrontColor(0f);
-            setScrimBehindColor(fraction
+            if (mWakingUpFromAodStarting) {
+                setScrimInFrontAlpha(1f);
+            } else {
+                setScrimInFrontAlpha(0f);
+            }
+            setScrimBehindAlpha(fraction
                     * (mScrimBehindAlphaKeyguard - mScrimBehindAlphaUnlocking)
                     + mScrimBehindAlphaUnlocking);
         }
@@ -297,30 +440,29 @@
         // let's start this 20% of the way down the screen
         frac = frac * 1.2f - 0.2f;
         if (frac <= 0) {
-            setScrimBehindColor(0);
+            setScrimBehindAlpha(0);
         } else {
             // woo, special effects
             final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
-            setScrimBehindColor(k * mScrimBehindAlpha);
+            setScrimBehindAlpha(k * mScrimBehindAlpha);
         }
     }
 
-    private void setScrimBehindColor(float alpha) {
-        setScrimColor(mScrimBehind, alpha);
+    private void setScrimBehindAlpha(float alpha) {
+        setScrimAlpha(mScrimBehind, alpha);
     }
 
-    private void setScrimInFrontColor(float alpha) {
-        setScrimColor(mScrimInFront, alpha);
+    private void setScrimInFrontAlpha(float alpha) {
+        setScrimAlpha(mScrimInFront, alpha);
         if (alpha == 0f) {
             mScrimInFront.setClickable(false);
         } else {
-
             // Eat touch events (unless dozing).
             mScrimInFront.setClickable(!mDozing);
         }
     }
 
-    private void setScrimColor(View scrim, float alpha) {
+    private void setScrimAlpha(View scrim, float alpha) {
         updateScrim(mAnimateChange, scrim, alpha, getCurrentScrimAlpha(scrim));
     }
 
@@ -346,30 +488,45 @@
         }
     }
 
-    protected void updateScrimColor(View scrim) {
+    private void updateScrimColor(View scrim) {
         float alpha1 = getCurrentScrimAlpha(scrim);
         if (scrim instanceof ScrimView) {
-            float alpha2 = getDozeAlpha(scrim);
-            float alpha = 1 - (1 - alpha1) * (1 - alpha2);
+            ScrimView scrimView = (ScrimView) scrim;
+            float dozeAlpha = getDozeAlpha(scrim);
+            float alpha = 1 - (1 - alpha1) * (1 - dozeAlpha);
             alpha = Math.max(0, Math.min(1.0f, alpha));
-            int baseColor = ((ScrimView) scrim).getScrimColor();
-            ((ScrimView) scrim).setScrimColor(
-                    ColorUtils.setAlphaComponent(baseColor, (int) (alpha * 255)));
+            scrimView.setViewAlpha(alpha);
+
+            Trace.traceCounter(Trace.TRACE_TAG_APP,
+                    scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
+                    (int) (alpha * 255));
+
+            int dozeTint = Color.TRANSPARENT;
+
+            boolean dozing = mAnimatingDozeUnlock || mDozing;
+            boolean frontScrimDozing = mWakingUpFromAodInProgress;
+            if (dozing || frontScrimDozing && scrim == mScrimInFront) {
+                dozeTint = Color.BLACK;
+            }
+            Trace.traceCounter(Trace.TRACE_TAG_APP,
+                    scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
+                    dozeTint == Color.BLACK ? 1 : 0);
+
+            scrimView.setTint(dozeTint);
         } else {
             scrim.setAlpha(alpha1);
         }
+        dispatchScrimsVisible();
     }
 
     private void startScrimAnimation(final View scrim, float target) {
         float current = getCurrentScrimAlpha(scrim);
         ValueAnimator anim = ValueAnimator.ofFloat(current, target);
-        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float alpha = (float) animation.getAnimatedValue();
-                setCurrentScrimAlpha(scrim, alpha);
-                updateScrimColor(scrim);
-            }
+        anim.addUpdateListener(animation -> {
+            float alpha = (float) animation.getAnimatedValue();
+            setCurrentScrimAlpha(scrim, alpha);
+            updateScrimColor(scrim);
+            dispatchScrimsVisible();
         });
         anim.setInterpolator(getInterpolator());
         anim.setStartDelay(mAnimationDelay);
@@ -377,16 +534,22 @@
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (mOnAnimationFinished != null) {
+                if (!mDeferFinishedListener && mOnAnimationFinished != null) {
                     mOnAnimationFinished.run();
                     mOnAnimationFinished = null;
                 }
                 if (mKeyguardFadingOutInProgress) {
                     mKeyguardFadeoutAnimation = null;
                     mKeyguardFadingOutInProgress = false;
+                    mAnimatingDozeUnlock = false;
+                }
+                if (mWakingUpFromAodAnimationRunning && !mDeferFinishedListener) {
+                    mWakingUpFromAodAnimationRunning = false;
+                    mWakingUpFromAodInProgress = false;
                 }
                 scrim.setTag(TAG_KEY_ANIM, null);
                 scrim.setTag(TAG_KEY_ANIM_TARGET, null);
+                dispatchScrimsVisible();
             }
         });
         anim.start();
@@ -394,6 +557,9 @@
             mKeyguardFadingOutInProgress = true;
             mKeyguardFadeoutAnimation = anim;
         }
+        if (mWakingUpFromAodInProgress) {
+            mWakingUpFromAodAnimationRunning = true;
+        }
         if (mSkipFirstFrame) {
             anim.setCurrentPlayTime(16);
         }
@@ -436,6 +602,8 @@
                 mOnAnimationFinished = null;
             }
             mKeyguardFadingOutInProgress = false;
+            if (!mWakeAndUnlocking || force)
+                mAnimatingDozeUnlock = false;
         }
     }
 
@@ -485,7 +653,12 @@
         float animEndValue = -1;
         if (previousAnimator != null) {
             if (animate || alpha == currentAlpha) {
+                // We are not done yet! Defer calling the finished listener.
+                if (animate) {
+                    mDeferFinishedListener = true;
+                }
                 previousAnimator.cancel();
+                mDeferFinishedListener = false;
             } else {
                 animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
             }
@@ -545,9 +718,9 @@
         return alpha * expandFactor;
     }
 
-    public void forceHideScrims(boolean hide) {
+    public void forceHideScrims(boolean hide, boolean animated) {
         mForceHideScrims = hide;
-        mAnimateChange = false;
+        mAnimateChange = animated;
         scheduleUpdate();
     }
 
@@ -559,8 +732,10 @@
         mScrimBehind.setExcludedArea(area);
     }
 
-    public int getScrimBehindColor() {
-        return mScrimBehind.getScrimColorWithAlpha();
+    public int getBackgroundColor() {
+        int color = mLockColors.getMainColor();
+        return Color.argb((int) (mScrimBehind.getAlpha() * Color.alpha(color)),
+                Color.red(color), Color.green(color), Color.blue(color));
     }
 
     public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
@@ -577,4 +752,20 @@
     public void setCurrentUser(int currentUser) {
         // Don't care in the base class.
     }
+
+    @Override
+    public void onColorsChanged(ColorExtractor colorExtractor, int which) {
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                    ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
+            mNeedsDrawableColorUpdate = true;
+            scheduleUpdate();
+        }
+        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+            mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                    ColorExtractor.TYPE_DARK, mKeyguardShowing);
+            mNeedsDrawableColorUpdate = true;
+            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 983a796..15ef742 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -23,20 +23,20 @@
 import android.graphics.ColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.Paint.Style;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
 import android.graphics.Path.FillType;
 import android.graphics.Path.Op;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.util.LayoutDirection;
-import android.util.Log;
 
 import com.android.settingslib.R;
 import com.android.settingslib.Utils;
+import com.android.systemui.qs.SlashDrawable;
 
 public class SignalDrawable extends Drawable {
 
@@ -85,12 +85,28 @@
             {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
     };
 
-    // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
-    // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
-    // one inset by this amount.
-    private final float mEmptyStrokeWidth;
+    // Rounded corners are achieved by arcing a circle of radius `R` from its tangent points along
+    // the curve (curve ≡ triangle). On the top and left corners of the triangle, the tangents are
+    // as follows:
+    //      1) Along the straight lines (y = 0 and x = width):
+    //          Ps = circleOffset + R
+    //      2) Along the diagonal line (y = x):
+    //          Pd = √((Ps^2) / 2)
+    //              or (remember: sin(π/4) ≈ 0.7071)
+    //          Pd = (circleOffset + R - 0.7071, height - R - 0.7071)
+    //         Where Pd is the (x,y) coords of the point that intersects the circle at the bottom
+    //         left of the triangle
+    private static final float RADIUS_RATIO = 0.75f / 17f;
+    private static final float DIAG_OFFSET_MULTIPLIER = 0.707107f;
+    // How far the circle defining the corners is inset from the edges
+    private final float mAppliedCornerInset;
+
     private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
-    private final float mEmptyDiagInset;  // == mEmptyStrokeWidth * INV_TAN
+    private static final float CUT_WIDTH_DP = 1f / 12f;
+
+    // Where the top and left points of the triangle would be if not for rounding
+    private final PointF mVirtualTop  = new PointF();
+    private final PointF mVirtualLeft = new PointF();
 
     private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -126,13 +142,11 @@
                 Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
 
-        // mCutPath parameters
-        mEmptyStrokeWidth = context.getResources()
-                .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
-        mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
-
         mHandler = new Handler();
         setDarkIntensity(0);
+
+        mAppliedCornerInset = context.getResources()
+                .getDimensionPixelSize(R.dimen.stat_sys_mobile_signal_circle_inset);
     }
 
     public void setIntrinsicSize(int size) {
@@ -185,6 +199,11 @@
         return true;
     }
 
+    public void setColors(int background, int foreground) {
+        mPaint.setColor(background);
+        mForegroundPaint.setColor(foreground);
+    }
+
     public void setDarkIntensity(float darkIntensity) {
         if (darkIntensity == mOldDarkIntensity) {
             return;
@@ -217,22 +236,57 @@
 
     @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);
-        float width = getBounds().width();
-        float height = getBounds().height();
-        float padding = Math.round(PAD * width);
-        mFullPath.moveTo(width - padding, height - padding);
-        mFullPath.lineTo(width - padding, padding);
-        mFullPath.lineTo(padding, height - padding);
-        mFullPath.lineTo(width - padding, height - padding);
+
+        final float padding = Math.round(PAD * width);
+        final float cornerRadius = RADIUS_RATIO * height;
+        // Offset from circle where the hypotenuse meets the circle
+        final float diagOffset = DIAG_OFFSET_MULTIPLIER * cornerRadius;
+
+        // 1 - Bottom right, above corner
+        mFullPath.moveTo(width - padding, height - padding - cornerRadius);
+        // 2 - Line to top right, below corner
+        mFullPath.lineTo(width - padding, padding + cornerRadius + mAppliedCornerInset);
+        // 3 - Arc to top right, on hypotenuse
+        mFullPath.arcTo(
+                width - padding - (2 * cornerRadius),
+                padding + mAppliedCornerInset,
+                width - padding,
+                padding + mAppliedCornerInset + (2 * cornerRadius),
+                0.f, -135.f, false
+        );
+        // 4 - Line to bottom left, on hypotenuse
+        mFullPath.lineTo(padding + mAppliedCornerInset + cornerRadius - diagOffset,
+                height - padding - cornerRadius - diagOffset);
+        // 5 - Arc to bottom left, on leg
+        mFullPath.arcTo(
+                padding + mAppliedCornerInset,
+                height - padding - (2 * cornerRadius),
+                padding + mAppliedCornerInset + ( 2 * cornerRadius),
+                height - padding,
+                -135.f, -135.f, false
+        );
+        // 6 - Line to bottom rght, before corner
+        mFullPath.lineTo(width - padding - cornerRadius, height - padding);
+        // 7 - Arc to beginning (bottom right, above corner)
+        mFullPath.arcTo(
+                width - padding - (2 * cornerRadius),
+                height - padding - (2 * cornerRadius),
+                width - padding,
+                height - padding,
+                90.f, -90.f, false
+        );
 
         if (mState == STATE_CARRIER_CHANGE) {
             float cutWidth = (DOT_CUT_WIDTH * width);
@@ -262,25 +316,32 @@
         }
 
         if (mState == STATE_EMPTY) {
+            // Where the corners would be if this were a real triangle
+            mVirtualTop.set(
+                    width - padding,
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius));
+            mVirtualLeft.set(
+                    (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
+                    height - padding);
+
+            final float cutWidth = CUT_WIDTH_DP * height;
+            final float cutDiagInset = cutWidth * INV_TAN;
+
             // Cut out a smaller triangle from the center of mFullPath
             mCutPath.reset();
             mCutPath.setFillType(FillType.WINDING);
-            mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth, padding + mEmptyDiagInset);
-            mCutPath.lineTo(padding + mEmptyDiagInset, height - padding - mEmptyStrokeWidth);
-            mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
-                    height - padding - mEmptyStrokeWidth);
+            mCutPath.moveTo(width - padding - cutWidth, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, mVirtualTop.y + cutDiagInset);
+            mCutPath.lineTo(mVirtualLeft.x + cutDiagInset, height - padding - cutWidth);
+            mCutPath.lineTo(width - padding - cutWidth, height - padding - cutWidth);
 
-            // In empty state, draw the full path as the foreground paint
-            mForegroundPath.set(mFullPath);
-            mFullPath.reset();
-            mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+            // Draw empty state as only background
+            mForegroundPath.reset();
+            mFullPath.op(mCutPath, Path.Op.DIFFERENCE);
         } else if (mState == STATE_AIRPLANE) {
-            // Airplane mode is slashed, full-signal
-            mForegroundPath.set(mFullPath);
-            mFullPath.reset();
-            mSlash.draw((int) height, (int) width, canvas, mForegroundPaint);
+            // Airplane mode is slashed, fully drawn background
+            mForegroundPath.reset();
+            mSlash.draw((int) height, (int) width, canvas, mPaint);
         } else if (mState != STATE_CARRIER_CHANGE) {
             mForegroundPath.reset();
             int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding));
@@ -417,6 +478,7 @@
 
         void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
             Matrix m = new Matrix();
+            final float radius = scale(SlashDrawable.CORNER_RADIUS, width);
             updateRect(
                     scale(LEFT, width),
                     scale(TOP, height),
@@ -425,7 +487,7 @@
 
             mPath.reset();
             // Draw the slash vertically
-            mPath.addRect(mSlashRect, Direction.CW);
+            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
             m.setRotate(ROTATION, width / 2, height / 2);
             mPath.transform(m);
             canvas.drawPath(mPath, paint);
@@ -435,7 +497,7 @@
             mPath.transform(m);
             m.setTranslate(mSlashRect.width(), 0);
             mPath.transform(m);
-            mPath.addRect(mSlashRect, Direction.CW);
+            mPath.addRoundRect(mSlashRect, radius, radius, Direction.CW);
             m.setRotate(ROTATION, width / 2, height / 2);
             mPath.transform(m);
             canvas.clipOutPath(mPath);
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 05e0c9b..83880e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1,5 +1,3 @@
-
-
 /*
  * Copyright (C) 2010 The Android Open Source Project
  *
@@ -21,7 +19,11 @@
 import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
+import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
 import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
@@ -31,10 +33,10 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
 
-import android.R.style;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
@@ -47,6 +49,8 @@
 import android.app.RemoteInput;
 import android.app.StatusBarManager;
 import android.app.TaskStackBuilder;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
@@ -55,6 +59,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -112,8 +118,8 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.view.ContextThemeWrapper;
 import android.view.Display;
+import android.view.HapticFeedbackConstants;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -136,6 +142,9 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+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;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -145,11 +154,11 @@
 import com.android.internal.util.NotificationMessagingUtil;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
-import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.ActivityStarterDelegate;
+import com.android.systemui.AutoReinflateContainer;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.DemoMode;
 import com.android.systemui.Dependency;
@@ -166,11 +175,15 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
+import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.fragments.ExtensionFragmentListener;
 import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.PluginFragmentListener;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
@@ -206,10 +219,10 @@
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.RowInflaterTask;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -219,6 +232,7 @@
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.statusbar.policy.ExtensionController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
@@ -257,7 +271,8 @@
         OnHeadsUpChangedListener, VisualStabilityManager.Callback, CommandQueue.Callbacks,
         ActivatableNotificationView.OnActivatedListener,
         ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
-        ExpandableNotificationRow.OnExpandClickListener, InflationCallback {
+        ExpandableNotificationRow.OnExpandClickListener, InflationCallback,
+        ColorExtractor.OnColorsChangedListener, ConfigurationListener {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_REMOTE_INPUT =
@@ -301,6 +316,7 @@
     public static final boolean DEBUG_GESTURES = false;
     public static final boolean DEBUG_MEDIA = false;
     public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
+    public static final boolean DEBUG_CAMERA_LIFT = false;
 
     public static final boolean DEBUG_WINDOW_STATE = false;
 
@@ -415,7 +431,6 @@
     private DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
     private PointF mWakeUpTouchLocation;
-    private boolean mScreenTurningOn;
 
     int mPixelFormat;
     Object mQueueLock = new Object();
@@ -427,13 +442,18 @@
     View mExpandedContents;
     TextView mNotificationPanelDebugText;
 
+    /**
+     * {@code true} if notifications not part of a group should by default be rendered in their
+     * expanded state. If {@code false}, then only the first notification will be expanded if
+     * possible.
+     */
+    private boolean mAlwaysExpandNonGroupedNotification;
+
     // settings
     private QSPanel mQSPanel;
 
     // top bar
     protected KeyguardStatusBarView mKeyguardStatusBar;
-    KeyguardStatusView mKeyguardStatusView;
-    KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
     KeyguardIndicationController mKeyguardIndicationController;
 
@@ -501,8 +521,8 @@
                 mUserSetup = userSetup;
                 if (!mUserSetup && mStatusBarView != null)
                     animateCollapseQuickSettings();
-                if (mKeyguardBottomArea != null) {
-                    mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+                if (mNotificationPanel != null) {
+                    mNotificationPanel.setUserSetupComplete(mUserSetup);
                 }
                 updateQsExpansionEnabled();
             }
@@ -550,7 +570,7 @@
         }};
 
     private boolean mWaitingForKeyguardExit;
-    private boolean mDozing;
+    protected boolean mDozing;
     private boolean mDozingRequested;
     protected boolean mScrimSrcModeEnabled;
 
@@ -621,6 +641,10 @@
     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
     private int mLastLoggedStateFingerprint;
 
+    public boolean isStartedGoingToSleep() {
+        return mStartedGoingToSleep;
+    }
+
     /**
      * If set, the device has started going to sleep but isn't fully non-interactive yet.
      */
@@ -710,14 +734,22 @@
     private NetworkController mNetworkController;
     private KeyguardMonitorImpl mKeyguardMonitor;
     private BatteryController mBatteryController;
-    private boolean mPanelExpanded;
+    protected boolean mPanelExpanded;
+    private IOverlayManager mOverlayManager;
+    private boolean mKeyguardRequested;
+    private boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private NotificationIconAreaController mNotificationIconAreaController;
-    private ConfigurationListener mConfigurationListener;
     private boolean mReinflateNotificationsOnUserSwitched;
     private HashMap<String, Entry> mPendingNotifications = new HashMap<>();
+    private boolean mClearAllEnabled;
+    @Nullable private View mAmbientIndicationContainer;
+    private String mKeyToRemoveOnGutsClosed;
+    private SysuiColorExtractor mColorExtractor;
     private ForegroundServiceController mForegroundServiceController;
+    private ScreenLifecycle mScreenLifecycle;
+    @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle;
 
     private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
         final int N = array.size();
@@ -756,25 +788,39 @@
         mNetworkController = Dependency.get(NetworkController.class);
         mUserSwitcherController = Dependency.get(UserSwitcherController.class);
         mKeyguardMonitor = (KeyguardMonitorImpl) Dependency.get(KeyguardMonitor.class);
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
+        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
+        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
         mBatteryController = Dependency.get(BatteryController.class);
         mAssistManager = Dependency.get(AssistManager.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
         mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
+        mOverlayManager = IOverlayManager.Stub.asInterface(
+                ServiceManager.getService(Context.OVERLAY_SERVICE));
+
+        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
+
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
 
         mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
 
-        mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mDisplay = mWindowManager.getDefaultDisplay();
         updateDisplaySize();
-        mScrimSrcModeEnabled = mContext.getResources().getBoolean(
-                R.bool.config_status_bar_scrim_behind_use_src);
+
+        Resources res = mContext.getResources();
+        mScrimSrcModeEnabled = res.getBoolean(R.bool.config_status_bar_scrim_behind_use_src);
+        mClearAllEnabled = res.getBoolean(R.bool.config_enableNotificationsClearAll);
+        mAlwaysExpandNonGroupedNotification =
+                res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
 
         DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
         putComponent(StatusBar.class, this);
 
         // start old BaseStatusBar.start().
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
-        mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
+        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
 
         mNotificationData = new NotificationData(this);
@@ -813,7 +859,7 @@
 
         mRecents = getComponent(Recents.class);
 
-        final Configuration currentConfig = mContext.getResources().getConfiguration();
+        final Configuration currentConfig = res.getConfiguration();
         mLocale = currentConfig.locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
 
@@ -826,7 +872,7 @@
         mCommandQueue.addCallbacks(this);
 
         int[] switches = new int[9];
-        ArrayList<IBinder> binders = new ArrayList<IBinder>();
+        ArrayList<IBinder> binders = new ArrayList<>();
         ArrayList<String> iconSlots = new ArrayList<>();
         ArrayList<StatusBarIcon> icons = new ArrayList<>();
         Rect fullscreenStackBounds = new Rect();
@@ -850,7 +896,6 @@
 
         // Set up the initial icon state
         int N = iconSlots.size();
-        int viewIndex = 0;
         for (int i=0; i < N; i++) {
             mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
         }
@@ -907,8 +952,8 @@
             Slog.e(TAG, "Failed to register VR mode state listener: " + e);
         }
 
-        mNonBlockablePkgs = new HashSet<String>();
-        Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
+        mNonBlockablePkgs = new HashSet<>();
+        Collections.addAll(mNonBlockablePkgs, res.getStringArray(
                 com.android.internal.R.array.config_nonBlockableNotificationPackages));
         // end old BaseStatusBar.start().
 
@@ -945,18 +990,7 @@
 
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
-        mConfigurationListener = new ConfigurationListener() {
-            @Override
-            public void onConfigChanged(Configuration newConfig) {
-                StatusBar.this.onConfigurationChanged(newConfig);
-            }
-
-            @Override
-            public void onDensityOrFontScaleChanged() {
-                StatusBar.this.onDensityOrFontScaleChanged();
-            }
-        };
-        Dependency.get(ConfigurationController.class).addCallback(mConfigurationListener);
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
     protected void createIconController() {
@@ -969,6 +1003,7 @@
         final Context context = mContext;
         updateDisplaySize(); // populates mDisplayMetrics
         updateResources();
+        updateTheme();
 
         inflateStatusBarWindow(context);
         mStatusBarWindow.setService(this);
@@ -982,6 +1017,9 @@
                 R.id.notification_stack_scroller);
         mNotificationPanel.setStatusBar(this);
         mNotificationPanel.setGroupManager(mGroupManager);
+        mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
+        mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
+                R.id.notification_container_parent));
         mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
@@ -998,6 +1036,7 @@
                     mStatusBarView.setBar(this);
                     mStatusBarView.setPanel(mNotificationPanel);
                     mStatusBarView.setScrimController(mScrimController);
+                    mStatusBarView.setBouncerShowing(mBouncerShowing);
                     setAreThereNotifications();
                     checkBarModes();
                 }).getFragmentManager()
@@ -1005,16 +1044,8 @@
                 .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                         CollapsedStatusBarFragment.TAG)
                 .commit();
-        Dependency.get(StatusBarIconController.class).addIconGroup(
-                new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
         mIconController = Dependency.get(StatusBarIconController.class);
 
-        if (!ActivityManager.isHighEndGfx()) {
-            mStatusBarWindow.setBackground(null);
-            mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
-                    R.color.notification_panel_solid_background)));
-        }
-
         mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
         mHeadsUpManager.setBar(this);
         mHeadsUpManager.addListener(this);
@@ -1064,15 +1095,15 @@
             mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
         }
 
-        mKeyguardStatusView =
-                (KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
-        mKeyguardBottomArea =
-                (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
         mKeyguardIndicationController =
                 SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
                 (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
-                mKeyguardBottomArea.getLockIcon());
-        mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
+                mNotificationPanel.getLockIcon());
+        mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+
+
+        mAmbientIndicationContainer = mStatusBarWindow.findViewById(
+                R.id.ambient_indication_container);
 
         // set the initial view visibility
         setAreThereNotifications();
@@ -1093,7 +1124,7 @@
             }
         });
 
-        mLightBarController = new LightBarController();
+        mLightBarController = new LightBarController(context);
         if (mNavigationBar != null) {
             mNavigationBar.setLightBarController(mLightBarController);
         }
@@ -1102,7 +1133,12 @@
         ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
         View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
         mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
-                scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
+                scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
+                scrimsVisible -> {
+                    if (mStatusBarWindowManager != null) {
+                        mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
+                    }
+                });
         if (mScrimSrcModeEnabled) {
             Runnable runnable = new Runnable() {
                 @Override
@@ -1122,8 +1158,7 @@
         // Other icons
         mVolumeComponent = getComponent(VolumeComponent.class);
 
-        mKeyguardBottomArea.setStatusBar(this);
-        mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+        mNotificationPanel.setUserSetupComplete(mUserSetup);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
             createUserSwitcher();
         }
@@ -1132,14 +1167,15 @@
         View container = mStatusBarWindow.findViewById(R.id.qs_frame);
         if (container != null) {
             FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
-            fragmentHostManager.getFragmentManager().beginTransaction()
-                    .replace(R.id.qs_frame, new QSFragment(), QS.TAG)
-                    .commit();
-            new PluginFragmentListener(container, QS.TAG, QSFragment.class, QS.class)
-                    .startListening();
+            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
+                    Dependency.get(ExtensionController.class).newExtension(QS.class)
+                            .withPlugin(QS.class)
+                            .withDefault(() -> new QSFragment())
+                            .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) {
@@ -1180,7 +1216,6 @@
             });
         }
 
-
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         if (!pm.isScreenOn()) {
             mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
@@ -1258,7 +1293,7 @@
         mNotificationShelf.setStatusBarState(mState);
     }
 
-    protected void onDensityOrFontScaleChanged() {
+    public void onDensityOrFontScaleChanged() {
         // start old BaseStatusBar.onDensityOrFontScaleChanged().
         if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
             updateNotificationsOnDensityOrFontScaleChanged();
@@ -1272,12 +1307,6 @@
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onDensityOrFontScaleChanged();
         }
-        inflateSignalClusters();
-        mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
-        inflateDismissView();
-        updateClearAll();
-        inflateEmptyShadeView();
-        updateEmptyShadeView();
         mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
         // TODO: Bring these out of StatusBar.
         ((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
@@ -1286,6 +1315,45 @@
         if (mKeyguardUserSwitcher != null) {
             mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
         }
+        mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+
+        reevaluateStyles();
+    }
+
+    private void reinflateViews() {
+        reevaluateStyles();
+
+        // Clock and bottom icons
+        mNotificationPanel.onOverlayChanged();
+        // The status bar on the keyguard is a special layout.
+        mKeyguardStatusBar.onOverlayChanged();
+        // Recreate Indication controller because internal references changed
+        mKeyguardIndicationController =
+                SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
+                        mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
+                        mNotificationPanel.getLockIcon());
+        mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+        mKeyguardIndicationController
+                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+        mKeyguardIndicationController.setVisible(mState == StatusBarState.KEYGUARD);
+        mKeyguardIndicationController.setDozing(mDozing);
+        if (mBrightnessMirrorController != null) {
+            mBrightnessMirrorController.onOverlayChanged();
+        }
+        if (mStatusBarKeyguardViewManager != null) {
+            mStatusBarKeyguardViewManager.onOverlayChanged();
+        }
+        if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
+            ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
+        }
+    }
+
+    protected void reevaluateStyles() {
+        inflateSignalClusters();
+        inflateDismissView();
+        updateClearAll();
+        inflateEmptyShadeView();
+        updateEmptyShadeView();
     }
 
     private void updateNotificationsOnDensityOrFontScaleChanged() {
@@ -1334,16 +1402,20 @@
     }
 
     private void inflateEmptyShadeView() {
+        if (mStackScroller == null) {
+            return;
+        }
         mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_no_notifications, mStackScroller, false);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
     }
 
     private void inflateDismissView() {
-        // Always inflate with a dark theme, since this sits on the scrim.
-        ContextThemeWrapper themedContext = new ContextThemeWrapper(mContext,
-                style.Theme_DeviceDefault);
-        mDismissView = (DismissView) LayoutInflater.from(themedContext).inflate(
+        if (!mClearAllEnabled || mStackScroller == null) {
+            return;
+        }
+
+        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
         mDismissView.setOnButtonClickListener(new View.OnClickListener() {
             @Override
@@ -1484,10 +1556,8 @@
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mScrimController,
                 mFingerprintUnlockController);
-        mKeyguardIndicationController.setStatusBarKeyguardViewManager(
-                mStatusBarKeyguardViewManager);
-        mKeyguardIndicationController.setUserInfoController(
-                Dependency.get(UserInfoController.class));
+        mKeyguardIndicationController
+                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
 
@@ -1746,6 +1816,14 @@
             mRemoteInputEntriesToRemoveOnCollapse.add(entry);
             return;
         }
+        if (entry != null && mNotificationGutsExposed != null
+                && mNotificationGutsExposed == entry.row.getGuts() && entry.row.getGuts() != null
+                && !entry.row.getGuts().isLeavebehind()) {
+            Log.w(TAG, "Keeping notification because it's showing guts. " + key);
+            mLatestRankingMap = ranking;
+            mKeyToRemoveOnGutsClosed = key;
+            return;
+        }
 
         if (entry != null) {
             mForegroundServiceController.removeNotification(entry.notification);
@@ -1834,6 +1912,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.
     }
 
@@ -1870,9 +1953,6 @@
             boolean sensitive = userPublic && needsRedaction;
             boolean deviceSensitive = devicePublic
                     && !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
-            if (sensitive) {
-                updatePublicContentView(ent, ent.notification);
-            }
             ent.row.setSensitive(sensitive, deviceSensitive);
             ent.row.setNeedsRedaction(needsRedaction);
             if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
@@ -2084,9 +2164,11 @@
     }
 
     private void updateClearAll() {
-        boolean showDismissView =
-                mState != StatusBarState.KEYGUARD &&
-               hasActiveClearableNotifications();
+        if (!mClearAllEnabled) {
+            return;
+        }
+        boolean showDismissView = mState != StatusBarState.KEYGUARD
+                && hasActiveClearableNotifications();
         mStackScroller.updateDismissView(showDismissView);
     }
 
@@ -2603,7 +2685,7 @@
 
     public void setQsExpanded(boolean expanded) {
         mStatusBarWindowManager.setQsExpanded(expanded);
-        mKeyguardStatusView.setImportantForAccessibility(expanded
+        mNotificationPanel.setStatusAccessibilityImportance(expanded
                 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
     }
@@ -2772,10 +2854,6 @@
         mRemoteInputEntriesToRemoveOnCollapse.clear();
     }
 
-    public void onScreenTurnedOff() {
-        mFalsingManager.onScreenOff();
-    }
-
     public NotificationStackScrollLayout getNotificationScrollLayout() {
         return mStackScroller;
     }
@@ -2797,6 +2875,27 @@
         return mNotificationPanel.hideStatusBarIconsWhenExpanded();
     }
 
+    @Override
+    public void onColorsChanged(ColorExtractor extractor, int which) {
+        updateTheme();
+    }
+
+    public boolean isUsingDarkTheme() {
+        OverlayInfo themeInfo = null;
+        try {
+            themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.dark",
+                    mCurrentUserId);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        return themeInfo != null && themeInfo.isEnabled();
+    }
+
+    @Nullable
+    public View getAmbientIndicationContainer() {
+        return mAmbientIndicationContainer;
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -2853,8 +2952,8 @@
      * settings. Down action closes the entire panel.
      */
     @Override
-    public void handleSystemNavigationKey(int key) {
-        if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
+    public void handleSystemKey(int key) {
+        if (SPEW) Log.d(TAG, "handleNavigationKey: " + key);
         if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
                 || mKeyguardMonitor.isShowing() && !mKeyguardMonitor.isOccluded()) {
             return;
@@ -3386,7 +3485,11 @@
         pw.println(Settings.Global.zenModeToString(mZenMode));
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
-        dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        pw.print("  mKeyToRemoveOnGutsClosed=");
+        pw.println(mKeyToRemoveOnGutsClosed);
+        if (mStatusBarView != null) {
+            dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        }
 
         pw.print("  mMediaSessionManager=");
         pw.println(mMediaSessionManager);
@@ -3412,6 +3515,19 @@
             pw.print  ("      ");
             mNotificationPanel.dump(fd, pw, args);
         }
+        pw.println("  mStackScroller: ");
+        if (mStackScroller != null) {
+            pw.print  ("      ");
+            mStackScroller.dump(fd, pw, args);
+        }
+        pw.println("  Theme:");
+        if (mOverlayManager == null) {
+            pw.println("    overlay manager not initialized!");
+        } else {
+            pw.println("    dark overlay on: " + isUsingDarkTheme());
+        }
+        final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
+        pw.println("    light wallpaper theme: " + lightWpTheme);
 
         DozeLog.dump(pw);
 
@@ -3452,7 +3568,9 @@
             pw.println("  mGroupManager: null");
         }
 
-        mLightBarController.dump(fd, pw, args);
+        if (mLightBarController != null) {
+            mLightBarController.dump(fd, pw, args);
+        }
 
         if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
@@ -3613,7 +3731,6 @@
                 }
             }
             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                notifyHeadsUpScreenOff();
                 finishBarAnimations();
                 resetUserExpandedStates();
             }
@@ -3665,6 +3782,15 @@
 
     private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
+        if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+                && mUnlockMethodCache.canSkipBouncer()
+                && !mLeaveOpenOnKeyguardHide
+                && isPulsing()) {
+            // Reuse the fingerprint wake-and-unlock transition if we dismiss keyguard from a pulse.
+            // TODO: Factor this transition out of FingerprintUnlockController.
+            mFingerprintUnlockController.startWakeAndUnlock(
+                    FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
+        }
         if (mStatusBarKeyguardViewManager.isShowing()) {
             mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
                     afterKeyguardGone);
@@ -3675,7 +3801,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
 
@@ -3846,12 +3972,6 @@
         }
     }
 
-    public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
-        if (mNavigationBar != null) {
-            mNavigationBar.onKeyguardOccludedChanged(keyguardOccluded);
-        }
-    }
-
     // State logging
 
     private void logStateToEventlog() {
@@ -4019,7 +4139,7 @@
         }
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
         mDeviceProvisionedController.removeCallback(mUserSetupObserver);
-        Dependency.get(ConfigurationController.class).removeCallback(mConfigurationListener);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     private boolean mDemoModeAllowed;
@@ -4106,6 +4226,47 @@
     }
 
     public void showKeyguard() {
+        mKeyguardRequested = true;
+        mLeaveOpenOnKeyguardHide = false;
+        mPendingRemoteInputView = null;
+        updateIsKeyguard();
+        mAssistManager.onLockscreenShown();
+    }
+
+    public boolean hideKeyguard() {
+        mKeyguardRequested = false;
+        return updateIsKeyguard();
+    }
+
+    private boolean updateIsKeyguard() {
+        boolean wakeAndUnlocking = mFingerprintUnlockController.getMode()
+                == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+
+        // For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
+        // there's no surface we can show to the user. Note that the device goes fully interactive
+        // late in the transition, so we also allow the device to start dozing once the screen has
+        // turned off fully.
+        boolean keyguardForDozing = mDozingRequested &&
+                (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard));
+        boolean shouldBeKeyguard = (mKeyguardRequested || keyguardForDozing) && !wakeAndUnlocking;
+        if (keyguardForDozing) {
+            updatePanelExpansionForKeyguard();
+        }
+        if (shouldBeKeyguard) {
+            if (isGoingToSleep()
+                    && mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF) {
+                // Delay showing the keyguard until screen turned off.
+            } else {
+                showKeyguardImpl();
+            }
+        } else {
+            return hideKeyguardImpl();
+        }
+        return false;
+    }
+
+    public void showKeyguardImpl() {
+        mIsKeyguard = true;
         if (mLaunchTransitionFadingAway) {
             mNotificationPanel.animate().cancel();
             onLaunchTransitionFadingEnded();
@@ -4117,19 +4278,21 @@
             setBarState(StatusBarState.KEYGUARD);
         }
         updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
-        if (mState == StatusBarState.KEYGUARD) {
-            instantExpandNotificationsPanel();
-        } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
-            instantCollapseNotificationPanel();
-        }
-        mLeaveOpenOnKeyguardHide = false;
+        updatePanelExpansionForKeyguard();
         if (mDraggedDownRow != null) {
             mDraggedDownRow.setUserLocked(false);
             mDraggedDownRow.notifyHeightChanged(false  /* needsAnimation */);
             mDraggedDownRow = null;
         }
-        mPendingRemoteInputView = null;
-        mAssistManager.onLockscreenShown();
+    }
+
+    private void updatePanelExpansionForKeyguard() {
+        if (mState == StatusBarState.KEYGUARD && mFingerprintUnlockController.getMode()
+                != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
+            instantExpandNotificationsPanel();
+        } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
+            instantCollapseNotificationPanel();
+        }
     }
 
     private void onLaunchTransitionFadingEnded() {
@@ -4138,7 +4301,7 @@
         releaseGestureWakeLock();
         runLaunchTransitionEndRunnable();
         mLaunchTransitionFadingAway = false;
-        mScrimController.forceHideScrims(false /* hide */);
+        mScrimController.forceHideScrims(false /* hide */, false /* animated */);
         updateMediaMetaData(true /* metaDataChanged */, true);
     }
 
@@ -4173,7 +4336,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);
@@ -4253,21 +4416,26 @@
     /**
      * @return true if we would like to stay in the shade, false if it should go away entirely
      */
-    public boolean hideKeyguard() {
+    public boolean hideKeyguardImpl() {
+        mIsKeyguard = false;
         Trace.beginSection("StatusBar#hideKeyguard");
         boolean staying = mLeaveOpenOnKeyguardHide;
         setBarState(StatusBarState.SHADE);
         View viewToClick = null;
         if (mLeaveOpenOnKeyguardHide) {
-            mLeaveOpenOnKeyguardHide = false;
+            if (!mKeyguardRequested) {
+                mLeaveOpenOnKeyguardHide = false;
+            }
             long delay = calculateGoingToFullShadeDelay();
             mNotificationPanel.animateToFullShade(delay);
             if (mDraggedDownRow != null) {
                 mDraggedDownRow.setUserLocked(false);
                 mDraggedDownRow = null;
             }
-            viewToClick = mPendingRemoteInputView;
-            mPendingRemoteInputView = null;
+            if (!mKeyguardRequested) {
+                viewToClick = mPendingRemoteInputView;
+                mPendingRemoteInputView = null;
+            }
 
             // Disable layout transitions in navbar for this transition because the load is just
             // too heavy for the CPU and GPU on any device.
@@ -4392,6 +4560,9 @@
                 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
             }
             mStatusBarView.removePendingHideExpandedRunnables();
+            if (mAmbientIndicationContainer != null) {
+                mAmbientIndicationContainer.setVisibility(View.VISIBLE);
+            }
         } else {
             mKeyguardIndicationController.setVisible(false);
             if (mKeyguardUserSwitcher != null) {
@@ -4400,6 +4571,9 @@
                         mState == StatusBarState.SHADE_LOCKED ||
                         fromShadeLocked);
             }
+            if (mAmbientIndicationContainer != null) {
+                mAmbientIndicationContainer.setVisibility(View.INVISIBLE);
+            }
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mScrimController.setKeyguardShowing(true);
@@ -4407,6 +4581,7 @@
             mScrimController.setKeyguardShowing(false);
         }
         mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
+        updateTheme();
         updateDozingState();
         updatePublicMode();
         updateStackScrollerState(goingToFullShade, fromShadeLocked);
@@ -4419,7 +4594,56 @@
         Trace.endSection();
     }
 
+    /**
+     * Switches theme from light to dark and vice-versa.
+     */
+    private void updateTheme() {
+        final boolean inflated = mStackScroller != null;
+
+        // The system wallpaper defines if QS should be light or dark.
+        WallpaperColors systemColors = mColorExtractor
+                .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+        final boolean useDarkTheme = systemColors != null
+                && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        if (isUsingDarkTheme() != useDarkTheme) {
+            try {
+                mOverlayManager.setEnabled("com.android.systemui.theme.dark",
+                        useDarkTheme, mCurrentUserId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't change theme", e);
+            }
+        }
+
+        // Lock wallpaper defines the color of the majority of the views, hence we'll use it
+        // to set our default theme.
+        final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
+                /* ignoreVisibility */).supportsDarkText();
+        final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
+        if (mContext.getThemeResId() != themeResId) {
+            mContext.setTheme(themeResId);
+            if (inflated) {
+                reinflateViews();
+            }
+        }
+
+        if (inflated) {
+            int which;
+            if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+                which = WallpaperManager.FLAG_LOCK;
+            } else {
+                which = WallpaperManager.FLAG_SYSTEM;
+            }
+            final boolean useDarkText = mColorExtractor.getColors(which,
+                    true /* ignoreVisibility */).supportsDarkText();
+            mStackScroller.updateDecorViews(useDarkText);
+
+            // Make sure we have the correct navbar/statusbar colors.
+            mStatusBarWindowManager.setKeyguardDark(useDarkText);
+        }
+    }
+
     private void updateDozingState() {
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
         Trace.beginSection("StatusBar#updateDozingState");
         boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
         mNotificationPanel.setDozing(mDozing, animate);
@@ -4520,10 +4744,10 @@
     }
 
     private void instantExpandNotificationsPanel() {
-
         // Make our window larger and the panel expanded.
         makeExpandedVisible(true);
         mNotificationPanel.expand(false /* animate */);
+        recomputeDisableFlags(false /* animate */);
     }
 
     private void instantCollapseNotificationPanel() {
@@ -4532,6 +4756,11 @@
 
     @Override
     public void onActivated(ActivatableNotificationView view) {
+        onActivated((View)view);
+        mStackScroller.setActivatedChild(view);
+    }
+
+    public void onActivated(View view) {
         mLockscreenGestureLogger.write(
                 MetricsEvent.ACTION_LS_NOTE,
                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
@@ -4540,7 +4769,6 @@
         if (previousView != null) {
             previousView.makeInactive(true /* animate */);
         }
-        mStackScroller.setActivatedChild(view);
     }
 
     /**
@@ -4567,17 +4795,22 @@
         mStackScroller.setStatusBarState(state);
         updateReportRejectedTouchVisibility();
         updateDozing();
+        updateTheme();
         mNotificationShelf.setStatusBarState(state);
     }
 
     @Override
     public void onActivationReset(ActivatableNotificationView view) {
         if (view == mStackScroller.getActivatedChild()) {
-            mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
+            onActivationReset((View)view);
         }
     }
 
+    public void onActivationReset(View view) {
+        mKeyguardIndicationController.hideTransientIndication();
+    }
+
     public void onTrackingStarted() {
         runPostCollapseRunnables();
     }
@@ -4638,10 +4871,21 @@
         return getMaxKeyguardNotifications(false /* recompute */);
     }
 
-    // TODO: Figure out way to remove this.
+    // TODO: Figure out way to remove these.
     public NavigationBarView getNavigationBarView() {
-        return (mNavigationBar != null) ?
-               (NavigationBarView) mNavigationBar.getView() : null;
+        return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null);
+    }
+
+    public View getNavigationBarWindow() {
+        return mNavigationBarView;
+    }
+
+    /**
+     * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
+     * @return bottom area view
+     */
+    public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+        return mNotificationPanel.getKeyguardBottomAreaView();
     }
 
     // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
@@ -4901,60 +5145,105 @@
 
     public void setBouncerShowing(boolean bouncerShowing) {
         mBouncerShowing = bouncerShowing;
-        mStatusBarView.setBouncerShowing(bouncerShowing);
+        if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         recomputeDisableFlags(true /* animate */);
     }
 
-    public void onStartedGoingToSleep() {
-        mStartedGoingToSleep = true;
-    }
 
-    public void onFinishedGoingToSleep() {
-        mNotificationPanel.onAffordanceLaunchEnded();
-        releaseGestureWakeLock();
-        mLaunchCameraOnScreenTurningOn = false;
-        mStartedGoingToSleep = false;
-        mDeviceInteractive = false;
-        mWakeUpComingFromTouch = false;
-        mWakeUpTouchLocation = null;
-        mStackScroller.setAnimationsEnabled(false);
-        mVisualStabilityManager.setScreenOn(false);
-        updateVisibleToUser();
-
-        // We need to disable touch events because these might
-        // collapse the panel after we expanded it, and thus we would end up with a blank
-        // Keyguard.
-        mNotificationPanel.setTouchDisabled(true);
-        mStatusBarWindow.cancelCurrentTouch();
-        if (mLaunchCameraOnFinishedGoingToSleep) {
-            mLaunchCameraOnFinishedGoingToSleep = false;
-
-            // This gets executed before we will show Keyguard, so post it in order that the state
-            // is correct.
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    onCameraLaunchGestureDetected(mLastCameraLaunchSource);
-                }
-            });
-        }
-    }
-
-    public void onStartedWakingUp() {
-        mDeviceInteractive = true;
-        mStackScroller.setAnimationsEnabled(true);
-        mVisualStabilityManager.setScreenOn(true);
-        mNotificationPanel.setTouchDisabled(false);
-        updateVisibleToUser();
-    }
-
-    public void onScreenTurningOn() {
-        mScreenTurningOn = true;
-        mFalsingManager.onScreenTurningOn();
-        mNotificationPanel.onScreenTurningOn();
-        if (mLaunchCameraOnScreenTurningOn) {
-            mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
+    WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+        @Override
+        public void onFinishedGoingToSleep() {
+            mNotificationPanel.onAffordanceLaunchEnded();
+            releaseGestureWakeLock();
             mLaunchCameraOnScreenTurningOn = false;
+            mDeviceInteractive = false;
+            mWakeUpComingFromTouch = false;
+            mWakeUpTouchLocation = null;
+            mStackScroller.setAnimationsEnabled(false);
+            mVisualStabilityManager.setScreenOn(false);
+            updateVisibleToUser();
+
+            // We need to disable touch events because these might
+            // collapse the panel after we expanded it, and thus we would end up with a blank
+            // Keyguard.
+            mNotificationPanel.setTouchDisabled(true);
+            mStatusBarWindow.cancelCurrentTouch();
+            if (mLaunchCameraOnFinishedGoingToSleep) {
+                mLaunchCameraOnFinishedGoingToSleep = false;
+
+                // This gets executed before we will show Keyguard, so post it in order that the state
+                // is correct.
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onCameraLaunchGestureDetected(mLastCameraLaunchSource);
+                    }
+                });
+            }
+            updateIsKeyguard();
+        }
+
+        @Override
+        public void onStartedGoingToSleep() {
+            notifyHeadsUpGoingToSleep();
+            dismissVolumeDialog();
+        }
+
+        @Override
+        public void onStartedWakingUp() {
+            mDeviceInteractive = true;
+            mStackScroller.setAnimationsEnabled(true);
+            mVisualStabilityManager.setScreenOn(true);
+            mNotificationPanel.setTouchDisabled(false);
+
+            maybePrepareWakeUpFromAod();
+
+            mDozeServiceHost.stopDozing();
+            updateVisibleToUser();
+            updateIsKeyguard();
+        }
+    };
+
+    ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurningOn() {
+            mFalsingManager.onScreenTurningOn();
+            mNotificationPanel.onScreenTurningOn();
+
+            maybePrepareWakeUpFromAod();
+
+            if (mLaunchCameraOnScreenTurningOn) {
+                mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
+                mLaunchCameraOnScreenTurningOn = false;
+            }
+        }
+
+        @Override
+        public void onScreenTurnedOn() {
+            mScrimController.wakeUpFromAod();
+            mDozeScrimController.onScreenTurnedOn();
+        }
+
+        @Override
+        public void onScreenTurnedOff() {
+            mFalsingManager.onScreenOff();
+            // If we pulse in from AOD, we turn the screen off first. However, updatingIsKeyguard
+            // in that case destroys the HeadsUpManager state, so don't do it in that case.
+            if (!isPulsing()) {
+                updateIsKeyguard();
+            }
+        }
+    };
+
+    public int getWakefulnessState() {
+        return mWakefulnessLifecycle.getWakefulness();
+    }
+
+    private void maybePrepareWakeUpFromAod() {
+        int wakefulness = mWakefulnessLifecycle.getWakefulness();
+        if (mDozing && (wakefulness == WAKEFULNESS_WAKING
+                || wakefulness == WAKEFULNESS_ASLEEP) && !isPulsing()) {
+            mScrimController.prepareWakeUpFromAod();
         }
     }
 
@@ -4963,9 +5252,12 @@
         mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
     }
 
-    public void onScreenTurnedOn() {
-        mScreenTurningOn = false;
-        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 mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF;
     }
 
     @Override
@@ -5012,12 +5304,15 @@
     @Override
     public void onCameraLaunchGestureDetected(int source) {
         mLastCameraLaunchSource = source;
-        if (mStartedGoingToSleep) {
+        if (isGoingToSleep()) {
+            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Finish going to sleep before launching camera");
             mLaunchCameraOnFinishedGoingToSleep = true;
             return;
         }
         if (!mNotificationPanel.canCameraGestureBeLaunched(
                 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
+            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Can't launch camera right now, mExpandedVisible: " +
+                    mExpandedVisible);
             return;
         }
         if (!mDeviceInteractive) {
@@ -5036,18 +5331,42 @@
                 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
                 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
             }
-            if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
+            if (isScreenTurningOnOrOn()) {
+                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera");
                 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
             } else {
                 // We need to defer the camera launch until the screen comes on, since otherwise
                 // we will dismiss us too early since we are waiting on an activity to be drawn and
                 // incorrectly get notified because of the screen on event (which resumes and pauses
                 // some activities)
+                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Deferring until screen turns on");
                 mLaunchCameraOnScreenTurningOn = true;
             }
         }
     }
 
+    boolean isCameraAllowedByAdmin() {
+        if (mDevicePolicyManager.getCameraDisabled(null, mCurrentUserId)) {
+            return false;
+        } else if (isKeyguardShowing() && isKeyguardSecure()) {
+            // Check if the admin has disabled the camera specifically for the keyguard
+            return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mCurrentUserId)
+                    & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+        }
+
+        return true;
+    }
+
+    private boolean isGoingToSleep() {
+        return mWakefulnessLifecycle.getWakefulness()
+                == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
+    }
+
+    private boolean isScreenTurningOnOrOn() {
+        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_ON
+                || mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
+    }
+
     public void notifyFpAuthModeChanged() {
         updateDozing();
     }
@@ -5065,17 +5384,26 @@
             mDozing = false;
         }
         mStatusBarWindowManager.setDozing(mDozing);
+        mStatusBarKeyguardViewManager.setDozing(mDozing);
+        if (mAmbientIndicationContainer instanceof DozeReceiver) {
+            ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
+        }
         updateDozingState();
         Trace.endSection();
     }
 
     public boolean isKeyguardShowing() {
+        if (mStatusBarKeyguardViewManager == null) {
+            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
+            return true;
+        }
         return mStatusBarKeyguardViewManager.isShowing();
     }
 
     private final class DozeServiceHost implements DozeHost {
         private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
         private boolean mAnimateWakeup;
+        private boolean mIgnoreTouchWhilePulsing;
 
         @Override
         public String toString() {
@@ -5110,11 +5438,18 @@
                 mDozingRequested = true;
                 DozeLog.traceDozing(mContext, mDozing);
                 updateDozing();
+                updateIsKeyguard();
             }
         }
 
         @Override
         public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
+            if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
+                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+                startAssist(new Bundle());
+                return;
+            }
+
             mDozeScrimController.pulse(new PulseCallback() {
 
                 @Override
@@ -5139,6 +5474,7 @@
                     mStackScroller.setPulsing(pulsing);
                     mNotificationPanel.setPulsing(pulsing != null);
                     mVisualStabilityManager.setPulsing(pulsing != null);
+                    mIgnoreTouchWhilePulsing = false;
                 }
             }, reason);
         }
@@ -5153,8 +5489,19 @@
         }
 
         @Override
+        public void onIgnoreTouchWhilePulsing(boolean ignore) {
+            if (ignore != mIgnoreTouchWhilePulsing) {
+                DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
+            }
+            mIgnoreTouchWhilePulsing = ignore;
+            if (isDozing() && ignore) {
+                mStatusBarWindow.cancelCurrentTouch();
+            }
+        }
+
+        @Override
         public void dozeTimeTick() {
-            mKeyguardStatusView.refreshTime();
+            mNotificationPanel.refreshTime();
         }
 
         @Override
@@ -5169,6 +5516,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);
         }
@@ -5185,14 +5547,64 @@
 
         @Override
         public void setAnimateWakeup(boolean animateWakeup) {
+            if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
+                    || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING) {
+                // Too late to change the wakeup animation.
+                return;
+            }
             mAnimateWakeup = animateWakeup;
         }
 
+        @Override
+        public void onDoubleTap(float screenX, float screenY) {
+            if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null 
+                && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) {
+                mAmbientIndicationContainer.getLocationOnScreen(mTmpInt2);
+                float viewX = screenX - mTmpInt2[0];
+                float viewY = screenY - mTmpInt2[1];
+                if (0 <= viewX && viewX <= mAmbientIndicationContainer.getWidth()
+                        && 0 <= viewY && viewY <= mAmbientIndicationContainer.getHeight()) {
+                    dispatchDoubleTap(viewX, viewY);
+                }
+            }
+        }
+
+        @Override
+        public void setDozeScreenBrightness(int value) {
+            mStatusBarWindowManager.setDozeScreenBrightness(value);
+        }
+
+        @Override
+        public void setAodDimmingScrim(float scrimOpacity) {
+            mDozeScrimController.setAodDimmingScrim(scrimOpacity);
+        }
+
+        public void dispatchDoubleTap(float viewX, float viewY) {
+            dispatchTap(mAmbientIndicationContainer, viewX, viewY);
+            dispatchTap(mAmbientIndicationContainer, viewX, viewY);
+        }
+
+        private void dispatchTap(View view, float x, float y) {
+            long now = SystemClock.elapsedRealtime();
+            dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_DOWN);
+            dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_UP);
+        }
+
+        private void dispatchTouchEvent(View view, float x, float y, long now, int action) {
+            MotionEvent ev = MotionEvent.obtain(now, now, action, x, y, 0 /* meta */);
+            view.dispatchTouchEvent(ev);
+            ev.recycle();
+        }
+
         private boolean shouldAnimateWakeup() {
             return mAnimateWakeup;
         }
     }
 
+    public boolean shouldIgnoreTouch() {
+        return isDozing() && mDozeServiceHost.mIgnoreTouchWhilePulsing;
+    }
+
     // Begin Extra BaseStatusBar methods.
 
     protected CommandQueue mCommandQueue;
@@ -5209,6 +5621,8 @@
     // for heads up notifications
     protected HeadsUpManager mHeadsUpManager;
 
+    private AboveShelfObserver mAboveShelfObserver;
+
     // handling reordering
     protected VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
 
@@ -5285,6 +5699,10 @@
 
     private Set<String> mNonBlockablePkgs;
 
+    public boolean isDeviceInteractive() {
+        return mDeviceInteractive;
+    }
+
     @Override  // NotificationData.Environment
     public boolean isDeviceProvisioned() {
         return mDeviceProvisionedController.isDeviceProvisioned();
@@ -5373,15 +5791,18 @@
                         boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
 
                         // close the shade if it was open
-                        if (handled) {
+                        if (handled && !mNotificationPanel.isFullyCollapsed()) {
                             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
                                     true /* force */);
                             visibilityChanged(false);
                             mAssistManager.hideAssist();
+
+                            // Wait for activity start.
+                            return true;
+                        } else {
+                            return false;
                         }
 
-                        // Wait for activity start.
-                        return handled;
                     }
                 }, afterKeyguardGone);
                 return true;
@@ -5630,11 +6051,12 @@
         }
     };
 
-    private final NotificationListenerService mNotificationListener =
-            new NotificationListenerService() {
+    private final NotificationListenerWithPlugins mNotificationListener =
+            new NotificationListenerWithPlugins() {
         @Override
         public void onListenerConnected() {
             if (DEBUG) Log.d(TAG, "onListenerConnected");
+            onPluginConnected();
             final StatusBarNotification[] notifications = getActiveNotifications();
             if (notifications == null) {
                 Log.w(TAG, "onListenerConnected unable to get active notifications.");
@@ -5659,7 +6081,7 @@
         public void onNotificationPosted(final StatusBarNotification sbn,
                 final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
-            if (sbn != null) {
+            if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
@@ -5703,14 +6125,9 @@
         public void onNotificationRemoved(StatusBarNotification sbn,
                 final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
-            if (sbn != null) {
+            if (sbn != null && !onPluginNotificationRemoved(sbn, rankingMap)) {
                 final String key = sbn.getKey();
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        removeNotification(key, rankingMap);
-                    }
-                });
+                mHandler.post(() -> removeNotification(key, rankingMap));
             }
         }
 
@@ -5718,13 +6135,10 @@
         public void onNotificationRankingUpdate(final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onRankingUpdate");
             if (rankingMap != null) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    updateNotificationRanking(rankingMap);
-                }
-            });
-        }                            }
+                RankingMap r = onPluginRankingUpdate(rankingMap);
+                mHandler.post(() -> updateNotificationRanking(r));
+            }
+        }
 
     };
 
@@ -5861,11 +6275,12 @@
     }
 
     public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
-        if (snoozeOption.criterion != null) {
-            mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
+        if (snoozeOption.getSnoozeCriterion() != null) {
+            mNotificationListener.snoozeNotification(sbn.getKey(),
+                    snoozeOption.getSnoozeCriterion().getId());
         } else {
             mNotificationListener.snoozeNotification(sbn.getKey(),
-                    snoozeOption.snoozeForMinutes * 60 * 1000);
+                    snoozeOption.getMinutesToSnoozeFor() * 60 * 1000);
         }
     }
 
@@ -5883,6 +6298,11 @@
                 mNotificationGutsExposed = null;
                 mGutsMenuItem = null;
             }
+            String key = sbn.getKey();
+            if (key.equals(mKeyToRemoveOnGutsClosed)) {
+                mKeyToRemoveOnGutsClosed = null;
+                removeNotification(key, mLatestRankingMap);
+            }
         });
 
         View gutsView = item.getGutsView();
@@ -5999,6 +6419,7 @@
                 if (row.isDark()) {
                     return false;
                 }
+                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                 if (row.areGutsExposed()) {
                     closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                             true /* removeControls */, -1 /* x */, -1 /* y */,
@@ -6246,6 +6667,10 @@
      * Called when the notification panel layouts
      */
     public void onPanelLaidOut() {
+        updateKeyguardMaxNotifications();
+    }
+
+    public void updateKeyguardMaxNotifications() {
         if (mState == StatusBarState.KEYGUARD) {
             // Since the number of notifications is determined based on the height of the view, we
             // need to update them.
@@ -6280,6 +6705,7 @@
         row.setExpansionLogger(this, entry.notification.getKey());
         row.setGroupManager(mGroupManager);
         row.setHeadsUpManager(mHeadsUpManager);
+        row.setAboveShelfChangedListener(mAboveShelfObserver);
         row.setRemoteInputController(mRemoteInputController);
         row.setOnExpandClickListener(this);
         row.setRemoteViewClickHandler(mOnClickHandler);
@@ -6426,12 +6852,16 @@
                     }
                 }.start();
 
-                // close the shade if it was open
-                animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                        true /* force */, true /* delayed */);
-                visibilityChanged(false);
+                if (!mNotificationPanel.isFullyCollapsed()) {
+                    // close the shade if it was open
+                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                            true /* force */, true /* delayed */);
+                    visibilityChanged(false);
 
-                return true;
+                    return true;
+                } else {
+                    return false;
+                }
             }
         }, afterKeyguardGone);
     }
@@ -6476,7 +6906,6 @@
                 }
             });
 
-            final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
             final boolean afterKeyguardGone = intent.isActivity()
                     && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
                             mCurrentUserId);
@@ -6503,7 +6932,7 @@
                         }
                     }
                     final StatusBarNotification parentToCancelFinal = parentToCancel;
-                    new Thread() {
+                    final Runnable runnable = new Runnable() {
                         @Override
                         public void run() {
                             try {
@@ -6575,14 +7004,25 @@
                                 });
                             }
                         }
-                    }.start();
+                    };
 
-                    // close the shade if it was open
-                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
-                            true /* force */, true /* delayed */);
-                    visibilityChanged(false);
+                    if (mStatusBarKeyguardViewManager.isShowing()
+                            && mStatusBarKeyguardViewManager.isOccluded()) {
+                        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+                    } else {
+                        new Thread(runnable).start();
+                    }
 
-                    return true;
+                    if (!mNotificationPanel.isFullyCollapsed()) {
+                        // close the shade if it was open
+                        animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                                true /* force */, true /* delayed */);
+                        visibilityChanged(false);
+
+                        return true;
+                    } else {
+                        return false;
+                    }
                 }
             }, afterKeyguardGone);
         }
@@ -6720,13 +7160,18 @@
         while(!stack.isEmpty()) {
             ExpandableNotificationRow row = stack.pop();
             NotificationData.Entry entry = row.getEntry();
-            boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
-            if (onKeyguard) {
-                row.setOnKeyguard(true);
-            } else {
-                row.setOnKeyguard(false);
-                row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
+            boolean isChildNotification =
+                    mGroupManager.isChildInGroupWithSummary(entry.notification);
+
+            row.setOnKeyguard(onKeyguard);
+
+            if (!onKeyguard) {
+                // If mAlwaysExpandNonGroupedNotification is false, then only expand the
+                // very first notification and if it's not a child of grouped notifications.
+                row.setSystemExpanded(mAlwaysExpandNonGroupedNotification
+                        || (visibleNotifications == 0 && !isChildNotification));
             }
+
             entry.row.setShowAmbient(isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
@@ -6741,7 +7186,7 @@
                 if (wasGone) {
                     entry.row.setVisibility(View.VISIBLE);
                 }
-                if (!childNotification && !entry.row.isRemoved()) {
+                if (!isChildNotification && !entry.row.isRemoved()) {
                     if (wasGone) {
                         // notify the scroller of a child addition
                         mStackScroller.generateAddAnimation(entry.row,
@@ -6761,9 +7206,26 @@
         }
         mNotificationPanel.setNoVisibleNotifications(visibleNotifications == 0);
 
-        mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
-        mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2);
-        mStackScroller.changeViewPosition(mNotificationShelf, mStackScroller.getChildCount() - 3);
+        // The following views will be moved to the end of mStackScroller. This counter represents
+        // the offset from the last child. Initialized to 1 for the very last position. It is post-
+        // incremented in the following "changeViewPosition" calls so that its value is correct for
+        // subsequent calls.
+        int offsetFromEnd = 1;
+        if (mDismissView != null) {
+            mStackScroller.changeViewPosition(mDismissView,
+                    mStackScroller.getChildCount() - offsetFromEnd++);
+        }
+
+        mStackScroller.changeViewPosition(mEmptyShadeView,
+                mStackScroller.getChildCount() - offsetFromEnd++);
+
+        // No post-increment for this call because it is the last one. Make sure to add one if
+        // another "changeViewPosition" call is ever added.
+        mStackScroller.changeViewPosition(mNotificationShelf,
+                mStackScroller.getChildCount() - offsetFromEnd);
+
+        // Scrim opacity varies based on notification count
+        mScrimController.setNotificationCount(mStackScroller.getNotGoneChildCount());
     }
 
     public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
@@ -6814,9 +7276,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();
@@ -6853,25 +7318,7 @@
         setAreThereNotifications();
     }
 
-    protected void updatePublicContentView(Entry entry,
-            StatusBarNotification sbn) {
-        final RemoteViews publicContentView = entry.cachedPublicContentView;
-        View inflatedView = entry.getPublicContentView();
-        if (entry.autoRedacted && publicContentView != null && inflatedView != null) {
-            final boolean disabledByPolicy =
-                    !adminAllowsUnredactedNotifications(entry.notification.getUserId());
-            String notificationHiddenText = mContext.getString(disabledByPolicy
-                    ? com.android.internal.R.string.notification_hidden_by_policy_text
-                    : com.android.internal.R.string.notification_hidden_text);
-            TextView titleView = (TextView) inflatedView.findViewById(android.R.id.title);
-            if (titleView != null
-                    && !titleView.getText().toString().equals(notificationHiddenText)) {
-                titleView.setText(notificationHiddenText);
-            }
-        }
-    }
-
-    protected void notifyHeadsUpScreenOff() {
+    protected void notifyHeadsUpGoingToSleep() {
         maybeEscalateHeadsUp();
     }
 
@@ -6904,7 +7351,12 @@
             return false;
         }
 
-        if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+        if (!isDozing() && mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+            return false;
+        }
+
+        if (isDozing() && mNotificationData.shouldSuppressScreenOff(sbn.getKey())) {
             if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
             return false;
         }
@@ -6931,6 +7383,9 @@
             if (mAccessibilityManager.isTouchExplorationEnabled()) {
                 if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
                 return false;
+            } else if (mDozing) {
+                // We never want heads up when we are dozing.
+                return false;
             } else {
                 // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
                 return !mStatusBarKeyguardViewManager.isShowing()
@@ -7006,6 +7461,10 @@
         }
     }
 
+    public NotificationPanelView getPanel() {
+        return mNotificationPanel;
+    }
+
     @Override
     public void startAssist(Bundle args) {
         if (mAssistManager != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a3ef91d..c240765 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -14,7 +14,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -26,6 +29,7 @@
 import android.widget.LinearLayout.LayoutParams;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -57,7 +61,6 @@
         return ret;
     }
 
-
     /**
      * Version of ViewGroup that observers state from the DarkIconDispatcher.
      */
@@ -108,6 +111,31 @@
         }
     }
 
+    public static class TintedIconManager extends IconManager {
+        private int mColor;
+
+        public TintedIconManager(ViewGroup group) {
+            super(group);
+        }
+
+        @Override
+        protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
+            StatusBarIconView v = addIcon(index, slot, blocked, icon);
+            v.setStaticDrawableColor(mColor);
+        }
+
+        public void setTint(int color) {
+            mColor = color;
+            for (int i = 0; i < mGroup.getChildCount(); i++) {
+                View child = mGroup.getChildAt(i);
+                if (child instanceof StatusBarIconView) {
+                    StatusBarIconView icon = (StatusBarIconView) child;
+                    icon.setStaticDrawableColor(mColor);
+                }
+            }
+        }
+    }
+
     /**
      * Turns info from StatusBarIconController into ImageViews in a ViewGroup.
      */
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 47c4692..b4b859c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+import static com.android.systemui.statusbar.phone.FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+import static com.android.systemui.statusbar.phone.FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
+
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.os.Bundle;
@@ -30,18 +34,15 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.keyguard.LatencyTracker;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.DejankUtils;
-import com.android.keyguard.LatencyTracker;
 import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.RemoteInputController;
 
-import static com.android.keyguard.KeyguardHostView.OnDismissAction;
-import static com.android.systemui.statusbar.phone.FingerprintUnlockController.*;
-
 import java.util.ArrayList;
 
 /**
@@ -70,6 +71,7 @@
 
     protected final Context mContext;
     private final StatusBarWindowManager mStatusBarWindowManager;
+    private final boolean mDisplayBlanksAfterDoze;
 
     protected LockPatternUtils mLockPatternUtils;
     protected ViewMediatorCallback mViewMediatorCallback;
@@ -79,12 +81,12 @@
 
     private ViewGroup mContainer;
 
-    private boolean mDeviceInteractive = false;
     private boolean mScreenTurnedOn;
     protected KeyguardBouncer mBouncer;
     protected boolean mShowing;
     protected boolean mOccluded;
     protected boolean mRemoteInputActive;
+    private boolean mDozing;
 
     protected boolean mFirstUpdate = true;
     protected boolean mLastShowing;
@@ -92,13 +94,17 @@
     private boolean mLastBouncerShowing;
     private boolean mLastBouncerDismissible;
     protected boolean mLastRemoteInputActive;
+    private boolean mLastDozing;
     private boolean mLastDeferScrimFadeOut;
+    private int mLastFpMode;
 
     private OnDismissAction mAfterKeyguardGoneAction;
     private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
-    private boolean mDeviceWillWakeUp;
     private boolean mDeferScrimFadeOut;
 
+    // Dismiss action to be launched when we stop dozing or the keyguard is gone.
+    private DismissWithActionRequest mPendingWakeupAction;
+
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
         @Override
@@ -107,7 +113,7 @@
             // Since we won't get a setOccluded call we have to reset the view manually such that
             // the bouncer goes away.
             if (mOccluded) {
-                reset(false /* hideBouncerWhenShowing */);
+                reset(true /* hideBouncerWhenShowing */);
             }
         }
     };
@@ -119,6 +125,8 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
         KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
+        mDisplayBlanksAfterDoze = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_displayBlanksAfterDoze);
     }
 
     public void registerStatusBar(StatusBar statusBar,
@@ -150,18 +158,23 @@
      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
      */
     protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
-        if (mBouncer.needsFullscreenBouncer()) {
-
+        if (mBouncer.needsFullscreenBouncer() && !mDozing) {
             // The keyguard might be showing (already). So we need to hide it.
             mStatusBar.hideKeyguard();
             mBouncer.show(true /* resetSecuritySelection */);
         } else {
             mStatusBar.showKeyguard();
             if (hideBouncerWhenShowing) {
-                mBouncer.hide(false /* destroyView */);
+                hideBouncer(false /* destroyView */);
                 mBouncer.prepare();
             }
         }
+        updateStates();
+    }
+
+    private void hideBouncer(boolean destroyView) {
+        mBouncer.hide(destroyView);
+        cancelPendingWakeupAction();
     }
 
     private void showBouncer() {
@@ -174,6 +187,15 @@
     public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
             boolean afterKeyguardGone) {
         if (mShowing) {
+            cancelPendingWakeupAction();
+            // If we're dozing, this needs to be delayed until after we wake up - unless we're
+            // wake-and-unlocking, because there dozing will last until the end of the transition.
+            if (mDozing && !isWakeAndUnlocking()) {
+                mPendingWakeupAction = new DismissWithActionRequest(
+                        r, cancelAction, afterKeyguardGone);
+                return;
+            }
+
             if (!afterKeyguardGone) {
                 mBouncer.showWithDismissAction(r, cancelAction);
             } else {
@@ -184,6 +206,11 @@
         updateStates();
     }
 
+    private boolean isWakeAndUnlocking() {
+        int mode = mFingerprintUnlockController.getMode();
+        return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
+    }
+
     /**
      * Adds a {@param runnable} to be executed after Keyguard is gone.
      */
@@ -196,10 +223,12 @@
      */
     public void reset(boolean hideBouncerWhenShowing) {
         if (mShowing) {
-            if (mOccluded) {
+            if (mOccluded && !mDozing) {
                 mStatusBar.hideKeyguard();
                 mStatusBar.stopWaitingForKeyguardExit();
-                mBouncer.hide(false /* destroyView */);
+                if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
+                    hideBouncer(false /* destroyView */);
+                }
             } else {
                 showBouncerOrKeyguard(hideBouncerWhenShowing);
             }
@@ -209,31 +238,19 @@
     }
 
     public void onStartedGoingToSleep() {
-        mStatusBar.onStartedGoingToSleep();
+        // TODO: remove
     }
 
     public void onFinishedGoingToSleep() {
-        mDeviceInteractive = false;
-        mStatusBar.onFinishedGoingToSleep();
         mBouncer.onScreenTurnedOff();
     }
 
     public void onStartedWakingUp() {
-        Trace.beginSection("StatusBarKeyguardViewManager#onStartedWakingUp");
-        mDeviceInteractive = true;
-        mDeviceWillWakeUp = false;
-        mStatusBar.onStartedWakingUp();
-        Trace.endSection();
+        // TODO: remove
     }
 
     public void onScreenTurningOn() {
-        Trace.beginSection("StatusBarKeyguardViewManager#onScreenTurningOn");
-        mStatusBar.onScreenTurningOn();
-        Trace.endSection();
-    }
-
-    public boolean isScreenTurnedOn() {
-        return mScreenTurnedOn;
+        // TODO: remove
     }
 
     public void onScreenTurnedOn() {
@@ -245,7 +262,6 @@
                     true /* skipFirstFrame */);
             updateStates();
         }
-        mStatusBar.onScreenTurnedOn();
         Trace.endSection();
     }
 
@@ -255,13 +271,26 @@
         updateStates();
     }
 
+    public void setDozing(boolean dozing) {
+        if (mDozing != dozing) {
+            mDozing = dozing;
+            if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
+                reset(dozing /* hideBouncerWhenShowing */);
+            }
+            updateStates();
+
+            if (!dozing) {
+                launchPendingWakeupAction();
+            }
+        }
+    }
+
     public void onScreenTurnedOff() {
         mScreenTurnedOn = false;
-        mStatusBar.onScreenTurnedOff();
     }
 
     public void notifyDeviceWakeUpRequested() {
-        mDeviceWillWakeUp = !mDeviceInteractive;
+        // TODO: remove
     }
 
     public void setNeedsInput(boolean needsInput) {
@@ -273,9 +302,6 @@
     }
 
     public void setOccluded(boolean occluded, boolean animate) {
-        if (occluded != mOccluded) {
-            mStatusBar.onKeyguardOccludedChanged(occluded);
-        }
         if (occluded && !mOccluded && mShowing) {
             if (mStatusBar.isInLaunchTransition()) {
                 mOccluded = true;
@@ -290,15 +316,19 @@
                 return;
             }
         }
+        boolean isOccluding = !mOccluded && occluded;
         mOccluded = occluded;
         if (mShowing) {
             mStatusBar.updateMediaMetaData(false, animate && !occluded);
         }
         mStatusBarWindowManager.setKeyguardOccluded(occluded);
 
-        // If Keyguard is reshown, don't hide the bouncer as it might just have been requested by
-        // a FLAG_DISMISS_KEYGUARD_ACTIVITY.
-        reset(false /* hideBouncerWhenShowing*/);
+        // setDozing(false) will call reset once we stop dozing.
+        if (!mDozing) {
+            // If Keyguard is reshown, don't hide the bouncer as it might just have been requested
+            // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
+            reset(isOccluding /* hideBouncerWhenShowing*/);
+        }
         if (animate && !occluded && mShowing) {
             mStatusBar.animateKeyguardUnoccluding();
         }
@@ -328,6 +358,7 @@
      */
     public void hide(long startTime, long fadeoutDuration) {
         mShowing = false;
+        launchPendingWakeupAction();
 
         if (KeyguardUpdateMonitor.getInstance(mContext).needsSlowUnlockTransition()) {
             fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
@@ -341,7 +372,7 @@
                 public void run() {
                     mStatusBarWindowManager.setKeyguardShowing(false);
                     mStatusBarWindowManager.setKeyguardFadingAway(true);
-                    mBouncer.hide(true /* destroyView */);
+                    hideBouncer(true /* destroyView */);
                     updateStates();
                     mScrimController.animateKeyguardFadingOut(
                             StatusBar.FADE_KEYGUARD_START_DELAY,
@@ -367,7 +398,7 @@
             }
             mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
             mFingerprintUnlockController.startKeyguardFadingAway();
-            mBouncer.hide(true /* destroyView */);
+            hideBouncer(true /* destroyView */);
             if (wakeUnlockPulsing) {
                 mStatusBarWindowManager.setKeyguardFadingAway(true);
                 mStatusBar.fadeKeyguardWhilePulsing();
@@ -380,7 +411,11 @@
                 if (!staying) {
                     mStatusBarWindowManager.setKeyguardFadingAway(true);
                     if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) {
-                        if (!mScreenTurnedOn) {
+                        boolean turnedOnSinceAuth =
+                                mFingerprintUnlockController.hasScreenTurnedOnSinceAuthenticating();
+                        if (!mScreenTurnedOn || mDisplayBlanksAfterDoze && !turnedOnSinceAuth) {
+                            // Not ready to animate yet; either because the screen is not on yet,
+                            // or it is on but will turn off before waking out of doze.
                             mDeferScrimFadeOut = true;
                         } else {
 
@@ -406,7 +441,12 @@
     }
 
     public void onDensityOrFontScaleChanged() {
-        mBouncer.hide(true /* destroyView */);
+        hideBouncer(true /* destroyView */);
+    }
+
+    public void onOverlayChanged() {
+        hideBouncer(true /* destroyView */);
+        mBouncer.prepare();
     }
 
     private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
@@ -498,11 +538,11 @@
     private long getNavBarShowDelay() {
         if (mStatusBar.isKeyguardFadingAway()) {
             return mStatusBar.getKeyguardFadingAwayDelay();
-        } else {
-
-            // Keyguard is not going away, thus we are showing the navigation bar because the
-            // bouncer is appearing.
+        } else if (mBouncer.isShowing()) {
             return NAV_BAR_SHOW_DELAY_BOUNCER;
+        } else {
+            // No longer dozing, or remote input is active. No delay.
+            return 0;
         }
     }
 
@@ -570,7 +610,9 @@
         mLastBouncerShowing = bouncerShowing;
         mLastBouncerDismissible = bouncerDismissible;
         mLastRemoteInputActive = remoteInputActive;
+        mLastDozing = mDozing;
         mLastDeferScrimFadeOut = mDeferScrimFadeOut;
+        mLastFpMode = mFingerprintUnlockController.getMode();
         mStatusBar.onKeyguardViewManagerStatesUpdated();
     }
 
@@ -578,16 +620,21 @@
      * @return Whether the navigation bar should be made visible based on the current state.
      */
     protected boolean isNavBarVisible() {
-        return (!(mShowing && !mOccluded) || mBouncer.isShowing() || mRemoteInputActive)
-                && !mDeferScrimFadeOut;
+        int fpMode = mFingerprintUnlockController.getMode();
+        boolean keyguardShowing = mShowing && !mOccluded;
+        boolean hideWhileDozing = mDozing && fpMode != MODE_WAKE_AND_UNLOCK_PULSING;
+        return (!keyguardShowing && !hideWhileDozing || mBouncer.isShowing()
+                || mRemoteInputActive) && !mDeferScrimFadeOut;
     }
 
     /**
      * @return Whether the navigation bar was made visible based on the last known state.
      */
     protected boolean getLastNavBarVisible() {
-        return (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing || mLastRemoteInputActive)
-                && !mLastDeferScrimFadeOut;
+        boolean keyguardShowing = mLastShowing && !mLastOccluded;
+        boolean hideWhileDozing = mLastDozing && mLastFpMode != MODE_WAKE_AND_UNLOCK_PULSING;
+        return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing
+                || mLastRemoteInputActive) && !mLastDeferScrimFadeOut;
     }
 
     public boolean shouldDismissOnMenuPressed() {
@@ -638,4 +685,38 @@
     public ViewRootImpl getViewRootImpl() {
         return mStatusBar.getStatusBarView().getViewRootImpl();
     }
+
+    public void launchPendingWakeupAction() {
+        DismissWithActionRequest request = mPendingWakeupAction;
+        mPendingWakeupAction = null;
+        if (request != null) {
+            if (mShowing) {
+                dismissWithAction(request.dismissAction, request.cancelAction,
+                        request.afterKeyguardGone);
+            } else if (request.dismissAction != null) {
+                request.dismissAction.onDismiss();
+            }
+        }
+    }
+
+    public void cancelPendingWakeupAction() {
+        DismissWithActionRequest request = mPendingWakeupAction;
+        mPendingWakeupAction = null;
+        if (request != null && request.cancelAction != null) {
+            request.cancelAction.run();
+        }
+    }
+
+    private static class DismissWithActionRequest {
+        final OnDismissAction dismissAction;
+        final Runnable cancelAction;
+        final boolean afterKeyguardGone;
+
+        DismissWithActionRequest(OnDismissAction dismissAction, Runnable cancelAction,
+                boolean afterKeyguardGone) {
+            this.dismissAction = dismissAction;
+            this.cancelAction = cancelAction;
+            this.afterKeyguardGone = afterKeyguardGone;
+        }
+    }
 }
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 0326e40..d886508 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;
 
@@ -111,6 +111,22 @@
         mLpChanged.copyFrom(mLp);
     }
 
+    public void setDozeScreenBrightness(int value) {
+        mScreenBrightnessDoze = value / 255f;
+    }
+
+    public void setKeyguardDark(boolean dark) {
+        int vis = mStatusBarView.getSystemUiVisibility();
+        if (dark) {
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        }
+        mStatusBarView.setSystemUiVisibility(vis);
+    }
+
     private void applyKeyguardFlags(State state) {
         if (state.keyguardShowing) {
             mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
@@ -126,7 +142,7 @@
     }
 
     private void adjustScreenOrientation(State state) {
-        if (state.isKeyguardShowingAndNotOccluded()) {
+        if (state.isKeyguardShowingAndNotOccluded() || state.dozing) {
             if (mKeyguardScreenRotation) {
                 mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
             } else {
@@ -170,7 +186,7 @@
     private boolean isExpanded(State state) {
         return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
                 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
-                || state.headsUpShowing);
+                || state.headsUpShowing || state.scrimsVisible);
     }
 
     private void applyFitsSystemWindows(State state) {
@@ -309,6 +325,11 @@
         apply(mCurrentState);
     }
 
+    public void setScrimsVisible(boolean scrimsVisible) {
+        mCurrentState.scrimsVisible = scrimsVisible;
+        apply(mCurrentState);
+    }
+
     public void setHeadsUpShowing(boolean showing) {
         mCurrentState.headsUpShowing = showing;
         apply(mCurrentState);
@@ -410,6 +431,7 @@
         boolean remoteInputActive;
         boolean forcePluginOpen;
         boolean dozing;
+        boolean scrimsVisible;
 
         private boolean isKeyguardShowingAndNotOccluded() {
             return keyguardShowing && !keyguardOccluded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index adc33a1..3d24bd0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -249,6 +249,10 @@
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+        boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+        if (!isCancel && mService.shouldIgnoreTouch()) {
+            return false;
+        }
         if (isDown && mNotificationPanel.isFullyCollapsed()) {
             mNotificationPanel.startExpandLatencyTracking();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 2783ec5..9b0179d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -17,10 +17,18 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
 /**
  * Base class for dialogs that should appear over panels and keyguard.
@@ -59,7 +67,7 @@
         setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
     }
 
-    public static void setShowForAllUsers(AlertDialog dialog, boolean show) {
+    public static void setShowForAllUsers(Dialog dialog, boolean show) {
         if (show) {
             dialog.getWindow().getAttributes().privateFlags |=
                     WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -69,9 +77,40 @@
         }
     }
 
-    public static void applyFlags(AlertDialog dialog) {
+    public static void setWindowOnTop(Dialog dialog) {
+        if (Dependency.get(KeyguardMonitor.class).isShowing()) {
+            dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_PANEL);
+        } else {
+            dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+        }
+    }
+
+    public static AlertDialog applyFlags(AlertDialog dialog) {
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
         dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        return dialog;
+    }
+
+    public static void registerDismissListener(Dialog dialog) {
+        boolean[] registered = new boolean[1];
+        Context context = dialog.getContext();
+        final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (dialog != null) {
+                    dialog.dismiss();
+                }
+            }
+        };
+        context.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
+                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
+        registered[0] = true;
+        dialog.setOnDismissListener(d -> {
+            if (registered[0]) {
+                context.unregisterReceiver(mReceiver);
+                registered[0] = false;
+            }
+        });
     }
 }
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..028da86 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.wallpaperTextColor));
         mPaint.setAntiAlias(true);
         mPaint.setStrokeWidth(mThickness);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
index d1e4963..c0a6837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
@@ -97,8 +97,9 @@
 
     @Override
     public void scanForAccessPoints() {
-        if (DEBUG) Log.d(TAG, "scan!");
-        mWifiTracker.forceScan();
+        if (DEBUG) Log.d(TAG, "force update APs!");
+        mWifiTracker.forceUpdate();
+        fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index fc86ac3..e8d5af6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -207,14 +207,19 @@
             registerReceiver();
             updatePowerSave();
         } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
-           String level = args.getString("level");
-           String plugged = args.getString("plugged");
-           if (level != null) {
-               mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
-           }
-           if (plugged != null) {
-               mPluggedIn = Boolean.parseBoolean(plugged);
-           }
+            String level = args.getString("level");
+            String plugged = args.getString("plugged");
+            String powerSave = args.getString("powersave");
+            if (level != null) {
+                mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+            }
+            if (plugged != null) {
+                mPluggedIn = Boolean.parseBoolean(plugged);
+            }
+            if (powerSave != null) {
+                mPowerSave = powerSave.equals("true");
+                firePowerSaveChanged();
+            }
             fireBatteryLevelChanged();
         }
     }
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 21d03fd..42ce4c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,51 +16,56 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
+import com.android.internal.util.Preconditions;
 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;
 
 /**
  * Controls showing and hiding of the brightness mirror.
  */
-public class BrightnessMirrorController {
+public class BrightnessMirrorController
+        implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
 
     private final NotificationStackScrollLayout mStackScroller;
     public long TRANSITION_DURATION_OUT = 150;
     public long TRANSITION_DURATION_IN = 200;
 
     private final StatusBarWindowView mStatusBarWindow;
-    private final ScrimView mScrimBehind;
+    private final ScrimController mScrimController;
     private final View mNotificationPanel;
+    private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
     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() {
@@ -84,7 +89,6 @@
                 .setInterpolator(Interpolators.ALPHA_IN);
     }
 
-
     public void setLocation(View original) {
         original.getLocationInWindow(mInt2Cache);
 
@@ -109,17 +113,44 @@
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mBrightnessMirror.getLayoutParams();
         lp.width = mBrightnessMirror.getResources().getDimensionPixelSize(
-                R.dimen.notification_panel_width);
+                R.dimen.qs_panel_width);
         lp.gravity = mBrightnessMirror.getResources().getInteger(
                 R.integer.notification_panel_layout_gravity);
         mBrightnessMirror.setLayoutParams(lp);
     }
 
+    public void onOverlayChanged() {
+        reinflate();
+    }
+
     public void onDensityOrFontScaleChanged() {
+        reinflate();
+    }
+
+    private void reinflate() {
         int index = mStatusBarWindow.indexOfChild(mBrightnessMirror);
         mStatusBarWindow.removeView(mBrightnessMirror);
         mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate(
                 R.layout.brightness_mirror, mStatusBarWindow, false);
         mStatusBarWindow.addView(mBrightnessMirror, index);
+
+        for (int i = 0; i < mBrightnessMirrorListeners.size(); i++) {
+            mBrightnessMirrorListeners.valueAt(i).onBrightnessMirrorReinflated(mBrightnessMirror);
+        }
+    }
+
+    @Override
+    public void addCallback(BrightnessMirrorListener listener) {
+        Preconditions.checkNotNull(listener);
+        mBrightnessMirrorListeners.add(listener);
+    }
+
+    @Override
+    public void removeCallback(BrightnessMirrorListener listener) {
+        mBrightnessMirrorListeners.remove(listener);
+    }
+
+    public interface BrightnessMirrorListener {
+        void onBrightnessMirrorReinflated(View brightnessMirror);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index b89a77b..2bf62bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -182,7 +182,7 @@
                 Log.w(TAG, "Projection is no longer active: " + projection);
             }
         } else {
-            mMediaRouter.getDefaultRoute().select();
+            mMediaRouter.getFallbackRoute().select();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
index 788fda8..3dca371 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
@@ -27,5 +27,7 @@
     interface ConfigurationListener {
         default void onConfigChanged(Configuration newConfig) {}
         default void onDensityOrFontScaleChanged() {}
+        default void onOverlayChanged() {}
+        default void onLocaleListChanged() {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index cfaca0d..f2283a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -102,15 +102,21 @@
     }
 
     private void notifyUserChanged() {
-        mListeners.forEach(c -> c.onUserSwitched());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSwitched();
+        }
     }
 
     private void notifySetupChanged() {
-        mListeners.forEach(c -> c.onUserSetupChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSetupChanged();
+        }
     }
 
     private void notifyProvisionedChanged() {
-        mListeners.forEach(c -> c.onDeviceProvisionedChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onDeviceProvisionedChanged();
+        }
     }
 
     protected final ContentObserver mSettingsObserver = new ContentObserver(Dependency.get(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
index 78e0028..ede8411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionController.java
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.content.Context;
+
 import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -28,12 +30,21 @@
 
     interface Extension<T> {
         T get();
+        Context getContext();
         void destroy();
+        void addCallback(Consumer<T> callback);
         /**
          * Triggers the extension to cycle through each of the sources again because something
          * (like configuration) may have changed.
          */
         T reload();
+
+        /**
+         * Null out the cached item for the purpose of memory saving, should only be done
+         * when any other references are already gotten.
+         * @param isDestroyed
+         */
+        void clearItem(boolean isDestroyed);
     }
 
     interface ExtensionBuilder<T> {
@@ -44,6 +55,7 @@
                 PluginConverter<T, P> converter);
         ExtensionBuilder<T> withDefault(Supplier<T> def);
         ExtensionBuilder<T> withCallback(Consumer<T> callback);
+        ExtensionBuilder<T> withUiMode(int mode, Supplier<T> def);
         Extension build();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
index cfc1d56..6df2051 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ExtensionControllerImpl.java
@@ -14,23 +14,39 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Handler;
+import android.util.ArrayMap;
+
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
-
-import android.content.Context;
-import android.util.ArrayMap;
+import com.android.systemui.util.leak.LeakDetector;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 public class ExtensionControllerImpl implements ExtensionController {
 
+    public static final int SORT_ORDER_PLUGIN  = 0;
+    public static final int SORT_ORDER_TUNER   = 1;
+    public static final int SORT_ORDER_UI_MODE = 2;
+    public static final int SORT_ORDER_DEFAULT = 3;
+
+    private final Context mDefaultContext;
+
+    public ExtensionControllerImpl(Context context) {
+        mDefaultContext = context;
+    }
+
     @Override
     public <T> ExtensionBuilder<T> newExtension(Class<T> cls) {
         return new ExtensionBuilder<>();
@@ -38,6 +54,7 @@
 
     private interface Producer<T> {
         T get();
+
         void destroy();
     }
 
@@ -75,6 +92,12 @@
             return this;
         }
 
+        public ExtensionController.ExtensionBuilder<T> withUiMode(int uiMode,
+                Supplier<T> supplier) {
+            mExtension.addUiMode(uiMode, supplier);
+            return this;
+        }
+
         @Override
         public ExtensionController.ExtensionBuilder<T> withCallback(
                 Consumer<T> callback) {
@@ -85,34 +108,21 @@
         @Override
         public ExtensionController.Extension build() {
             // Manually sort, plugins first, tuners second, defaults last.
-            Collections.sort(mExtension.mProducers, (o1, o2) -> {
-                if (o1 instanceof ExtensionImpl.PluginItem) {
-                    if (o2 instanceof ExtensionImpl.PluginItem) {
-                        return 0;
-                    } else {
-                        return -1;
-                    }
-                }
-                if (o1 instanceof ExtensionImpl.TunerItem) {
-                    if (o2 instanceof ExtensionImpl.PluginItem) {
-                        return 1;
-                    } else if (o2 instanceof ExtensionImpl.TunerItem) {
-                        return 0;
-                    } else {
-                        return -1;
-                    }
-                }
-                return 0;
-            });
+            Collections.sort(mExtension.mProducers, Comparator.comparingInt(Item::sortOrder));
             mExtension.notifyChanged();
             return mExtension;
         }
     }
 
     private class ExtensionImpl<T> implements ExtensionController.Extension<T> {
-        private final ArrayList<Producer<T>> mProducers = new ArrayList<>();
+        private final ArrayList<Item<T>> mProducers = new ArrayList<>();
         private final ArrayList<Consumer<T>> mCallbacks = new ArrayList<>();
         private T mItem;
+        private Context mPluginContext;
+
+        public void addCallback(Consumer<T> callback) {
+            mCallbacks.add(callback);
+        }
 
         @Override
         public T get() {
@@ -120,6 +130,11 @@
         }
 
         @Override
+        public Context getContext() {
+            return mPluginContext != null ? mPluginContext : mDefaultContext;
+        }
+
+        @Override
         public void destroy() {
             for (int i = 0; i < mProducers.size(); i++) {
                 mProducers.get(i).destroy();
@@ -132,7 +147,19 @@
             return get();
         }
 
+        @Override
+        public void clearItem(boolean isDestroyed) {
+            if (isDestroyed && mItem != null) {
+                Dependency.get(LeakDetector.class).trackGarbage(mItem);
+            }
+            mItem = null;
+        }
+
         private void notifyChanged() {
+            if (mItem != null) {
+                Dependency.get(LeakDetector.class).trackGarbage(mItem);
+            }
+            mItem = null;
             for (int i = 0; i < mProducers.size(); i++) {
                 final T item = mProducers.get(i).get();
                 if (item != null) {
@@ -154,10 +181,14 @@
         }
 
         public void addTunerFactory(TunerFactory<T> factory, String[] keys) {
-            mProducers.add(new TunerItem(factory, factory.keys()));
+            mProducers.add(new TunerItem(factory, keys));
         }
 
-        private class PluginItem<P extends Plugin> implements Producer<T>, PluginListener<P> {
+        public void addUiMode(int uiMode, Supplier<T> mode) {
+            mProducers.add(new UiModeItem(uiMode, mode));
+        }
+
+        private class PluginItem<P extends Plugin> implements Item<T>, PluginListener<P> {
             private final PluginConverter<T, P> mConverter;
             private T mItem;
 
@@ -168,6 +199,7 @@
 
             @Override
             public void onPluginConnected(P plugin, Context pluginContext) {
+                mPluginContext = pluginContext;
                 if (mConverter != null) {
                     mItem = mConverter.getInterfaceFromPlugin(plugin);
                 } else {
@@ -178,6 +210,7 @@
 
             @Override
             public void onPluginDisconnected(P plugin) {
+                mPluginContext = null;
                 mItem = null;
                 notifyChanged();
             }
@@ -191,9 +224,14 @@
             public void destroy() {
                 Dependency.get(PluginManager.class).removePluginListener(this);
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_PLUGIN;
+            }
         }
 
-        private class TunerItem<T> implements Producer<T>, Tunable {
+        private class TunerItem<T> implements Item<T>, Tunable {
             private final TunerFactory<T> mFactory;
             private final ArrayMap<String, String> mSettings = new ArrayMap<>();
             private T mItem;
@@ -219,9 +257,54 @@
                 mItem = mFactory.create(mSettings);
                 notifyChanged();
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_TUNER;
+            }
         }
 
-        private class Default<T> implements Producer<T> {
+        private class UiModeItem<T> implements Item<T>, ConfigurationListener {
+
+            private final int mDesiredUiMode;
+            private final Supplier<T> mSupplier;
+            private int mUiMode;
+            private Handler mHandler = new Handler();
+
+            public UiModeItem(int uiMode, Supplier<T> supplier) {
+                mDesiredUiMode = uiMode;
+                mSupplier = supplier;
+                mUiMode = mDefaultContext.getResources().getConfiguration().uiMode;
+                Dependency.get(ConfigurationController.class).addCallback(this);
+            }
+
+            @Override
+            public void onConfigChanged(Configuration newConfig) {
+                int newMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK;
+                if (newMode != mUiMode) {
+                    mUiMode = newMode;
+                    // Post to make sure we don't have concurrent modifications.
+                    mHandler.post(ExtensionImpl.this::notifyChanged);
+                }
+            }
+
+            @Override
+            public T get() {
+                return (mUiMode == mDesiredUiMode) ? mSupplier.get() : null;
+            }
+
+            @Override
+            public void destroy() {
+                Dependency.get(ConfigurationController.class).removeCallback(this);
+            }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_UI_MODE;
+            }
+        }
+
+        private class Default<T> implements Item<T> {
             private final Supplier<T> mSupplier;
 
             public Default(Supplier<T> supplier) {
@@ -237,6 +320,15 @@
             public void destroy() {
 
             }
+
+            @Override
+            public int sortOrder() {
+                return SORT_ORDER_DEFAULT;
+            }
         }
     }
+
+    private interface Item<T> extends Producer<T> {
+        int sortOrder();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5f7ac5d..53dfb24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.v4.util.ArraySet;
@@ -65,7 +66,7 @@
     private final ArrayMap<String, Long> mSnoozedPackages;
     private final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
     private final int mDefaultSnoozeLengthMs;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Pools.Pool<HeadsUpEntry> mEntryPool = new Pools.Pool<HeadsUpEntry>() {
 
         private Stack<HeadsUpEntry> mPoolObjects = new Stack<>();
@@ -257,6 +258,12 @@
         mEntryPool.release(remove);
     }
 
+    public void removeAllHeadsUpEntries() {
+        for (String key : mHeadsUpEntries.keySet()) {
+            removeHeadsUpEntry(mHeadsUpEntries.get(key).entry);
+        }
+    }
+
     private void updatePinnedMode() {
         boolean hasPinnedNotification = hasPinnedNotificationInternal();
         if (hasPinnedNotification == mHasPinnedNotification) {
@@ -618,6 +625,7 @@
 
     @Override
     public void onReorderingAllowed() {
+        mBar.getNotificationScrollLayout().setHeadsUpGoingAwayAnimationsAllowed(false);
         for (NotificationData.Entry entry : mEntriesToRemoveWhenReorderingAllowed) {
             if (isHeadsUp(entry.key)) {
                 // Maybe the heads-up was removed already
@@ -625,6 +633,7 @@
             }
         }
         mEntriesToRemoveWhenReorderingAllowed.clear();
+        mBar.getNotificationScrollLayout().setHeadsUpGoingAwayAnimationsAllowed(true);
     }
 
     public void setVisualStabilityManager(VisualStabilityManager visualStabilityManager) {
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 d777961..65bfabd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -113,6 +113,11 @@
         setBackground(mRipple);
     }
 
+    @Override
+    public boolean isClickable() {
+        return mCode != 0 || super.isClickable();
+    }
+
     public void setCode(int code) {
         mCode = code;
     }
@@ -226,6 +231,11 @@
             case MotionEvent.ACTION_UP:
                 final boolean doIt = isPressed() && !mLongClicked;
                 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.
+                if ((SystemClock.uptimeMillis() - mDownTime) > 150 && !mLongClicked) {
+                    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/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
index 728005d..ccfbb26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -21,12 +21,13 @@
     boolean isSecure();
     boolean canSkipBouncer();
     boolean isShowing();
+    boolean isOccluded();
     boolean isKeyguardFadingAway();
     boolean isKeyguardGoingAway();
     long getKeyguardFadingAwayDuration();
     long getKeyguardFadingAwayDelay();
 
-    public interface Callback {
+    interface Callback {
         void onKeyguardShowingChanged();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b21a5e8..b93fb22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -236,6 +236,9 @@
     }
 
     private int getNumLevels() {
+        if (mConfig.inflateSignalStrengths) {
+            return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
+        }
         return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
     }
 
@@ -244,7 +247,11 @@
         if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
             return SignalDrawable.getCarrierChangeState(getNumLevels());
         } else if (mCurrentState.connected) {
-            return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
+            int level = mCurrentState.level;
+            if (mConfig.inflateSignalStrengths) {
+                level++;
+            }
+            return SignalDrawable.getState(level, getNumLevels(),
                     mCurrentState.inetCondition == 0);
         } else if (mCurrentState.enabled) {
             return SignalDrawable.getEmptyState(getNumLevels());
@@ -335,6 +342,10 @@
     }
 
     private boolean isRoaming() {
+        // During a carrier change, roaming indications need to be supressed.
+        if (isCarrierNetworkChangeActive()) {
+            return false;
+        }
         if (isCdma()) {
             final int iconMode = mServiceState.getCdmaEriIconMode();
             return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c02ce0e..2771011 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -67,29 +67,15 @@
 
     public static class IconState {
         public final boolean visible;
-
         public final int icon;
-
-        /**
-         * Optional iconOverlay resource id.
-         *
-         * <p>Set to -1 if not present.
-         */
-        public final int iconOverlay;
-
         public final String contentDescription;
 
-        public IconState(boolean visible, int icon, int iconOverlay, String contentDescription) {
+        public IconState(boolean visible, int icon, String contentDescription) {
             this.visible = visible;
             this.icon = icon;
-            this.iconOverlay = iconOverlay;
             this.contentDescription = contentDescription;
         }
 
-        public IconState(boolean visible, int icon, String contentDescription) {
-            this(visible, icon, -1 /* iconOverlay */, contentDescription);
-        }
-
         public IconState(boolean visible, int icon, int contentDescription,
                 Context context) {
             this(visible, icon, context.getString(contentDescription));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index c21f444..c217bda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -24,7 +24,6 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -92,7 +91,6 @@
     private final DataSaverController mDataSaverController;
     private final CurrentUserTracker mUserTracker;
     private Config mConfig;
-    private final NetworkScoreManager mNetworkScoreManager;
 
     // Subcontrollers.
     @VisibleForTesting
@@ -149,12 +147,9 @@
     public NetworkControllerImpl(Context context, Looper bgLooper,
             DeviceProvisionedController deviceProvisionedController) {
         this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
-                context.getSystemService(NetworkScoreManager.class),
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
                 (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
-                SubscriptionManager.from(context),
-                Config.readConfig(context),
-                bgLooper,
+                SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
                 new CallbackHandler(),
                 new AccessPointControllerImpl(context, bgLooper),
                 new DataUsageController(context),
@@ -165,12 +160,8 @@
 
     @VisibleForTesting
     NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
-            NetworkScoreManager networkScoreManager,
-            TelephonyManager telephonyManager,
-            WifiManager wifiManager,
-            SubscriptionManager subManager,
-            Config config,
-            Looper bgLooper,
+            TelephonyManager telephonyManager, WifiManager wifiManager,
+            SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
             AccessPointControllerImpl accessPointController,
             DataUsageController dataUsageController,
@@ -193,7 +184,6 @@
 
         // wifi
         mWifiManager = wifiManager;
-        mNetworkScoreManager = networkScoreManager;
 
         mLocale = mContext.getResources().getConfiguration().locale;
         mAccessPoints = accessPointController;
@@ -207,7 +197,7 @@
             }
         });
         mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
-                mCallbackHandler, this, mNetworkScoreManager);
+                mCallbackHandler, this);
 
         mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
 
@@ -968,6 +958,7 @@
         boolean show4gForLte = false;
         boolean hideLtePlus = false;
         boolean hspaDataDistinguishable;
+        boolean inflateSignalStrengths = false;
 
         static Config readConfig(Context context) {
             Config config = new Config();
@@ -980,6 +971,7 @@
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
             config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
+            config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
             return config;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index efbf76b..b22ce18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -90,6 +90,10 @@
     private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>();
 
     public SecurityControllerImpl(Context context) {
+        this(context, null);
+    }
+
+    public SecurityControllerImpl(Context context, SecurityControllerCallback callback) {
         super(context);
         mContext = context;
         mDevicePolicyManager = (DevicePolicyManager)
@@ -102,6 +106,8 @@
         mUserManager = (UserManager)
                 context.getSystemService(Context.USER_SERVICE);
 
+        addCallback(callback);
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
         context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index b1e4b03..527addf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -131,6 +131,7 @@
         final int userId = userInfo.id;
         final boolean isGuest = userInfo.isGuest();
         final String userName = userInfo.name;
+        final boolean lightIcon = mContext.getThemeResId() != R.style.Theme_SystemUI_Light;
 
         final Resources res = mContext.getResources();
         final int avatarSize = Math.max(
@@ -154,7 +155,7 @@
                             .setIcon(rawAvatar).setBadgeIfManagedUser(mContext, userId).bake();
                 } else {
                     avatar = UserIcons.getDefaultUserIcon(isGuest? UserHandle.USER_NULL : userId,
-                            /* light= */ true);
+                            lightIcon);
                 }
 
                 // If it's a single-user device, get the profile name, since the nickname is not
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index e0f4429..700c01a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -57,6 +57,8 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.GuestResumeSessionReceiver;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUISecondaryUserService;
@@ -235,6 +237,9 @@
                         }
                     }
                 }
+                if (records.size() > 1 || guestRecord != null) {
+                    Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
+                }
 
                 boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(
                                 UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 2104cb1..2819624 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -17,50 +17,33 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.database.ContentObserver;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
-import android.net.NetworkKey;
-import android.net.NetworkScoreManager;
-import android.net.ScoredNetwork;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiNetworkScoreCache;
-import android.net.wifi.WifiNetworkScoreCache.CacheListener;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
-import android.provider.Settings;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.AsyncChannel;
-import com.android.settingslib.Utils;
 import com.android.settingslib.wifi.WifiStatusTracker;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
-import com.android.systemui.R;
-
 import java.util.Objects;
-import java.util.List;
 
 
 public class WifiSignalController extends
         SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
-
     private final WifiManager mWifiManager;
     private final AsyncChannel mWifiChannel;
     private final boolean mHasMobileData;
-    private final NetworkScoreManager mNetworkScoreManager;
-    private final WifiNetworkScoreCache mScoreCache;
     private final WifiStatusTracker mWifiTracker;
 
-    private boolean mScoringUiEnabled = false;
-
     public WifiSignalController(Context context, boolean hasMobileData,
-            CallbackHandler callbackHandler, NetworkControllerImpl networkController,
-            NetworkScoreManager networkScoreManager) {
+            CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
         super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
                 callbackHandler, networkController);
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -85,44 +68,6 @@
                 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
                 );
 
-        mScoreCache = new WifiNetworkScoreCache(context, new CacheListener(handler) {
-            @Override
-            public void networkCacheUpdated(List<ScoredNetwork> networks) {
-                mCurrentState.badgeEnum = getWifiBadgeEnum();
-                notifyListenersIfNecessary();
-            }
-        });
-
-        // Setup scoring
-        mNetworkScoreManager = networkScoreManager;
-        configureScoringGating();
-        registerScoreCache();
-    }
-
-    private void configureScoringGating() {
-        ContentObserver observer = new ContentObserver(new Handler(Looper.getMainLooper())) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mScoringUiEnabled =
-                        Settings.Global.getInt(
-                                mContext.getContentResolver(),
-                                Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
-            }
-        };
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
-                false /* notifyForDescendants */,
-                observer);
-
-        observer.onChange(false /* selfChange */); // Set the initial values
-    }
-
-    private void registerScoreCache() {
-        Log.d(mTag, "Registered score cache");
-        mNetworkScoreManager.registerNetworkScoreCache(
-                NetworkKey.TYPE_WIFI,
-                mScoreCache,
-                NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK);
     }
 
     @Override
@@ -143,77 +88,27 @@
                     ("," + mContext.getString(R.string.accessibility_quick_settings_no_internet));
         }
 
-        IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(),
-                Utils.getWifiBadgeResource(mCurrentState.badgeEnum), contentDescription);
-        IconState qsIcon = new IconState(
-                mCurrentState.connected, getQsCurrentIconId(),
-                Utils.getWifiBadgeResource(mCurrentState.badgeEnum), contentDescription);
+        IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
+        IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
+                contentDescription);
         callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
                 ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
                 wifiDesc, mCurrentState.isTransient);
     }
 
-    @Override
-    public int getCurrentIconId() {
-        if (mCurrentState.badgeEnum != NetworkBadging.BADGING_NONE) {
-            return Utils.WIFI_PIE_FOR_BADGING[mCurrentState.level];
-        }
-        return super.getCurrentIconId();
-    }
-
     /**
      * Extract wifi state directly from broadcasts about changes in wifi state.
      */
     public void handleBroadcast(Intent intent) {
-        // Update the WifiStatusTracker with the new information and update the score cache.
-        NetworkKey previousNetworkKey = mWifiTracker.networkKey;
         mWifiTracker.handleBroadcast(intent);
-        updateScoreCacheIfNecessary(previousNetworkKey);
-
-        mCurrentState.isTransient = mWifiTracker.state == WifiManager.WIFI_STATE_ENABLING
-                || mWifiTracker.state == WifiManager.WIFI_AP_STATE_DISABLING
-                || mWifiTracker.connecting;
         mCurrentState.enabled = mWifiTracker.enabled;
         mCurrentState.connected = mWifiTracker.connected;
         mCurrentState.ssid = mWifiTracker.ssid;
         mCurrentState.rssi = mWifiTracker.rssi;
         mCurrentState.level = mWifiTracker.level;
-        mCurrentState.badgeEnum = getWifiBadgeEnum();
         notifyListenersIfNecessary();
     }
 
-    /**
-     * Clears old scores out of the cache and requests new scores if the network key has changed.
-     *
-     * <p>New scores are requested asynchronously.
-     */
-    private void updateScoreCacheIfNecessary(NetworkKey previousNetworkKey) {
-        if (mWifiTracker.networkKey == null) {
-            return;
-        }
-        if ((previousNetworkKey == null) || !mWifiTracker.networkKey.equals(previousNetworkKey)) {
-            mScoreCache.clearScores();
-            mNetworkScoreManager.requestScores(new NetworkKey[]{mWifiTracker.networkKey});
-        }
-    }
-
-    /**
-     * Returns the wifi badge enum for the current {@link #mWifiTracker} state.
-     *
-     * <p>{@link #updateScoreCacheIfNecessary} should be called prior to this method.
-     */
-    private int getWifiBadgeEnum() {
-        if (!mScoringUiEnabled || mWifiTracker.networkKey == null) {
-            return NetworkBadging.BADGING_NONE;
-        }
-        ScoredNetwork score = mScoreCache.getScoredNetwork(mWifiTracker.networkKey);
-
-        if (score != null) {
-            return score.calculateBadge(mWifiTracker.rssi);
-        }
-        return NetworkBadging.BADGING_NONE;
-    }
-
     @VisibleForTesting
     void setActivity(int wifiActivity) {
         mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
@@ -254,7 +149,6 @@
 
     static class WifiState extends SignalController.State {
         String ssid;
-        int badgeEnum;
         boolean isTransient;
 
         @Override
@@ -262,7 +156,6 @@
             super.copyFrom(s);
             WifiState state = (WifiState) s;
             ssid = state.ssid;
-            badgeEnum = state.badgeEnum;
             isTransient = state.isTransient;
         }
 
@@ -270,7 +163,6 @@
         protected void toString(StringBuilder builder) {
             super.toString(builder);
             builder.append(',').append("ssid=").append(ssid);
-            builder.append(',').append("badgeEnum=").append(badgeEnum);
             builder.append(',').append("isTransient=").append(isTransient);
         }
 
@@ -278,7 +170,6 @@
         public boolean equals(Object o) {
             return super.equals(o)
                     && Objects.equals(((WifiState) o).ssid, ssid)
-                    && (((WifiState) o).badgeEnum == badgeEnum)
                     && (((WifiState) o).isTransient == isTransient);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index 41ef781..4d8da44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -21,11 +21,15 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.ArrayList;
+import java.util.Collection;
 
 /**
  * A global state to track all input states for the algorithm.
@@ -59,8 +63,10 @@
     private boolean mPanelTracking;
     private boolean mExpansionChanging;
     private boolean mPanelFullWidth;
-    private boolean mHasPulsingNotifications;
+    private Collection<HeadsUpManager.HeadsUpEntry> mPulsing;
     private boolean mUnlockHintRunning;
+    private boolean mQsCustomizerShowing;
+    private int mIntrinsicPadding;
 
     public AmbientState(Context context) {
         reload(context);
@@ -288,11 +294,23 @@
     }
 
     public boolean hasPulsingNotifications() {
-        return mHasPulsingNotifications;
+        return mPulsing != null;
     }
 
-    public void setHasPulsingNotifications(boolean hasPulsing) {
-        mHasPulsingNotifications = hasPulsing;
+    public void setPulsing(Collection<HeadsUpManager.HeadsUpEntry> hasPulsing) {
+        mPulsing = hasPulsing;
+    }
+
+    public boolean isPulsing(NotificationData.Entry entry) {
+        if (mPulsing == null) {
+            return false;
+        }
+        for (HeadsUpManager.HeadsUpEntry e : mPulsing) {
+            if (e.entry == entry) {
+                return true;
+            }
+        }
+        return false;
     }
 
     public boolean isPanelTracking() {
@@ -314,4 +332,50 @@
     public boolean isUnlockHintRunning() {
         return mUnlockHintRunning;
     }
+
+    public boolean isQsCustomizerShowing() {
+        return mQsCustomizerShowing;
+    }
+
+    public void setQsCustomizerShowing(boolean qsCustomizerShowing) {
+        mQsCustomizerShowing = qsCustomizerShowing;
+    }
+
+    public void setIntrinsicPadding(int intrinsicPadding) {
+        mIntrinsicPadding = intrinsicPadding;
+    }
+
+    public int getIntrinsicPadding() {
+        return mIntrinsicPadding;
+    }
+
+    /**
+     * Similar to the normal is above shelf logic but doesn't allow it to be above in AOD1.
+     *
+     * @param expandableView the view to check
+     */
+    public boolean isAboveShelf(ExpandableView expandableView) {
+        if (!(expandableView instanceof ExpandableNotificationRow)) {
+            return expandableView.isAboveShelf();
+        }
+        ExpandableNotificationRow row = (ExpandableNotificationRow) expandableView;
+        return row.isAboveShelf() && !isDozingAndNotPulsing(row);
+    }
+
+    /**
+     * @return whether a view is dozing and not pulsing right now
+     */
+    public boolean isDozingAndNotPulsing(ExpandableView view) {
+        if (view instanceof ExpandableNotificationRow) {
+            return isDozingAndNotPulsing((ExpandableNotificationRow) view);
+        }
+        return false;
+    }
+
+    /**
+     * @return whether a row is dozing and not pulsing right now
+     */
+    public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) {
+        return isDark() && !isPulsing(row.getEntry());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index b6964a03..fe53104 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -19,6 +19,7 @@
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.drawable.ColorDrawable;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
@@ -66,8 +67,9 @@
     private final HybridGroupManager mHybridGroupManager;
     private int mChildPadding;
     private int mDividerHeight;
-    private int mMaxNotificationHeight;
+    private float mDividerAlpha;
     private int mNotificationHeaderMargin;
+
     private int mNotificatonTopPadding;
     private float mCollapsedBottompadding;
     private boolean mChildrenExpanded;
@@ -80,6 +82,11 @@
     private boolean mNeverAppliedGroupState;
     private int mHeaderHeight;
 
+    /**
+     * Whether or not individual notifications that are part of this container will have shadows.
+     */
+    private boolean mEnableShadowOnChildNotifications;
+
     private NotificationHeaderView mNotificationHeader;
     private NotificationViewWrapper mNotificationHeaderWrapper;
     private NotificationHeaderView mNotificationHeaderLowPriority;
@@ -93,6 +100,9 @@
     private OnClickListener mHeaderClickListener;
     private ViewGroup mCurrentHeader;
 
+    private boolean mShowDividersWhenExpanded;
+    private boolean mHideDividersDuringExpand;
+
     public NotificationChildrenContainer(Context context) {
         this(context, null);
     }
@@ -113,19 +123,25 @@
     }
 
     private void initDimens() {
-        mChildPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_children_padding);
-        mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
-                R.dimen.notification_divider_height));
-        mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.notification_header_height);
-        mMaxNotificationHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
-        mNotificationHeaderMargin = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_top);
-        mNotificatonTopPadding = getResources().getDimensionPixelSize(
+        Resources res = getResources();
+        mChildPadding = res.getDimensionPixelSize(R.dimen.notification_children_padding);
+        mDividerHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_divider_height);
+        mDividerAlpha = res.getFloat(R.dimen.notification_divider_alpha);
+        mHeaderHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_header_height);
+        mNotificationHeaderMargin = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_margin_top);
+        mNotificatonTopPadding = res.getDimensionPixelSize(
                 R.dimen.notification_children_container_top_padding);
-        mCollapsedBottompadding = getResources().getDimensionPixelSize(
+        mCollapsedBottompadding = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_bottom);
+        mEnableShadowOnChildNotifications =
+                res.getBoolean(R.bool.config_enableShadowOnChildNotifications);
+        mShowDividersWhenExpanded =
+                res.getBoolean(R.bool.config_showDividersWhenGroupNotificationExpanded);
+        mHideDividersDuringExpand =
+                res.getBoolean(R.bool.config_hideDividersDuringExpand);
     }
 
     @Override
@@ -566,7 +582,8 @@
             childState.hidden = false;
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
-            childState.zTranslation = childrenExpandedAndNotAnimating
+            childState.zTranslation =
+                    (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications)
                     ? mContainingNotification.getTranslationZ()
                     : 0;
             childState.dimmed = parentState.dimmed;
@@ -677,7 +694,9 @@
             expandFraction = getGroupExpandFraction();
         }
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
@@ -687,7 +706,7 @@
             View divider = mDividers.get(i);
             tmpState.initFrom(divider);
             tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
-            float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+            float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
             if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
                 alpha = NotificationUtils.interpolate(0, 0.5f,
                         Math.min(viewState.alpha, expandFraction));
@@ -751,7 +770,9 @@
         ViewState tmpState = new ViewState();
         float expandFraction = getGroupExpandFraction();
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = childCount - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
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 3cc3604..291ec1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -23,6 +23,7 @@
 import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.ColorInt;
 import android.annotation.FloatRange;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -38,11 +39,13 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.service.notification.StatusBarNotification;
+import android.support.annotation.NonNull;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Property;
+import android.view.ContextThemeWrapper;
 import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -57,8 +60,10 @@
 import android.view.animation.Interpolator;
 import android.widget.OverScroller;
 import android.widget.ScrollView;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -87,6 +92,10 @@
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 
+import android.support.v4.graphics.ColorUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -147,6 +156,7 @@
     private int mPaddingBetweenElements;
     private int mIncreasedPaddingBetweenElements;
     private int mTopPadding;
+    private int mBottomMargin;
     private int mBottomInset = 0;
 
     /**
@@ -205,6 +215,7 @@
     protected DismissView mDismissView;
     protected EmptyShadeView mEmptyShadeView;
     private boolean mDismissAllInProgress;
+    private boolean mFadeNotificationsOnDismiss;
 
     /**
      * Was the scroller scrolled to the top when the down motion was observed?
@@ -355,12 +366,14 @@
                     return object.getBackgroundFadeAmount();
                 }
             };
+    private boolean mUsingLightTheme;
     private boolean mQsExpanded;
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
     private int mMaxDisplayedNotifications = -1;
     private int mStatusBarHeight;
+    private int mMinInteractionHeight;
     private boolean mNoAmbient;
     private final Rect mClipRect = new Rect();
     private boolean mIsClipped;
@@ -369,6 +382,7 @@
     private boolean mHeadsUpAnimatingAway;
     private int mStatusBarState;
     private int mCachedBackgroundColor;
+    private boolean mHeadsUpGoingAwayAnimationsAllowed = true;
     private Runnable mAnimateScroll = this::animateScroll;
 
     public NotificationStackScrollLayout(Context context) {
@@ -403,6 +417,8 @@
         mFalsingManager = FalsingManager.getInstance(context);
         mShouldDrawNotificationBackground =
                 res.getBoolean(R.bool.config_drawNotificationBackground);
+        mFadeNotificationsOnDismiss =
+                res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
 
         updateWillNotDraw();
         if (DEBUG) {
@@ -475,16 +491,8 @@
         float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount);
         alpha *= mBackgroundFadeAmount;
         // We need to manually blend in the background color
-        int scrimColor = mScrimController.getScrimBehindColor();
-        // SRC_OVER blending Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc
-        float alphaInv = 1 - alpha;
-        int color = Color.argb((int) (alpha * 255 + alphaInv * Color.alpha(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.red(mBgColor)
-                        + alphaInv * Color.red(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.green(mBgColor)
-                        + alphaInv * Color.green(scrimColor)),
-                (int) (mBackgroundFadeAmount * Color.blue(mBgColor)
-                        + alphaInv * Color.blue(scrimColor)));
+        int scrimColor = mScrimController.getBackgroundColor();
+        int color = ColorUtils.blendARGB(scrimColor, mBgColor, alpha);
         if (mCachedBackgroundColor != color) {
             mCachedBackgroundColor = color;
             mBackgroundPaint.setColor(color);
@@ -501,17 +509,21 @@
         mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mOverflingDistance = configuration.getScaledOverflingDistance();
-        mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_min_height);
+
+        Resources res = context.getResources();
+        mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
         mStackScrollAlgorithm.initView(context);
         mAmbientState.reload(context);
-        mPaddingBetweenElements = Math.max(1, context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height));
-        mIncreasedPaddingBetweenElements = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
+        mPaddingBetweenElements = Math.max(1,
+                res.getDimensionPixelSize(R.dimen.notification_divider_height));
+        mIncreasedPaddingBetweenElements =
+                res.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
+        mMinTopOverScrollToEscape = res.getDimensionPixelSize(
                 R.dimen.min_top_overscroll_to_qs);
-        mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
+        mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
+        mBottomMargin = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
+        mMinInteractionHeight = res.getDimensionPixelSize(
+                R.dimen.notification_min_interaction_height);
     }
 
     public void setDrawBackgroundAsSrc(boolean asSrc) {
@@ -800,7 +812,7 @@
      */
     private float getAppearStartPosition() {
         if (mTrackingHeadsUp && mFirstVisibleBackgroundChild != null) {
-            if (mFirstVisibleBackgroundChild.isAboveShelf()) {
+            if (mAmbientState.isAboveShelf(mFirstVisibleBackgroundChild)) {
                 // If we ever expanded beyond the first notification, it's allowed to merge into
                 // the shelf
                 return mFirstVisibleBackgroundChild.getPinnedHeadsUpHeight();
@@ -818,13 +830,15 @@
         int notGoneChildCount = getNotGoneChildCount();
         if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
             int minNotificationsForShelf = 1;
-            if (mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
+            if (mTrackingHeadsUp
+                    || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = mHeadsUpManager.getTopHeadsUpPinnedHeight();
                 minNotificationsForShelf = 2;
             } else {
                 appearPosition = 0;
             }
-            if (notGoneChildCount >= minNotificationsForShelf) {
+            if (notGoneChildCount >= minNotificationsForShelf
+                    && mShelf.getVisibility() != GONE) {
                 appearPosition += mShelf.getIntrinsicHeight();
             }
         } else {
@@ -966,7 +980,8 @@
             mScrimController.setTopHeadsUpDragAmount(animView,
                     Math.min(Math.abs(swipeProgress / 2f - 1.0f), 1.0f));
         }
-        return true; // Don't fade out the notification
+        // Returning true prevents alpha fading.
+        return !mFadeNotificationsOnDismiss;
     }
 
     @Override
@@ -1071,7 +1086,7 @@
         final int count = getChildCount();
         for (int childIdx = 0; childIdx < count; childIdx++) {
             ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
-            if (slidingChild.getVisibility() == GONE
+            if (slidingChild.getVisibility() != VISIBLE
                     || slidingChild instanceof StackScrollerDecorView) {
                 continue;
             }
@@ -1085,7 +1100,8 @@
             int left = 0;
             int right = getWidth();
 
-            if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
+            if (bottom - top >= mMinInteractionHeight
+                    && touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
                 if (slidingChild instanceof ExpandableNotificationRow) {
                     ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
                     if (!mIsExpanded && row.isHeadsUp() && row.isPinned()
@@ -1995,18 +2011,14 @@
                 }
             }
         }
-        mContentHeight = height + mTopPadding;
+        mContentHeight = height + mTopPadding + mBottomMargin;
         updateScrollability();
+        clampScrollPosition();
         mAmbientState.setLayoutMaxHeight(mContentHeight);
     }
 
     private boolean isPulsing(NotificationData.Entry entry) {
-        for (HeadsUpManager.HeadsUpEntry e : mPulsing) {
-            if (e.entry == entry) {
-                return true;
-            }
-        }
-        return false;
+        return mAmbientState.isPulsing(entry);
     }
 
     public boolean hasPulsingNotifications() {
@@ -2232,10 +2244,11 @@
                 top = (int) Math.ceil(firstView.getTranslationY());
             }
         }
-        ActivatableNotificationView lastView = mShelf.hasItemsInStableShelf()
-                ? mShelf
-                : mLastVisibleBackgroundChild;
-        int bottom = 0;
+        ActivatableNotificationView lastView =
+                mShelf.hasItemsInStableShelf() && mShelf.getVisibility() != GONE
+                        ? mShelf
+                        : mLastVisibleBackgroundChild;
+        int bottom;
         if (lastView != null) {
             int finalTranslationY;
             if (lastView == mShelf) {
@@ -2385,7 +2398,7 @@
     }
 
     public int getLayoutMinHeight() {
-        return mShelf.getIntrinsicHeight();
+        return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
     }
 
     public int getFirstChildIntrinsicHeight() {
@@ -2410,7 +2423,7 @@
         final int firstChildMinHeight = firstChild != null ? firstChild.getCollapsedHeight()
                 : mCollapsedSize;
         int shelfHeight = 0;
-        if (mLastVisibleBackgroundChild != null) {
+        if (mLastVisibleBackgroundChild != null && mShelf.getVisibility() != GONE) {
             shelfHeight = mShelf.getIntrinsicHeight();
         }
         return mIntrinsicPadding + firstChildMinHeight + shelfHeight;
@@ -2581,9 +2594,6 @@
         }
         updateAnimationState(false, child);
 
-        // Make sure the clipRect we might have set is removed
-        expandableView.setClipTopAmount(0);
-
         focusNextViewIfFocused(child);
     }
 
@@ -2729,7 +2739,7 @@
         return view.getHeight();
     }
 
-    private int getPositionInLinearLayout(View requestedView) {
+    public int getPositionInLinearLayout(View requestedView) {
         ExpandableNotificationRow childInGroup = null;
         ExpandableNotificationRow requestedRow = null;
         if (isChildInGroup(requestedView)) {
@@ -3030,10 +3040,6 @@
     private void generateChildRemovalEvents() {
         for (View child : mChildrenToRemoveAnimated) {
             boolean childWasSwipedOut = mSwipedOutViews.contains(child);
-            int animationType = childWasSwipedOut
-                    ? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
-                    : AnimationEvent.ANIMATION_TYPE_REMOVE;
-            AnimationEvent event = new AnimationEvent(child, animationType);
 
             // we need to know the view after this one
             float removedTranslation = child.getTranslationY();
@@ -3044,7 +3050,16 @@
                     removedTranslation = row.getTranslationWhenRemoved();
                     ignoreChildren = false;
                 }
+                childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
             }
+            if (!childWasSwipedOut) {
+                Rect clipBounds = child.getClipBounds();
+                childWasSwipedOut = clipBounds.height() == 0;
+            }
+            int animationType = childWasSwipedOut
+                    ? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
+                    : AnimationEvent.ANIMATION_TYPE_REMOVE;
+            AnimationEvent event = new AnimationEvent(child, animationType);
             event.viewAfterChangingView = getFirstChildBelowTranlsationY(removedTranslation,
                     ignoreChildren);
             mAnimationEvents.add(event);
@@ -3352,15 +3367,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());
             }
         }
     }
@@ -3395,6 +3424,7 @@
         if (changed) {
             if (!mIsExpanded) {
                 mGroupManager.collapseAllGroups();
+                mExpandHelper.cancelImmediately();
             }
             updateNotificationAnimationStates();
             updateChronometers();
@@ -3442,7 +3472,7 @@
     }
 
     private void updateScrollPositionOnExpandInBottom(ExpandableView view) {
-        if (view instanceof ExpandableNotificationRow) {
+        if (view instanceof ExpandableNotificationRow && !onKeyguard()) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             if (row.isUserLocked() && row != getFirstChildNotGone()) {
                 if (row.isSummaryWithChildren()) {
@@ -3454,7 +3484,7 @@
                     endPosition += row.getNotificationParent().getTranslationY();
                 }
                 int layoutEnd = mMaxLayoutHeight + (int) mStackTranslation;
-                if (row != mLastVisibleBackgroundChild) {
+                if (row != mLastVisibleBackgroundChild && mShelf.getVisibility() != GONE) {
                     layoutEnd -= mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
                 }
                 if (endPosition > layoutEnd) {
@@ -3627,8 +3657,27 @@
         mTmpSortedChildren.clear();
     }
 
+    /**
+     * Update colors of "dismiss" and "empty shade" views.
+     *
+     * @param lightTheme True if light theme should be used.
+     */
+    public void updateDecorViews(boolean lightTheme) {
+        if (lightTheme == mUsingLightTheme) {
+            return;
+        }
+        mUsingLightTheme = lightTheme;
+        Context context = new ContextThemeWrapper(mContext,
+                lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI);
+        final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
+        mDismissView.setTextColor(textColor);
+        mEmptyShadeView.setTextColor(textColor);
+    }
+
     public void goToFullShade(long delay) {
-        mDismissView.setInvisible();
+        if (mDismissView != null) {
+            mDismissView.setInvisible();
+        }
         mEmptyShadeView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
@@ -3642,6 +3691,7 @@
 
     public void setIntrinsicPadding(int intrinsicPadding) {
         mIntrinsicPadding = intrinsicPadding;
+        mAmbientState.setIntrinsicPadding(intrinsicPadding);
     }
 
     public int getIntrinsicPadding() {
@@ -3664,6 +3714,9 @@
      * See {@link AmbientState#setDark}.
      */
     public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
+        if (mAmbientState.isDark() == dark) {
+            return;
+        }
         mAmbientState.setDark(dark);
         if (animate && mAnimationsEnabled) {
             mDarkNeedsAnimation = true;
@@ -3741,7 +3794,7 @@
         return -1;
     }
 
-    public void setDismissView(DismissView dismissView) {
+    public void setDismissView(@NonNull DismissView dismissView) {
         int index = -1;
         if (mDismissView != null) {
             index = indexOfChild(mDismissView);
@@ -3797,6 +3850,10 @@
     }
 
     public void updateDismissView(boolean visible) {
+        if (mDismissView == null) {
+            return;
+        }
+
         int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
         int newVisibility = visible ? VISIBLE : GONE;
         if (oldVisibility != newVisibility) {
@@ -3854,15 +3911,17 @@
     }
 
     public boolean isDismissViewNotGone() {
-        return mDismissView.getVisibility() != View.GONE && !mDismissView.willBeGone();
+        return mDismissView != null
+                && mDismissView.getVisibility() != View.GONE
+                && !mDismissView.willBeGone();
     }
 
     public boolean isDismissViewVisible() {
-        return mDismissView.isVisible();
+        return mDismissView != null && mDismissView.isVisible();
     }
 
     public int getDismissViewHeight() {
-        return mDismissView.getHeight() + mPaddingBetweenElements;
+        return mDismissView == null ? 0 : mDismissView.getHeight() + mPaddingBetweenElements;
     }
 
     public int getEmptyShadeViewHeight() {
@@ -4047,7 +4106,7 @@
     }
 
     public void generateHeadsUpAnimation(ExpandableNotificationRow row, boolean isHeadsUp) {
-        if (mAnimationsEnabled) {
+        if (mAnimationsEnabled && (isHeadsUp || mHeadsUpGoingAwayAnimationsAllowed)) {
             mHeadsUpChangeAnimations.add(new Pair<>(row, isHeadsUp));
             mNeedsAnimation = true;
             if (!mIsExpanded && !isHeadsUp) {
@@ -4081,12 +4140,7 @@
 
     public void setScrimController(ScrimController scrimController) {
         mScrimController = scrimController;
-        mScrimController.setScrimBehindChangeRunnable(new Runnable() {
-            @Override
-            public void run() {
-                updateBackgroundDimming();
-            }
-        });
+        mScrimController.setScrimBehindChangeRunnable(this::updateBackgroundDimming);
     }
 
     public void forceNoOverlappingRendering(boolean force) {
@@ -4119,7 +4173,7 @@
             return;
         }
         mPulsing = pulsing;
-        mAmbientState.setHasPulsingNotifications(hasPulsingNotifications());
+        mAmbientState.setPulsing(pulsing);
         updateNotificationAnimationStates();
         updateContentHeight();
         notifyHeightChangeListener(mShelf);
@@ -4234,6 +4288,32 @@
         mAmbientState.setUnlockHintRunning(running);
     }
 
+    public void setQsCustomizerShowing(boolean isShowing) {
+        mAmbientState.setQsCustomizerShowing(isShowing);
+        requestChildrenUpdate();
+    }
+
+    public void setHeadsUpGoingAwayAnimationsAllowed(boolean headsUpGoingAwayAnimationsAllowed) {
+        mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed;
+    }
+
+    public void setDarkShelfOffsetX(int shelfOffsetX) {
+        mShelf.setDarkOffsetX(shelfOffsetX);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println(String.format("[%s: pulsing=%s qsCustomizerShowing=%s visibility=%s"
+                        + " alpha:%f scrollY:%d]",
+                this.getClass().getSimpleName(),
+                mPulsing != null ?"T":"f",
+                mAmbientState.isQsCustomizerShowing() ? "T":"f",
+                getVisibility() == View.VISIBLE ? "visible"
+                        : getVisibility() == View.GONE ? "gone"
+                                : "invisible",
+                getAlpha(),
+                mAmbientState.getScrollY()));
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
@@ -4293,10 +4373,10 @@
         @Override
         public void onDownUpdate(View currView, MotionEvent ev) {
             mTranslatingParentView = currView;
-            mCurrMenuRow = null;
             if (mCurrMenuRow != null) {
                 mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
             }
+            mCurrMenuRow = null;
             mHandler.removeCallbacks(mFalsingCheck);
 
             // Slide back any notifications that might be showing a menu
@@ -4307,6 +4387,7 @@
                 mCurrMenuRow = row.createMenu();
                 mCurrMenuRow.setSwipeActionHelper(NotificationSwipeHelper.this);
                 mCurrMenuRow.setMenuClickListener(NotificationStackScrollLayout.this);
+                mCurrMenuRow.onTouchEvent(currView, ev, 0 /* velocity */);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5c10e7e..c060b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -17,10 +17,10 @@
 package com.android.systemui.statusbar.stack;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.systemui.R;
 import com.android.systemui.statusbar.DismissView;
 import com.android.systemui.statusbar.EmptyShadeView;
@@ -48,6 +48,7 @@
 
     private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
     private boolean mIsExpanded;
+    private boolean mClipNotificationScrollToTop;
     private int mStatusBarHeight;
 
     public StackScrollAlgorithm(Context context) {
@@ -59,13 +60,14 @@
     }
 
     private void initConstants(Context context) {
-        mPaddingBetweenElements = context.getResources().getDimensionPixelSize(
+        Resources res = context.getResources();
+        mPaddingBetweenElements = res.getDimensionPixelSize(
                 R.dimen.notification_divider_height);
-        mIncreasedPaddingBetweenElements = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-        mCollapsedSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_min_height);
-        mStatusBarHeight = context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
+        mIncreasedPaddingBetweenElements =
+                res.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
+        mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
+        mStatusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
+        mClipNotificationScrollToTop = res.getBoolean(R.bool.config_clipNotificationScrollToTop);
     }
 
     public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -142,7 +144,8 @@
             float newNotificationEnd = newYTranslation + newHeight;
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) child).isPinned();
-            if (!state.inShelf && newYTranslation < previousNotificationEnd
+            if (mClipNotificationScrollToTop
+                    && !state.inShelf && newYTranslation < previousNotificationEnd
                     && (!isHeadsUp || ambientState.isShadeExpanded())) {
                 // The previous view is overlapping on top, clip!
                 float overlapAmount = previousNotificationEnd - newYTranslation;
@@ -246,14 +249,28 @@
         state.paddingMap.clear();
         int notGoneIndex = 0;
         ExpandableView lastView = null;
+        int firstHiddenIndex = ambientState.isDark()
+                ? (ambientState.hasPulsingNotifications() ? 1 : 0)
+                : childCount;
+
+        // The goal here is to fill the padding map, by iterating over how much padding each child
+        // needs. The map is thereby reused, by first filling it with the padding amount and when
+        // iterating over it again, it's filled with the actual resolved value.
+
         for (int i = 0; i < childCount; i++) {
             ExpandableView v = (ExpandableView) hostView.getChildAt(i);
             if (v.getVisibility() != View.GONE) {
                 if (v == ambientState.getShelf()) {
                     continue;
                 }
+                if (i >= firstHiddenIndex) {
+                    // we need normal padding now, to be in sync with what the stack calculates
+                    lastView = null;
+                    ExpandableViewState viewState = resultState.getViewStateForView(v);
+                    viewState.hidden = true;
+                }
                 notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
-                float increasedPadding = v.getIncreasedPaddingAmount();;
+                float increasedPadding = v.getIncreasedPaddingAmount();
                 if (increasedPadding != 0.0f) {
                     state.paddingMap.put(v, increasedPadding);
                     if (lastView != null) {
@@ -276,6 +293,8 @@
                         state.paddingMap.put(lastView, newValue);
                     }
                 } else if (lastView != null) {
+
+                    // Let's now resolve the value to an actual padding
                     float newValue = getPaddingForValue(state.paddingMap.get(lastView));
                     state.paddingMap.put(lastView, newValue);
                 }
@@ -410,7 +429,7 @@
             if (mIsExpanded) {
                 // Ensure that the heads up is always visible even when scrolled off
                 clampHunToTop(ambientState, row, childState);
-                if (i == 0 && row.isAboveShelf()) {
+                if (i == 0 && ambientState.isAboveShelf(row)) {
                     // the first hun can't get off screen.
                     clampHunToMaxTranslation(ambientState, row, childState);
                     childState.hidden = false;
@@ -512,7 +531,7 @@
         ExpandableViewState childViewState = resultState.getViewStateForView(child);
         int zDistanceBetweenElements = ambientState.getZDistanceBetweenElements();
         float baseZ = ambientState.getBaseZHeight();
-        if (child.mustStayOnScreen()
+        if (child.mustStayOnScreen() && !ambientState.isDozingAndNotPulsing(child)
                 && childViewState.yTranslation < ambientState.getTopPadding()
                 + ambientState.getStackTranslation()) {
             if (childrenOnTop != 0.0f) {
@@ -524,7 +543,7 @@
             }
             childViewState.zTranslation = baseZ
                     + childrenOnTop * zDistanceBetweenElements;
-        } else if (i == 0 && child.isAboveShelf()) {
+        } else if (i == 0 && ambientState.isAboveShelf(child)) {
             // In case this is a new view that has never been measured before, we don't want to
             // elevate if we are currently expanded more then the notification
             int shelfHeight = ambientState.getShelf().getIntrinsicHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index 2082daf..7c98e13 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -154,7 +154,7 @@
         getContext().sendBroadcast(intent);
 
         intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK);
-        intent.putExtra("hhmm", "0800");
+        intent.putExtra("hhmm", "0700");
         getContext().sendBroadcast(intent);
 
         intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
new file mode 100644
index 0000000..af99236
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
@@ -0,0 +1,84 @@
+/*
+ * 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.tuner;
+
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+/**
+ * Version of Space that can be resized by a tunable setting.
+ */
+public class TunablePadding implements Tunable {
+
+    public static final int FLAG_START = 1;
+    public static final int FLAG_END = 2;
+    public static final int FLAG_TOP = 4;
+    public static final int FLAG_BOTTOM = 8;
+
+    private final int mFlags;
+    private final View mView;
+    private final int mDefaultSize;
+    private final float mDensity;
+
+    private TunablePadding(String key, int def, int flags, View view) {
+        mDefaultSize = def;
+        mFlags = flags;
+        mView = view;
+        DisplayMetrics metrics = new DisplayMetrics();
+        view.getContext().getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+        Dependency.get(TunerService.class).addTunable(this, key);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        int dimen = mDefaultSize;
+        if (newValue != null) {
+            dimen = (int) (Integer.parseInt(newValue) * mDensity);
+        }
+        int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
+        int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
+        mView.setPadding(getPadding(dimen, left), getPadding(dimen, FLAG_TOP),
+                getPadding(dimen, right), getPadding(dimen, FLAG_BOTTOM));
+    }
+
+    private int getPadding(int dimen, int flag) {
+        return ((mFlags & flag) != 0) ? dimen : 0;
+    }
+
+    public void destroy() {
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    // Exists for easy injecting in tests.
+    public static class TunablePaddingService {
+        public TunablePadding add(View view, String key, int defaultSize, int flags) {
+            if (view == null) {
+                throw new IllegalArgumentException();
+            }
+            return new TunablePadding(key, defaultSize, flags, view);
+        }
+    }
+
+    public static TunablePadding addTunablePadding(View view, String key, int defaultSize,
+            int flags) {
+        return Dependency.get(TunablePaddingService.class).add(view, key, defaultSize, flags);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
new file mode 100644
index 0000000..f7f61af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import android.app.AlarmManager;
+import android.os.Handler;
+import android.os.SystemClock;
+
+/**
+ * Schedules a timeout through AlarmManager. Ensures that the timeout is called even when
+ * the device is asleep.
+ */
+public class AlarmTimeout implements AlarmManager.OnAlarmListener {
+
+    public static final int MODE_CRASH_IF_SCHEDULED = 0;
+    public static final int MODE_IGNORE_IF_SCHEDULED = 1;
+    public static final int MODE_RESCHEDULE_IF_SCHEDULED = 2;
+
+    private final AlarmManager mAlarmManager;
+    private final AlarmManager.OnAlarmListener mListener;
+    private final String mTag;
+    private final Handler mHandler;
+    private boolean mScheduled;
+
+    public AlarmTimeout(AlarmManager alarmManager, AlarmManager.OnAlarmListener listener,
+            String tag, Handler handler) {
+        mAlarmManager = alarmManager;
+        mListener = listener;
+        mTag = tag;
+        mHandler = handler;
+    }
+
+    public void schedule(long timeout, int mode) {
+        switch (mode) {
+            case MODE_CRASH_IF_SCHEDULED:
+                if (mScheduled) {
+                    throw new IllegalStateException(mTag + " timeout is already scheduled");
+                }
+                break;
+            case MODE_IGNORE_IF_SCHEDULED:
+                if (mScheduled) {
+                    return;
+                }
+                break;
+            case MODE_RESCHEDULE_IF_SCHEDULED:
+                if (mScheduled) {
+                    cancel();
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Illegal mode: " + mode);
+        }
+
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                SystemClock.elapsedRealtime() + timeout, mTag, this, mHandler);
+        mScheduled = true;
+    }
+
+    public boolean isScheduled() {
+        return mScheduled;
+    }
+
+    public void cancel() {
+        if (mScheduled) {
+            mAlarmManager.cancel(this);
+            mScheduled = false;
+        }
+    }
+
+    @Override
+    public void onAlarm() {
+        if (!mScheduled) {
+            // We canceled the alarm, but it still fired. Ignore.
+            return;
+        }
+        mScheduled = false;
+        mListener.onAlarm();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
new file mode 100644
index 0000000..5790ba3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -0,0 +1,162 @@
+/*
+ * 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.util;
+
+import android.hardware.HardwareBuffer;
+import android.hardware.Sensor;
+import android.hardware.SensorAdditionalInfo;
+import android.hardware.SensorDirectChannel;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEventListener;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.MemoryFile;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Wrapper around sensor manager that hides potential sources of latency.
+ *
+ * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread
+ * without blocking. Note that this means registering listeners now always appears successful even
+ * if it is not.
+ */
+public class AsyncSensorManager extends SensorManager {
+
+    private static final String TAG = "AsyncSensorManager";
+
+    private final SensorManager mInner;
+    private final List<Sensor> mSensorCache;
+    private final HandlerThread mHandlerThread = new HandlerThread("async_sensor");
+    @VisibleForTesting final Handler mHandler;
+
+    public AsyncSensorManager(SensorManager inner) {
+        mInner = inner;
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL);
+    }
+
+    @Override
+    protected List<Sensor> getFullSensorList() {
+        return mSensorCache;
+    }
+
+    @Override
+    protected List<Sensor> getFullDynamicSensorList() {
+        return mInner.getDynamicSensorList(Sensor.TYPE_ALL);
+    }
+
+    @Override
+    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs,
+            Handler handler, int maxReportLatencyUs, int reservedFlags) {
+        mHandler.post(() -> {
+            if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) {
+                Log.e(TAG, "Registering " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean flushImpl(SensorEventListener listener) {
+        return mInner.flush(listener);
+    }
+
+    @Override
+    protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile,
+            HardwareBuffer hardwareBuffer) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void destroyDirectChannelImpl(SensorDirectChannel channel) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback,
+            Handler handler) {
+        mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler));
+    }
+
+    @Override
+    protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) {
+        mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback));
+    }
+
+    @Override
+    protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
+        mHandler.post(() -> {
+            if (!mInner.requestTriggerSensor(listener, sensor)) {
+                Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
+            boolean disable) {
+        Preconditions.checkArgument(disable);
+
+        mHandler.post(() -> {
+            if (!mInner.cancelTriggerSensor(listener, sensor)) {
+                Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed.");
+            }
+        });
+        return true;
+    }
+
+    @Override
+    protected boolean initDataInjectionImpl(boolean enable) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
+            long timestamp) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) {
+        mHandler.post(() -> mInner.setOperationParameter(parameter));
+        return true;
+    }
+
+    @Override
+    protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
+        mHandler.post(() -> {
+            if (sensor == null) {
+                mInner.unregisterListener(listener);
+            } else {
+                mInner.unregisterListener(listener, sensor);
+            }
+        });
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index ba9e60a..021f9c4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemProperties;
+import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 
 import com.android.systemui.Dependency;
@@ -84,12 +85,15 @@
         // TODO(b/35345376): Turn this back on for debuggable builds after known leak fixed.
         private static final boolean ENABLED = Build.IS_DEBUGGABLE
                 && SystemProperties.getBoolean("debug.enable_leak_reporting", false);
+        private static final String FORCE_ENABLE = "sysui_force_garbage_monitor";
 
         private GarbageMonitor mGarbageMonitor;
 
         @Override
         public void start() {
-            if (!ENABLED) {
+            boolean forceEnable = Settings.Secure.getInt(mContext.getContentResolver(),
+                    FORCE_ENABLE, 0) != 0;
+            if (!ENABLED && !forceEnable) {
                 return;
             }
             mGarbageMonitor = Dependency.get(GarbageMonitor.class);
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
new file mode 100644
index 0000000..ad20900
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.leak;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.view.Surface;
+
+public class RotationUtils {
+
+    public static final int ROTATION_NONE = 0;
+    public static final int ROTATION_LANDSCAPE = 1;
+    public static final int ROTATION_SEASCAPE = 2;
+
+    public static int getRotation(Context context) {
+        Configuration config = context.getResources().getConfiguration();
+        int rot = context.getDisplay().getRotation();
+        if (config.smallestScreenWidthDp < 600) {
+            if (rot == Surface.ROTATION_90) {
+                return ROTATION_LANDSCAPE;
+            } else if (rot == Surface.ROTATION_270) {
+                return ROTATION_SEASCAPE;
+            }
+        }
+        return ROTATION_NONE;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
new file mode 100644
index 0000000..b835909
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util.wakelock;
+
+import android.os.Handler;
+
+/**
+ * A wake lock that has a built in delay when releasing to give the framebuffer time to update.
+ */
+public class DelayedWakeLock implements WakeLock {
+
+    private static final long RELEASE_DELAY_MS = 100;
+
+    private final Handler mHandler;
+    private final WakeLock mInner;
+    private final Runnable mRelease;
+
+    public DelayedWakeLock(Handler h, WakeLock inner) {
+        mHandler = h;
+        mInner = inner;
+        mRelease = mInner::release;
+    }
+
+    @Override
+    public void acquire() {
+        mInner.acquire();
+    }
+
+    @Override
+    public void release() {
+        mHandler.postDelayed(mRelease, RELEASE_DELAY_MS);
+    }
+
+    @Override
+    public Runnable wrap(Runnable r) {
+        return WakeLock.wrapImpl(this, r);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index 215604b..edf294e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -42,6 +42,17 @@
                     .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
     }
 
+    static Runnable wrapImpl(WakeLock w, Runnable r) {
+        w.acquire();
+        return () -> {
+            try {
+                r.run();
+            } finally {
+                w.release();
+            }
+        };
+    }
+
     static WakeLock wrap(final PowerManager.WakeLock inner) {
         return new WakeLock() {
             /** @see PowerManager.WakeLock#acquire() */
@@ -56,7 +67,7 @@
 
             /** @see PowerManager.WakeLock#wrap(Runnable) */
             public Runnable wrap(Runnable runnable) {
-                return inner.wrap(runnable);
+                return wrapImpl(this, runnable);
             }
         };
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 5d51a33..b08b26d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -43,12 +43,17 @@
 import android.service.notification.Condition;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.statusbar.phone.StatusBar;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -88,13 +93,14 @@
     private final W mWorker;
     private final Context mContext;
     private AudioManager mAudio;
+    protected StatusBar mStatusBar;
     private final NotificationManager mNoMan;
     private final SettingObserver mObserver;
     private final Receiver mReceiver = new Receiver();
     private final MediaSessions mMediaSessions;
-    private final C mCallbacks = new C();
+    protected C mCallbacks = new C();
     private final State mState = new State();
-    private final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
+    protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks();
     private final Vibrator mVibrator;
     private final boolean mHasVibrator;
     private boolean mShowA11yStream;
@@ -122,6 +128,13 @@
         mReceiver.init();
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
+        updateStatusBar();
+
+        boolean accessibilityVolumeStreamActive = context.getSystemService(
+                AccessibilityManager.class).isAccessibilityVolumeStreamActive();
+        mVolumeController.setA11yMode(accessibilityVolumeStreamActive ?
+                    VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
+                        VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
     }
 
     public AudioManager getAudioManager() {
@@ -210,6 +223,7 @@
 
     public void addCallback(Callbacks callback, Handler handler) {
         mCallbacks.add(callback, handler);
+        callback.onAccessibilityModeChanged(mShowA11yStream);
     }
 
     public void setUserActivityListener(UserActivityListener listener) {
@@ -318,8 +332,23 @@
         return changed;
     }
 
-    private boolean onVolumeChangedW(int stream, int flags) {
-        final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
+    private void updateStatusBar() {
+        if (mStatusBar == null) {
+            mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        }
+    }
+
+    private boolean shouldShowUI(int flags) {
+        updateStatusBar();
+        return mStatusBar != null
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
+                && mStatusBar.isDeviceInteractive()
+                && (flags & AudioManager.FLAG_SHOW_UI) != 0;
+    }
+
+    boolean onVolumeChangedW(int stream, int flags) {
+        final boolean showUI = shouldShowUI(flags);
         final boolean fromKey = (flags & AudioManager.FLAG_FROM_KEY) != 0;
         final boolean showVibrateHint = (flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0;
         final boolean showSilentHint = (flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0;
@@ -630,7 +659,7 @@
         }
     }
 
-    private final class C implements Callbacks {
+    class C implements Callbacks {
         private final HashMap<Callbacks, Handler> mCallbackMap = new HashMap<>();
 
         public void add(Callbacks callback, Handler handler) {
@@ -877,18 +906,14 @@
         }
     }
 
-    private final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
+    protected final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
         private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
 
         private int mNextStream = DYNAMIC_STREAM_START_INDEX;
 
         @Override
         public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
-            if (!mRemoteStreams.containsKey(token)) {
-                mRemoteStreams.put(token, mNextStream);
-                if (D.BUG) Log.d(TAG, "onRemoteUpdate: " + name + " is stream " + mNextStream);
-                mNextStream++;
-            }
+            addStream(token, "onRemoteUpdate");
             final int stream = mRemoteStreams.get(token);
             boolean changed = mState.states.indexOfKey(stream) < 0;
             final StreamState ss = streamStateW(stream);
@@ -913,8 +938,9 @@
 
         @Override
         public void onRemoteVolumeChanged(Token token, int flags) {
+            addStream(token, "onRemoteVolumeChanged");
             final int stream = mRemoteStreams.get(token);
-            final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
+            final boolean showUI = shouldShowUI(flags);
             boolean changed = updateActiveStreamW(stream);
             if (showUI) {
                 changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC);
@@ -929,6 +955,11 @@
 
         @Override
         public void onRemoteRemoved(Token token) {
+            if (!mRemoteStreams.containsKey(token)) {
+                if (D.BUG) Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
+                        + "aborting remote removed for token:" +  token.toString());
+                return;
+            }
             final int stream = mRemoteStreams.get(token);
             mState.states.remove(stream);
             if (mState.activeStream == stream) {
@@ -954,6 +985,15 @@
             }
             return null;
         }
+
+        private void addStream(Token token, String triggeringMethod) {
+            if (!mRemoteStreams.containsKey(token)) {
+                mRemoteStreams.put(token, mNextStream);
+                if (D.BUG) Log.d(TAG, triggeringMethod + ": added stream " +  mNextStream
+                        + " from token + "+ token.toString());
+                mNextStream++;
+            }
+        }
     }
 
     public interface UserActivityListener {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 8d8931f..9e50e81 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -25,6 +25,7 @@
 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;
@@ -32,6 +33,7 @@
 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;
@@ -51,6 +53,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
@@ -149,7 +152,7 @@
     private TunerZenModePanel mZenPanel;
 
     public VolumeDialogImpl(Context context) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mZenModeController = Dependency.get(ZenModeController.class);
         mController = Dependency.get(VolumeDialogController.class);
         mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
@@ -178,7 +181,13 @@
 
     @Override
     public void destroy() {
+        mAccessibility.destroy();
         mController.removeCallback(mControllerCallbackH);
+        if (mZenFooter != null) {
+            mZenFooter.cleanup();
+        }
+        Dependency.get(TunerService.class).removeTunable(this);
+        mHandler.removeCallbacksAndMessages(null);
     }
 
     private void initDialog() {
@@ -694,11 +703,12 @@
         final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
                 && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
                 && !mZenPanel.isEditing();
-
-        if (wasVisible != visible) {
-            mZenFooter.update();
-            Util.setVisOrGone(mZenFooter, visible);
+        TransitionManager.beginDelayedTransition(mDialogView, getTransistion());
+        if (wasVisible != visible && !visible) {
+            prepareForCollapse();
         }
+        Util.setVisOrGone(mZenFooter, visible);
+        mZenFooter.update();
 
         final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
         final boolean fullVisible = mShowFullZen && !visible;
@@ -1238,16 +1248,14 @@
                 }
             });
             mDialogView.setAccessibilityDelegate(this);
-            mAccessibilityMgr.addAccessibilityStateChangeListener(
-                    new AccessibilityStateChangeListener() {
-                        @Override
-                        public void onAccessibilityStateChanged(boolean enabled) {
-                            updateFeedbackEnabled();
-                        }
-                    });
+            mAccessibilityMgr.addAccessibilityStateChangeListener(mListener);
             updateFeedbackEnabled();
         }
 
+        public void destroy() {
+            mAccessibilityMgr.removeAccessibilityStateChangeListener(mListener);
+        }
+
         @Override
         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
                 AccessibilityEvent event) {
@@ -1270,6 +1278,9 @@
             }
             return false;
         }
+
+        private final AccessibilityStateChangeListener mListener =
+                enabled -> updateFeedbackEnabled();
     }
 
     private static class VolumeRow {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index d6d0f75..01d31e2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -25,6 +25,7 @@
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnDismissListener;
 import android.content.DialogInterface.OnShowListener;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.util.Log;
 import android.view.View;
@@ -132,12 +133,11 @@
                 .setDuration(scaledDuration(300))
                 .setInterpolator(new LogDecelerateInterpolator())
                 .setListener(null)
-                .setUpdateListener(new AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
+                .setUpdateListener(animation -> {
+                    if (mChevronPositionAnimator != null) {
+                        final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         if (mChevronPositionAnimator == null) return;
                         // reposition chevron
-                        final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         final int posY = chevronPosY();
                         mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
                     }
@@ -258,13 +258,13 @@
         return (int) (base * ANIMATION_SCALE);
     }
 
-    private static final class LogDecelerateInterpolator implements TimeInterpolator {
+    public static final class LogDecelerateInterpolator implements TimeInterpolator {
         private final float mBase;
         private final float mDrift;
         private final float mTimeScale;
         private final float mOutputScale;
 
-        private LogDecelerateInterpolator() {
+        public LogDecelerateInterpolator() {
             this(400f, 1.4f, 0);
         }
 
@@ -286,12 +286,12 @@
         }
     }
 
-    private static final class LogAccelerateInterpolator implements TimeInterpolator {
+    public static final class LogAccelerateInterpolator implements TimeInterpolator {
         private final int mBase;
         private final int mDrift;
         private final float mLogScale;
 
-        private LogAccelerateInterpolator() {
+        public LogAccelerateInterpolator() {
             this(100, 0);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 17d98b1..7464212 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -111,7 +111,9 @@
         if (mZen == zen) return;
         mZen = zen;
         update();
-        updateIntroduction();
+        post(() -> {
+            updateIntroduction();
+        });
     }
 
     private void setConfig(ZenModeConfig config) {
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/src/com/android/systemui/volume/ZenRadioLayout.java b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
new file mode 100644
index 0000000..5dbcd8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenRadioLayout.java
@@ -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.
+ */
+
+package com.android.systemui.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Specialized layout for zen mode that allows the radio buttons to reside within
+ * a RadioGroup, but also makes sure that all the heights off the radio buttons align
+ * with the corresponding content in the second child of this view.
+ */
+public class ZenRadioLayout extends LinearLayout {
+
+    public ZenRadioLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Run 2 measurement passes, 1 that figures out the size of the content, and another
+     * that sets the size of the radio buttons to the heights of the corresponding content.
+     */
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        ViewGroup radioGroup = (ViewGroup) getChildAt(0);
+        ViewGroup radioContent = (ViewGroup) getChildAt(1);
+        int size = radioGroup.getChildCount();
+        if (size != radioContent.getChildCount()) {
+            throw new IllegalStateException("Expected matching children");
+        }
+        boolean hasChanges = false;
+        for (int i = 0; i < size; i++) {
+            View radio = radioGroup.getChildAt(i);
+            View content = radioContent.getChildAt(i);
+            if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
+                hasChanges = true;
+                radio.getLayoutParams().height = content.getMeasuredHeight();
+            }
+        }
+        // Measure again if any heights changed.
+        if (hasChanges) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index b12fd1c..adb3baf 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -38,6 +38,10 @@
     <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" />
+    <uses-permission android:name="android.permission.TRUST_LISTENER" />
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -48,7 +52,7 @@
             android:process=":killable" />
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.systemui.tests"
         android:label="Tests for SystemUI">
     </instrumentation>
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index ee78bcd..6ca42e8 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -19,8 +19,9 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="SystemUITests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.systemui.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
index 855adb4..e37ea95 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -36,12 +37,17 @@
 public class KeyguardClockAccessibilityDelegateTest extends SysuiTestCase {
 
     private TextView mView;
+    private String m12HoursFormat;
+    private String m24HoursFormat;
 
     @Before
     public void setUp() throws Exception {
+        m12HoursFormat = mContext.getString(R.string.keyguard_widget_12_hours_format);
+        m24HoursFormat = mContext.getString(R.string.keyguard_widget_24_hours_format);
+
         mView = new TextView(mContext);
-        mView.setText(R.string.keyguard_widget_12_hours_format);
-        mView.setContentDescription(mContext.getString(R.string.keyguard_widget_12_hours_format));
+        mView.setText(m12HoursFormat);
+        mView.setContentDescription(m12HoursFormat);
         mView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
     }
 
@@ -77,6 +83,21 @@
         assertTrue(isAscii(info.getContentDescription()));
     }
 
+    @Test
+    public void isNeeded_returnsTrueIfDateFormatsContainNonAscii() {
+        if (!isAscii(m12HoursFormat) || !isAscii(m24HoursFormat)) {
+            assertTrue(KeyguardClockAccessibilityDelegate.isNeeded(mContext));
+        }
+    }
+
+    @Test
+    public void isNeeded_returnsWhetherFancyColonExists() {
+        boolean hasFancyColon = !TextUtils.isEmpty(mContext.getString(
+                R.string.keyguard_fancy_colon));
+
+        assertEquals(hasFancyColon, KeyguardClockAccessibilityDelegate.isNeeded(mContext));
+    }
+
     private boolean isAscii(CharSequence text) {
         return text.chars().allMatch((i) -> i < 128);
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
new file mode 100644
index 0000000..fcf327b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.keyguard;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.UiThreadTest;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KeyguardSecurityContainerTest extends SysuiTestCase {
+
+    @UiThreadTest
+    @Test
+    public void showSecurityScreen_canInflateAllModes() {
+        KeyguardSecurityContainer keyguardSecurityContainer =
+                new KeyguardSecurityContainer(getContext());
+
+        Context context = getContext();
+
+        for (int theme : new int[] {R.style.Theme_SystemUI, R.style.Theme_SystemUI_Light}) {
+            context.setTheme(theme);
+            final LayoutInflater inflater = LayoutInflater.from(context);
+            KeyguardSecurityModel.SecurityMode[] modes =
+                    KeyguardSecurityModel.SecurityMode.values();
+            for (KeyguardSecurityModel.SecurityMode mode : modes) {
+                final int resId = keyguardSecurityContainer.getLayoutIdFor(mode);
+                if (resId == 0) {
+                    continue;
+                }
+                inflater.inflate(resId, null /* root */, false /* attach */);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
new file mode 100644
index 0000000..2a44771
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R.dimen;
+import com.android.systemui.RoundedCorners.TunablePaddingTagListener;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class RoundedCornersTest extends SysuiTestCase {
+
+    private RoundedCorners mRoundedCorners;
+    private StatusBar mStatusBar;
+    private WindowManager mWindowManager;
+    private FragmentService mFragmentService;
+    private FragmentHostManager mFragmentHostManager;
+    private TunerService mTunerService;
+    private StatusBarWindowView mView;
+    private TunablePaddingService mTunablePaddingService;
+
+    @Before
+    public void setup() {
+        mStatusBar = mock(StatusBar.class);
+        mWindowManager = mock(WindowManager.class);
+        mView = spy(new StatusBarWindowView(mContext, null));
+        when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        when(mStatusBar.getNavigationBarWindow()).thenReturn(mView);
+        mContext.putComponent(StatusBar.class, mStatusBar);
+
+        Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
+        when(mWindowManager.getDefaultDisplay()).thenReturn(display);
+        mContext.addMockSystemService(WindowManager.class, mWindowManager);
+
+        mFragmentService = mDependency.injectMockDependency(FragmentService.class);
+        mFragmentHostManager = mock(FragmentHostManager.class);
+        when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+
+        mRoundedCorners = new RoundedCorners();
+        mRoundedCorners.mContext = mContext;
+        mRoundedCorners.mComponents = mContext.getComponents();
+
+        mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
+    }
+
+    @Test
+    public void testNoRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+
+        mRoundedCorners.start();
+        // No views added.
+        verify(mWindowManager, never()).addView(any(), any());
+        // No Fragments watched.
+        verify(mFragmentHostManager, never()).addTagListener(any(), any());
+        // No Tuners tuned.
+        verify(mTunerService, never()).addTunable(any(), any());
+    }
+
+    @Test
+    public void testRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 20);
+
+        mRoundedCorners.start();
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+
+        // Add 2 tag listeners for each of the fragments that are needed.
+        verify(mFragmentHostManager, times(2)).addTagListener(any(), any());
+        // One tunable.
+        verify(mTunerService, times(1)).addTunable(any(), any());
+        // One TunablePadding.
+        verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testPaddingTagListener() {
+        TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
+        View v = mock(View.class);
+        View child = mock(View.class);
+        Fragment f = mock(Fragment.class);
+        TunablePadding padding = mock(TunablePadding.class);
+
+        when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
+                .thenReturn(padding);
+        when(f.getView()).thenReturn(v);
+        when(v.findViewById(5)).thenReturn(child);
+
+        // Trigger callback and verify we get a TunablePadding created.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(mTunablePaddingService).add(eq(child), eq(RoundedCorners.PADDING), eq(14),
+                eq(FLAG_START | FLAG_END));
+
+        // Call again and verify destroy is called.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(padding).destroy();
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 361a20f..66d00dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,8 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -56,10 +58,14 @@
 
         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
         Instrumentation inst = spy(mRealInstrumentation);
-        when(inst.getContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
-        when(inst.getTargetContext()).thenThrow(new RuntimeException(
-                "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+        when(inst.getContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
+        when(inst.getTargetContext()).thenAnswer(invocation -> {
+            throw new RuntimeException(
+                    "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
+        });
         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index b94a2fb..9d3124e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -31,6 +31,11 @@
         super(base, check);
     }
 
+    public ArrayMap<Class<?>, Object> getComponents() {
+        if (mComponents == null) mComponents = new ArrayMap<>();
+        return mComponents;
+    }
+
     @SuppressWarnings("unchecked")
     public <T> T getComponent(Class<T> interfaceType) {
         return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
new file mode 100644
index 0000000..d0f0bfd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -0,0 +1,95 @@
+/*
+ * 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.colorextraction;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.types.Tonal;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests color extraction generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SysuiColorExtractorTests extends SysuiTestCase {
+
+    private static int[] sWhich = new int[]{
+            WallpaperManager.FLAG_SYSTEM,
+            WallpaperManager.FLAG_LOCK};
+    private static int[] sTypes = new int[]{
+            ColorExtractor.TYPE_NORMAL,
+            ColorExtractor.TYPE_DARK,
+            ColorExtractor.TYPE_EXTRA_DARK};
+
+    @Test
+    public void getColors_usesGreyIfWallpaperNotVisible() {
+        SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(),
+                new Tonal(getContext()), false);
+        simulateEvent(extractor);
+        extractor.setWallpaperVisible(false);
+
+        ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors();
+
+        for (int which : sWhich) {
+            for (int type : sTypes) {
+                assertEquals("Not using fallback!", extractor.getColors(which, type),
+                        fallbackColors);
+            }
+        }
+    }
+
+    @Test
+    public void getColors_doesntUseFallbackIfVisible() {
+        ColorExtractor.GradientColors colors = new ColorExtractor.GradientColors();
+        colors.setMainColor(Color.RED);
+        colors.setSecondaryColor(Color.RED);
+
+        SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(),
+                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
+                        outGradientColorsExtraDark) -> {
+                    outGradientColorsNormal.set(colors);
+                    outGradientColorsDark.set(colors);
+                    outGradientColorsExtraDark.set(colors);
+                }, false);
+        simulateEvent(extractor);
+        extractor.setWallpaperVisible(true);
+
+        for (int which : sWhich) {
+            for (int type : sTypes) {
+                assertEquals("Not using extracted colors!",
+                        extractor.getColors(which, type), colors);
+            }
+        }
+    }
+
+    private void simulateEvent(SysuiColorExtractor extractor) {
+        // Let's fake a color event
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.GREEN), null, null, 0),
+                WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
index bbe324d..64507be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.doze;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,7 +42,7 @@
     }
 
     @Test
-    public void alwaysOn_offByDefault() throws Exception {
+    public void alwaysOn_onByDefault() throws Exception {
         if (!mDozeConfig.alwaysOnAvailable()) {
             return;
         }
@@ -50,6 +50,6 @@
         Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON,
                 null);
 
-        assertFalse(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
+        assertTrue(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
     }
 }
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 ee0fe7b..333e73d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -27,6 +27,9 @@
     boolean pulseAborted;
     boolean pulseExtended;
     boolean animateWakeup;
+    boolean dozing;
+    float doubleTapX;
+    float doubleTapY;
 
     @Override
     public void addCallback(@NonNull Callback callback) {
@@ -40,7 +43,7 @@
 
     @Override
     public void startDozing() {
-        throw new RuntimeException("not implemented");
+        dozing = true;
     }
 
     @Override
@@ -50,7 +53,7 @@
 
     @Override
     public void stopDozing() {
-        throw new RuntimeException("not implemented");
+        dozing = false;
     }
 
     @Override
@@ -69,11 +72,25 @@
     }
 
     @Override
+    public boolean isProvisioned() {
+        return false;
+    }
+
+    @Override
+    public boolean isBlockingDoze() {
+        return false;
+    }
+
+    @Override
     public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
         throw new RuntimeException("not implemented");
     }
 
     @Override
+    public void onIgnoreTouchWhilePulsing(boolean ignore) {
+    }
+
+    @Override
     public void abortPulsing() {
         pulseAborted = true;
     }
@@ -87,4 +104,14 @@
     public void setAnimateWakeup(boolean animateWakeup) {
         this.animateWakeup = animateWakeup;
     }
+
+    @Override
+    public void onDoubleTap(float x, float y) {
+        doubleTapX = y;
+        doubleTapY = y;
+    }
+
+    @Override
+    public void setDozeScreenBrightness(int value) {
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 7519b2d..368c814f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -215,54 +215,6 @@
     }
 
     @Test
-    public void testScreen_offInDoze() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE);
-
-        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInAod() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE_AOD);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInPulse() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-        mMachine.requestState(DOZE_PULSING);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_offInRequestPulseWithoutAoD() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-
-        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
-    }
-
-    @Test
-    public void testScreen_onInRequestPulseWithoutAoD() {
-        mMachine.requestState(INITIALIZED);
-
-        mMachine.requestState(DOZE_AOD);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
-
-        assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
-    }
-
-    @Test
     public void testTransitions_canRequestTransitions() {
         mMachine.requestState(INITIALIZED);
         mMachine.requestState(DOZE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
new file mode 100644
index 0000000..c275806
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.FINISH;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.PowerManager;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.utils.hardware.FakeSensorManager;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Ignore
+public class DozeScreenBrightnessTest extends SysuiTestCase {
+
+    DozeServiceFake mServiceFake;
+    DozeScreenBrightness mScreen;
+    FakeSensorManager.FakeGenericSensor mSensor;
+    FakeSensorManager mSensorManager;
+    DozeHostFake mHostFake;
+
+    @Before
+    public void setUp() throws Exception {
+        mServiceFake = new DozeServiceFake();
+        mHostFake = new DozeHostFake();
+        mSensorManager = new FakeSensorManager(mContext);
+        mSensor = mSensorManager.getFakeLightSensor();
+        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
+                mSensor.getSensor(), mHostFake, null /* handler */);
+    }
+
+    @Test
+    public void testInitialize_setsScreenBrightnessToValidValue() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+
+        assertNotEquals(PowerManager.BRIGHTNESS_DEFAULT, mServiceFake.screenBrightness);
+        assertTrue(mServiceFake.screenBrightness <= PowerManager.BRIGHTNESS_ON);
+    }
+
+    @Test
+    public void testAod_usesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPausingAod_pausesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        mSensor.sendSensorEvent(1001);
+
+        assertNotEquals(1001, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPausingAod_resetsBrightness() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(1000);
+
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testPulsing_usesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testDozingAfterPulsing_pausesLightSensor() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+        mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING);
+        mScreen.transitionTo(DOZE_PULSING, DOZE_PULSE_DONE);
+        mScreen.transitionTo(DOZE_PULSE_DONE, DOZE);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testNullSensor() throws Exception {
+        mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
+                null /* sensor */, mHostFake, null /* handler */);
+
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+        mScreen.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+    }
+
+    @Test
+    public void testNoBrightnessDeliveredAfterFinish() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+        mScreen.transitionTo(DOZE_AOD, FINISH);
+
+        mSensor.sendSensorEvent(1000);
+
+        assertNotEquals(1000, mServiceFake.screenBrightness);
+    }
+
+    @Test
+    public void testBrightness_atLeastOne() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mSensor.sendSensorEvent(0);
+
+        assertTrue("Brightness must be at least 1, but was " + mServiceFake.screenBrightness,
+                mServiceFake.screenBrightness >= 1);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
new file mode 100644
index 0000000..c787eff
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Display;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DozeScreenStateTest extends SysuiTestCase {
+
+    DozeServiceFake mServiceFake;
+    DozeScreenState mScreen;
+    private ImmediateHandler mHandler;
+
+    @Before
+    public void setUp() throws Exception {
+        mServiceFake = new DozeServiceFake();
+        mHandler = spy(new ImmediateHandler(Looper.getMainLooper()));
+        mScreen = new DozeScreenState(mServiceFake, mHandler);
+    }
+
+    @Test
+    public void testScreen_offInDoze() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_onInAod() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_onInPulse() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+        mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING);
+
+        assertEquals(Display.STATE_ON, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_offInRequestPulseWithoutAoD() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void testScreen_offInRequestPulseWithAoD() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE);
+
+        assertEquals(Display.STATE_OFF, mServiceFake.screenState);
+    }
+
+    @Test
+    public void test_postedToHandler() {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+
+        verify(mHandler).sendMessageAtTime(any(), anyLong());
+    }
+
+    private static class ImmediateHandler extends Handler {
+
+        public ImmediateHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            Runnable callback = msg.getCallback();
+            if (callback != null) {
+                callback.run();
+                return false;
+            }
+            return super.sendMessageAtTime(msg, uptimeMillis);
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
index c1e7fe4..34026b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeServiceFake.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.os.PowerManager;
 import android.view.Display;
 
 public class DozeServiceFake implements DozeMachine.Service {
@@ -23,6 +24,7 @@
     public boolean finished;
     public int screenState;
     public boolean requestedWakeup;
+    public int screenBrightness;
 
     public DozeServiceFake() {
         reset();
@@ -38,13 +40,19 @@
         screenState = state;
     }
 
-    public void reset() {
-        finished = false;
-        screenState = Display.STATE_UNKNOWN;
-    }
-
     @Override
     public void requestWakeUp() {
         requestedWakeup = true;
     }
+
+    @Override
+    public void setDozeScreenBrightness(int brightness) {
+        screenBrightness = brightness;
+    }
+
+    public void reset() {
+        finished = false;
+        screenState = Display.STATE_UNKNOWN;
+        screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
new file mode 100644
index 0000000..d78e739
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.view.Display;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase {
+
+    private DozeMachine.Service mInner;
+    private DozeSuspendScreenStatePreventingAdapter mWrapper;
+
+    @Before
+    public void setup() throws Exception {
+        mInner = mock(DozeMachine.Service.class);
+        mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner);
+    }
+
+    @Test
+    public void forwards_finish() throws Exception {
+        mWrapper.finish();
+        verify(mInner).finish();
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_on() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_ON);
+        verify(mInner).setDozeScreenState(Display.STATE_ON);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_off() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_OFF);
+        verify(mInner).setDozeScreenState(Display.STATE_OFF);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_doze() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_DOZE);
+        verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+    }
+
+    @Test
+    public void forwards_setDozeScreenState_doze_suspend() throws Exception {
+        mWrapper.setDozeScreenState(Display.STATE_DOZE_SUSPEND);
+        verify(mInner).setDozeScreenState(Display.STATE_DOZE);
+    }
+
+    @Test
+    public void forwards_requestWakeUp() throws Exception {
+        mWrapper.requestWakeUp();
+        verify(mInner).requestWakeUp();
+    }
+
+    @Test
+    public void wrapIfNeeded_needed() throws Exception {
+        DozeParameters params = mock(DozeParameters.class);
+        when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false);
+
+        assertEquals(DozeSuspendScreenStatePreventingAdapter.class,
+                DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params).getClass());
+    }
+
+    @Test
+    public void wrapIfNeeded_not_needed() throws Exception {
+        DozeParameters params = mock(DozeParameters.class);
+        when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true);
+
+        assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params));
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index b054690..a8ea1c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -23,11 +23,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.AlarmManager;
 import android.app.Instrumentation;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -40,10 +40,12 @@
 
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
+@Ignore("failing")
 @RunWith(AndroidJUnit4.class)
 public class DozeTriggersTest extends SysuiTestCase {
     private DozeTriggers mTriggers;
@@ -55,6 +57,7 @@
     private Handler mHandler;
     private WakeLock mWakeLock;
     private Instrumentation mInstrumentation;
+    private AlarmManager mAlarmManager;
 
     @BeforeClass
     public static void setupSuite() {
@@ -66,6 +69,7 @@
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mMachine = mock(DozeMachine.class);
+        mAlarmManager = mock(AlarmManager.class);
         mHost = new DozeHostFake();
         mConfig = DozeConfigurationUtil.createMockConfig();
         mParameters = DozeConfigurationUtil.createMockParameters();
@@ -74,12 +78,11 @@
         mWakeLock = new WakeLockFake();
 
         mInstrumentation.runOnMainSync(() -> {
-            mTriggers = new DozeTriggers(mContext, mMachine, mHost,
+            mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager,
                     mConfig, mParameters, mSensors, mHandler, mWakeLock, true);
         });
     }
 
-    @FlakyTest
     @Test
     public void testOnNotification_stillWorksAfterOneFailedProxCheck() throws Exception {
         when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
@@ -109,4 +112,4 @@
         verify(mMachine).requestPulse(anyInt());
     }
 
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
new file mode 100644
index 0000000..19a30cc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.wakelock.WakeLockFake;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DozeUiTest extends SysuiTestCase {
+
+    private AlarmManager mAlarmManager;
+    private DozeMachine mMachine;
+    private WakeLockFake mWakeLock;
+    private DozeHostFake mHost;
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private DozeUi mDozeUi;
+
+    @Before
+    public void setUp() throws Exception {
+        mHandlerThread = new HandlerThread("DozeUiTest");
+        mHandlerThread.start();
+        mAlarmManager = mock(AlarmManager.class);
+        mMachine = mock(DozeMachine.class);
+        mWakeLock = new WakeLockFake();
+        mHost = new DozeHostFake();
+        mHandler = mHandlerThread.getThreadHandler();
+
+        mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mHandlerThread.quit();
+        mHandler = null;
+        mHandlerThread = null;
+    }
+
+    @Test
+    public void pausingAndUnpausingAod_registersTimeTickAfterUnpausing() throws Exception {
+        mDozeUi.transitionTo(UNINITIALIZED, INITIALIZED);
+        mDozeUi.transitionTo(INITIALIZED, DOZE_AOD);
+        mDozeUi.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
+
+        clearInvocations(mAlarmManager);
+
+        mDozeUi.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
+
+        verify(mAlarmManager).setExact(anyInt(), anyLong(), eq("doze_time_tick"), any(), any());
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
new file mode 100644
index 0000000..e0807d6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class LifecycleTest extends SysuiTestCase {
+
+    private final Object mObj1 = new Object();
+    private final Object mObj2 = new Object();
+
+    private Lifecycle<Object> mLifecycle;
+    private ArrayList<Object> mDispatchedObjects;
+
+    @Before
+    public void setUp() throws Exception {
+        mLifecycle = new Lifecycle<>();
+        mDispatchedObjects = new ArrayList<>();
+    }
+
+    @Test
+    public void addObserver_addsObserver() throws Exception {
+        mLifecycle.addObserver(mObj1);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertTrue(mDispatchedObjects.contains(mObj1));
+    }
+
+    @Test
+    public void removeObserver() throws Exception {
+        mLifecycle.addObserver(mObj1);
+        mLifecycle.removeObserver(mObj1);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertFalse(mDispatchedObjects.contains(mObj1));
+    }
+
+    @Test
+    public void dispatch() throws Exception {
+        mLifecycle.addObserver(mObj1);
+        mLifecycle.addObserver(mObj2);
+
+        mLifecycle.dispatch(mDispatchedObjects::add);
+
+        assertTrue(mDispatchedObjects.contains(mObj1));
+        assertTrue(mDispatchedObjects.contains(mObj2));
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
new file mode 100644
index 0000000..8c918f6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ScreenLifecycleTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ScreenLifecycleTest extends SysuiTestCase {
+
+    private ScreenLifecycle mScreen;
+    private ScreenLifecycle.Observer mScreenObserverMock;
+
+    @Before
+    public void setUp() throws Exception {
+        mScreen = new ScreenLifecycle();
+        mScreenObserverMock = mock(ScreenLifecycle.Observer.class);
+        mScreen.addObserver(mScreenObserverMock);
+    }
+
+    @Test
+    public void baseState() throws Exception {
+        assertEquals(ScreenLifecycle.SCREEN_OFF, mScreen.getScreenState());
+        verifyNoMoreInteractions(mScreenObserverMock);
+    }
+
+    @Test
+    public void screenTurningOn() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+
+        assertEquals(ScreenLifecycle.SCREEN_TURNING_ON, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurningOn();
+    }
+
+    @Test
+    public void screenTurnedOn() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+
+        assertEquals(ScreenLifecycle.SCREEN_ON, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurnedOn();
+    }
+
+    @Test
+    public void screenTurningOff() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+        mScreen.dispatchScreenTurningOff();
+
+        assertEquals(ScreenLifecycle.SCREEN_TURNING_OFF, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurningOff();
+    }
+
+    @Test
+    public void screenTurnedOff() throws Exception {
+        mScreen.dispatchScreenTurningOn();
+        mScreen.dispatchScreenTurnedOn();
+        mScreen.dispatchScreenTurningOff();
+        mScreen.dispatchScreenTurnedOff();
+
+        assertEquals(ScreenLifecycle.SCREEN_OFF, mScreen.getScreenState());
+        verify(mScreenObserverMock).onScreenTurnedOff();
+    }
+
+    @Test
+    public void dump() throws Exception {
+        mScreen.dump(null, new PrintWriter(new ByteArrayOutputStream()), new String[0]);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
new file mode 100644
index 0000000..e15e0b4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.keyguard;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class WakefulnessLifecycleTest extends SysuiTestCase {
+
+    private WakefulnessLifecycle mWakefulness;
+    private WakefulnessLifecycle.Observer mWakefulnessObserver;
+
+    @Before
+    public void setUp() throws Exception {
+        mWakefulness = new WakefulnessLifecycle();
+        mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
+        mWakefulness.addObserver(mWakefulnessObserver);
+    }
+
+    @Test
+    public void baseState() throws Exception {
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_ASLEEP, mWakefulness.getWakefulness());
+
+        verifyNoMoreInteractions(mWakefulnessObserver);
+    }
+
+    @Test
+    public void dispatchStartedWakingUp() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_WAKING, mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onStartedWakingUp();
+    }
+
+    @Test
+    public void dispatchFinishedWakingUp() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_AWAKE, mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onFinishedWakingUp();
+    }
+
+    @Test
+    public void dispatchStartedGoingToSleep() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+        mWakefulness.dispatchStartedGoingToSleep();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP,
+                mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onStartedGoingToSleep();
+    }
+
+    @Test
+    public void dispatchFinishedGoingToSleep() throws Exception {
+        mWakefulness.dispatchStartedWakingUp();
+        mWakefulness.dispatchFinishedWakingUp();
+        mWakefulness.dispatchStartedGoingToSleep();
+        mWakefulness.dispatchFinishedGoingToSleep();
+
+        assertEquals(WakefulnessLifecycle.WAKEFULNESS_ASLEEP,
+                mWakefulness.getWakefulness());
+
+        verify(mWakefulnessObserver).onFinishedGoingToSleep();
+    }
+
+    @Test
+    public void dump() throws Exception {
+        mWakefulness.dump(null, new PrintWriter(new ByteArrayOutputStream()), new String[0]);
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
index b8e9fcd..bba982c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
@@ -26,8 +26,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Uri;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -36,11 +34,10 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index eb59a34..1b74ebb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -51,8 +51,8 @@
     @Before
     public void setUp() throws Exception {
         // Test Instance.
-        mPowerNotificationWarnings = new PowerNotificationWarnings(
-                mContext, mMockNotificationManager, null);
+        mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
+        mPowerNotificationWarnings = new PowerNotificationWarnings(mContext);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
new file mode 100644
index 0000000..e4734a4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.power;
+
+import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_CURRENT;
+import static android.os.HardwarePropertiesManager.TEMPERATURE_SHUTDOWN;
+import static android.provider.Settings.Global.SHOW_TEMPERATURE_WARNING;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HardwarePropertiesManager;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestableResources;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.power.PowerUI.WarningsUI;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class PowerUITest extends SysuiTestCase {
+
+    private HardwarePropertiesManager mHardProps;
+    private WarningsUI mMockWarnings;
+    private PowerUI mPowerUI;
+
+    @Before
+    public void setup() {
+        mMockWarnings = mDependency.injectMockDependency(WarningsUI.class);
+        mHardProps = mock(HardwarePropertiesManager.class);
+        mContext.putComponent(StatusBar.class, mock(StatusBar.class));
+        mContext.addMockSystemService(Context.HARDWARE_PROPERTIES_SERVICE, mHardProps);
+
+        createPowerUi();
+    }
+
+    @Test
+    public void testNoConfig_NoWarnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_NoWarnings() {
+        setUnderThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testConfig_Warnings() {
+        setOverThreshold();
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testSettingOverrideConfig() {
+        setOverThreshold();
+        Settings.Global.putInt(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, 1);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 0);
+        resources.addOverride(R.integer.config_warningTemperature, 55);
+
+        mPowerUI.start();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    @Test
+    public void testShutdownBasedThreshold() {
+        int tolerance = 2;
+        Settings.Global.putString(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, null);
+        TestableResources resources = mContext.getOrCreateTestableResources();
+        resources.addOverride(R.integer.config_showTemperatureWarning, 1);
+        resources.addOverride(R.integer.config_warningTemperature, -1);
+        resources.addOverride(R.integer.config_warningTemperatureTolerance, tolerance);
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_SHUTDOWN))
+                .thenReturn(new float[] { 55 + tolerance });
+
+        setCurrentTemp(54); // Below threshold.
+        mPowerUI.start();
+        verify(mMockWarnings, never()).showHighTemperatureWarning();
+
+        setCurrentTemp(56); // Above threshold.
+        mPowerUI.updateTemperatureWarning();
+        verify(mMockWarnings).showHighTemperatureWarning();
+    }
+
+    private void setCurrentTemp(float temp) {
+        when(mHardProps.getDeviceTemperatures(DEVICE_TEMPERATURE_SKIN, TEMPERATURE_CURRENT))
+                .thenReturn(new float[] { temp });
+    }
+
+    private void setOverThreshold() {
+        setCurrentTemp(50000);
+    }
+
+    private void setUnderThreshold() {
+        setCurrentTemp(5);
+    }
+
+    private void createPowerUi() {
+        mPowerUI = new PowerUI();
+        mPowerUI.mContext = mContext;
+        mPowerUI.mComponents = mContext.getComponents();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
new file mode 100644
index 0000000..40f8059
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.qs;
+
+import static com.android.systemui.statusbar.phone.AutoTileManager.INVERSION;
+import static com.android.systemui.statusbar.phone.AutoTileManager.SAVER;
+import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.provider.Settings.Secure;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class AutoAddTrackerTest extends SysuiTestCase {
+
+    private AutoAddTracker mAutoTracker;
+
+    @Test
+    public void testMigration() {
+        Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
+        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+        assertTrue(mAutoTracker.isAdded(WORK));
+        assertFalse(mAutoTracker.isAdded(INVERSION));
+
+        assertFalse(Prefs.getBoolean(mContext, Key.QS_DATA_SAVER_ADDED, false));
+        assertFalse(Prefs.getBoolean(mContext, Key.QS_WORK_ADDED, false));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testChangeFromBackup() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+
+        Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES, SAVER);
+        mAutoTracker.mObserver.onChange(false);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testSetAdded() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+        mAutoTracker.setTileAdded(SAVER);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+    @Test
+    public void testPersist() {
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertFalse(mAutoTracker.isAdded(SAVER));
+        mAutoTracker.setTileAdded(SAVER);
+
+        mAutoTracker.destroy();
+        mAutoTracker = new AutoAddTracker(mContext);
+
+        assertTrue(mAutoTracker.isAdded(SAVER));
+
+        mAutoTracker.destroy();
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index d270de8..ed47fbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -23,8 +23,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import org.junit.After;
-import org.junit.Ignore;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -40,12 +38,14 @@
 import com.android.systemui.plugins.qs.DetailAdapter;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
+@Ignore("failing")
 public class QSDetailTest extends SysuiTestCase {
 
     private MetricsLogger mMetricsLogger;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
index 402b12d..d25bbe1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -41,6 +41,7 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
+@Ignore("failing")
 public class QSFooterTest extends LeakCheckedTest {
 
     private QSFooter mFooter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 0b7da1f..8cece92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -52,6 +52,7 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
+@Ignore("failing")
 public class QSFragmentTest extends SysuiBaseFragmentTest {
 
     private MetricsLogger mMockMetricsLogger;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index e5ff866..85cdfcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -30,7 +30,6 @@
 import com.android.systemui.qs.customize.QSCustomizer;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index ebd266b..a8487b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -16,12 +16,16 @@
 
 import static junit.framework.Assert.assertEquals;
 
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserManager;
+import android.provider.Settings;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
@@ -39,6 +43,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 /*
  * Compile and run the whole SystemUI test suite:
@@ -63,6 +68,7 @@
     private TestableImageView mFooterIcon;
     private QSSecurityFooter mFooter;
     private SecurityController mSecurityController = mock(SecurityController.class);
+    private UserManager mUserManager;
 
     @Before
     public void setUp() {
@@ -72,6 +78,8 @@
                 new LayoutInflaterBuilder(mContext)
                         .replace("ImageView", TestableImageView.class)
                         .build());
+        mUserManager = Mockito.mock(UserManager.class);
+        mContext.addMockSystemService(Context.USER_SERVICE, mUserManager);
         Handler h = new Handler(Looper.getMainLooper());
         h.post(() -> mFooter = new QSSecurityFooter(null, mContext));
         waitForIdleSync(h);
@@ -123,6 +131,21 @@
     }
 
     @Test
+    public void testManagedDemoMode() {
+        when(mSecurityController.isDeviceManaged()).thenReturn(true);
+        when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null);
+        final UserInfo mockUserInfo = Mockito.mock(UserInfo.class);
+        when(mockUserInfo.isDemo()).thenReturn(true);
+        when(mUserManager.getUserInfo(anyInt())).thenReturn(mockUserInfo);
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 1);
+
+        mFooter.refreshState();
+
+        waitForIdleSync(mFooter.mHandler);
+        assertEquals(View.GONE, mRootView.getVisibility());
+    }
+
+    @Test
     public void testNetworkLoggingEnabled() {
         when(mSecurityController.isDeviceManaged()).thenReturn(true);
         when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java
new file mode 100644
index 0000000..9fe3e10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.qs;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile.SlashState;
+import com.android.systemui.qs.tileimpl.SlashImageView;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class SlashImageViewTest extends SysuiTestCase {
+    private TestableSlashImageView mSlashView;
+
+    @Test
+    public void testSetNonNullSlashStateCreatesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+        mSlashView = new TestableSlashImageView(mContext);
+        assertTrue(mSlashView.getSlashDrawable() == null);
+
+        mSlashView.setState(mockState, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() != null);
+    }
+
+    @Test
+    public void testSetNullSlashStateRemovesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+        mSlashView = new TestableSlashImageView(mContext);
+        mSlashView.setState(mockState, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() != null);
+
+        mSlashView.setState(null, mockDrawable);
+
+        assertTrue(mSlashView.getSlashDrawable() == null);
+    }
+
+    @Test
+    public void testSetNullDrawableRemovesSlashDrawable() {
+        SlashState mockState = mock(SlashState.class);
+        Drawable mockDrawable = mock(Drawable.class);
+
+        mSlashView = new TestableSlashImageView(mContext);
+        mSlashView.setImageDrawable(mockDrawable);
+        mSlashView.setState(mockState, mockDrawable);
+        mSlashView.setImageDrawable(null);
+
+        assertTrue(mSlashView.getSlashDrawable() == null);
+    }
+
+    // Expose getSlashDrawable
+    private static class TestableSlashImageView extends SlashImageView {
+        TestableSlashImageView(Context c) {
+            super(c);
+        }
+
+        private SlashDrawable getSlashDrawable() {
+            return mSlash;
+        }
+    }
+}
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 ddd6615..c016a85 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,7 +54,7 @@
 
     @Before
     public void setUp() throws Exception {
-        TestableLooper.get(this).setAsMainLooper();
+        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/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 8cacb4b..9603207 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -269,9 +269,9 @@
     }
 
     @Test
-    public void testHandleSysnavKey() {
-        mCommandQueue.handleSystemNavigationKey(1);
+    public void testHandleSysKey() {
+        mCommandQueue.handleSystemKey(1);
         waitForIdleSync();
-        verify(mCallbacks).handleSystemNavigationKey(eq(1));
+        verify(mCallbacks).handleSystemKey(eq(1));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 2e547e1..2f6511c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -21,20 +21,16 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
 
-import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -102,4 +98,40 @@
         row.setDark(true, false, 0);
         verify(row).updateShelfIconColor();
     }
+
+    @Test
+    public void testAboveShelfChangedListenerCalled() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setHeadsUp(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+
+    @Test
+    public void testAboveShelfChangedListenerCalledPinned() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setPinned(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+
+    @Test
+    public void testAboveShelfChangedListenerCalledHeadsUpGoingAway() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setHeadsUpAnimatingAway(true);
+        verify(listener).onAboveShelfStateChanged(true);
+    }
+    @Test
+    public void testAboveShelfChangedListenerCalledWhenGoingBelow() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setHeadsUp(true);
+        AboveShelfChangedListener listener = mock(AboveShelfChangedListener.class);
+        row.setAboveShelfChangedListener(listener);
+        row.setAboveShelf(false);
+        verify(listener).onAboveShelfStateChanged(false);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 8dcc408..436849c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,27 +16,23 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
 import com.android.systemui.SysuiTestCase;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationContentViewTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index 917a9f5..6e59d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -16,10 +16,7 @@
 
 package com.android.systemui.statusbar;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.View;
@@ -32,7 +29,6 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 6380847..b6827ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -232,6 +232,17 @@
     }
 
     @Test
+    public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mContext.getString(R.string.notification_header_default_channel),
+                textView.getText());
+    }
+
+    @Test
     public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
             throws Exception {
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
@@ -332,6 +343,21 @@
     }
 
     @Test
+    public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn,
+                (View v, NotificationChannel c, int appUid) -> {
+                }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView settingsButton =
+                (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+        assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
+    }
+
+    @Test
     public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -502,6 +528,19 @@
     }
 
     @Test
+    public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, Collections.singleton(TEST_PACKAGE_NAME));
+        final TextView numChannelsView =
+                (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+        assertEquals(View.VISIBLE, numChannelsView.getVisibility());
+        assertEquals(mContext.getString(R.string.notification_unblockable_desc),
+                numChannelsView.getText());
+    }
+
+    @Test
     @UiThreadTest
     public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel()
             throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index e0d8042..2a2acab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -42,7 +42,7 @@
     @Test
     public void testAttachDetach() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null);
+        row.createMenu(null, null);
         ViewUtils.attachView(row.getMenuView());
         TestableLooper.get(this).processAllMessages();
         ViewUtils.detachView(row.getMenuView());
@@ -52,9 +52,15 @@
     @Test
     public void testRecreateMenu() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null);
+        row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
-        row.createMenu(null);
+        row.createMenu(null, null);
         assertTrue(row.getMenuView() != null);
     }
+
+    @Test
+    public void testResetUncreatedMenu() {
+        NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+        row.resetMenu();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index cb238dd..6e7477f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -24,12 +24,16 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.InstrumentationRegistry;
 import android.view.LayoutInflater;
+import android.widget.FrameLayout;
 import android.widget.RemoteViews;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.NotificationInflaterTest;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 /**
  * A helper class to create {@link ExpandableNotificationRow}
@@ -42,10 +46,12 @@
     private final NotificationGroupManager mGroupManager = new NotificationGroupManager();
     private ExpandableNotificationRow mRow;
     private InflationException mException;
+    private HeadsUpManager mHeadsUpManager;
 
     public NotificationTestHelper(Context context) {
         mContext = context;
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mHeadsUpManager = new HeadsUpManager(mContext, null, mGroupManager);
     }
 
     public ExpandableNotificationRow createRow() throws Exception {
@@ -73,6 +79,8 @@
         });
         ExpandableNotificationRow row = mRow;
         row.setGroupManager(mGroupManager);
+        row.setHeadsUpManager(mHeadsUpManager);
+        row.setAboveShelfChangedListener(aboveShelf -> {});
         UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
         StatusBarNotification sbn = new StatusBarNotification("com.android.systemui",
                 "com.android.systemui", mId++, null, 1000,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
new file mode 100644
index 0000000..4c3bf10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ScrimViewTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.statusbar;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+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.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;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+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);
+        assertEquals(drawable, mView.getDrawable());
+    }
+
+    @Test
+    public void testCreation_initialColor() {
+        GradientDrawable drawable = (GradientDrawable) mView.getDrawable();
+        ColorExtractor.GradientColors colors = mView.getColors();
+        assertEquals("Main color should be set upon creation",
+                drawable.getMainColor(), colors.getMainColor());
+        assertEquals("Secondary color should be set upon creation",
+                drawable.getSecondaryColor(), colors.getSecondaryColor());
+    }
+
+    @Test
+    public void testSetViewAlpha_propagatesToDrawable() {
+        float alpha = 0.5f;
+        mView.setViewAlpha(alpha);
+        assertEquals(mView.getViewAlpha(), alpha);
+    }
+
+    @Test
+    public void testOnDraw_ExcludeRectDrawable() {
+        mView.setExcludedArea(new Rect(10, 10, 20, 20));
+        Canvas canvas = mock(Canvas.class);
+        mView.onDraw(canvas);
+        // One time for each rect side
+        verify(canvas, times(4)).clipRect(anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void setTint_set() {
+        int tint = Color.BLUE;
+        mView.setTint(tint);
+        assertEquals(mView.getTint(), tint);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
new file mode 100644
index 0000000..1ee9b32
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.statusbar.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.widget.FrameLayout;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AboveShelfObserverTest extends SysuiTestCase {
+
+    private AboveShelfObserver mObserver;
+    private FrameLayout mHostLayout;
+    private NotificationTestHelper mNotificationTestHelper;
+    private AboveShelfObserver.HasViewAboveShelfChangedListener mListener;
+
+    @Before
+    public void setUp() throws Exception {
+        mNotificationTestHelper = new NotificationTestHelper(getContext());
+        mHostLayout = new FrameLayout(getContext());
+        mObserver = new AboveShelfObserver(mHostLayout);
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setAboveShelfChangedListener(mObserver);
+        mHostLayout.addView(row);
+        row = mNotificationTestHelper.createRow();
+        row.setAboveShelfChangedListener(mObserver);
+        mHostLayout.addView(row);
+        mListener = mock(AboveShelfObserver.HasViewAboveShelfChangedListener.class);
+    }
+
+    @Test
+    public void testObserverChangesWhenGoingAbove() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        mObserver.setListener(mListener);
+        row.setHeadsUp(true);
+        verify(mListener).onHasViewsAboveShelfChanged(true);
+    }
+
+    @Test
+    public void testObserverChangesWhenGoingBelow() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        row.setHeadsUp(true);
+        mObserver.setListener(mListener);
+        row.setHeadsUp(false);
+        verify(mListener).onHasViewsAboveShelfChanged(false);
+    }
+
+    @Test
+    public void testStaysAboveWhenOneGoesAway() {
+        ExpandableNotificationRow row = (ExpandableNotificationRow) mHostLayout.getChildAt(0);
+        row.setHeadsUp(true);
+        row = (ExpandableNotificationRow) mHostLayout.getChildAt(1);
+        row.setHeadsUp(true);
+        row.setHeadsUp(false);
+        Assert.assertTrue("There are still views above the shelf but removing one cleared it",
+                mObserver.hasViewsAboveShelf());
+    }
+}
+
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 3429d5c..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;
@@ -56,6 +55,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@FlakyTest
 public class NotificationInflaterTest extends SysuiTestCase {
 
     private NotificationInflater mNotificationInflater;
@@ -149,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/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
new file mode 100644
index 0000000..ed1491d3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class NearestTouchFrameTest extends SysuiTestCase {
+
+    private NearestTouchFrame mNearestTouchFrame;
+
+    @Before
+    public void setup() {
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 500;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+    }
+
+    @Test
+    public void testNoActionOnLargeDevices() {
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 700;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Left() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Right() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                18 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(right).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Top() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 12 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(top).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Bottom() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.onMeasure(0, 0);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 18 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(bottom).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    private View mockViewAt(int x, int y, int width, int height) {
+        View v = spy(new View(mContext));
+        doAnswer(invocation -> {
+            int[] pos = (int[]) invocation.getArguments()[0];
+            pos[0] = x;
+            pos[1] = y;
+            return null;
+        }).when(v).getLocationInWindow(any());
+        when(v.isClickable()).thenReturn(true);
+
+        // Stupid final methods.
+        v.setLeft(0);
+        v.setRight(width);
+        v.setTop(0);
+        v.setBottom(height);
+        return v;
+    }
+}
\ No newline at end of file
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 0e3ea7a..a706368 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
@@ -38,6 +38,8 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.Notification;
+import android.app.trust.TrustManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -55,6 +57,7 @@
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.DisplayMetrics;
+import android.view.ViewGroup.LayoutParams;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -62,8 +65,10 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 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;
@@ -75,6 +80,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 @SmallTest
@@ -99,6 +106,8 @@
 
     @Before
     public void setup() throws Exception {
+        mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
+        mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
         mUnlockMethodCache = mock(UnlockMethodCache.class);
         mKeyguardIndicationController = mock(KeyguardIndicationController.class);
@@ -108,6 +117,7 @@
         mNotificationData = mock(NotificationData.class);
         mSystemServicesProxy = mock(SystemServicesProxy.class);
         mNotificationPanelView = mock(NotificationPanelView.class);
+        when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
         mNotificationList = mock(ArrayList.class);
         IPowerManager powerManagerService = mock(IPowerManager.class);
         HandlerThread handlerThread = new HandlerThread("TestThread");
@@ -122,6 +132,7 @@
                 mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
                 mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView,
                 mBarService);
+        mStatusBar.mContext = mContext;
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
             onDismissAction.onDismiss();
@@ -147,6 +158,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);
@@ -318,6 +335,83 @@
     }
 
     @Test
+    public void testShouldPeek_suppressedScreenOn_dozing() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = true;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(true);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(false);
+
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+
+        assertTrue(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testShouldPeek_suppressedScreenOn_noDoze() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = false;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(true);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(false);
+
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        assertFalse(mStatusBar.shouldPeek(entry, sbn));
+    }
+    @Test
+    public void testShouldPeek_suppressedScreenOff_dozing() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = true;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(true);
+
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        assertFalse(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testShouldPeek_suppressedScreenOff_noDoze() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        mStatusBar.mDozing = false;
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOff(any())).thenReturn(true);
+
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        assertTrue(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+
+    @Test
     public void testLogHidden() {
         try {
             mStatusBar.handleVisibleToUserChanged(false);
@@ -385,6 +479,11 @@
         TestableLooper.get(this).processAllMessages();
     }
 
+    @Test
+    public void testDump_DoesNotCrash() {
+        mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
+    }
+
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
@@ -402,6 +501,14 @@
             mSystemServicesProxy = ssp;
             mNotificationPanel = panelView;
             mBarService = barService;
+            mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
+        }
+
+        private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
+            WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+            wakefulnessLifecycle.dispatchStartedWakingUp();
+            wakefulnessLifecycle.dispatchFinishedWakingUp();
+            return wakefulnessLifecycle;
         }
 
         public void setBarStateForTest(int state) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index cb20639..51bd7bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -18,6 +18,7 @@
 import android.os.HandlerThread;
 import android.support.test.runner.AndroidJUnit4;
 import android.telephony.SubscriptionInfo;
+import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
new file mode 100644
index 0000000..a915cb2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.statusbar.policy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.util.Log;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.OverlayPlugin;
+import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
+import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ExtensionControllerImplTest extends SysuiTestCase {
+
+    private PluginManager mPluginManager;
+    private TunerService mTunerService;
+    private ExtensionController mExtensionController;
+    private ConfigurationController mConfigurationController;
+
+    @Before
+    public void setup() {
+        mPluginManager = mDependency.injectMockDependency(PluginManager.class);
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+        mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class);
+        mExtensionController = Dependency.get(ExtensionController.class);
+    }
+
+    @Test
+    public void testPlugin() {
+        OverlayPlugin plugin = mock(OverlayPlugin.class);
+
+        Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
+                .withPlugin(OverlayPlugin.class)
+                .build();
+        ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+        verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), listener.capture(),
+                eq(OverlayPlugin.class));
+
+        listener.getValue().onPluginConnected(plugin, null);
+        assertEquals(plugin, ext.get());
+
+        ext.destroy();
+        verify(mPluginManager).removePluginListener(any());
+    }
+
+    @Test
+    public void testTuner() {
+        String[] keys = new String[] { "key1", "key2" };
+        TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
+            @Override
+            public String[] keys() {
+                return keys;
+            }
+
+            @Override
+            public Object create(Map settings) {
+                return null;
+            }
+        };
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withTunerFactory(factory)
+                .build();
+        verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
+
+        ext.destroy();
+        verify(mTunerService).removeTunable(any());
+    }
+
+    @Test
+    @RunWithLooper
+    public void testUiMode() {
+        Object o = new Object();
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> o)
+                .build();
+        ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
+                ConfigurationListener.class);
+        verify(mConfigurationController).addCallback(captor.capture());
+
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.uiMode = 0;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertNull(ext.get());
+
+        c.uiMode = Configuration.UI_MODE_TYPE_CAR;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertEquals(o, ext.get());
+
+        ext.destroy();
+        verify(mConfigurationController).removeCallback(eq(captor.getValue()));
+    }
+
+    @Test
+    public void testDefault() {
+        Object o = new Object();
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withDefault(() -> o)
+                .build();
+        assertEquals(o, ext.get());
+    }
+
+    @Test
+    @RunWithLooper
+    public void testSortOrder() {
+        Log.d("TestTest", "Config " + mContext.getResources().getConfiguration().uiMode);
+        Object def = new Object();
+        Object uiMode = new Object();
+        Object tuner = new Object();
+        Plugin plugin = mock(Plugin.class);
+        TunerFactory<Object> factory = mock(TunerFactory.class);
+        Extension ext = mExtensionController.newExtension(Object.class)
+                .withDefault(() -> def)
+                .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> uiMode)
+                .withTunerFactory(factory)
+                .withPlugin(Object.class, "some_action")
+                .build();
+
+        // Test default first.
+        assertEquals(def, ext.get());
+
+        // Enable a UI mode and check that.
+        ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
+                ConfigurationListener.class);
+        verify(mConfigurationController).addCallback(captor.capture());
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.uiMode |= Configuration.UI_MODE_TYPE_CAR;
+        captor.getValue().onConfigChanged(c);
+        TestableLooper.get(this).processAllMessages();
+        assertEquals(uiMode, ext.get());
+
+        // Turn on tuner item and check that.
+        when(factory.create(any())).thenReturn(tuner);
+        ArgumentCaptor<Tunable> tunable = ArgumentCaptor.forClass(Tunable.class);
+        verify(mTunerService).addTunable(tunable.capture(), any());
+        tunable.getValue().onTuningChanged(null, null);
+        assertEquals(tuner, ext.get());
+
+        // Lastly, check a plugin.
+        ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+        verify(mPluginManager).addPluginListener(any(), listener.capture(), any());
+        listener.getValue().onPluginConnected(plugin, null);
+        assertEquals(plugin, ext.get());
+    }
+
+    @Test
+    public void testCallback() {
+        Consumer<Object> callback = mock(Consumer.class);
+        final Object o = new Object();
+        mExtensionController.newExtension(Object.class)
+                .withDefault(() -> o)
+                .withCallback(callback)
+                .build();
+        verify(callback).accept(eq(o));
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java
deleted file mode 100644
index 3d79d5b..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerTest.java
+++ /dev/null
@@ -1,108 +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.
- */
-
-package com.android.systemui.statusbar.policy;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.support.test.filters.SmallTest;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.OverlayPlugin;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.statusbar.policy.ExtensionController.Extension;
-import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
-import com.android.systemui.tuner.TunerService;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Map;
-import java.util.function.Consumer;
-
-@SmallTest
-public class ExtensionControllerTest extends SysuiTestCase {
-
-    private PluginManager mPluginManager;
-    private TunerService mTunerService;
-    private ExtensionController mExtensionController;
-
-    @Before
-    public void setup() {
-        mPluginManager = mDependency.injectMockDependency(PluginManager.class);
-        mTunerService = mDependency.injectMockDependency(TunerService.class);
-        mExtensionController = Dependency.get(ExtensionController.class);
-    }
-
-    @Test
-    public void testPlugin() {
-        Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
-                .withPlugin(OverlayPlugin.class)
-                .build();
-        verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), any(),
-                eq(OverlayPlugin.class));
-
-        ext.destroy();
-        verify(mPluginManager).removePluginListener(any());
-    }
-
-    @Test
-    public void testTuner() {
-        String[] keys = new String[] { "key1", "key2" };
-        TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
-            @Override
-            public String[] keys() {
-                return keys;
-            }
-
-            @Override
-            public Object create(Map settings) {
-                return null;
-            }
-        };
-        Extension ext = mExtensionController.newExtension(Object.class)
-                .withTunerFactory(factory)
-                .build();
-        verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
-
-        ext.destroy();
-        verify(mTunerService).removeTunable(any());
-    }
-
-    @Test
-    public void testDefault() {
-        Object o = new Object();
-        Extension ext = mExtensionController.newExtension(Object.class)
-                .withDefault(() -> o)
-                .build();
-        assertEquals(o, ext.get());
-    }
-
-    @Test
-    public void testCallback() {
-        Consumer<Object> callback = mock(Consumer.class);
-        final Object o = new Object();
-        mExtensionController.newExtension(Object.class)
-                .withDefault(() -> o)
-                .withCallback(callback)
-                .build();
-        verify(callback).accept(eq(o));
-    }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 505e1d8..a8319a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -19,7 +19,6 @@
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
-import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.os.Looper;
 import android.telephony.PhoneStateListener;
@@ -84,7 +83,6 @@
     protected Config mConfig;
     protected CallbackHandler mCallbackHandler;
     protected SubscriptionDefaults mMockSubDefaults;
-    protected NetworkScoreManager mMockNetworkScoreManager;
     protected DeviceProvisionedController mMockProvisionController;
     protected DeviceProvisionedListener mUserCallback;
 
@@ -113,8 +111,6 @@
         mMockCm = mock(ConnectivityManager.class);
         mMockSubDefaults = mock(SubscriptionDefaults.class);
         mNetCapabilities = new NetworkCapabilities();
-        mMockNetworkScoreManager = mock(NetworkScoreManager.class);
-
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
         when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
                 new NetworkCapabilities[] { mNetCapabilities });
@@ -135,8 +131,7 @@
             return null;
         }).when(mMockProvisionController).addCallback(any());
 
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mMockProvisionController);
@@ -177,8 +172,8 @@
     protected NetworkControllerImpl setUpNoMobileData() {
       when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
       NetworkControllerImpl networkControllerNoMobile
-              = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
-                        mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
+              = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
+                        mConfig, mContext.getMainLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
                         mock(DataUsageController.class), mMockSubDefaults,
                         mock(DeviceProvisionedController.class));
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 dfe00f9..7708adb 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
@@ -21,6 +21,7 @@
 public class NetworkControllerDataTest extends NetworkControllerBaseTest {
 
     @Test
+    @Ignore("Flaky")
     public void test3gDataIcon() {
         setupDefaultSignal();
 
@@ -29,6 +30,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test2gDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -39,6 +41,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -49,6 +52,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEdgeDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -59,6 +63,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testLteDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -69,6 +74,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testHspaDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -79,6 +85,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testWfcNoDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -88,11 +95,11 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test4gDataIcon() {
         // Switch to showing 4g icon and re-initialize the NetworkController.
         mConfig.show4gForLte = true;
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class),
                 mock(DataUsageController.class), mMockSubDefaults,
@@ -107,8 +114,8 @@
                 TelephonyIcons.QS_DATA_4G);
     }
 
-    @Ignore("Flaky")
     @Test
+    @Ignore("Flaky")
     public void testDataDisabledIcon() {
         setupNetworkController();
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
@@ -121,6 +128,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
@@ -135,6 +143,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void test4gDataIconConfigChange() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -152,6 +161,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataChangeWithoutConnectionState() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -168,6 +178,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testDataActivity() {
         setupDefaultSignal();
 
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 1627925..9055022 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;
@@ -50,12 +51,12 @@
 public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
 
     @Test
+    @Ignore("Flaky")
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
         Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class));
@@ -65,6 +66,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoSimsIconPresent() {
         // No Subscriptions.
         mNetworkController.mMobileSignalControllers.clear();
@@ -74,6 +76,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEmergencyOnly() {
         setupDefaultSignal();
         mNetworkController.recalculateEmergency();
@@ -85,6 +88,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testEmergencyOnlyNoSubscriptions() {
         setupDefaultSignal();
         setSubscriptions();
@@ -95,6 +99,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoEmergencyOnlyWrongSubscription() {
         setupDefaultSignal();
         setDefaultSubId(42);
@@ -103,6 +108,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoEmengencyNoSubscriptions() {
         setupDefaultSignal();
         setSubscriptions();
@@ -113,12 +119,12 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
         Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager,
-                mMockTm, mMockWm, mMockSm,
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class));
@@ -132,6 +138,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSignalStrength() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -149,6 +156,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaSignalStrength() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -163,6 +171,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSignalRoaming() {
         for (int testStrength = 0;
                 testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
@@ -177,6 +186,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaSignalRoaming() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -192,6 +202,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testQsSignalStrength() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -205,6 +216,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCdmaQsSignalStrength() {
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
@@ -219,6 +231,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testNoBangWithWifi() {
         setupDefaultSignal();
         setConnectivity(mMobileSignalController.mTransportType, false, false);
@@ -230,6 +243,7 @@
     // Some tests of actual NetworkController code, just internals not display stuff
     // TODO: Put this somewhere else, maybe in its own file.
     @Test
+    @Ignore("Flaky")
     public void testHasCorrectMobileControllers() {
         int[] testSubscriptions = new int[] { 1, 5, 3 };
         int notTestSubscription = 0;
@@ -257,6 +271,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testSetCurrentSubscriptions() {
         // We will not add one controller to make sure it gets created.
         int indexToSkipController = 0;
@@ -310,6 +325,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testHistorySize() {
         // Verify valid history size, otherwise it gits printed out the wrong order and whatnot.
         assertEquals(0, SignalController.HISTORY_SIZE & (SignalController.HISTORY_SIZE - 1));
@@ -323,6 +339,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_spn() {
         String expectedMNetworkName = "Test";
         Intent intent = createStringsUpdatedIntent(true /* showSpn */,
@@ -336,6 +353,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_plmn() {
         String expectedMNetworkName = "Test";
 
@@ -350,6 +368,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothFalse() {
         Intent intent = createStringsUpdatedIntent(false /* showSpn */,
               "Irrelevant" /* spn */,
@@ -365,6 +384,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothTrueAndNull() {
         Intent intent = createStringsUpdatedIntent(true /* showSpn */,
             null /* spn */,
@@ -379,6 +399,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnReceive_stringsUpdatedAction_bothTrueAndNonNull() {
         String spn = "Test1";
         String plmn = "Test2";
@@ -413,6 +434,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataIn() {
         setupDefaultSignal();
 
@@ -427,6 +449,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataOut() {
       setupDefaultSignal();
 
@@ -440,6 +463,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataInOut() {
       setupDefaultSignal();
 
@@ -454,6 +478,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testOnUpdateDataActivity_dataActivityNone() {
       setupDefaultSignal();
 
@@ -468,6 +493,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testCarrierNetworkChange_carrierNetworkChange() {
       int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
 
@@ -496,6 +522,81 @@
               DEFAULT_ICON /* typeIcon */);
     }
 
+    @Test
+    @Ignore("Flaky")
+    public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+      setGsmRoaming(true);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
+    @Test
+    @Ignore("Flaky")
+    public void testCarrierNetworkChange_roamingAfterNetworkChange() {
+      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+      setupDefaultSignal();
+      setLevel(strength);
+
+      // Verify baseline
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              false /* roaming */);
+
+      // API call is made
+      setCarrierNetworkChange(true /* enabled */);
+
+      // Carrier network change is true, show special indicator, no roaming.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      setGsmRoaming(true);
+
+      // Roaming should not show.
+      verifyLastMobileDataIndicators(true /* visible */,
+              SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+              0 /* typeIcon */,
+              false /* roaming */);
+
+      // Revert back
+      setCarrierNetworkChange(false /* enabled */);
+
+      // Verify back in previous state
+      verifyLastMobileDataIndicators(true /* visible */,
+              strength /* strengthIcon */,
+              DEFAULT_ICON /* typeIcon */,
+              true /* roaming */);
+    }
+
     private void verifyEmergencyOnly(boolean isEmergencyOnly) {
         ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index dbaa2c5..ffd0165 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -1,47 +1,24 @@
 package com.android.systemui.statusbar.policy;
 
 import android.content.Intent;
-import android.net.NetworkBadging;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
-import android.net.NetworkKey;
-import android.net.RssiCurve;
-import android.net.ScoredNetwork;
-import android.net.WifiKey;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiNetworkScoreCache;
-import android.os.Bundle;
-import android.provider.Settings;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -50,13 +27,6 @@
     private static final int MIN_RSSI = -100;
     private static final int MAX_RSSI = -55;
 
-    private static final int LATCH_TIMEOUT = 2000;
-    private static final String TEST_SSID = "\"Test SSID\"";
-    private static final String TEST_BSSID = "00:00:00:00:00:00";
-
-    private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
-    private CountDownLatch mRequestScoresLatch;
-
     @Test
     public void testWifiIcon() {
         String testSsid = "Test SSID";
@@ -77,79 +47,6 @@
     }
 
     @Test
-    public void testBadgedWifiIcon() throws Exception {
-        // TODO(sghuman): Refactor this setup code when creating a test for the badged QsIcon.
-        int testLevel = 1;
-        RssiCurve mockBadgeCurve = mock(RssiCurve.class);
-        Bundle attr = new Bundle();
-        attr.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
-        ScoredNetwork score =
-                new ScoredNetwork(
-                        new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)),
-                        null,
-                        false /* meteredHint */,
-                        attr);
-
-        // Must set the Settings value before instantiating the NetworkControllerImpl due to bugs in
-        // TestableSettingsProvider.
-        Settings.Global.putString(mContext.getContentResolver(),
-                Settings.Global.NETWORK_SCORING_UI_ENABLED,
-                "1");
-        super.setUp(); // re-instantiate NetworkControllImpl now that setting has been updated
-        setupNetworkScoreManager();
-
-        // Test Requesting Scores
-        mRequestScoresLatch = new CountDownLatch(1);
-        setWifiEnabled(true);
-        setWifiState(true, TEST_SSID, TEST_BSSID);
-        mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
-
-        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) NetworkBadging.BADGING_SD);
-
-        ArgumentCaptor<WifiNetworkScoreCache> scoreCacheCaptor =
-                ArgumentCaptor.forClass(WifiNetworkScoreCache.class);
-        verify(mMockNetworkScoreManager).registerNetworkScoreCache(
-                anyInt(),
-                scoreCacheCaptor.capture(),
-                Matchers.anyInt());
-        scoreCacheCaptor.getValue().updateScores(Arrays.asList(score));
-
-        //  Test badge is set
-        setWifiLevel(testLevel);
-
-        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
-        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
-                anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
-                any(), anyBoolean());
-        IconState iconState = iconArg.getValue();
-
-        assertEquals("Badged Wifi Resource is set",
-                Utils.WIFI_PIE_FOR_BADGING[testLevel],
-                iconState.icon);
-        assertEquals("SD Badge is set",
-                Utils.getWifiBadgeResource(NetworkBadging.BADGING_SD),
-                iconState.iconOverlay);
-    }
-
-    private void setupNetworkScoreManager() {
-        // Capture requested keys and count down latch if present
-        doAnswer(
-                new Answer<Boolean>() {
-                    @Override
-                    public Boolean answer(InvocationOnMock input) {
-                        if (mRequestScoresLatch != null) {
-                            mRequestScoresLatch.countDown();
-                        }
-                        NetworkKey[] keys = (NetworkKey[]) input.getArguments()[0];
-                        for (NetworkKey key : keys) {
-                            mRequestedKeys.add(key);
-                        }
-                        return true;
-                    }
-                }).when(mMockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
-    }
-
-    @Test
     public void testQsWifiIcon() {
         String testSsid = "Test SSID";
 
@@ -200,7 +97,7 @@
     @Test
     public void testRoamingIconDuringWifi() {
         // Setup normal connection
-        String testSsid = "\"Test SSID\"";
+        String testSsid = "Test SSID";
         int testLevel = 2;
         setWifiEnabled(true);
         setWifiState(true, testSsid);
@@ -241,19 +138,12 @@
     }
 
     protected void setWifiState(boolean connected, String ssid) {
-        setWifiState(connected, ssid, null);
-    }
-
-    protected void setWifiState(boolean connected, String ssid, String bssid) {
         Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
         Mockito.when(networkInfo.isConnected()).thenReturn(connected);
 
         WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
         Mockito.when(wifiInfo.getSSID()).thenReturn(ssid);
-        if (bssid != null) {
-            Mockito.when(wifiInfo.getBSSID()).thenReturn(bssid);
-        }
 
         i.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
         i.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
@@ -278,7 +168,7 @@
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
                 enabledArg.capture(), any(), iconArg.capture(), anyBoolean(),
-                anyBoolean(),  descArg.capture(), anyBoolean());
+                anyBoolean(), descArg.capture(), anyBoolean());
         IconState iconState = iconArg.getValue();
         assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
         assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index ae0509a..7ca9d73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.doThrow;
@@ -29,7 +30,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.StringParceledListSlice;
+import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
+import android.os.UserManager;
 import android.security.IKeyChainService;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -55,6 +58,7 @@
 public class SecurityControllerTest extends SysuiTestCase implements SecurityControllerCallback {
     private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
     private final IKeyChainService.Stub mKeyChainService = mock(IKeyChainService.Stub.class);
+    private final UserManager mUserManager = mock(UserManager.class);
     private SecurityControllerImpl mSecurityController;
     private CountDownLatch mStateChangedLatch;
 
@@ -67,12 +71,15 @@
     @Before
     public void setUp() throws Exception {
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+        mContext.addMockSystemService(Context.USER_SERVICE, mUserManager);
         mContext.addMockSystemService(Context.CONNECTIVITY_SERVICE, mock(ConnectivityManager.class));
 
         Intent intent = new Intent(IKeyChainService.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         mContext.addMockService(comp, mKeyChainService);
 
+        when(mUserManager.getUserInfo(anyInt())).thenReturn(new UserInfo());
+
         when(mKeyChainService.getUserCaAliases())
                 .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
         // Without this line, mKeyChainService gets wrapped in a proxy when Stub.asInterface() is
@@ -80,12 +87,10 @@
         when(mKeyChainService.queryLocalInterface("android.security.IKeyChainService"))
                 .thenReturn(mKeyChainService);
 
-        mSecurityController = new SecurityControllerImpl(mContext);
-
-        // Wait for one or two state changes from the CACertLoader(s) in the constructor of
-        // mSecurityController
-        mStateChangedLatch = new CountDownLatch(mSecurityController.hasWorkProfile() ? 2 : 1);
-        mSecurityController.addCallback(this);
+        // Wait for callbacks from 1) the CACertLoader and 2) the onUserSwitched() function in the
+        // constructor of mSecurityController
+        mStateChangedLatch = new CountDownLatch(2);
+        mSecurityController = new SecurityControllerImpl(mContext, this);
     }
 
     @After
@@ -109,13 +114,40 @@
     }
 
     @Test
-    @Ignore("Flaky")
-    public void testCaCertLoader() throws Exception {
+    public void testWorkAccount() throws Exception {
+        // Wait for the callbacks from setUp()
+        assertTrue(mStateChangedLatch.await(1, TimeUnit.SECONDS));
+        assertFalse(mSecurityController.hasCACertInCurrentUser());
+
+        final int PRIMARY_USER_ID = 0;
+        final int MANAGED_USER_ID = 1;
+        List<UserInfo> profiles = Arrays.asList(new UserInfo(PRIMARY_USER_ID, "Primary",
+                                                             UserInfo.FLAG_PRIMARY),
+                                                new UserInfo(MANAGED_USER_ID, "Working",
+                                                             UserInfo.FLAG_MANAGED_PROFILE));
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+        assertTrue(mSecurityController.hasWorkProfile());
+        assertFalse(mSecurityController.hasCACertInWorkProfile());
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(Arrays.asList("One CA Alias")));
+
+        mSecurityController.new CACertLoader()
+                           .execute(MANAGED_USER_ID);
+
         assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInWorkProfile());
+    }
+
+    @Test
+    public void testCaCertLoader() throws Exception {
+        // Wait for the callbacks from setUp()
+        assertTrue(mStateChangedLatch.await(1, TimeUnit.SECONDS));
         assertFalse(mSecurityController.hasCACertInCurrentUser());
 
         // With a CA cert
-
         mStateChangedLatch = new CountDownLatch(1);
 
         when(mKeyChainService.getUserCaAliases())
@@ -138,7 +170,7 @@
         mSecurityController.new CACertLoader()
                            .execute(0);
 
-        assertFalse(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertFalse(mStateChangedLatch.await(1, TimeUnit.SECONDS));
         assertTrue(mSecurityController.hasCACertInCurrentUser());
         // The retry takes 30s
         //assertTrue(mStateChangedLatch.await(31, TimeUnit.SECONDS));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index 2dd96b6..5ac965c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.stack;
 
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.NotificationHeaderView;
@@ -31,7 +27,6 @@
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
new file mode 100644
index 0000000..9fd8cc3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.tuner;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.support.test.filters.SmallTest;
+import android.testing.LeakCheck.Tracker;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class TunablePaddingTest extends LeakCheckedTest {
+
+    private static final String KEY = "KEY";
+    private static final int DEFAULT = 42;
+    private View mView;
+    private TunablePadding mTunablePadding;
+    private TunerService mTunerService;
+
+    @Before
+    public void setup() {
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mView = mock(View.class, withSettings().spiedInstance(new View(mContext)));
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+        Tracker tracker = mLeakCheck.getTracker("tuner");
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable());
+            return null;
+        }).when(mTunerService).addTunable(any(), any());
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).clearAllocations();
+            return null;
+        }).when(mTunerService).removeTunable(any());
+    }
+
+    @Test
+    public void testFlags() {
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_TOP);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(DEFAULT), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_BOTTOM);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(0), eq(DEFAULT));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testRtl() {
+        when(mView.isLayoutRtl()).thenReturn(true);
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testTuning() {
+        int value = 3;
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(KEY, String.valueOf(value));
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class).getDefaultDisplay().getMetrics(metrics);
+        int output = (int) (metrics.density * value);
+        verify(mView).setPadding(eq(output), eq(0), eq(0), eq(0));
+
+        mTunablePadding.destroy();
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
new file mode 100644
index 0000000..469bdc0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.utils.hardware.FakeSensorManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class AsyncSensorManagerTest extends SysuiTestCase {
+
+    private TestableAsyncSensorManager mAsyncSensorManager;
+    private FakeSensorManager mFakeSensorManager;
+    private SensorEventListener mListener;
+    private FakeSensorManager.MockProximitySensor mSensor;
+
+    @Before
+    public void setUp() throws Exception {
+        mFakeSensorManager = new FakeSensorManager(mContext);
+        mAsyncSensorManager = new TestableAsyncSensorManager(mFakeSensorManager);
+        mSensor = mFakeSensorManager.getMockProximitySensor();
+        mListener = mock(SensorEventListener.class);
+    }
+
+    @Test
+    public void registerListenerImpl() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was registered.
+        mSensor.sendProximityResult(true);
+        verify(mListener).onSensorChanged(any());
+    }
+
+    @Test
+    public void unregisterListenerImpl_withNullSensor() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+        mAsyncSensorManager.unregisterListener(mListener);
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was unregistered.
+        mSensor.sendProximityResult(true);
+        verifyNoMoreInteractions(mListener);
+    }
+
+    @Test
+    public void unregisterListenerImpl_withSensor() throws Exception {
+        mAsyncSensorManager.registerListener(mListener, mSensor.getSensor(), 100);
+        mAsyncSensorManager.unregisterListener(mListener, mSensor.getSensor());
+
+        mAsyncSensorManager.waitUntilRequestsCompleted();
+
+        // Verify listener was unregistered.
+        mSensor.sendProximityResult(true);
+        verifyNoMoreInteractions(mListener);
+    }
+
+    private class TestableAsyncSensorManager extends AsyncSensorManager {
+        public TestableAsyncSensorManager(SensorManager sensorManager) {
+            super(sensorManager);
+        }
+
+        public void waitUntilRequestsCompleted() {
+            assertTrue(mHandler.runWithScissors(() -> {}, 0));
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index 30be665..a4ae166 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -30,13 +30,15 @@
 import android.os.SystemClock;
 import android.util.ArraySet;
 
-import com.google.android.collect.Lists;
+import com.android.internal.util.Preconditions;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Rudimentary fake for SensorManager
@@ -49,6 +51,8 @@
 public class FakeSensorManager extends SensorManager {
 
     private final MockProximitySensor mMockProximitySensor;
+    private final FakeGenericSensor mFakeLightSensor;
+    private final FakeGenericSensor[] mSensors;
 
     public FakeSensorManager(Context context) throws Exception {
         Sensor proxSensor = context.getSystemService(SensorManager.class)
@@ -57,13 +61,21 @@
             // No prox? Let's create a fake one!
             proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
         }
-        mMockProximitySensor = new MockProximitySensor(proxSensor);
+
+        mSensors = new FakeGenericSensor[]{
+                mMockProximitySensor = new MockProximitySensor(proxSensor),
+                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT)),
+        };
     }
 
     public MockProximitySensor getMockProximitySensor() {
         return mMockProximitySensor;
     }
 
+    public FakeGenericSensor getFakeLightSensor() {
+        return mFakeLightSensor;
+    }
+
     @Override
     public Sensor getDefaultSensor(int type) {
         Sensor s = super.getDefaultSensor(type);
@@ -77,7 +89,10 @@
 
     @Override
     protected List<Sensor> getFullSensorList() {
-        return Lists.newArrayList(mMockProximitySensor.sensor);
+        return Arrays
+                .stream(mSensors)
+                .map(i -> i.mSensor)
+                .collect(Collectors.toList());
     }
 
     @Override
@@ -87,8 +102,11 @@
 
     @Override
     protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
-        if (sensor == mMockProximitySensor.sensor || sensor == null) {
-            mMockProximitySensor.listeners.remove(listener);
+        Preconditions.checkNotNull(listener);
+        for (FakeGenericSensor s : mSensors) {
+            if (sensor == null || s.mSensor == sensor) {
+                s.mListeners.remove(listener);
+            }
         }
     }
 
@@ -96,9 +114,13 @@
     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
             int delayUs,
             Handler handler, int maxReportLatencyUs, int reservedFlags) {
-        if (sensor == mMockProximitySensor.sensor) {
-            mMockProximitySensor.listeners.add(listener);
-            return true;
+        Preconditions.checkNotNull(sensor);
+        Preconditions.checkNotNull(listener);
+        for (FakeGenericSensor s : mSensors) {
+            if (s.mSensor == sensor) {
+                s.mListeners.add(listener);
+                return true;
+            }
         }
         return false;
     }
@@ -196,18 +218,35 @@
         setter.invoke(sensor, type);
     }
 
-    public class MockProximitySensor {
-        final Sensor sensor;
-        final ArraySet<SensorEventListener> listeners = new ArraySet<>();
+    public class MockProximitySensor extends FakeGenericSensor {
 
         private MockProximitySensor(Sensor sensor) {
-            this.sensor = sensor;
+            super(sensor);
         }
 
         public void sendProximityResult(boolean far) {
-            SensorEvent event = createSensorEvent(1);
-            event.values[0] = far ? sensor.getMaximumRange() : 0;
-            for (SensorEventListener listener : listeners) {
+            sendSensorEvent(far ? getSensor().getMaximumRange() : 0);
+        }
+    }
+
+    public class FakeGenericSensor {
+
+        private final Sensor mSensor;
+        private final ArraySet<SensorEventListener> mListeners = new ArraySet<>();
+
+        public FakeGenericSensor(
+                Sensor sensor) {
+            this.mSensor = sensor;
+        }
+
+        public Sensor getSensor() {
+            return mSensor;
+        }
+
+        public void sendSensorEvent(float... values) {
+            SensorEvent event = createSensorEvent(values.length);
+            System.arraycopy(values, 0, event.values, 0, values.length);
+            for (SensorEventListener listener : mListeners) {
                 listener.onSensorChanged(event);
             }
         }
@@ -222,7 +261,7 @@
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
-            event.sensor = sensor;
+            event.sensor = mSensor;
             event.timestamp = SystemClock.elapsedRealtimeNanos();
 
             return event;
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/FakeExtensionController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
index 00846dc..586a424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeExtensionController.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui.utils.leaks;
 
+import android.content.Context;
 import android.testing.LeakCheck;
 import android.testing.LeakCheck.Tracker;
 
@@ -75,6 +76,11 @@
         }
 
         @Override
+        public ExtensionBuilder<T> withUiMode(int mode, Supplier<T> def) {
+            return null;
+        }
+
+        @Override
         public Extension build() {
             return new FakeExtension(mAllocation);
         }
@@ -94,11 +100,24 @@
         }
 
         @Override
+        public void clearItem(boolean isDestroyed) {
+
+        }
+
+        @Override
+        public Context getContext() {
+            return null;
+        }
+
+        @Override
         public void destroy() {
             mTracker.getLeakInfo(mAllocation).clearAllocations();
         }
 
         @Override
+        public void addCallback(Consumer<T> callback) {
+        }
+
         public T reload() {
             return null;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
index 51e35cc..3f952c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
@@ -47,6 +47,11 @@
     }
 
     @Override
+    public boolean isOccluded() {
+        return false;
+    }
+
+    @Override
     public boolean isKeyguardFadingAway() {
         return false;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
index 0a83a89..d1b1c5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -14,7 +14,6 @@
 
 package com.android.systemui.utils.leaks;
 
-import android.content.Context;
 import android.testing.LeakCheck;
 
 import com.android.systemui.plugins.Plugin;
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/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
new file mode 100644
index 0000000..06568f7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.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 com.android.systemui.volume;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.session.MediaSession;
+import android.support.test.filters.SmallTest;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class VolumeDialogControllerImplTest extends SysuiTestCase {
+
+    TestableVolumeDialogControllerImpl mVolumeController;
+    VolumeDialogControllerImpl.C mCallback;
+    StatusBar mStatusBar;
+
+    @Before
+    public void setup() throws Exception {
+        mCallback = mock(VolumeDialogControllerImpl.C.class);
+        mStatusBar = mock(StatusBar.class);
+        mVolumeController = new TestableVolumeDialogControllerImpl(mContext, mCallback, mStatusBar);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceNotInteractiveAOD() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(false);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, never()).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceInteractive() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(true);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testVolumeChangeW_deviceInteractive_StartedSleeping() {
+        when(mStatusBar.isDeviceInteractive()).thenReturn(true);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        when(mStatusBar.isDeviceInteractive()).thenReturn(false);
+        when(mStatusBar.getWakefulnessState()).thenReturn(WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP);
+        mVolumeController.onVolumeChangedW(0, AudioManager.FLAG_SHOW_UI);
+        verify(mCallback, times(1)).onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
+    }
+
+    @Test
+    public void testOnRemoteVolumeChanged_newStream_noNullPointer() {
+        MediaSession.Token token = new MediaSession.Token(null);
+        mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0);
+    }
+
+    @Test
+    public void testOnRemoteRemove_newStream_noNullPointer() {
+        MediaSession.Token token = new MediaSession.Token(null);
+        mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(token);
+    }
+
+    static class TestableVolumeDialogControllerImpl extends VolumeDialogControllerImpl {
+        public TestableVolumeDialogControllerImpl(Context context, C callback, StatusBar s) {
+            super(context);
+            mCallbacks = callback;
+            mStatusBar = s;
+        }
+    }
+
+}
diff --git a/packages/VpnDialogs/res/values-ar/strings.xml b/packages/VpnDialogs/res/values-ar/strings.xml
index e36eef4..d29c407 100644
--- a/packages/VpnDialogs/res/values-ar/strings.xml
+++ b/packages/VpnDialogs/res/values-ar/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"طلب الاتصال"</string>
-    <string name="warning" msgid="809658604548412033">"‏يريد <xliff:g id="APP">%s</xliff:g> إعداد الاتصال بالشبكة الافتراضية الخاصة التي تتيح له مراقبة حركة المرور على الشبكة. فلا توافق إلا إذا كنت تثق في المصدر. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; يظهر في الجزء العلوي من الشاشة عندما تكون الشبكة الافتراضية الخاصة نشطة."</string>
+    <string name="warning" msgid="809658604548412033">"‏يريد <xliff:g id="APP">%s</xliff:g> إعداد الاتصال بالشبكة الظاهرية الخاصة التي تتيح له مراقبة حركة المرور على الشبكة. فلا توافق إلا إذا كنت تثق في المصدر. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; يظهر في الجزء العلوي من الشاشة عندما تكون الشبكة الظاهرية الخاصة نشطة."</string>
     <string name="legacy_title" msgid="192936250066580964">"‏VPN متصلة"</string>
     <string name="configure" msgid="4905518375574791375">"تهيئة"</string>
     <string name="disconnect" msgid="971412338304200056">"قطع الاتصال"</string>
diff --git a/packages/overlays/SysuiDarkThemeOverlay/Android.mk b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
new file mode 100644
index 0000000..4b83058
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := SysuiDarkTheme
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := SysuiDarkThemeOverlay
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..8b6ee2b
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.systemui.theme.dark"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="com.android.systemui" android:priority="1"/>
+
+    <application android:label="@string/sysui_overlay_dark" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml b/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml
new file mode 100644
index 0000000..71f48d6
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <string name="sysui_overlay_dark">Dark</string>
+
+</resources>
+
diff --git a/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
new file mode 100644
index 0000000..0c1b0ef
--- /dev/null
+++ b/packages/overlays/SysuiDarkThemeOverlay/res/values/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="qs_base" parent="android:Theme.DeviceDefault">
+        <item name="android:colorPrimary">@*android:color/primary_device_default_settings</item>
+        <item name="android:colorPrimaryDark">@*android:color/primary_dark_device_default_settings</item>
+        <item name="android:colorSecondary">@*android:color/secondary_device_default_settings</item>
+        <item name="android:colorAccent">@*android:color/accent_device_default_dark</item>
+        <item name="android:colorControlNormal">?android:attr/textColorPrimary</item>
+        <item name="android:colorBackgroundFloating">#000</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto
new file mode 100644
index 0000000..c54ddad
--- /dev/null
+++ b/proto/src/gnss.proto
@@ -0,0 +1,45 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+// Author: siddharthr@google.com (Siddharth Ray)
+// Protos for uploading GNSS metrics.
+
+syntax = "proto2";
+
+package clearcut.connectivity;
+
+option java_package = "com.android.internal.location";
+option java_outer_classname = "GnssLogsProto";
+
+message GnssLog {
+  // Number of location reports processed
+  optional int32 num_location_report_processed = 1;
+
+  // Location failure (in percent)
+  optional int32 percentage_location_failure = 2;
+
+  // Number of time to first fix processed
+  optional int32 num_time_to_first_fix_processed = 3;
+
+  // Mean time to first fix (in seconds)
+  optional int32 mean_time_to_first_fix_secs = 4;
+
+  // Standard deviation of time to first fix (in seconds)
+  optional int32 standard_deviation_time_to_first_fix_secs = 5;
+
+  // Number of position accuracy processed
+  optional int32 num_position_accuracy_processed = 6;
+
+  // Mean position accuracy (in meters)
+  optional int32 mean_position_accuracy_meters = 7;
+
+  // Standard deviation of position accuracy (in meters)
+  optional int32 standard_deviation_position_accuracy_meters = 8;
+
+  // Number of top 4 average CN0 processed
+  optional int32 num_top_four_average_cn0_processed = 9;
+
+  // Mean of top 4 average CN0 (dB-Hz)
+  optional double mean_top_four_average_cn0_db_hz = 10;
+
+  // Standard deviation of top 4 average CN0 (dB-Hz)
+  optional double standard_deviation_top_four_average_cn0_db_hz = 11;
+}
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index dd84d84..a4849fc 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -138,6 +138,18 @@
     REASON_TIMEOUT = 19;
   }
 
+  // Subtypes of camera events for ACTION_CAMERA_EVENT
+  enum CameraEvent {
+    // A back-facing camera was used
+    CAMERA_BACK_USED = 0;
+
+    // A front-facing camera was used
+    CAMERA_FRONT_USED = 1;
+
+    // An external camera was used
+    CAMERA_EXTERNAL_USED = 2;
+  }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -3974,6 +3986,81 @@
 
     // ---- End O Constants, all O constants go above this line ----
 
+    // OPEN: Settings > System > Languages & input > Advanced > Lift to open camera
+    SETTINGS_GESTURE_CAMERA_LIFT_TRIGGER = 986;
+
+    // OPEN: Settings > Battery > High Usage > Abnormal app page
+    // CATEGORY: SETTINGS
+    FUELGAUGE_ANOMALY_DETAIL = 987;
+
+    // OPEN: Settings > Battery > High Usage
+    DIALOG_HANDLE_ANOMALY = 988;
+
+    // ACTION: Camera lift gesture
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    ACTION_CAMERA_LIFT_TRIGGER = 989;
+
+    // OPEN: Choose screen lock dialog in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_CHOOSE_LOCK_DIALOG = 990;
+
+    // OPEN: Assist Gesture training intro in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991;
+
+    // OPEN: Assist Gesture training enrolling in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992;
+
+    // OPEN: Assist Gesture training finished in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993;
+
+    // FIELD: The numeric preference value (of type long) when it is changed in Settings
+    FIELD_SETTINGS_PREFERENCE_CHANGE_LONG_VALUE = 994;
+
+    // FIELD: The numeric preference value (of type float) when it is changed in Settings
+    FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE = 995;
+
+    // OPEN: Settings > System > Languages & input > Assist gesture
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE = 996;
+
+    // ACTION: Assist gesture released without triggering
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_RELEASED = 997;
+
+    // ACTION: Assist gesture primed
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_PRIMED = 998;
+
+    // ACTION: Assist gesture triggered
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O DR
+    ASSIST_GESTURE_TRIGGERED = 999;
+
+    // ACTION: Update default app from Settings
+    ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000;
+
+    // FIELD - Query length when Settings search result is clicked
+    FIELD_SETTINGS_SERACH_QUERY_LENGTH = 1001;
+
+    // FIELD - Number of results when Settings search result is clicked
+    FIELD_SETTINGS_SERACH_RESULT_COUNT = 1002;
+
+    // OPEN: Settings > Display > Ambient Display
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    AMBIENT_DISPLAY_SETTINGS = 1003;
+
     // ACTION: CaptivePortalLoginActivity starts
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: O DR
@@ -3999,11 +4086,141 @@
     // OS: O DR
     ACTION_WIFI_SIGNIN = 1008;
 
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    BLUETOOTH_DEVICE_DETAILS = 1009;
+
+    // OPEN: Settings > credential pages - prompt for key guard configuration confirmation
+    CONFIGURE_KEYGUARD_DIALOG = 1010;
+
+    // Open: Settings > Search > No Result View
+    SETTINGS_SEARCH_NO_RESULT = 1011;
+
+    // OPEN: Assist Gesture before training
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_ASSIST_GESTURE_FIRST_TIME = 1012;
+
     // CaptivePortalLoginActivity displays SSL error page
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: O DR
     CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR = 1013;
 
+    // OPEN: Settings > Network > Tether > Wi-Fi hotspot
+    WIFI_TETHER_SETTINGS = 1014;
+
+    // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device)
+    // -> Edit name button.
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015;
+
+    // ACTION: Settings > Notification Settings > Open application notification
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016;
+
+    // ACTION: Settings > App Info > Open app settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_OPEN_APP_SETTING = 1017;
+
+    // OPEN: Settings > Connected devices > Bluetooth > Pair new device
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    BLUETOOTH_PAIRING = 1018;
+
+    // ACTION: Collect PSD Signals
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_PSD_LOADER = 1019;
+
+    // ACTION: Background check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_BACKGROUND_CHECK = 1020;
+
+    // ACTION: Location check action on an app
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    ACTION_APP_LOCATION_CHECK = 1021;
+
+    // Device headset status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is DON, 2 is DOFF
+    // OS: O DR
+    ACTION_HEADSET_STATUS = 1022;
+
+    // Device Headset Plug status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is AC power, 2 is USB power, 3 is Unplug
+    // OS: O DR
+    ACTION_HEADSET_PLUG = 1023;
+
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_PLUG_BATTERY_PERCENTAGE = 1024;
+
+    // Device Headset battery level on Plug
+    // CATEGORY: OTHER
+    // FIELD - The battery percentage when the user decided to plug in
+    // Type: integer
+    // OS: O DR
+    FIELD_UNPLUG_BATTERY_PERCENTAGE = 1025;
+
+    // Device Headset Pose status
+    // CATEGORY: OTHER
+    //  SUBTYPE: 1 is 6DOF, 2 is 3DOF
+    // OS: O DR
+    ACTION_HEADSET_POSE_STATUS = 1026;
+
+    // Device Headset Usage session time
+    // CATEGORY: OTHER
+    // FIELD - The time the headset was used in a session
+    // OS: O DR
+    FIELD_SESSION_TIME_MS = 1027;
+
+    // Device Headset Idle time
+    // CATEGORY: OTHER
+    // FIELD - The time in between each session
+    // OS: O DR
+    FIELD_TIME_ELAPSED_BETWEEN_SESSION_MS = 1028;
+
+    // Device Headset charge session time
+    // CATEGORY: OTHER
+    // FIELD - The time taken for each charge
+    // OS: O DR
+    FIELD_TIME_OF_CHARGE_MS = 1029;
+
+    // Device Headset time between charge
+    // CATEGORY: OTHER
+    // FIELD - The time in between each charge
+    // 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;
+
+    // An event from the camera service
+    // CATEGORY: OTHER
+    //  SUBTYPE: CameraEvent
+    // OS: O DR
+    ACTION_CAMERA_EVENT = 1032;
+
+    // OPEN: Settings > Trampoline Intent > Settings page
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    TRAMPOLINE_SETTINGS_EVENT = 1033;
+
+    // ---- End O-DR1 Constants, all O-DR1 constants go above this line ----
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 2f6b7e6..52f721b 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -180,6 +180,13 @@
     // Package: android
     NOTE_FOREGROUND_SERVICES = 40;
 
+    // Inform the user that the connected audio accessory is not supported
+    NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED = 41;
+
+    // Inform the user that a wrong password was detected while attempting to connect
+    // to a Wi-Fi network
+    NOTE_WIFI_WRONG_PASSWORD = 42;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
@@ -216,6 +223,10 @@
     // Package: com.android.systemui
     NOTE_TV_PIP = 1100;
 
+    // Notify the user that open Wi-Fi networks are available.
+    // Package: android
+    NOTE_NETWORK_AVAILABLE = 17303299;
+
     // Communicate to the user about remote bugreports.
     // Package: android
     NOTE_REMOTE_BUGREPORT = 678432343;
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 564d135..c4dc506 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -255,6 +255,63 @@
   // Indicates the number of times an error was encountered in
   // Wificond when wifi was turned on.
   optional int32 num_wifi_on_failure_due_to_wificond = 56;
+
+  // Wi-Fi Aware metrics
+  optional WifiAwareLog wifi_aware_log = 57;
+
+  // Number of saved Passpoint providers in user profile.
+  optional int32 num_passpoint_providers = 58;
+
+  // Count of times Passpoint provider being installed.
+  optional int32 num_passpoint_provider_installation = 59;
+
+  // Count of times Passpoint provivider is installed successfully.
+  optional int32 num_passpoint_provider_install_success = 60;
+
+  // Count of times Passpoint provider is being uninstalled.
+  optional int32 num_passpoint_provider_uninstallation = 61;
+
+  // Count of times Passpoint provider is uninstalled successfully.
+  optional int32 num_passpoint_provider_uninstall_success = 62;
+
+  // Count of saved Passpoint providers device has ever connected to.
+  optional int32 num_passpoint_providers_successfully_connected = 63;
+
+  // Histogram counting instances of scans with N many ScanResults with unique ssids
+  repeated NumConnectableNetworksBucket total_ssids_in_scan_histogram = 64;
+
+  // Histogram counting instances of scans with N many ScanResults/bssids
+  repeated NumConnectableNetworksBucket total_bssids_in_scan_histogram = 65;
+
+  // Histogram counting instances of scans with N many unique open ssids
+  repeated NumConnectableNetworksBucket available_open_ssids_in_scan_histogram = 66;
+
+  // Histogram counting instances of scans with N many bssids for open networks
+  repeated NumConnectableNetworksBucket available_open_bssids_in_scan_histogram = 67;
+
+  // Histogram counting instances of scans with N many unique ssids for saved networks
+  repeated NumConnectableNetworksBucket available_saved_ssids_in_scan_histogram = 68;
+
+  // Histogram counting instances of scans with N many bssids for saved networks
+  repeated NumConnectableNetworksBucket available_saved_bssids_in_scan_histogram = 69;
+
+  // Histogram counting instances of scans with N many unique SSIDs for open or saved networks
+  repeated NumConnectableNetworksBucket available_open_or_saved_ssids_in_scan_histogram = 70;
+
+  // Histogram counting instances of scans with N many BSSIDs for open or saved networks
+  repeated NumConnectableNetworksBucket available_open_or_saved_bssids_in_scan_histogram = 71;
+
+  // Histogram counting instances of scans with N many ScanResults matching unique saved passpoint providers
+  repeated NumConnectableNetworksBucket available_saved_passpoint_provider_profiles_in_scan_histogram = 72;
+
+  // Histogram counting instances of scans with N many ScanResults BSSIDs matching a saved passpoint provider
+  repeated NumConnectableNetworksBucket available_saved_passpoint_provider_bssids_in_scan_histogram = 73;
+
+  // Counts the number of AllSingleScanLister.onResult calls with a full band scan result
+  optional int32 full_band_all_single_scan_listener_results = 74;
+
+  // Counts the number of AllSingleScanLister.onResult calls with a partial (channels) scan result
+  optional int32 partial_all_single_scan_listener_results = 75;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -676,3 +733,197 @@
   // Authentication failure reason, as reported by WifiManager (calculated from state & deauth code)
   optional AuthFailureReason auth_failure_reason = 13 [default = AUTH_FAILURE_UNKNOWN];
 }
+
+// Wi-Fi Aware metrics
+message WifiAwareLog {
+  // total number of unique apps that used Aware (measured on attach)
+  optional int32 num_apps = 1;
+
+  // total number of unique apps that used an identity callback when attaching
+  optional int32 num_apps_using_identity_callback = 2;
+
+  // maximum number of attaches for an app
+  optional int32 max_concurrent_attach_sessions_in_app = 3;
+
+  // histogram of attach request results
+  repeated NanStatusHistogramBucket histogram_attach_session_status = 4;
+
+  // maximum number of concurrent publish sessions in a single app
+  optional int32 max_concurrent_publish_in_app = 5;
+
+  // maximum number of concurrent subscribe sessions in a single app
+  optional int32 max_concurrent_subscribe_in_app = 6;
+
+  // maximum number of concurrent discovery (publish+subscribe) sessions in a single app
+  optional int32 max_concurrent_discovery_sessions_in_app = 7;
+
+  // maximum number of concurrent publish sessions in the system
+  optional int32 max_concurrent_publish_in_system = 8;
+
+  // maximum number of concurrent subscribe sessions in the system
+  optional int32 max_concurrent_subscribe_in_system = 9;
+
+  // maximum number of concurrent discovery (publish+subscribe) sessions in the system
+  optional int32 max_concurrent_discovery_sessions_in_system = 10;
+
+  // histogram of publish request results
+  repeated NanStatusHistogramBucket histogram_publish_status = 11;
+
+  // histogram of subscribe request results
+  repeated NanStatusHistogramBucket histogram_subscribe_status = 12;
+
+  // number of unique apps which experienced a discovery session creation failure due to lack of
+  // resources
+  optional int32 num_apps_with_discovery_session_failure_out_of_resources = 13;
+
+  // histogram of create ndp request results
+  repeated NanStatusHistogramBucket histogram_request_ndp_status = 14;
+
+  // histogram of create ndp out-of-band (OOB) request results
+  repeated NanStatusHistogramBucket histogram_request_ndp_oob_status = 15;
+
+  // maximum number of concurrent active data-interfaces (NDI) in a single app
+  optional int32 max_concurrent_ndi_in_app = 19;
+
+  // maximum number of concurrent active data-interfaces (NDI) in the system
+  optional int32 max_concurrent_ndi_in_system = 20;
+
+  // maximum number of concurrent data-paths (NDP) in a single app
+  optional int32 max_concurrent_ndp_in_app = 21;
+
+  // maximum number of concurrent data-paths (NDP) in the system
+  optional int32 max_concurrent_ndp_in_system = 22;
+
+  // maximum number of concurrent secure data-paths (NDP) in a single app
+  optional int32 max_concurrent_secure_ndp_in_app = 23;
+
+  // maximum number of concurrent secure data-paths (NDP) in the system
+  optional int32 max_concurrent_secure_ndp_in_system = 24;
+
+  // maximum number of concurrent data-paths (NDP) per data-interface (NDI)
+  optional int32 max_concurrent_ndp_per_ndi = 25;
+
+  // histogram of durations of Aware being available
+  repeated HistogramBucket histogram_aware_available_duration_ms = 26;
+
+  // histogram of durations of Aware being enabled
+  repeated HistogramBucket histogram_aware_enabled_duration_ms = 27;
+
+  // histogram of duration (in ms) of attach sessions
+  repeated HistogramBucket histogram_attach_duration_ms = 28;
+
+  // histogram of duration (in ms) of publish sessions
+  repeated HistogramBucket histogram_publish_session_duration_ms = 29;
+
+  // histogram of duration (in ms) of subscribe sessions
+  repeated HistogramBucket histogram_subscribe_session_duration_ms = 30;
+
+  // histogram of duration (in ms) of data-paths (NDP)
+  repeated HistogramBucket histogram_ndp_session_duration_ms = 31;
+
+  // histogram of usage (in MB) of data-paths (NDP)
+  repeated HistogramBucket histogram_ndp_session_data_usage_mb = 32;
+
+  // histogram of usage (in MB) of data-path creation time (in ms) measured as request -> confirm
+  repeated HistogramBucket histogram_ndp_creation_time_ms = 33;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: minimum
+  optional int64 ndp_creation_time_ms_min = 34;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: maximum
+  optional int64 ndp_creation_time_ms_max = 35;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: sum
+  optional int64 ndp_creation_time_ms_sum = 36;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: sum of sq
+  optional int64 ndp_creation_time_ms_sum_of_sq = 37;
+
+  // statistics for data-path (NDP) creation time (in ms) measured as request -> confirm: number of
+  // samples
+  optional int64 ndp_creation_time_ms_num_samples = 38;
+
+  // total time within the logging window that aware was available
+  optional int64 available_time_ms = 39;
+
+  // total time within the logging window that aware was enabled
+  optional int64 enabled_time_ms = 40;
+
+  // Histogram bucket for Wi-Fi Aware logs. Range is [start, end)
+  message HistogramBucket {
+    // lower range of the bucket (inclusive)
+    optional int64 start = 1;
+
+    // upper range of the bucket (exclusive)
+    optional int64 end = 2;
+
+    // number of samples in the bucket
+    optional int32 count = 3;
+  }
+
+  // Status of various NAN operations
+  enum NanStatusTypeEnum {
+    // constant to be used by proto
+    UNKNOWN = 0;
+
+    // NAN operation succeeded
+    SUCCESS = 1;
+
+    // NAN Discovery Engine/Host driver failures
+    INTERNAL_FAILURE = 2;
+
+    // NAN OTA failures
+    PROTOCOL_FAILURE = 3;
+
+    // The publish/subscribe discovery session id is invalid
+    INVALID_SESSION_ID = 4;
+
+    // Out of resources to fufill request
+    NO_RESOURCES_AVAILABLE = 5;
+
+    // Invalid arguments passed
+    INVALID_ARGS = 6;
+
+    // Invalid peer id
+    INVALID_PEER_ID = 7;
+
+    // Invalid NAN data-path (ndp) id
+    INVALID_NDP_ID = 8;
+
+    // Attempting to enable NAN when not available, e.g. wifi is disabled
+    NAN_NOT_ALLOWED = 9;
+
+    // Over the air ACK not received
+    NO_OTA_ACK = 10;
+
+    // Attempting to enable NAN when already enabled
+    ALREADY_ENABLED = 11;
+
+    // Can't queue tx followup message foor transmission
+    FOLLOWUP_TX_QUEUE_FULL = 12;
+
+    // Unsupported concurrency of NAN and another feature - NAN disabled
+    UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 13;
+
+    // Unknown NanStatusType
+    UNKNOWN_HAL_STATUS = 14;
+  }
+
+  // Histogram bucket for Wi-Fi Aware (NAN) status.
+  message NanStatusHistogramBucket {
+    // status type defining the bucket
+    optional NanStatusTypeEnum nan_status_type = 1;
+
+    // number of samples in the bucket
+    optional int32 count = 2;
+  }
+}
+
+// Data point used to build 'Number of Connectable Network' histograms
+message NumConnectableNetworksBucket {
+  // Number of connectable networks seen in a scan result
+  optional int32 num_connectable_networks = 1 [default = 0];
+
+  // Number of scan results with num_connectable_networks
+  optional int32 count = 2 [default = 0];
+}
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 5070e39..f9f6bf7 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1325,12 +1325,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
                                                   (RsType)type, (RsAllocationMipmapControl)mip,
                                                   ptr, bitmap.getSize(), usage);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1341,12 +1339,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
                                             (RsType)type, (RsAllocationMipmapControl)mip,
                                             (uint32_t)usage, (uintptr_t)ptr);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1357,12 +1353,10 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
                                                       (RsType)type, (RsAllocationMipmapControl)mip,
                                                       ptr, bitmap.getSize(), usage);
-    bitmap.unlockPixels();
     return id;
 }
 
@@ -1374,12 +1368,10 @@
     int w = bitmap.width();
     int h = bitmap.height();
 
-    bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
     rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
                        0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
                        w, h, ptr, bitmap.getSize(), 0);
-    bitmap.unlockPixels();
 }
 
 static void
@@ -1388,10 +1380,8 @@
     SkBitmap bitmap;
     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
 
-    bitmap.lockPixels();
     void* ptr = bitmap.getPixels();
     rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
-    bitmap.unlockPixels();
     bitmap.notifyPixelsChanged();
 }
 
diff --git a/services/Android.mk b/services/Android.mk
index 17fc468..b811b0d 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -34,7 +34,6 @@
     net \
     print \
     restrictions \
-    retaildemo \
     usage \
     usb \
     voiceinteraction
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 9e4d89c..0e42e6d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -271,6 +271,7 @@
 
     private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
         if (!state.shouldProcessKeyEvent(event)) {
+            super.onInputEvent(event, policyFlags);
             return;
         }
         mEventHandler.onKeyEvent(event, policyFlags);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7ddc1a2..a58ba09 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -489,15 +489,6 @@
                 if (pip != null) {
                     int pipId = pip.getId();
                     event.setWindowId(pipId);
-                    event.setSealed(true);
-                    AccessibilityNodeInfo info = event.getSource();
-                    info.setSealed(false);
-                    event.setSealed(false);
-                    if (info != null) {
-                        info.setSourceNodeId(info.getSourceNodeId(), pipId);
-                        event.setSource(info);
-                        info.recycle();
-                    }
                 }
             }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 72ad752..6bc9c9c 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -217,7 +217,12 @@
                     fillContextWithAllowedValues(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);
@@ -932,7 +937,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 30de4ba..1bb147c 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -123,8 +123,8 @@
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
 import com.android.server.backup.PackageManagerBackupAgent.Metadata;
-
 import com.android.server.power.BatterySaverPolicy.ServiceType;
+
 import libcore.io.IoUtils;
 
 import java.io.BufferedInputStream;
@@ -189,7 +189,7 @@
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.SecretKeySpec;
 
-public class BackupManagerService {
+public class BackupManagerService implements BackupManagerServiceInterface {
 
     private static final String TAG = "BackupManagerService";
     static final boolean DEBUG = true;
@@ -306,6 +306,7 @@
     private PowerManager mPowerManager;
     private AlarmManager mAlarmManager;
     private IStorageManager mStorageManager;
+
     IBackupManager mBackupManagerBinder;
 
     private final TransportManager mTransportManager;
@@ -690,6 +691,7 @@
     final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>();
     final Object mCurrentOpLock = new Object();
     final Random mTokenGenerator = new Random();
+    final AtomicInteger mNextToken = new AtomicInteger();
 
     final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<AdbParams>();
 
@@ -762,14 +764,15 @@
     @GuardedBy("mQueueLock")
     ArrayList<FullBackupEntry> mFullBackupQueue;
 
-    // Utility: build a new random integer token
-    int generateToken() {
-        int token;
-        do {
-            synchronized (mTokenGenerator) {
-                token = mTokenGenerator.nextInt();
-            }
-        } while (token < 0);
+    // Utility: build a new random integer token.  The low bits are the ordinal of the
+    // operation for near-time uniqueness, and the upper bits are random for app-
+    // side unpredictability.
+    @Override
+    public int generateRandomIntegerToken() {
+        int token = mTokenGenerator.nextInt();
+        if (token < 0) token = -token;
+        token &= ~0xFF;
+        token |= (mNextToken.incrementAndGet() & 0xFF);
         return token;
     }
 
@@ -837,6 +840,29 @@
         return !appGetsFullBackup(pkg);
     }
 
+    /*
+     * Construct a backup agent instance for the metadata pseudopackage.  This is a
+     * process-local non-lifecycle agent instance, so we manually set up the context
+     * topology for it.
+     */
+    PackageManagerBackupAgent makeMetadataAgent() {
+        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
+        pmAgent.attach(mContext);
+        pmAgent.onCreate();
+        return pmAgent;
+    }
+
+    /*
+     * Same as above but with the explicit package-set configuration.
+     */
+    PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
+        PackageManagerBackupAgent pmAgent =
+                new PackageManagerBackupAgent(mPackageManager, packages);
+        pmAgent.attach(mContext);
+        pmAgent.onCreate();
+        return pmAgent;
+    }
+
     // ----- Asynchronous backup/restore handler thread -----
 
     private class BackupHandler extends Handler {
@@ -1752,6 +1778,7 @@
         return false;
     }
 
+    @Override
     public boolean setBackupPassword(String currentPw, String newPw) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupPassword");
@@ -1832,6 +1859,7 @@
         return false;
     }
 
+    @Override
     public boolean hasBackupPassword() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "hasBackupPassword");
@@ -2297,7 +2325,8 @@
     }
 
     // fire off a backup agent, blocking until it attaches or times out
-    IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+    @Override
+    public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
         IBackupAgent agent = null;
         synchronized(mAgentConnectLock) {
             mConnecting = true;
@@ -2393,6 +2422,7 @@
 
     // Get the restore-set token for the best-available restore set for this package:
     // the active set if possible, else the ancestral one.  Returns zero if none available.
+    @Override
     public long getAvailableRestoreToken(String packageName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getAvailableRestoreToken");
@@ -2410,10 +2440,12 @@
         return token;
     }
 
+    @Override
     public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
         return requestBackup(packages, observer, null, flags);
     }
 
+    @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
@@ -2485,6 +2517,7 @@
     }
 
     // Cancel all running backups.
+    @Override
     public void cancelBackups(){
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
         if (MORE_DEBUG) {
@@ -2514,22 +2547,9 @@
         }
     }
 
-    // -----
-    // Interface and methods used by the asynchronous-with-timeout backup/restore operations
-
-    interface BackupRestoreTask {
-        // Execute one tick of whatever state machine the task implements
-        void execute();
-
-        // An operation that wanted a callback has completed
-        void operationComplete(long result);
-
-        // An operation that wanted a callback has timed out
-        void handleCancel(boolean cancelAll);
-    }
-
-    void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
-            int operationType) {
+    @Override
+    public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+        int operationType) {
         if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
             Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
                     Integer.toHexString(token) + " of type " + operationType);
@@ -2573,7 +2593,8 @@
     }
 
     // synchronous waiter case
-    boolean waitUntilOperationComplete(int token) {
+    @Override
+    public boolean waitUntilOperationComplete(int token) {
         if (MORE_DEBUG) Slog.i(TAG, "Blocking until operation complete for "
                 + Integer.toHexString(token));
         int finalState = OP_PENDING;
@@ -2739,7 +2760,7 @@
             mNonIncremental = nonIncremental;
 
             mStateDir = new File(mBaseStateDir, dirName);
-            mCurrentOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
 
             mFinished = false;
 
@@ -2802,11 +2823,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;
                 }
             }
@@ -2896,8 +2917,7 @@
                     // because it's cheap and this way we guarantee that we don't get out of
                     // step even if we're selecting among various transports at run time.
                     if (mStatus == BackupTransport.TRANSPORT_OK) {
-                        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
-                                mPackageManager);
+                        PackageManagerBackupAgent pmAgent = makeMetadataAgent();
                         mStatus = invokeAgentForBackup(PACKAGE_MANAGER_SENTINEL,
                                 IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
                         addBackupTrace("PMBA invoke: " + mStatus);
@@ -3161,6 +3181,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();
@@ -3190,7 +3211,7 @@
             mNewState = null;
 
             boolean callingAgent = false;
-            mEphemeralOpToken = generateToken();
+            mEphemeralOpToken = generateRandomIntegerToken();
             try {
                 // Look up the package info & signatures.  This is first so that if it
                 // throws an exception, there's no file setup yet that would need to
@@ -3687,7 +3708,7 @@
             ParcelFileDescriptor[] pipes = null;
             try {
                 pipes = ParcelFileDescriptor.createPipe();
-                int token = generateToken();
+                int token = generateRandomIntegerToken();
                 prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
                         null, OP_TYPE_BACKUP_WAIT);
                 mService.backupObbs(pkg.packageName, pipes[1], token, mBackupManagerBinder);
@@ -3773,7 +3794,8 @@
         }
     }
 
-    void tearDownAgentAndKill(ApplicationInfo app) {
+    @Override
+    public void tearDownAgentAndKill(ApplicationInfo app) {
         if (app == null) {
             // Null means the system package, so just quietly move on.  :)
             return;
@@ -4225,7 +4247,7 @@
                 String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
                 boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
             super(observer);
-            mCurrentOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
             mLatch = latch;
 
             mOutputFile = fd;
@@ -4675,8 +4697,8 @@
             mBackupObserver = backupObserver;
             mMonitor = monitor;
             mUserInitiated = userInitiated;
-            mCurrentOpToken = generateToken();
-            mBackupRunnerOpToken = generateToken();
+            mCurrentOpToken = generateRandomIntegerToken();
+            mBackupRunnerOpToken = generateRandomIntegerToken();
 
             if (isBackupOperationInProgress()) {
                 if (DEBUG) {
@@ -4850,6 +4872,7 @@
                 final int N = mPackages.size();
                 final byte[] buffer = new byte[8192];
                 for (int i = 0; i < N; i++) {
+                    mBackupRunner = null;
                     PackageInfo currentPackage = mPackages.get(i);
                     String packageName = currentPackage.packageName;
                     if (DEBUG) {
@@ -5033,7 +5056,13 @@
                         }
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
                                 "transport rejected");
-                        // Do nothing, clean up, and continue looping.
+                        // This failure state can come either a-priori from the transport, or
+                        // from the preflight pass.  If we got as far as preflight, we now need
+                        // to tear down the target process.
+                        if (mBackupRunner != null) {
+                            tearDownAgentAndKill(currentPackage.applicationInfo);
+                        }
+                        // ... and continue looping.
                     } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
                         sendBackupOnPackageResult(mBackupObserver, packageName,
                                 BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
@@ -5042,6 +5071,7 @@
                             EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
                                     packageName);
                         }
+                        tearDownAgentAndKill(currentPackage.applicationInfo);
                         // Do nothing, clean up, and continue looping.
                     } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
                         sendBackupOnPackageResult(mBackupObserver, packageName,
@@ -5065,6 +5095,7 @@
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                         // Abort entire backup pass.
                         backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                        tearDownAgentAndKill(currentPackage.applicationInfo);
                         return;
                     } else {
                         // Success!
@@ -5269,7 +5300,7 @@
                 mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                 mTarget = target;
                 mCurrentOpToken = currentOpToken;
-                mEphemeralToken = generateToken();
+                mEphemeralToken = generateRandomIntegerToken();
                 mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
                 mPreflightLatch = new CountDownLatch(1);
                 mBackupLatch = new CountDownLatch(1);
@@ -5499,7 +5530,8 @@
      * @return Whether ongoing work will continue.  The return value here will be passed
      *         along as the return value to the scheduled job's onStartJob() callback.
      */
-    boolean beginFullBackup(FullBackupJob scheduledJob) {
+    @Override
+    public boolean beginFullBackup(FullBackupJob scheduledJob) {
         long now = System.currentTimeMillis();
         FullBackupEntry entry = null;
         long latency = MIN_FULL_BACKUP_INTERVAL;
@@ -5657,7 +5689,8 @@
 
     // The job scheduler says our constraints don't hold any more,
     // so tear down any ongoing backup task right away.
-    void endFullBackup() {
+    @Override
+    public void endFullBackup() {
         // offload the mRunningFullBackupTask.handleCancel() call to another thread,
         // as we might have to wait for mCancelLock
         Runnable endFullBackupRunnable = new Runnable() {
@@ -5666,13 +5699,15 @@
                 PerformFullTransportBackupTask pftbt = null;
                 synchronized (mQueueLock) {
                     if (mRunningFullBackupTask != null) {
-                        if (DEBUG_SCHEDULING) {
-                            Slog.i(TAG, "Telling running backup to stop");
-                        }
                         pftbt = mRunningFullBackupTask;
                     }
                 }
-                pftbt.handleCancel(true);
+                if (pftbt != null) {
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Telling running backup to stop");
+                    }
+                    pftbt.handleCancel(true);
+                }
             }
         };
         new Thread(endFullBackupRunnable, "end-full-backup").start();
@@ -5725,30 +5760,6 @@
 
     // ----- Full restore from a file/socket -----
 
-    // Description of a file in the restore datastream
-    static class FileMetadata {
-        String packageName;             // name of the owning app
-        String installerPackageName;    // name of the market-type app that installed the owner
-        int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
-        String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
-        String path;                    // subpath within the semantic domain
-        long mode;                      // e.g. 0666 (actually int)
-        long mtime;                     // last mod time, UTC time_t (actually int)
-        long size;                      // bytes of content
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("FileMetadata{");
-            sb.append(packageName); sb.append(',');
-            sb.append(type); sb.append(',');
-            sb.append(domain); sb.append(':'); sb.append(path); sb.append(',');
-            sb.append(size);
-            sb.append('}');
-            return sb.toString();
-        }
-    }
-
     enum RestorePolicy {
         IGNORE,
         ACCEPT,
@@ -7179,7 +7190,7 @@
             mObserver = observer;
             mLatchObject = latch;
             mAgent = null;
-            mPackageManagerBackupAgent = new PackageManagerBackupAgent(mPackageManager);
+            mPackageManagerBackupAgent = makeMetadataAgent();
             mAgentPackage = null;
             mTargetApp = null;
             mObbConnection = new FullBackupObbConnection();
@@ -7598,7 +7609,7 @@
                             final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
                             final long timeout = isSharedStorage ?
                                     TIMEOUT_SHARED_BACKUP_INTERVAL : TIMEOUT_RESTORE_INTERVAL;
-                            final int token = generateToken();
+                            final int token = generateRandomIntegerToken();
                             try {
                                 prepareOperationTimeout(token, timeout, null,
                                         OP_TYPE_RESTORE_WAIT);
@@ -7742,7 +7753,7 @@
                 try {
                     // In the adb restore case, we do restore-finished here
                     if (doRestoreFinished) {
-                        final int token = generateToken();
+                        final int token = generateRandomIntegerToken();
                         final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(token);
                         prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch,
                                 OP_TYPE_RESTORE_WAIT);
@@ -8621,7 +8632,7 @@
         PerformUnifiedRestoreTask(IBackupTransport transport, IRestoreObserver observer,
                 IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
                 int pmToken, boolean isFullSystemRestore, String[] filterSet) {
-            mEphemeralOpToken = generateToken();
+            mEphemeralOpToken = generateRandomIntegerToken();
             mState = UnifiedRestoreState.INITIAL;
             mStartRealtime = SystemClock.elapsedRealtime();
 
@@ -8841,7 +8852,7 @@
                 // Pull the Package Manager metadata from the restore set first
                 mCurrentPackage = new PackageInfo();
                 mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
-                mPmAgent = new PackageManagerBackupAgent(mPackageManager, null);
+                mPmAgent = makeMetadataAgent(null);
                 mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
                 if (MORE_DEBUG) {
                     Slog.v(TAG, "initiating restore for PMBA");
@@ -9254,7 +9265,7 @@
             private final int mEphemeralOpToken;
 
             public StreamFeederThread() throws IOException {
-                mEphemeralOpToken = generateToken();
+                mEphemeralOpToken = generateRandomIntegerToken();
                 mTransportPipes = ParcelFileDescriptor.createPipe();
                 mEnginePipes = ParcelFileDescriptor.createPipe();
                 setRunning(true);
@@ -9909,6 +9920,7 @@
 
     // ----- IBackupManager binder interface -----
 
+    @Override
     public void dataChanged(final String packageName) {
         final int callingUserHandle = UserHandle.getCallingUserId();
         if (callingUserHandle != UserHandle.USER_SYSTEM) {
@@ -9939,6 +9951,7 @@
     }
 
     // Clear the given package's backup data from the current transport
+    @Override
     public void clearBackupData(String transportName, String packageName) {
         if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
         PackageInfo info;
@@ -9996,6 +10009,7 @@
 
     // Run a backup pass immediately for any applications that have declared
     // that they have pending updates.
+    @Override
     public void backupNow() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
 
@@ -10032,6 +10046,7 @@
     //
     // This is the variant used by 'adb backup'; it requires on-screen confirmation
     // by the user because it can be used to offload data over untrusted USB.
+    @Override
     public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
             boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
             boolean compress, boolean doKeyValue, String[] pkgList) {
@@ -10072,7 +10087,7 @@
             AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
                     includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
                     pkgList);
-            final int token = generateToken();
+            final int token = generateRandomIntegerToken();
             synchronized (mAdbBackupRestoreConfirmations) {
                 mAdbBackupRestoreConfirmations.put(token, params);
             }
@@ -10107,6 +10122,7 @@
         }
     }
 
+    @Override
     public void fullTransportBackup(String[] pkgNames) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
                 "fullTransportBackup");
@@ -10156,6 +10172,7 @@
         }
     }
 
+    @Override
     public void adbRestore(ParcelFileDescriptor fd) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
 
@@ -10178,7 +10195,7 @@
             Slog.i(TAG, "Beginning restore...");
 
             AdbRestoreParams params = new AdbRestoreParams(fd);
-            final int token = generateToken();
+            final int token = generateRandomIntegerToken();
             synchronized (mAdbBackupRestoreConfirmations) {
                 mAdbBackupRestoreConfirmations.put(token, params);
             }
@@ -10254,6 +10271,7 @@
 
     // Confirm that the previously-requested full backup/restore operation can proceed.  This
     // is used to require a user-facing disclosure about the operation.
+    @Override
     public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
             String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
         if (DEBUG) Slog.d(TAG, "acknowledgeAdbBackupOrRestore : token=" + token
@@ -10354,6 +10372,7 @@
     }
 
     // Enable/disable backups
+    @Override
     public void setBackupEnabled(boolean enable) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupEnabled");
@@ -10401,6 +10420,7 @@
     }
 
     // Enable/disable automatic restore of app data at install time
+    @Override
     public void setAutoRestore(boolean doAutoRestore) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setAutoRestore");
@@ -10420,6 +10440,7 @@
     }
 
     // Mark the backup service as having been provisioned
+    @Override
     public void setBackupProvisioned(boolean available) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupProvisioned");
@@ -10429,12 +10450,14 @@
     }
 
     // Report whether the backup mechanism is currently enabled
+    @Override
     public boolean isBackupEnabled() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "isBackupEnabled");
         return mEnabled;    // no need to synchronize just to read it
     }
 
     // Report the name of the currently active transport
+    @Override
     public String getCurrentTransport() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getCurrentTransport");
@@ -10444,18 +10467,21 @@
     }
 
     // Report all known, available backup transports
+    @Override
     public String[] listAllTransports() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "listAllTransports");
 
         return mTransportManager.getBoundTransportNames();
     }
 
+    @Override
     public ComponentName[] listAllTransportComponents() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "listAllTransportComponents");
         return mTransportManager.getAllTransportCompenents();
     }
 
+    @Override
     public String[] getTransportWhitelist() {
         // No permission check, intentionally.
         Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
@@ -10469,6 +10495,7 @@
     }
 
     // Select which transport to use for the next backup operation.
+    @Override
     public String selectBackupTransport(String transport) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "selectBackupTransport");
@@ -10485,6 +10512,7 @@
         }
     }
 
+    @Override
     public void selectBackupTransportAsync(final ComponentName transport,
             final ISelectBackupTransportCallback listener) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
@@ -10547,6 +10575,7 @@
     // Supply the configuration Intent for the given transport.  If the name is not one
     // of the available transports, or if the transport does not supply any configuration
     // UI, the method returns null.
+    @Override
     public Intent getConfigurationIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getConfigurationIntent");
@@ -10572,6 +10601,7 @@
     // summary / destination string, the method can return null.
     //
     // This string is used VERBATIM as the summary text of the relevant Settings item!
+    @Override
     public String getDestinationString(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDestinationString");
@@ -10592,6 +10622,7 @@
     }
 
     // Supply the manage-data intent for the given transport.
+    @Override
     public Intent getDataManagementIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementIntent");
@@ -10614,6 +10645,7 @@
 
     // Supply the menu label for affordances that fire the manage-data intent
     // for the given transport.
+    @Override
     public String getDataManagementLabel(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementLabel");
@@ -10635,6 +10667,7 @@
 
     // Callback: a requested backup agent has been instantiated.  This should only
     // be called from the Activity Manager.
+    @Override
     public void agentConnected(String packageName, IBinder agentBinder) {
         synchronized(mAgentConnectLock) {
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
@@ -10653,6 +10686,7 @@
     // Callback: a backup agent has failed to come up, or has unexpectedly quit.
     // If the agent failed to come up in the first place, the agentBinder argument
     // will be null.  This should only be called from the Activity Manager.
+    @Override
     public void agentDisconnected(String packageName) {
         // TODO: handle backup being interrupted
         synchronized(mAgentConnectLock) {
@@ -10669,6 +10703,7 @@
 
     // An application being installed will need a restore pass, then the Package Manager
     // will need to be told when the restore is finished.
+    @Override
     public void restoreAtInstall(String packageName, int token) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
@@ -10736,6 +10771,7 @@
     }
 
     // Hand off a restore session
+    @Override
     public IRestoreSession beginRestoreSession(String packageName, String transport) {
         if (DEBUG) Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
                 + " transport=" + transport);
@@ -10799,6 +10835,7 @@
 
     // Note that a currently-active backup agent has notified us that it has
     // completed the given outstanding asynchronous backup/restore operation.
+    @Override
     public void opComplete(int token, long result) {
         if (MORE_DEBUG) {
             Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
@@ -10836,6 +10873,7 @@
         }
     }
 
+    @Override
     public boolean isAppEligibleForBackup(String packageName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "isAppEligibleForBackup");
@@ -11200,6 +11238,7 @@
         }
     }
 
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
 
@@ -11425,4 +11464,10 @@
         }
         return null;
     }
+
+    @Override
+    public IBackupManager getBackupManagerBinder() {
+        return mBackupManagerBinder;
+    }
+
 }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
new file mode 100644
index 0000000..e415494
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -0,0 +1,178 @@
+/*
+ * 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.backup;
+
+import android.app.IBackupAgent;
+import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Interface for BackupManagerService.
+ *
+ * Current and future implementations of BackupManagerService should use this interface, so that
+ * Trampoline is able to switch between them.
+ */
+public interface BackupManagerServiceInterface {
+
+  // Utility: build a new random integer token
+  int generateRandomIntegerToken();
+
+  boolean setBackupPassword(String currentPw, String newPw);
+
+  boolean hasBackupPassword();
+
+  // fire off a backup agent, blocking until it attaches or times out
+  IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode);
+
+  // Get the restore-set token for the best-available restore set for this package:
+  // the active set if possible, else the ancestral one.  Returns zero if none available.
+  long getAvailableRestoreToken(String packageName);
+
+  int requestBackup(String[] packages, IBackupObserver observer, int flags);
+
+  int requestBackup(String[] packages, IBackupObserver observer,
+      IBackupManagerMonitor monitor, int flags);
+
+  // Cancel all running backups.
+  void cancelBackups();
+
+  void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+      int operationType);
+
+  // synchronous waiter case
+  boolean waitUntilOperationComplete(int token);
+
+  void tearDownAgentAndKill(ApplicationInfo app);
+
+  boolean beginFullBackup(FullBackupJob scheduledJob);
+
+  // The job scheduler says our constraints don't hold any more,
+  // so tear down any ongoing backup task right away.
+  void endFullBackup();
+
+  void dataChanged(String packageName);
+
+  // Clear the given package's backup data from the current transport
+  void clearBackupData(String transportName, String packageName);
+
+  // Run a backup pass immediately for any applications that have declared
+  // that they have pending updates.
+  void backupNow();
+
+  // Run a backup pass for the given packages, writing the resulting data stream
+  // to the supplied file descriptor.  This method is synchronous and does not return
+  // to the caller until the backup has been completed.
+  //
+  // This is the variant used by 'adb backup'; it requires on-screen confirmation
+  // by the user because it can be used to offload data over untrusted USB.
+  void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
+      boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
+      boolean compress, boolean doKeyValue, String[] pkgList);
+
+  void fullTransportBackup(String[] pkgNames);
+
+  void adbRestore(ParcelFileDescriptor fd);
+
+  // Confirm that the previously-requested full backup/restore operation can proceed.  This
+  // is used to require a user-facing disclosure about the operation.
+  void acknowledgeAdbBackupOrRestore(int token, boolean allow,
+      String curPassword, String encPpassword, IFullBackupRestoreObserver observer);
+
+  // Enable/disable backups
+  void setBackupEnabled(boolean enable);
+
+  // Enable/disable automatic restore of app data at install time
+  void setAutoRestore(boolean doAutoRestore);
+
+  // Mark the backup service as having been provisioned
+  void setBackupProvisioned(boolean available);
+
+  // Report whether the backup mechanism is currently enabled
+  boolean isBackupEnabled();
+
+  // Report the name of the currently active transport
+  String getCurrentTransport();
+
+  // Report all known, available backup transports
+  String[] listAllTransports();
+
+  ComponentName[] listAllTransportComponents();
+
+  String[] getTransportWhitelist();
+
+  // Select which transport to use for the next backup operation.
+  String selectBackupTransport(String transport);
+
+  void selectBackupTransportAsync(ComponentName transport,
+      ISelectBackupTransportCallback listener);
+
+  // Supply the configuration Intent for the given transport.  If the name is not one
+  // of the available transports, or if the transport does not supply any configuration
+  // UI, the method returns null.
+  Intent getConfigurationIntent(String transportName);
+
+  // Supply the configuration summary string for the given transport.  If the name is
+  // not one of the available transports, or if the transport does not supply any
+  // summary / destination string, the method can return null.
+  //
+  // This string is used VERBATIM as the summary text of the relevant Settings item!
+  String getDestinationString(String transportName);
+
+  // Supply the manage-data intent for the given transport.
+  Intent getDataManagementIntent(String transportName);
+
+  // Supply the menu label for affordances that fire the manage-data intent
+  // for the given transport.
+  String getDataManagementLabel(String transportName);
+
+  // Callback: a requested backup agent has been instantiated.  This should only
+  // be called from the Activity Manager.
+  void agentConnected(String packageName, IBinder agentBinder);
+
+  // Callback: a backup agent has failed to come up, or has unexpectedly quit.
+  // If the agent failed to come up in the first place, the agentBinder argument
+  // will be null.  This should only be called from the Activity Manager.
+  void agentDisconnected(String packageName);
+
+  // An application being installed will need a restore pass, then the Package Manager
+  // will need to be told when the restore is finished.
+  void restoreAtInstall(String packageName, int token);
+
+  // Hand off a restore session
+  IRestoreSession beginRestoreSession(String packageName, String transport);
+
+  // Note that a currently-active backup agent has notified us that it has
+  // completed the given outstanding asynchronous backup/restore operation.
+  void opComplete(int token, long result);
+
+  boolean isAppEligibleForBackup(String packageName);
+
+  void dump(FileDescriptor fd, PrintWriter pw, String[] args);
+
+  IBackupManager getBackupManagerBinder();
+}
diff --git a/services/backup/java/com/android/server/backup/BackupRestoreTask.java b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
new file mode 100644
index 0000000..acaab0c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupRestoreTask.java
@@ -0,0 +1,32 @@
+/*
+ * 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.backup;
+
+/**
+ * Interface and methods used by the asynchronous-with-timeout backup/restore operations.
+ */
+public interface BackupRestoreTask {
+
+    // Execute one tick of whatever state machine the task implements
+    void execute();
+
+    // An operation that wanted a callback has completed
+    void operationComplete(long result);
+
+    // An operation that wanted a callback has timed out
+    void handleCancel(boolean cancelAll);
+}
diff --git a/services/backup/java/com/android/server/backup/FileMetadata.java b/services/backup/java/com/android/server/backup/FileMetadata.java
new file mode 100644
index 0000000..5465609
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/FileMetadata.java
@@ -0,0 +1,88 @@
+/*
+ * 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.backup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupAgent;
+import android.util.Slog;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Description of a file in the restore datastream.
+ */
+public class FileMetadata {
+    public String packageName;             // name of the owning app
+    public String installerPackageName;    // name of the market-type app that installed the owner
+    public int type;                       // e.g. BackupAgent.TYPE_DIRECTORY
+    public String domain;                  // e.g. FullBackup.DATABASE_TREE_TOKEN
+    public String path;                    // subpath within the semantic domain
+    public long mode;                      // e.g. 0666 (actually int)
+    public long mtime;                     // last mod time, UTC time_t (actually int)
+    public long size;                      // bytes of content
+    public int version;                    // App version.
+    public boolean hasApk;                 // Whether backup file contains apk.
+
+    @Override
+    public String toString() {
+        // TODO: Clean this up.
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("FileMetadata{");
+        sb.append(packageName);
+        sb.append(',');
+        sb.append(type);
+        sb.append(',');
+        sb.append(domain);
+        sb.append(':');
+        sb.append(path);
+        sb.append(',');
+        sb.append(size);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public void dump() {
+        StringBuilder b = new StringBuilder(128);
+
+        // mode string
+        b.append((type == BackupAgent.TYPE_DIRECTORY) ? 'd' : '-');
+        b.append(((mode & 0400) != 0) ? 'r' : '-');
+        b.append(((mode & 0200) != 0) ? 'w' : '-');
+        b.append(((mode & 0100) != 0) ? 'x' : '-');
+        b.append(((mode & 0040) != 0) ? 'r' : '-');
+        b.append(((mode & 0020) != 0) ? 'w' : '-');
+        b.append(((mode & 0010) != 0) ? 'x' : '-');
+        b.append(((mode & 0004) != 0) ? 'r' : '-');
+        b.append(((mode & 0002) != 0) ? 'w' : '-');
+        b.append(((mode & 0001) != 0) ? 'x' : '-');
+        b.append(String.format(" %9d ", size));
+
+        Date stamp = new Date(mtime);
+        b.append(new SimpleDateFormat("MMM dd HH:mm:ss ").format(stamp));
+
+        b.append(packageName);
+        b.append(" :: ");
+        b.append(domain);
+        b.append(" :: ");
+        b.append(path);
+
+        Slog.i(TAG, b.toString());
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index cd13760..279c828 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -35,7 +35,7 @@
  * TODO: We should create unified backup/restore engines that can be used for both transport and
  * adb backup/restore, and for fullbackup and key-value backup.
  */
-class KeyValueAdbBackupEngine {
+public class KeyValueAdbBackupEngine {
     private static final String TAG = "KeyValueAdbBackupEngine";
     private static final boolean DEBUG = false;
 
@@ -44,7 +44,7 @@
     private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
     private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";
 
-    private BackupManagerService mBackupManagerService;
+    private BackupManagerServiceInterface mBackupManagerService;
     private final PackageManager mPackageManager;
     private final OutputStream mOutput;
     private final PackageInfo mCurrentPackage;
@@ -58,8 +58,8 @@
     private ParcelFileDescriptor mBackupData;
     private ParcelFileDescriptor mNewState;
 
-    KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
-            BackupManagerService backupManagerService, PackageManager packageManager,
+    public KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
+            BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
             File baseStateDir, File dataDir) {
         mOutput = output;
         mCurrentPackage = packageInfo;
@@ -81,7 +81,7 @@
         mManifestFile = new File(mDataDir, BackupManagerService.BACKUP_MANIFEST_FILENAME);
     }
 
-    void backupOnePackage() throws IOException {
+    public void backupOnePackage() throws IOException {
         ApplicationInfo targetApp = mCurrentPackage.applicationInfo;
 
         try {
@@ -145,14 +145,14 @@
 
     // Return true on backup success, false otherwise
     private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
-        int token = mBackupManagerService.generateToken();
+        int token = mBackupManagerService.generateRandomIntegerToken();
         try {
             mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
                     OP_TYPE_BACKUP_WAIT);
 
             // Start backup and wait for BackupManagerService to get callback for success or timeout
             agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
-                    mBackupManagerService.mBackupManagerBinder);
+                    mBackupManagerService.getBackupManagerBinder());
             if (!mBackupManagerService.waitUntilOperationComplete(token)) {
                 Slog.e(TAG, "Key-value backup failed on package " + packageName);
                 return false;
@@ -214,7 +214,7 @@
                 }
 
                 try {
-                    mBackupManagerService.mBackupManagerBinder.opComplete(mToken, 0);
+                    mBackupManagerService.getBackupManagerBinder().opComplete(mToken, 0);
                 } catch (RemoteException e) {
                     // we'll time out anyway, so we're safe
                 }
@@ -229,7 +229,7 @@
 
     private void writeBackupData() throws IOException {
 
-        int token = mBackupManagerService.generateToken();
+        int token = mBackupManagerService.generateRandomIntegerToken();
 
         ParcelFileDescriptor[] pipes = null;
         try {
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
index 6fb9355..b62bb5c 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
@@ -13,7 +13,6 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.BackupManagerService.FileMetadata;
 import libcore.io.IoUtils;
 
 import java.io.File;
@@ -34,11 +33,11 @@
  * TODO: We should create unified backup/restore engines that can be used for both transport and
  * adb backup/restore, and for fullbackup and key-value backup.
  */
-class KeyValueAdbRestoreEngine implements Runnable {
+public class KeyValueAdbRestoreEngine implements Runnable {
     private static final String TAG = "KeyValueAdbRestoreEngine";
     private static final boolean DEBUG = false;
 
-    private final BackupManagerService mBackupManagerService;
+    private final BackupManagerServiceInterface mBackupManagerService;
     private final File mDataDir;
 
     FileMetadata mInfo;
@@ -47,8 +46,9 @@
     IBackupAgent mAgent;
     int mToken;
 
-    KeyValueAdbRestoreEngine(BackupManagerService backupManagerService, File dataDir,
-            FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent, int token) {
+    public KeyValueAdbRestoreEngine(BackupManagerServiceInterface backupManagerService,
+            File dataDir, FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent,
+            int token) {
         mBackupManagerService = backupManagerService;
         mDataDir = dataDir;
         mInfo = info;
@@ -96,7 +96,7 @@
                         + versionCode);
             }
             agent.doRestore(backupData, versionCode, newState, mToken,
-                    mBackupManagerService.mBackupManagerBinder);
+                    mBackupManagerService.getBackupManagerBinder());
         } catch (IOException e) {
             Slog.e(TAG, "Exception opening file. " + e);
         } catch (RemoteException e) {
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index 642b8bf..8d91e0d 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -108,11 +108,11 @@
 
     // We're constructed with the set of applications that are participating
     // in backup.  This set changes as apps are installed & removed.
-    PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
+    public PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
         init(packageMgr, packages);
     }
 
-    PackageManagerBackupAgent(PackageManager packageMgr) {
+    public PackageManagerBackupAgent(PackageManager packageMgr) {
         init(packageMgr, null);
 
         evaluateStorablePackages();
diff --git a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
new file mode 100644
index 0000000..b57c0bc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
@@ -0,0 +1,3652 @@
+/*
+ * 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.backup;
+
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND;
+
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_FULL_CONFIRMATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_OP_COMPLETE;
+import static com.android.server.backup.internal.BackupHandler.MSG_REQUEST_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RETRY_CLEAR;
+import static com.android.server.backup.internal.BackupHandler.MSG_RETRY_INIT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_ADB_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_ADB_RESTORE;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_BACKUP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_CLEAR;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_INITIALIZE;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
+import static com.android.server.backup.internal.BackupHandler.MSG_SCHEDULE_BACKUP_PACKAGE;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.app.AppGlobals;
+import android.app.IActivityManager;
+import android.app.IBackupAgent;
+import android.app.PendingIntent;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.app.backup.SelectBackupTransportCallback;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+import android.os.PowerSaveState;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SELinux;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.EventLog;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.DumpUtils;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.SystemConfig;
+import com.android.server.SystemService;
+import com.android.server.backup.fullbackup.FullBackupEntry;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.internal.BackupHandler;
+import com.android.server.backup.internal.BackupRequest;
+import com.android.server.backup.internal.ClearDataObserver;
+import com.android.server.backup.internal.Operation;
+import com.android.server.backup.internal.ProvisionedObserver;
+import com.android.server.backup.internal.RunBackupReceiver;
+import com.android.server.backup.internal.RunInitializeReceiver;
+import com.android.server.backup.params.AdbBackupParams;
+import com.android.server.backup.params.AdbParams;
+import com.android.server.backup.params.AdbRestoreParams;
+import com.android.server.backup.params.BackupParams;
+import com.android.server.backup.params.ClearParams;
+import com.android.server.backup.params.ClearRetryParams;
+import com.android.server.backup.params.RestoreParams;
+import com.android.server.backup.restore.ActiveRestoreSession;
+import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+import com.android.server.backup.utils.PasswordUtils;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+public class RefactoredBackupManagerService implements BackupManagerServiceInterface {
+
+    public static final String TAG = "BackupManagerService";
+    public static final boolean DEBUG = true;
+    public static final boolean MORE_DEBUG = false;
+    public static final boolean DEBUG_SCHEDULING = MORE_DEBUG || true;
+
+    // File containing backup-enabled state.  Contains a single byte;
+    // nonzero == enabled.  File missing or contains a zero byte == disabled.
+    private static final String BACKUP_ENABLE_FILE = "backup_enabled";
+
+    // System-private key used for backing up an app's widget state.  Must
+    // begin with U+FFxx by convention (we reserve all keys starting
+    // with U+FF00 or higher for system use).
+    public static final String KEY_WIDGET_STATE = "\uffed\uffedwidget";
+
+    // Historical and current algorithm names
+    public static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1";
+    public static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit";
+
+    // Name and current contents version of the full-backup manifest file
+    //
+    // Manifest version history:
+    //
+    // 1 : initial release
+    public static final String BACKUP_MANIFEST_FILENAME = "_manifest";
+    public static final int BACKUP_MANIFEST_VERSION = 1;
+
+    // External archive format version history:
+    //
+    // 1 : initial release
+    // 2 : no format change per se; version bump to facilitate PBKDF2 version skew detection
+    // 3 : introduced "_meta" metadata file; no other format change per se
+    // 4 : added support for new device-encrypted storage locations
+    // 5 : added support for key-value packages
+    public static final int BACKUP_FILE_VERSION = 5;
+    public static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
+    private static final int BACKUP_PW_FILE_VERSION = 2;
+    public static final String BACKUP_METADATA_FILENAME = "_meta";
+    public static final int BACKUP_METADATA_VERSION = 1;
+    public static final int BACKUP_WIDGET_METADATA_TOKEN = 0x01FFED01;
+
+    private static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production
+
+    public static final String SETTINGS_PACKAGE = "com.android.providers.settings";
+    public static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup";
+    private static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
+
+    // Retry interval for clear/init when the transport is unavailable
+    private static final long TRANSPORT_RETRY_INTERVAL = 1 * AlarmManager.INTERVAL_HOUR;
+
+    public static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
+    public static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
+
+    // Timeout interval for deciding that a bind or clear-data has taken too long
+    private static final long TIMEOUT_INTERVAL = 10 * 1000;
+
+    // Timeout intervals for agent backup & restore operations
+    public static final long TIMEOUT_BACKUP_INTERVAL = 30 * 1000;
+    public static final long TIMEOUT_FULL_BACKUP_INTERVAL = 5 * 60 * 1000;
+    public static final long TIMEOUT_SHARED_BACKUP_INTERVAL = 30 * 60 * 1000;
+    public static final long TIMEOUT_RESTORE_INTERVAL = 60 * 1000;
+    public static final long TIMEOUT_RESTORE_FINISHED_INTERVAL = 30 * 1000;
+
+    // User confirmation timeout for a full backup/restore operation.  It's this long in
+    // order to give them time to enter the backup password.
+    private static final long TIMEOUT_FULL_CONFIRMATION = 60 * 1000;
+
+    // How long between attempts to perform a full-data backup of any given app
+    private static final long MIN_FULL_BACKUP_INTERVAL = 1000 * 60 * 60 * 24; // one day
+
+    // If an app is busy when we want to do a full-data backup, how long to defer the retry.
+    // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz)
+    private static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60;  // one hour
+    private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2;  // two hours
+
+    private Context mContext;
+    private PackageManager mPackageManager;
+    private IPackageManager mPackageManagerBinder;
+    private IActivityManager mActivityManager;
+    private PowerManager mPowerManager;
+    private AlarmManager mAlarmManager;
+    private IStorageManager mStorageManager;
+
+    private IBackupManager mBackupManagerBinder;
+
+    private final TransportManager mTransportManager;
+
+    private boolean mEnabled;   // access to this is synchronized on 'this'
+    private boolean mProvisioned;
+    private boolean mAutoRestore;
+    private PowerManager.WakeLock mWakelock;
+    private HandlerThread mHandlerThread;
+    private BackupHandler mBackupHandler;
+    private PendingIntent mRunBackupIntent;
+    private PendingIntent mRunInitIntent;
+    private BroadcastReceiver mRunBackupReceiver;
+    private BroadcastReceiver mRunInitReceiver;
+    // map UIDs to the set of participating packages under that UID
+    private final SparseArray<HashSet<String>> mBackupParticipants
+            = new SparseArray<>();
+
+    // Backups that we haven't started yet.  Keys are package names.
+    private HashMap<String, BackupRequest> mPendingBackups
+            = new HashMap<>();
+
+    // Pseudoname that we use for the Package Manager metadata "package"
+    public static final String PACKAGE_MANAGER_SENTINEL = "@pm@";
+
+    // locking around the pending-backup management
+    private final Object mQueueLock = new Object();
+
+    // The thread performing the sequence of queued backups binds to each app's agent
+    // in succession.  Bind notifications are asynchronously delivered through the
+    // Activity Manager; use this lock object to signal when a requested binding has
+    // completed.
+    private final Object mAgentConnectLock = new Object();
+    private IBackupAgent mConnectedAgent;
+    private volatile boolean mBackupRunning;
+    private volatile boolean mConnecting;
+    private volatile long mLastBackupPass;
+
+    // For debugging, we maintain a progress trace of operations during backup
+    public static final boolean DEBUG_BACKUP_TRACE = true;
+    private final List<String> mBackupTrace = new ArrayList<>();
+
+    // A similar synchronization mechanism around clearing apps' data for restore
+    private final Object mClearDataLock = new Object();
+    private volatile boolean mClearingData;
+
+    @GuardedBy("mPendingRestores")
+    private boolean mIsRestoreInProgress;
+    @GuardedBy("mPendingRestores")
+    private final Queue<PerformUnifiedRestoreTask> mPendingRestores = new ArrayDeque<>();
+
+    private ActiveRestoreSession mActiveRestoreSession;
+
+    // Watch the device provisioning operation during setup
+    private ContentObserver mProvisionedObserver;
+
+    // The published binder is actually to a singleton trampoline object that calls
+    // through to the proper code.  This indirection lets us turn down the heavy
+    // implementation object on the fly without disturbing binders that have been
+    // cached elsewhere in the system.
+    static Trampoline sInstance;
+
+    static Trampoline getInstance() {
+        // Always constructed during system bringup, so no need to lazy-init
+        return sInstance;
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    public PackageManager getPackageManager() {
+        return mPackageManager;
+    }
+
+    public void setPackageManager(PackageManager packageManager) {
+        mPackageManager = packageManager;
+    }
+
+    public IPackageManager getPackageManagerBinder() {
+        return mPackageManagerBinder;
+    }
+
+    public void setPackageManagerBinder(IPackageManager packageManagerBinder) {
+        mPackageManagerBinder = packageManagerBinder;
+    }
+
+    public IActivityManager getActivityManager() {
+        return mActivityManager;
+    }
+
+    public void setActivityManager(IActivityManager activityManager) {
+        mActivityManager = activityManager;
+    }
+
+    public AlarmManager getAlarmManager() {
+        return mAlarmManager;
+    }
+
+    public void setAlarmManager(AlarmManager alarmManager) {
+        mAlarmManager = alarmManager;
+    }
+
+    public void setBackupManagerBinder(IBackupManager backupManagerBinder) {
+        mBackupManagerBinder = backupManagerBinder;
+    }
+
+    public TransportManager getTransportManager() {
+        return mTransportManager;
+    }
+
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        mEnabled = enabled;
+    }
+
+    public boolean isProvisioned() {
+        return mProvisioned;
+    }
+
+    public void setProvisioned(boolean provisioned) {
+        mProvisioned = provisioned;
+    }
+
+    public PowerManager.WakeLock getWakelock() {
+        return mWakelock;
+    }
+
+    public void setWakelock(PowerManager.WakeLock wakelock) {
+        mWakelock = wakelock;
+    }
+
+    public BackupHandler getBackupHandler() {
+        return mBackupHandler;
+    }
+
+    public void setBackupHandler(BackupHandler backupHandler) {
+        mBackupHandler = backupHandler;
+    }
+
+    public PendingIntent getRunInitIntent() {
+        return mRunInitIntent;
+    }
+
+    public void setRunInitIntent(PendingIntent runInitIntent) {
+        mRunInitIntent = runInitIntent;
+    }
+
+    public HashMap<String, BackupRequest> getPendingBackups() {
+        return mPendingBackups;
+    }
+
+    public void setPendingBackups(
+            HashMap<String, BackupRequest> pendingBackups) {
+        mPendingBackups = pendingBackups;
+    }
+
+    public Object getQueueLock() {
+        return mQueueLock;
+    }
+
+    public boolean isBackupRunning() {
+        return mBackupRunning;
+    }
+
+    public void setBackupRunning(boolean backupRunning) {
+        mBackupRunning = backupRunning;
+    }
+
+    public long getLastBackupPass() {
+        return mLastBackupPass;
+    }
+
+    public void setLastBackupPass(long lastBackupPass) {
+        mLastBackupPass = lastBackupPass;
+    }
+
+    public Object getClearDataLock() {
+        return mClearDataLock;
+    }
+
+    public boolean isClearingData() {
+        return mClearingData;
+    }
+
+    public void setClearingData(boolean clearingData) {
+        mClearingData = clearingData;
+    }
+
+    public boolean isRestoreInProgress() {
+        return mIsRestoreInProgress;
+    }
+
+    public void setRestoreInProgress(boolean restoreInProgress) {
+        mIsRestoreInProgress = restoreInProgress;
+    }
+
+    public Queue<PerformUnifiedRestoreTask> getPendingRestores() {
+        return mPendingRestores;
+    }
+
+    public ActiveRestoreSession getActiveRestoreSession() {
+        return mActiveRestoreSession;
+    }
+
+    public void setActiveRestoreSession(
+            ActiveRestoreSession activeRestoreSession) {
+        mActiveRestoreSession = activeRestoreSession;
+    }
+
+    public SparseArray<Operation> getCurrentOperations() {
+        return mCurrentOperations;
+    }
+
+    public Object getCurrentOpLock() {
+        return mCurrentOpLock;
+    }
+
+    public SparseArray<AdbParams> getAdbBackupRestoreConfirmations() {
+        return mAdbBackupRestoreConfirmations;
+    }
+
+    public File getBaseStateDir() {
+        return mBaseStateDir;
+    }
+
+    public void setBaseStateDir(File baseStateDir) {
+        mBaseStateDir = baseStateDir;
+    }
+
+    public File getDataDir() {
+        return mDataDir;
+    }
+
+    public void setDataDir(File dataDir) {
+        mDataDir = dataDir;
+    }
+
+    public File getJournal() {
+        return mJournal;
+    }
+
+    public void setJournal(File journal) {
+        mJournal = journal;
+    }
+
+    public SecureRandom getRng() {
+        return mRng;
+    }
+
+    public Set<String> getAncestralPackages() {
+        return mAncestralPackages;
+    }
+
+    public void setAncestralPackages(Set<String> ancestralPackages) {
+        mAncestralPackages = ancestralPackages;
+    }
+
+    public long getAncestralToken() {
+        return mAncestralToken;
+    }
+
+    public void setAncestralToken(long ancestralToken) {
+        mAncestralToken = ancestralToken;
+    }
+
+    public long getCurrentToken() {
+        return mCurrentToken;
+    }
+
+    public void setCurrentToken(long currentToken) {
+        mCurrentToken = currentToken;
+    }
+
+    public HashSet<String> getPendingInits() {
+        return mPendingInits;
+    }
+
+    public void setPendingInits(HashSet<String> pendingInits) {
+        mPendingInits = pendingInits;
+    }
+
+    public PerformFullTransportBackupTask getRunningFullBackupTask() {
+        return mRunningFullBackupTask;
+    }
+
+    public void setRunningFullBackupTask(
+            PerformFullTransportBackupTask runningFullBackupTask) {
+        mRunningFullBackupTask = runningFullBackupTask;
+    }
+
+    public static final class Lifecycle extends SystemService {
+
+        public Lifecycle(Context context) {
+            super(context);
+            sInstance = new Trampoline(context);
+        }
+
+        @Override
+        public void onStart() {
+            publishBinderService(Context.BACKUP_SERVICE, sInstance);
+        }
+
+        @Override
+        public void onUnlockUser(int userId) {
+            if (userId == UserHandle.USER_SYSTEM) {
+                sInstance.initialize(userId);
+
+                // Migrate legacy setting
+                if (!backupSettingMigrated(userId)) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "Backup enable apparently not migrated");
+                    }
+                    final ContentResolver r = sInstance.mContext.getContentResolver();
+                    final int enableState = Settings.Secure.getIntForUser(r,
+                            Settings.Secure.BACKUP_ENABLED, -1, userId);
+                    if (enableState >= 0) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Migrating enable state " + (enableState != 0));
+                        }
+                        writeBackupEnableState(enableState != 0, userId);
+                        Settings.Secure.putStringForUser(r,
+                                Settings.Secure.BACKUP_ENABLED, null, userId);
+                    } else {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Backup not yet configured; retaining null enable state");
+                        }
+                    }
+                }
+
+                try {
+                    sInstance.setBackupEnabled(readBackupEnableState(userId));
+                } catch (RemoteException e) {
+                    // can't happen; it's a local object
+                }
+            }
+        }
+    }
+
+    // Bookkeeping of in-flight operations for timeout etc. purposes.  The operation
+    // token is the index of the entry in the pending-operations list.
+    public static final int OP_PENDING = 0;
+    private static final int OP_ACKNOWLEDGED = 1;
+    private static final int OP_TIMEOUT = -1;
+
+    // Waiting for backup agent to respond during backup operation.
+    public static final int OP_TYPE_BACKUP_WAIT = 0;
+
+    // Waiting for backup agent to respond during restore operation.
+    public static final int OP_TYPE_RESTORE_WAIT = 1;
+
+    // An entire backup operation spanning multiple packages.
+    public static final int OP_TYPE_BACKUP = 2;
+
+    /**
+     * mCurrentOperations contains the list of currently active operations.
+     *
+     * If type of operation is OP_TYPE_WAIT, it are waiting for an ack or timeout.
+     * An operation wraps a BackupRestoreTask within it.
+     * It's the responsibility of this task to remove the operation from this array.
+     *
+     * A BackupRestore task gets notified of ack/timeout for the operation via
+     * BackupRestoreTask#handleCancel, BackupRestoreTask#operationComplete and notifyAll called
+     * on the mCurrentOpLock.
+     * {@link RefactoredBackupManagerService#waitUntilOperationComplete(int)} is
+     * used in various places to 'wait' for notifyAll and detect change of pending state of an
+     * operation. So typically, an operation will be removed from this array by:
+     *   - BackupRestoreTask#handleCancel and
+     *   - BackupRestoreTask#operationComplete OR waitUntilOperationComplete. Do not remove at both
+     *     these places because waitUntilOperationComplete relies on the operation being present to
+     *     determine its completion status.
+     *
+     * If type of operation is OP_BACKUP, it is a task running backups. It provides a handle to
+     * cancel backup tasks.
+     */
+    @GuardedBy("mCurrentOpLock")
+    private final SparseArray<Operation> mCurrentOperations = new SparseArray<>();
+    private final Object mCurrentOpLock = new Object();
+    private final Random mTokenGenerator = new Random();
+
+    private final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<>();
+
+    // Where we keep our journal files and other bookkeeping
+    private File mBaseStateDir;
+    private File mDataDir;
+    private File mJournalDir;
+    private File mJournal;
+
+    // Backup password, if any, and the file where it's saved.  What is stored is not the
+    // password text itself; it's the result of a PBKDF2 hash with a randomly chosen (but
+    // persisted) salt.  Validation is performed by running the challenge text through the
+    // same PBKDF2 cycle with the persisted salt; if the resulting derived key string matches
+    // the saved hash string, then the challenge text matches the originally supplied
+    // password text.
+    private final SecureRandom mRng = new SecureRandom();
+    private String mPasswordHash;
+    private File mPasswordHashFile;
+    private int mPasswordVersion;
+    private File mPasswordVersionFile;
+    private byte[] mPasswordSalt;
+
+    // Keep a log of all the apps we've ever backed up, and what the
+    // dataset tokens are for both the current backup dataset and
+    // the ancestral dataset.
+    private File mEverStored;
+    private HashSet<String> mEverStoredApps = new HashSet<>();
+
+    private static final int CURRENT_ANCESTRAL_RECORD_VERSION = 1;
+    // increment when the schema changes
+    private File mTokenFile;
+    private Set<String> mAncestralPackages = null;
+    private long mAncestralToken = 0;
+    private long mCurrentToken = 0;
+
+    // Persistently track the need to do a full init
+    private static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
+    private HashSet<String> mPendingInits = new HashSet<>();  // transport names
+
+    // Round-robin queue for scheduling full backup passes
+    private static final int SCHEDULE_FILE_VERSION = 1; // current version of the schedule file
+
+    private File mFullBackupScheduleFile;
+    // If we're running a schedule-driven full backup, this is the task instance doing it
+
+    @GuardedBy("mQueueLock")
+    private PerformFullTransportBackupTask mRunningFullBackupTask;
+
+    @GuardedBy("mQueueLock")
+    private ArrayList<FullBackupEntry> mFullBackupQueue;
+
+    // Utility: build a new random integer token
+    @Override
+    public int generateRandomIntegerToken() {
+        int token;
+        do {
+            synchronized (mTokenGenerator) {
+                token = mTokenGenerator.nextInt();
+            }
+        } while (token < 0);
+        return token;
+    }
+
+    // ----- Debug-only backup operation trace -----
+    public void addBackupTrace(String s) {
+        if (DEBUG_BACKUP_TRACE) {
+            synchronized (mBackupTrace) {
+                mBackupTrace.add(s);
+            }
+        }
+    }
+
+    public void clearBackupTrace() {
+        if (DEBUG_BACKUP_TRACE) {
+            synchronized (mBackupTrace) {
+                mBackupTrace.clear();
+            }
+        }
+    }
+
+    // ----- Main service implementation -----
+
+    public RefactoredBackupManagerService(Context context, Trampoline parent) {
+        mContext = context;
+        mPackageManager = context.getPackageManager();
+        mPackageManagerBinder = AppGlobals.getPackageManager();
+        mActivityManager = ActivityManager.getService();
+
+        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
+
+        mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
+
+        // spin up the backup/restore handler thread
+        mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
+        mHandlerThread.start();
+        mBackupHandler = new BackupHandler(this, mHandlerThread.getLooper());
+
+        // Set up our bookkeeping
+        final ContentResolver resolver = context.getContentResolver();
+        mProvisioned = Settings.Global.getInt(resolver,
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        mAutoRestore = Settings.Secure.getInt(resolver,
+                Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
+
+        mProvisionedObserver = new ProvisionedObserver(this, mBackupHandler);
+        resolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                false, mProvisionedObserver);
+
+        // If Encrypted file systems is enabled or disabled, this call will return the
+        // correct directory.
+        mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
+        mBaseStateDir.mkdirs();
+        if (!SELinux.restorecon(mBaseStateDir)) {
+            Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
+        }
+
+        // This dir on /cache is managed directly in init.rc
+        mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup_stage");
+
+        mPasswordVersion = 1;       // unless we hear otherwise
+        mPasswordVersionFile = new File(mBaseStateDir, "pwversion");
+        if (mPasswordVersionFile.exists()) {
+            FileInputStream fin = null;
+            DataInputStream in = null;
+            try {
+                fin = new FileInputStream(mPasswordVersionFile);
+                in = new DataInputStream(fin);
+                mPasswordVersion = in.readInt();
+            } catch (IOException e) {
+                Slog.e(TAG, "Unable to read backup pw version");
+            } finally {
+                try {
+                    if (in != null) in.close();
+                    if (fin != null) fin.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error closing pw version files");
+                }
+            }
+        }
+
+        mPasswordHashFile = new File(mBaseStateDir, "pwhash");
+        if (mPasswordHashFile.exists()) {
+            FileInputStream fin = null;
+            DataInputStream in = null;
+            try {
+                fin = new FileInputStream(mPasswordHashFile);
+                in = new DataInputStream(new BufferedInputStream(fin));
+                // integer length of the salt array, followed by the salt,
+                // then the hex pw hash string
+                int saltLen = in.readInt();
+                byte[] salt = new byte[saltLen];
+                in.readFully(salt);
+                mPasswordHash = in.readUTF();
+                mPasswordSalt = salt;
+            } catch (IOException e) {
+                Slog.e(TAG, "Unable to read saved backup pw hash");
+            } finally {
+                try {
+                    if (in != null) in.close();
+                    if (fin != null) fin.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close streams");
+                }
+            }
+        }
+
+        // Alarm receivers for scheduled backups & initialization operations
+        mRunBackupReceiver = new RunBackupReceiver(this);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(RUN_BACKUP_ACTION);
+        context.registerReceiver(mRunBackupReceiver, filter,
+                android.Manifest.permission.BACKUP, null);
+
+        mRunInitReceiver = new RunInitializeReceiver(this);
+        filter = new IntentFilter();
+        filter.addAction(RUN_INITIALIZE_ACTION);
+        context.registerReceiver(mRunInitReceiver, filter,
+                android.Manifest.permission.BACKUP, null);
+
+        Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
+        backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mRunBackupIntent = PendingIntent.getBroadcast(context, MSG_RUN_BACKUP, backupIntent, 0);
+
+        Intent initIntent = new Intent(RUN_INITIALIZE_ACTION);
+        backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mRunInitIntent = PendingIntent.getBroadcast(context, MSG_RUN_INITIALIZE, initIntent, 0);
+
+        // Set up the backup-request journaling
+        mJournalDir = new File(mBaseStateDir, "pending");
+        mJournalDir.mkdirs();   // creates mBaseStateDir along the way
+        mJournal = null;        // will be created on first use
+
+        // Set up the various sorts of package tracking we do
+        mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
+        initPackageTracking();
+
+        // Build our mapping of uid to backup client services.  This implicitly
+        // schedules a backup pass on the Package Manager metadata the first
+        // time anything needs to be backed up.
+        synchronized (mBackupParticipants) {
+            addPackageParticipantsLocked(null);
+        }
+
+        // Set up our transport options and initialize the default transport
+        // TODO: Don't create transports that we don't need to?
+        SystemConfig systemConfig = SystemConfig.getInstance();
+        Set<ComponentName> transportWhitelist = systemConfig.getBackupTransportWhitelist();
+
+        String transport = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.BACKUP_TRANSPORT);
+        if (TextUtils.isEmpty(transport)) {
+            transport = null;
+        }
+        String currentTransport = transport;
+        if (DEBUG) Slog.v(TAG, "Starting with transport " + currentTransport);
+
+        mTransportManager = new TransportManager(context, transportWhitelist, currentTransport,
+                mTransportBoundListener, mHandlerThread.getLooper());
+        mTransportManager.registerAllTransports();
+
+        // Now that we know about valid backup participants, parse any
+        // leftover journal files into the pending backup set
+        mBackupHandler.post(() -> parseLeftoverJournals());
+
+        // Power management
+        mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*");
+    }
+
+    private void initPackageTracking() {
+        if (MORE_DEBUG) Slog.v(TAG, "` tracking");
+
+        // Remember our ancestral dataset
+        mTokenFile = new File(mBaseStateDir, "ancestral");
+        try {
+            RandomAccessFile tf = new RandomAccessFile(mTokenFile, "r");
+            int version = tf.readInt();
+            if (version == CURRENT_ANCESTRAL_RECORD_VERSION) {
+                mAncestralToken = tf.readLong();
+                mCurrentToken = tf.readLong();
+
+                int numPackages = tf.readInt();
+                if (numPackages >= 0) {
+                    mAncestralPackages = new HashSet<>();
+                    for (int i = 0; i < numPackages; i++) {
+                        String pkgName = tf.readUTF();
+                        mAncestralPackages.add(pkgName);
+                    }
+                }
+            }
+            tf.close();
+        } catch (FileNotFoundException fnf) {
+            // Probably innocuous
+            Slog.v(TAG, "No ancestral data");
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to read token file", e);
+        }
+
+        // Keep a log of what apps we've ever backed up.  Because we might have
+        // rebooted in the middle of an operation that was removing something from
+        // this log, we sanity-check its contents here and reconstruct it.
+        mEverStored = new File(mBaseStateDir, "processed");
+        File tempProcessedFile = new File(mBaseStateDir, "processed.new");
+
+        // If we were in the middle of removing something from the ever-backed-up
+        // file, there might be a transient "processed.new" file still present.
+        // Ignore it -- we'll validate "processed" against the current package set.
+        if (tempProcessedFile.exists()) {
+            tempProcessedFile.delete();
+        }
+
+        // If there are previous contents, parse them out then start a new
+        // file to continue the recordkeeping.
+        if (mEverStored.exists()) {
+            RandomAccessFile temp = null;
+            RandomAccessFile in = null;
+
+            try {
+                temp = new RandomAccessFile(tempProcessedFile, "rws");
+                in = new RandomAccessFile(mEverStored, "r");
+
+                // Loop until we hit EOF
+                while (true) {
+                    String pkg = in.readUTF();
+                    try {
+                        // is this package still present?
+                        mPackageManager.getPackageInfo(pkg, 0);
+                        // if we get here then yes it is; remember it
+                        mEverStoredApps.add(pkg);
+                        temp.writeUTF(pkg);
+                        if (MORE_DEBUG) Slog.v(TAG, "   + " + pkg);
+                    } catch (NameNotFoundException e) {
+                        // nope, this package was uninstalled; don't include it
+                        if (MORE_DEBUG) Slog.v(TAG, "   - " + pkg);
+                    }
+                }
+            } catch (EOFException e) {
+                // Once we've rewritten the backup history log, atomically replace the
+                // old one with the new one then reopen the file for continuing use.
+                if (!tempProcessedFile.renameTo(mEverStored)) {
+                    Slog.e(TAG, "Error renaming " + tempProcessedFile + " to " + mEverStored);
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Error in processed file", e);
+            } finally {
+                try {
+                    if (temp != null) temp.close();
+                } catch (IOException e) {
+                }
+                try {
+                    if (in != null) in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        synchronized (mQueueLock) {
+            // Resume the full-data backup queue
+            mFullBackupQueue = readFullBackupSchedule();
+        }
+
+        // Register for broadcasts about package install, etc., so we can
+        // update the provider list.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+        // Register for events related to sdcard installation.
+        IntentFilter sdFilter = new IntentFilter();
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+        mContext.registerReceiver(mBroadcastReceiver, sdFilter);
+    }
+
+    private ArrayList<FullBackupEntry> readFullBackupSchedule() {
+        boolean changed = false;
+        ArrayList<FullBackupEntry> schedule = null;
+        List<PackageInfo> apps =
+                PackageManagerBackupAgent.getStorableApplications(mPackageManager);
+
+        if (mFullBackupScheduleFile.exists()) {
+            FileInputStream fstream = null;
+            BufferedInputStream bufStream = null;
+            DataInputStream in = null;
+            try {
+                fstream = new FileInputStream(mFullBackupScheduleFile);
+                bufStream = new BufferedInputStream(fstream);
+                in = new DataInputStream(bufStream);
+
+                int version = in.readInt();
+                if (version != SCHEDULE_FILE_VERSION) {
+                    Slog.e(TAG, "Unknown backup schedule version " + version);
+                    return null;
+                }
+
+                final int N = in.readInt();
+                schedule = new ArrayList<>(N);
+
+                // HashSet instead of ArraySet specifically because we want the eventual
+                // lookups against O(hundreds) of entries to be as fast as possible, and
+                // we discard the set immediately after the scan so the extra memory
+                // overhead is transient.
+                HashSet<String> foundApps = new HashSet<>(N);
+
+                for (int i = 0; i < N; i++) {
+                    String pkgName = in.readUTF();
+                    long lastBackup = in.readLong();
+                    foundApps.add(pkgName); // all apps that we've addressed already
+                    try {
+                        PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
+                        if (AppBackupUtils.appGetsFullBackup(pkg)
+                                && AppBackupUtils.appIsEligibleForBackup(
+                                pkg.applicationInfo)) {
+                            schedule.add(new FullBackupEntry(pkgName, lastBackup));
+                        } else {
+                            if (DEBUG) {
+                                Slog.i(TAG, "Package " + pkgName
+                                        + " no longer eligible for full backup");
+                            }
+                        }
+                    } catch (NameNotFoundException e) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Package " + pkgName
+                                    + " not installed; dropping from full backup");
+                        }
+                    }
+                }
+
+                // New apps can arrive "out of band" via OTA and similar, so we also need to
+                // scan to make sure that we're tracking all full-backup candidates properly
+                for (PackageInfo app : apps) {
+                    if (AppBackupUtils.appGetsFullBackup(app)
+                            && AppBackupUtils.appIsEligibleForBackup(
+                            app.applicationInfo)) {
+                        if (!foundApps.contains(app.packageName)) {
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "New full backup app " + app.packageName + " found");
+                            }
+                            schedule.add(new FullBackupEntry(app.packageName, 0));
+                            changed = true;
+                        }
+                    }
+                }
+
+                Collections.sort(schedule);
+            } catch (Exception e) {
+                Slog.e(TAG, "Unable to read backup schedule", e);
+                mFullBackupScheduleFile.delete();
+                schedule = null;
+            } finally {
+                IoUtils.closeQuietly(in);
+                IoUtils.closeQuietly(bufStream);
+                IoUtils.closeQuietly(fstream);
+            }
+        }
+
+        if (schedule == null) {
+            // no prior queue record, or unable to read it.  Set up the queue
+            // from scratch.
+            changed = true;
+            schedule = new ArrayList<>(apps.size());
+            for (PackageInfo info : apps) {
+                if (AppBackupUtils.appGetsFullBackup(info) && AppBackupUtils.appIsEligibleForBackup(
+                        info.applicationInfo)) {
+                    schedule.add(new FullBackupEntry(info.packageName, 0));
+                }
+            }
+        }
+
+        if (changed) {
+            writeFullBackupScheduleAsync();
+        }
+        return schedule;
+    }
+
+    private Runnable mFullBackupScheduleWriter = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mQueueLock) {
+                try {
+                    ByteArrayOutputStream bufStream = new ByteArrayOutputStream(4096);
+                    DataOutputStream bufOut = new DataOutputStream(bufStream);
+                    bufOut.writeInt(SCHEDULE_FILE_VERSION);
+
+                    // version 1:
+                    //
+                    // [int] # of packages in the queue = N
+                    // N * {
+                    //     [utf8] package name
+                    //     [long] last backup time for this package
+                    //     }
+                    int N = mFullBackupQueue.size();
+                    bufOut.writeInt(N);
+
+                    for (int i = 0; i < N; i++) {
+                        FullBackupEntry entry = mFullBackupQueue.get(i);
+                        bufOut.writeUTF(entry.packageName);
+                        bufOut.writeLong(entry.lastBackup);
+                    }
+                    bufOut.flush();
+
+                    AtomicFile af = new AtomicFile(mFullBackupScheduleFile);
+                    FileOutputStream out = af.startWrite();
+                    out.write(bufStream.toByteArray());
+                    af.finishWrite(out);
+                } catch (Exception e) {
+                    Slog.e(TAG, "Unable to write backup schedule!", e);
+                }
+            }
+        }
+    };
+
+    private void writeFullBackupScheduleAsync() {
+        mBackupHandler.removeCallbacks(mFullBackupScheduleWriter);
+        mBackupHandler.post(mFullBackupScheduleWriter);
+    }
+
+    private void parseLeftoverJournals() {
+        for (File f : mJournalDir.listFiles()) {
+            if (mJournal == null || f.compareTo(mJournal) != 0) {
+                // This isn't the current journal, so it must be a leftover.  Read
+                // out the package names mentioned there and schedule them for
+                // backup.
+                DataInputStream in = null;
+                try {
+                    Slog.i(TAG, "Found stale backup journal, scheduling");
+                    // Journals will tend to be on the order of a few kilobytes(around 4k), hence,
+                    // setting the buffer size to 8192.
+                    InputStream bufferedInputStream = new BufferedInputStream(
+                            new FileInputStream(f), 8192);
+                    in = new DataInputStream(bufferedInputStream);
+                    while (true) {
+                        String packageName = in.readUTF();
+                        if (MORE_DEBUG) Slog.i(TAG, "  " + packageName);
+                        dataChangedImpl(packageName);
+                    }
+                } catch (EOFException e) {
+                    // no more data; we're done
+                } catch (Exception e) {
+                    Slog.e(TAG, "Can't read " + f, e);
+                } finally {
+                    // close/delete the file
+                    try {
+                        if (in != null) in.close();
+                    } catch (IOException e) {
+                    }
+                    f.delete();
+                }
+            }
+        }
+    }
+
+    // Used for generating random salts or passwords
+    public byte[] randomBytes(int bits) {
+        byte[] array = new byte[bits / 8];
+        mRng.nextBytes(array);
+        return array;
+    }
+
+    private boolean passwordMatchesSaved(String algorithm, String candidatePw, int rounds) {
+        if (mPasswordHash == null) {
+            // no current password case -- require that 'currentPw' be null or empty
+            if (candidatePw == null || "".equals(candidatePw)) {
+                return true;
+            } // else the non-empty candidate does not match the empty stored pw
+        } else {
+            // hash the stated current pw and compare to the stored one
+            if (candidatePw != null && candidatePw.length() > 0) {
+                String currentPwHash = PasswordUtils.buildPasswordHash(algorithm, candidatePw,
+                        mPasswordSalt,
+                        rounds);
+                if (mPasswordHash.equalsIgnoreCase(currentPwHash)) {
+                    // candidate hash matches the stored hash -- the password matches
+                    return true;
+                }
+            } // else the stored pw is nonempty but the candidate is empty; no match
+        }
+        return false;
+    }
+
+    @Override
+    public boolean setBackupPassword(String currentPw, String newPw) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupPassword");
+
+        // When processing v1 passwords we may need to try two different PBKDF2 checksum regimes
+        final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+
+        // If the supplied pw doesn't hash to the the saved one, fail.  The password
+        // might be caught in the legacy crypto mismatch; verify that too.
+        if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS)
+                && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+                currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS))) {
+            return false;
+        }
+
+        // Snap up to current on the pw file version
+        mPasswordVersion = BACKUP_PW_FILE_VERSION;
+        FileOutputStream pwFout = null;
+        DataOutputStream pwOut = null;
+        try {
+            pwFout = new FileOutputStream(mPasswordVersionFile);
+            pwOut = new DataOutputStream(pwFout);
+            pwOut.writeInt(mPasswordVersion);
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to write backup pw version; password not changed");
+            return false;
+        } finally {
+            try {
+                if (pwOut != null) pwOut.close();
+                if (pwFout != null) pwFout.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to close pw version record");
+            }
+        }
+
+        // Clearing the password is okay
+        if (newPw == null || newPw.isEmpty()) {
+            if (mPasswordHashFile.exists()) {
+                if (!mPasswordHashFile.delete()) {
+                    // Unable to delete the old pw file, so fail
+                    Slog.e(TAG, "Unable to clear backup password");
+                    return false;
+                }
+            }
+            mPasswordHash = null;
+            mPasswordSalt = null;
+            return true;
+        }
+
+        try {
+            // Okay, build the hash of the new backup password
+            byte[] salt = randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+            String newPwHash = PasswordUtils.buildPasswordHash(PBKDF_CURRENT, newPw, salt,
+                    PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+            OutputStream pwf = null, buffer = null;
+            DataOutputStream out = null;
+            try {
+                pwf = new FileOutputStream(mPasswordHashFile);
+                buffer = new BufferedOutputStream(pwf);
+                out = new DataOutputStream(buffer);
+                // integer length of the salt array, followed by the salt,
+                // then the hex pw hash string
+                out.writeInt(salt.length);
+                out.write(salt);
+                out.writeUTF(newPwHash);
+                out.flush();
+                mPasswordHash = newPwHash;
+                mPasswordSalt = salt;
+                return true;
+            } finally {
+                if (out != null) out.close();
+                if (buffer != null) buffer.close();
+                if (pwf != null) pwf.close();
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to set backup password");
+        }
+        return false;
+    }
+
+    @Override
+    public boolean hasBackupPassword() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "hasBackupPassword");
+
+        return mPasswordHash != null && mPasswordHash.length() > 0;
+    }
+
+    public boolean backupPasswordMatches(String currentPw) {
+        if (hasBackupPassword()) {
+            final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+            if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS)
+                    && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+                    currentPw, PasswordUtils.PBKDF2_HASH_ROUNDS))) {
+                if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // Maintain persistent state around whether need to do an initialize operation.
+    // Must be called with the queue lock held.
+    public void recordInitPendingLocked(boolean isPending, String transportName) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "recordInitPendingLocked: " + isPending
+                    + " on transport " + transportName);
+        }
+        mBackupHandler.removeMessages(MSG_RETRY_INIT);
+
+        try {
+            IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+            if (transport != null) {
+                String transportDirName = transport.transportDirName();
+                File stateDir = new File(mBaseStateDir, transportDirName);
+                File initPendingFile = new File(stateDir, INIT_SENTINEL_FILE_NAME);
+
+                if (isPending) {
+                    // We need an init before we can proceed with sending backup data.
+                    // Record that with an entry in our set of pending inits, as well as
+                    // journaling it via creation of a sentinel file.
+                    mPendingInits.add(transportName);
+                    try {
+                        (new FileOutputStream(initPendingFile)).close();
+                    } catch (IOException ioe) {
+                        // Something is badly wrong with our permissions; just try to move on
+                    }
+                } else {
+                    // No more initialization needed; wipe the journal and reset our state.
+                    initPendingFile.delete();
+                    mPendingInits.remove(transportName);
+                }
+                return; // done; don't fall through to the error case
+            }
+        } catch (Exception e) {
+            // transport threw when asked its name; fall through to the lookup-failed case
+            Slog.e(TAG, "Transport " + transportName + " failed to report name: "
+                    + e.getMessage());
+        }
+
+        // The named transport doesn't exist or threw.  This operation is
+        // important, so we record the need for a an init and post a message
+        // to retry the init later.
+        if (isPending) {
+            mPendingInits.add(transportName);
+            mBackupHandler.sendMessageDelayed(
+                    mBackupHandler.obtainMessage(MSG_RETRY_INIT,
+                            (isPending ? 1 : 0),
+                            0,
+                            transportName),
+                    TRANSPORT_RETRY_INTERVAL);
+        }
+    }
+
+    // Reset all of our bookkeeping, in response to having been told that
+    // the backend data has been wiped [due to idle expiry, for example],
+    // so we must re-upload all saved settings.
+    public void resetBackupState(File stateFileDir) {
+        synchronized (mQueueLock) {
+            // Wipe the "what we've ever backed up" tracking
+            mEverStoredApps.clear();
+            mEverStored.delete();
+
+            mCurrentToken = 0;
+            writeRestoreTokens();
+
+            // Remove all the state files
+            for (File sf : stateFileDir.listFiles()) {
+                // ... but don't touch the needs-init sentinel
+                if (!sf.getName().equals(INIT_SENTINEL_FILE_NAME)) {
+                    sf.delete();
+                }
+            }
+        }
+
+        // Enqueue a new backup of every participant
+        synchronized (mBackupParticipants) {
+            final int N = mBackupParticipants.size();
+            for (int i = 0; i < N; i++) {
+                HashSet<String> participants = mBackupParticipants.valueAt(i);
+                if (participants != null) {
+                    for (String packageName : participants) {
+                        dataChangedImpl(packageName);
+                    }
+                }
+            }
+        }
+    }
+
+    private TransportManager.TransportBoundListener mTransportBoundListener =
+            new TransportManager.TransportBoundListener() {
+                @Override
+                public boolean onTransportBound(IBackupTransport transport) {
+                    // If the init sentinel file exists, we need to be sure to perform the init
+                    // as soon as practical.  We also create the state directory at registration
+                    // time to ensure it's present from the outset.
+                    String name = null;
+                    try {
+                        name = transport.name();
+                        String transportDirName = transport.transportDirName();
+                        File stateDir = new File(mBaseStateDir, transportDirName);
+                        stateDir.mkdirs();
+
+                        File initSentinel = new File(stateDir, INIT_SENTINEL_FILE_NAME);
+                        if (initSentinel.exists()) {
+                            synchronized (mQueueLock) {
+                                mPendingInits.add(name);
+
+                                // TODO: pick a better starting time than now + 1 minute
+                                long delay = 1000 * 60; // one minute, in milliseconds
+                                mAlarmManager.set(AlarmManager.RTC_WAKEUP,
+                                        System.currentTimeMillis() + delay, mRunInitIntent);
+                            }
+                        }
+                        return true;
+                    } catch (Exception e) {
+                        // the transport threw when asked its file naming prefs; declare it invalid
+                        Slog.w(TAG, "Failed to regiser transport: " + name);
+                        return false;
+                    }
+                }
+            };
+
+    // ----- Track installation/removal of packages -----
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (MORE_DEBUG) Slog.d(TAG, "Received broadcast " + intent);
+
+            String action = intent.getAction();
+            boolean replacing = false;
+            boolean added = false;
+            boolean changed = false;
+            Bundle extras = intent.getExtras();
+            String pkgList[] = null;
+            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+                    Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+                Uri uri = intent.getData();
+                if (uri == null) {
+                    return;
+                }
+                String pkgName = uri.getSchemeSpecificPart();
+                if (pkgName != null) {
+                    pkgList = new String[]{pkgName};
+                }
+                changed = Intent.ACTION_PACKAGE_CHANGED.equals(action);
+
+                // At package-changed we only care about looking at new transport states
+                if (changed) {
+                    String[] components =
+                            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
+
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Package " + pkgName + " changed; rechecking");
+                        for (int i = 0; i < components.length; i++) {
+                            Slog.i(TAG, "   * " + components[i]);
+                        }
+                    }
+
+                    mTransportManager.onPackageChanged(pkgName, components);
+                    return; // nothing more to do in the PACKAGE_CHANGED case
+                }
+
+                added = Intent.ACTION_PACKAGE_ADDED.equals(action);
+                replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
+            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
+                added = true;
+                pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+                added = false;
+                pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            }
+
+            if (pkgList == null || pkgList.length == 0) {
+                return;
+            }
+
+            final int uid = extras.getInt(Intent.EXTRA_UID);
+            if (added) {
+                synchronized (mBackupParticipants) {
+                    if (replacing) {
+                        // This is the package-replaced case; we just remove the entry
+                        // under the old uid and fall through to re-add.  If an app
+                        // just added key/value backup participation, this picks it up
+                        // as a known participant.
+                        removePackageParticipantsLocked(pkgList, uid);
+                    }
+                    addPackageParticipantsLocked(pkgList);
+                }
+                // If they're full-backup candidates, add them there instead
+                final long now = System.currentTimeMillis();
+                for (String packageName : pkgList) {
+                    try {
+                        PackageInfo app = mPackageManager.getPackageInfo(packageName, 0);
+                        if (AppBackupUtils.appGetsFullBackup(app)
+                                && AppBackupUtils.appIsEligibleForBackup(
+                                app.applicationInfo)) {
+                            enqueueFullBackup(packageName, now);
+                            scheduleNextFullBackupJob(0);
+                        } else {
+                            // The app might have just transitioned out of full-data into
+                            // doing key/value backups, or might have just disabled backups
+                            // entirely.  Make sure it is no longer in the full-data queue.
+                            synchronized (mQueueLock) {
+                                dequeueFullBackupLocked(packageName);
+                            }
+                            writeFullBackupScheduleAsync();
+                        }
+
+                        mTransportManager.onPackageAdded(packageName);
+
+                    } catch (NameNotFoundException e) {
+                        // doesn't really exist; ignore it
+                        if (DEBUG) {
+                            Slog.w(TAG, "Can't resolve new app " + packageName);
+                        }
+                    }
+                }
+
+                // Whenever a package is added or updated we need to update
+                // the package metadata bookkeeping.
+                dataChangedImpl(PACKAGE_MANAGER_SENTINEL);
+            } else {
+                if (replacing) {
+                    // The package is being updated.  We'll receive a PACKAGE_ADDED shortly.
+                } else {
+                    // Outright removal.  In the full-data case, the app will be dropped
+                    // from the queue when its (now obsolete) name comes up again for
+                    // backup.
+                    synchronized (mBackupParticipants) {
+                        removePackageParticipantsLocked(pkgList, uid);
+                    }
+                }
+                for (String pkgName : pkgList) {
+                    mTransportManager.onPackageRemoved(pkgName);
+                }
+            }
+        }
+    };
+
+    // Add the backup agents in the given packages to our set of known backup participants.
+    // If 'packageNames' is null, adds all backup agents in the whole system.
+    private void addPackageParticipantsLocked(String[] packageNames) {
+        // Look for apps that define the android:backupAgent attribute
+        List<PackageInfo> targetApps = allAgentPackages();
+        if (packageNames != null) {
+            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length);
+            for (String packageName : packageNames) {
+                addPackageParticipantsLockedInner(packageName, targetApps);
+            }
+        } else {
+            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all");
+            addPackageParticipantsLockedInner(null, targetApps);
+        }
+    }
+
+    private void addPackageParticipantsLockedInner(String packageName,
+            List<PackageInfo> targetPkgs) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Examining " + packageName + " for backup agent");
+        }
+
+        for (PackageInfo pkg : targetPkgs) {
+            if (packageName == null || pkg.packageName.equals(packageName)) {
+                int uid = pkg.applicationInfo.uid;
+                HashSet<String> set = mBackupParticipants.get(uid);
+                if (set == null) {
+                    set = new HashSet<>();
+                    mBackupParticipants.put(uid, set);
+                }
+                set.add(pkg.packageName);
+                if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
+
+                // Schedule a backup for it on general principles
+                if (MORE_DEBUG) Slog.i(TAG, "Scheduling backup for new app " + pkg.packageName);
+                Message msg = mBackupHandler
+                        .obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName);
+                mBackupHandler.sendMessage(msg);
+            }
+        }
+    }
+
+    // Remove the given packages' entries from our known active set.
+    private void removePackageParticipantsLocked(String[] packageNames, int oldUid) {
+        if (packageNames == null) {
+            Slog.w(TAG, "removePackageParticipants with null list");
+            return;
+        }
+
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "removePackageParticipantsLocked: uid=" + oldUid
+                    + " #" + packageNames.length);
+        }
+        for (String pkg : packageNames) {
+            // Known previous UID, so we know which package set to check
+            HashSet<String> set = mBackupParticipants.get(oldUid);
+            if (set != null && set.contains(pkg)) {
+                removePackageFromSetLocked(set, pkg);
+                if (set.isEmpty()) {
+                    if (MORE_DEBUG) Slog.v(TAG, "  last one of this uid; purging set");
+                    mBackupParticipants.remove(oldUid);
+                }
+            }
+        }
+    }
+
+    private void removePackageFromSetLocked(final HashSet<String> set,
+            final String packageName) {
+        if (set.contains(packageName)) {
+            // Found it.  Remove this one package from the bookkeeping, and
+            // if it's the last participating app under this uid we drop the
+            // (now-empty) set as well.
+            // Note that we deliberately leave it 'known' in the "ever backed up"
+            // bookkeeping so that its current-dataset data will be retrieved
+            // if the app is subsequently reinstalled
+            if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + packageName);
+            set.remove(packageName);
+            mPendingBackups.remove(packageName);
+        }
+    }
+
+    // Returns the set of all applications that define an android:backupAgent attribute
+    private List<PackageInfo> allAgentPackages() {
+        // !!! TODO: cache this and regenerate only when necessary
+        int flags = PackageManager.GET_SIGNATURES;
+        List<PackageInfo> packages = mPackageManager.getInstalledPackages(flags);
+        int N = packages.size();
+        for (int a = N - 1; a >= 0; a--) {
+            PackageInfo pkg = packages.get(a);
+            try {
+                ApplicationInfo app = pkg.applicationInfo;
+                if (((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
+                        || app.backupAgentName == null
+                        || (app.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0) {
+                    packages.remove(a);
+                } else {
+                    // we will need the shared library path, so look that up and store it here.
+                    // This is used implicitly when we pass the PackageInfo object off to
+                    // the Activity Manager to launch the app for backup/restore purposes.
+                    app = mPackageManager.getApplicationInfo(pkg.packageName,
+                            PackageManager.GET_SHARED_LIBRARY_FILES);
+                    pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles;
+                }
+            } catch (NameNotFoundException e) {
+                packages.remove(a);
+            }
+        }
+        return packages;
+    }
+
+    // Called from the backup tasks: record that the given app has been successfully
+    // backed up at least once.  This includes both key/value and full-data backups
+    // through the transport.
+    public void logBackupComplete(String packageName) {
+        if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) return;
+
+        synchronized (mEverStoredApps) {
+            if (!mEverStoredApps.add(packageName)) return;
+
+            RandomAccessFile out = null;
+            try {
+                out = new RandomAccessFile(mEverStored, "rws");
+                out.seek(out.length());
+                out.writeUTF(packageName);
+            } catch (IOException e) {
+                Slog.e(TAG, "Can't log backup of " + packageName + " to " + mEverStored);
+            } finally {
+                try {
+                    if (out != null) out.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    // Remove our awareness of having ever backed up the given package
+    void removeEverBackedUp(String packageName) {
+        if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName);
+        if (MORE_DEBUG) Slog.v(TAG, "New set:");
+
+        synchronized (mEverStoredApps) {
+            // Rewrite the file and rename to overwrite.  If we reboot in the middle,
+            // we'll recognize on initialization time that the package no longer
+            // exists and fix it up then.
+            File tempKnownFile = new File(mBaseStateDir, "processed.new");
+            RandomAccessFile known = null;
+            try {
+                known = new RandomAccessFile(tempKnownFile, "rws");
+                mEverStoredApps.remove(packageName);
+                for (String s : mEverStoredApps) {
+                    known.writeUTF(s);
+                    if (MORE_DEBUG) Slog.v(TAG, "    " + s);
+                }
+                known.close();
+                known = null;
+                if (!tempKnownFile.renameTo(mEverStored)) {
+                    throw new IOException("Can't rename " + tempKnownFile + " to " + mEverStored);
+                }
+            } catch (IOException e) {
+                // Bad: we couldn't create the new copy.  For safety's sake we
+                // abandon the whole process and remove all what's-backed-up
+                // state entirely, meaning we'll force a backup pass for every
+                // participant on the next boot or [re]install.
+                Slog.w(TAG, "Error rewriting " + mEverStored, e);
+                mEverStoredApps.clear();
+                tempKnownFile.delete();
+                mEverStored.delete();
+            } finally {
+                try {
+                    if (known != null) known.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    // Persistently record the current and ancestral backup tokens as well
+    // as the set of packages with data [supposedly] available in the
+    // ancestral dataset.
+    public void writeRestoreTokens() {
+        try {
+            RandomAccessFile af = new RandomAccessFile(mTokenFile, "rwd");
+
+            // First, the version number of this record, for futureproofing
+            af.writeInt(CURRENT_ANCESTRAL_RECORD_VERSION);
+
+            // Write the ancestral and current tokens
+            af.writeLong(mAncestralToken);
+            af.writeLong(mCurrentToken);
+
+            // Now write the set of ancestral packages
+            if (mAncestralPackages == null) {
+                af.writeInt(-1);
+            } else {
+                af.writeInt(mAncestralPackages.size());
+                if (DEBUG) Slog.v(TAG, "Ancestral packages:  " + mAncestralPackages.size());
+                for (String pkgName : mAncestralPackages) {
+                    af.writeUTF(pkgName);
+                    if (MORE_DEBUG) Slog.v(TAG, "   " + pkgName);
+                }
+            }
+            af.close();
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to write token file:", e);
+        }
+    }
+
+    // What name is this transport registered under...?
+    private String getTransportName(IBackupTransport transport) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Searching for transport name of " + transport);
+        }
+        return mTransportManager.getTransportName(transport);
+    }
+
+    // fire off a backup agent, blocking until it attaches or times out
+    @Override
+    public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+        IBackupAgent agent = null;
+        synchronized (mAgentConnectLock) {
+            mConnecting = true;
+            mConnectedAgent = null;
+            try {
+                if (mActivityManager.bindBackupAgent(app.packageName, mode,
+                        UserHandle.USER_OWNER)) {
+                    Slog.d(TAG, "awaiting agent for " + app);
+
+                    // success; wait for the agent to arrive
+                    // only wait 10 seconds for the bind to happen
+                    long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+                    while (mConnecting && mConnectedAgent == null
+                            && (System.currentTimeMillis() < timeoutMark)) {
+                        try {
+                            mAgentConnectLock.wait(5000);
+                        } catch (InterruptedException e) {
+                            // just bail
+                            Slog.w(TAG, "Interrupted: " + e);
+                            mConnecting = false;
+                            mConnectedAgent = null;
+                        }
+                    }
+
+                    // if we timed out with no connect, abort and move on
+                    if (mConnecting == true) {
+                        Slog.w(TAG, "Timeout waiting for agent " + app);
+                        mConnectedAgent = null;
+                    }
+                    if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent);
+                    agent = mConnectedAgent;
+                }
+            } catch (RemoteException e) {
+                // can't happen - ActivityManager is local
+            }
+        }
+        if (agent == null) {
+            try {
+                mActivityManager.clearPendingBackup();
+            } catch (RemoteException e) {
+                // can't happen - ActivityManager is local
+            }
+        }
+        return agent;
+    }
+
+    // clear an application's data, blocking until the operation completes or times out
+    public void clearApplicationDataSynchronous(String packageName) {
+        // Don't wipe packages marked allowClearUserData=false
+        try {
+            PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
+            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "allowClearUserData=false so not wiping "
+                            + packageName);
+                }
+                return;
+            }
+        } catch (NameNotFoundException e) {
+            Slog.w(TAG, "Tried to clear data for " + packageName + " but not found");
+            return;
+        }
+
+        ClearDataObserver observer = new ClearDataObserver(this);
+
+        synchronized (mClearDataLock) {
+            mClearingData = true;
+            try {
+                mActivityManager.clearApplicationUserData(packageName, observer, 0);
+            } catch (RemoteException e) {
+                // can't happen because the activity manager is in this process
+            }
+
+            // only wait 10 seconds for the clear data to happen
+            long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+            while (mClearingData && (System.currentTimeMillis() < timeoutMark)) {
+                try {
+                    mClearDataLock.wait(5000);
+                } catch (InterruptedException e) {
+                    // won't happen, but still.
+                    mClearingData = false;
+                }
+            }
+        }
+    }
+
+    // Get the restore-set token for the best-available restore set for this package:
+    // the active set if possible, else the ancestral one.  Returns zero if none available.
+    @Override
+    public long getAvailableRestoreToken(String packageName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getAvailableRestoreToken");
+
+        long token = mAncestralToken;
+        synchronized (mQueueLock) {
+            if (mEverStoredApps.contains(packageName)) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "App in ever-stored, so using current token");
+                }
+                token = mCurrentToken;
+            }
+        }
+        if (MORE_DEBUG) Slog.i(TAG, "getAvailableRestoreToken() == " + token);
+        return token;
+    }
+
+    @Override
+    public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
+        return requestBackup(packages, observer, null, flags);
+    }
+
+    @Override
+    public int requestBackup(String[] packages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, int flags) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
+
+        if (packages == null || packages.length < 1) {
+            Slog.e(TAG, "No packages named for backup request");
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            monitor = BackupManagerMonitorUtils.monitorEvent(monitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES,
+                    null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            throw new IllegalArgumentException("No packages are provided for backup");
+        }
+
+        IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+        if (transport == null) {
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            monitor = BackupManagerMonitorUtils.monitorEvent(monitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL,
+                    null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+
+        ArrayList<String> fullBackupList = new ArrayList<>();
+        ArrayList<String> kvBackupList = new ArrayList<>();
+        for (String packageName : packages) {
+            if (PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
+                kvBackupList.add(packageName);
+                continue;
+            }
+            try {
+                PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+                        PackageManager.GET_SIGNATURES);
+                if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo)) {
+                    BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                }
+                if (AppBackupUtils.appGetsFullBackup(packageInfo)) {
+                    fullBackupList.add(packageInfo.packageName);
+                } else {
+                    kvBackupList.add(packageInfo.packageName);
+                }
+            } catch (NameNotFoundException e) {
+                BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
+                        BackupManager.ERROR_PACKAGE_NOT_FOUND);
+            }
+        }
+        EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
+                fullBackupList.size());
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: " +
+                    fullBackupList.size() + " full backups, " + kvBackupList.size()
+                    + " k/v backups");
+        }
+
+        String dirName;
+        try {
+            dirName = transport.transportDirName();
+        } catch (Exception e) {
+            Slog.e(TAG, "Transport unavailable while attempting backup: " + e.getMessage());
+            BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+
+        boolean nonIncrementalBackup = (flags & BackupManager.FLAG_NON_INCREMENTAL_BACKUP) != 0;
+
+        Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP);
+        msg.obj = new BackupParams(transport, dirName, kvBackupList, fullBackupList, observer,
+                monitor, true, nonIncrementalBackup);
+        mBackupHandler.sendMessage(msg);
+        return BackupManager.SUCCESS;
+    }
+
+    // Cancel all running backups.
+    @Override
+    public void cancelBackups() {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "cancelBackups() called.");
+        }
+        final long oldToken = Binder.clearCallingIdentity();
+        try {
+            List<Integer> operationsToCancel = new ArrayList<>();
+            synchronized (mCurrentOpLock) {
+                for (int i = 0; i < mCurrentOperations.size(); i++) {
+                    Operation op = mCurrentOperations.valueAt(i);
+                    int token = mCurrentOperations.keyAt(i);
+                    if (op.type == OP_TYPE_BACKUP) {
+                        operationsToCancel.add(token);
+                    }
+                }
+            }
+            for (Integer token : operationsToCancel) {
+                handleCancel(token, true /* cancelAll */);
+            }
+            // We don't want the backup jobs to kick in any time soon.
+            // Reschedules them to run in the distant future.
+            KeyValueBackupJob.schedule(mContext, BUSY_BACKOFF_MIN_MILLIS);
+            FullBackupJob.schedule(mContext, 2 * BUSY_BACKOFF_MIN_MILLIS);
+        } finally {
+            Binder.restoreCallingIdentity(oldToken);
+        }
+    }
+
+    @Override
+    public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
+            int operationType) {
+        if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
+            Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation " +
+                    Integer.toHexString(token) + " of type " + operationType);
+            return;
+        }
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+                    + " interval=" + interval + " callback=" + callback);
+        }
+
+        synchronized (mCurrentOpLock) {
+            mCurrentOperations.put(token, new Operation(OP_PENDING, callback, operationType));
+            Message msg = mBackupHandler.obtainMessage(getMessageIdForOperationType(operationType),
+                    token, 0, callback);
+            mBackupHandler.sendMessageDelayed(msg, interval);
+        }
+    }
+
+    private int getMessageIdForOperationType(int operationType) {
+        switch (operationType) {
+            case OP_TYPE_BACKUP_WAIT:
+                return MSG_BACKUP_OPERATION_TIMEOUT;
+            case OP_TYPE_RESTORE_WAIT:
+                return MSG_RESTORE_OPERATION_TIMEOUT;
+            default:
+                Slog.wtf(TAG, "getMessageIdForOperationType called on invalid operation type: " +
+                        operationType);
+                return -1;
+        }
+    }
+
+    public void removeOperation(int token) {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Removing operation token=" + Integer.toHexString(token));
+        }
+        synchronized (mCurrentOpLock) {
+            if (mCurrentOperations.get(token) == null) {
+                Slog.w(TAG, "Duplicate remove for operation. token=" +
+                        Integer.toHexString(token));
+            }
+            mCurrentOperations.remove(token);
+        }
+    }
+
+    // synchronous waiter case
+    @Override
+    public boolean waitUntilOperationComplete(int token) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Blocking until operation complete for "
+                    + Integer.toHexString(token));
+        }
+        int finalState = OP_PENDING;
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            while (true) {
+                op = mCurrentOperations.get(token);
+                if (op == null) {
+                    // mysterious disappearance: treat as success with no callback
+                    break;
+                } else {
+                    if (op.state == OP_PENDING) {
+                        try {
+                            mCurrentOpLock.wait();
+                        } catch (InterruptedException e) {
+                        }
+                        // When the wait is notified we loop around and recheck the current state
+                    } else {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Unblocked waiting for operation token=" +
+                                    Integer.toHexString(token));
+                        }
+                        // No longer pending; we're done
+                        finalState = op.state;
+                        break;
+                    }
+                }
+            }
+        }
+
+        removeOperation(token);
+        if (op != null) {
+            mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+        }
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "operation " + Integer.toHexString(token)
+                    + " complete: finalState=" + finalState);
+        }
+        return finalState == OP_ACKNOWLEDGED;
+    }
+
+    public void handleCancel(int token, boolean cancelAll) {
+        // Notify any synchronous waiters
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            op = mCurrentOperations.get(token);
+            if (MORE_DEBUG) {
+                if (op == null) {
+                    Slog.w(TAG, "Cancel of token " + Integer.toHexString(token)
+                            + " but no op found");
+                }
+            }
+            int state = (op != null) ? op.state : OP_TIMEOUT;
+            if (state == OP_ACKNOWLEDGED) {
+                // The operation finished cleanly, so we have nothing more to do.
+                if (DEBUG) {
+                    Slog.w(TAG, "Operation already got an ack." +
+                            "Should have been removed from mCurrentOperations.");
+                }
+                op = null;
+                mCurrentOperations.delete(token);
+            } else if (state == OP_PENDING) {
+                if (DEBUG) Slog.v(TAG, "Cancel: token=" + Integer.toHexString(token));
+                op.state = OP_TIMEOUT;
+                // Can't delete op from mCurrentOperations here. waitUntilOperationComplete may be
+                // called after we receive cancel here. We need this op's state there.
+
+                // Remove all pending timeout messages for this operation type.
+                mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+            }
+            mCurrentOpLock.notifyAll();
+        }
+
+        // If there's a TimeoutHandler for this event, call it
+        if (op != null && op.callback != null) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "   Invoking cancel on " + op.callback);
+            }
+            op.callback.handleCancel(cancelAll);
+        }
+    }
+
+    // ----- Back up a set of applications via a worker thread -----
+
+    public boolean isBackupOperationInProgress() {
+        synchronized (mCurrentOpLock) {
+            for (int i = 0; i < mCurrentOperations.size(); i++) {
+                Operation op = mCurrentOperations.valueAt(i);
+                if (op.type == OP_TYPE_BACKUP && op.state == OP_PENDING) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    @Override
+    public void tearDownAgentAndKill(ApplicationInfo app) {
+        if (app == null) {
+            // Null means the system package, so just quietly move on.  :)
+            return;
+        }
+
+        try {
+            // unbind and tidy up even on timeout or failure, just in case
+            mActivityManager.unbindBackupAgent(app);
+
+            // The agent was running with a stub Application object, so shut it down.
+            // !!! We hardcode the confirmation UI's package name here rather than use a
+            //     manifest flag!  TODO something less direct.
+            if (app.uid >= Process.FIRST_APPLICATION_UID
+                    && !app.packageName.equals("com.android.backupconfirm")) {
+                if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process");
+                mActivityManager.killApplicationProcess(app.processName, app.uid);
+            } else {
+                if (MORE_DEBUG) Slog.d(TAG, "Not killing after operation: " + app.processName);
+            }
+        } catch (RemoteException e) {
+            Slog.d(TAG, "Lost app trying to shut down");
+        }
+    }
+
+    public boolean deviceIsEncrypted() {
+        try {
+            return mStorageManager.getEncryptionState()
+                    != StorageManager.ENCRYPTION_STATE_NONE
+                    && mStorageManager.getPasswordType()
+                    != StorageManager.CRYPT_TYPE_DEFAULT;
+        } catch (Exception e) {
+            // If we can't talk to the storagemanager service we have a serious problem; fail
+            // "secure" i.e. assuming that the device is encrypted.
+            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
+            return true;
+        }
+    }
+
+    // ----- Full-data backup scheduling -----
+
+    /**
+     * Schedule a job to tell us when it's a good time to run a full backup
+     */
+    public void scheduleNextFullBackupJob(long transportMinLatency) {
+        synchronized (mQueueLock) {
+            if (mFullBackupQueue.size() > 0) {
+                // schedule the next job at the point in the future when the least-recently
+                // backed up app comes due for backup again; or immediately if it's already
+                // due.
+                final long upcomingLastBackup = mFullBackupQueue.get(0).lastBackup;
+                final long timeSinceLast = System.currentTimeMillis() - upcomingLastBackup;
+                final long appLatency = (timeSinceLast < MIN_FULL_BACKUP_INTERVAL)
+                        ? (MIN_FULL_BACKUP_INTERVAL - timeSinceLast) : 0;
+                final long latency = Math.max(transportMinLatency, appLatency);
+                Runnable r = new Runnable() {
+                    @Override
+                    public void run() {
+                        FullBackupJob.schedule(mContext, latency);
+                    }
+                };
+                mBackupHandler.postDelayed(r, 2500);
+            } else {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Full backup queue empty; not scheduling");
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove a package from the full-data queue.
+     */
+    private void dequeueFullBackupLocked(String packageName) {
+        final int N = mFullBackupQueue.size();
+        for (int i = N - 1; i >= 0; i--) {
+            final FullBackupEntry e = mFullBackupQueue.get(i);
+            if (packageName.equals(e.packageName)) {
+                mFullBackupQueue.remove(i);
+            }
+        }
+    }
+
+    /**
+     * Enqueue full backup for the given app, with a note about when it last ran.
+     */
+    public void enqueueFullBackup(String packageName, long lastBackedUp) {
+        FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
+        synchronized (mQueueLock) {
+            // First, sanity check that we aren't adding a duplicate.  Slow but
+            // straightforward; we'll have at most on the order of a few hundred
+            // items in this list.
+            dequeueFullBackupLocked(packageName);
+
+            // This is also slow but easy for modest numbers of apps: work backwards
+            // from the end of the queue until we find an item whose last backup
+            // time was before this one, then insert this new entry after it.  If we're
+            // adding something new we don't bother scanning, and just prepend.
+            int which = -1;
+            if (lastBackedUp > 0) {
+                for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
+                    final FullBackupEntry entry = mFullBackupQueue.get(which);
+                    if (entry.lastBackup <= lastBackedUp) {
+                        mFullBackupQueue.add(which + 1, newEntry);
+                        break;
+                    }
+                }
+            }
+            if (which < 0) {
+                // this one is earlier than any existing one, so prepend
+                mFullBackupQueue.add(0, newEntry);
+            }
+        }
+        writeFullBackupScheduleAsync();
+    }
+
+    private boolean fullBackupAllowable(IBackupTransport transport) {
+        if (transport == null) {
+            Slog.w(TAG, "Transport not present; full data backup not performed");
+            return false;
+        }
+
+        // Don't proceed unless we have already established package metadata
+        // for the current dataset via a key/value backup pass.
+        try {
+            File stateDir = new File(mBaseStateDir, transport.transportDirName());
+            File pmState = new File(stateDir, PACKAGE_MANAGER_SENTINEL);
+            if (pmState.length() <= 0) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Full backup requested but dataset not yet initialized");
+                }
+                return false;
+            }
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to get transport name: " + e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Conditions are right for a full backup operation, so run one.  The model we use is
+     * to perform one app backup per scheduled job execution, and to reschedule the job
+     * with zero latency as long as conditions remain right and we still have work to do.
+     *
+     * <p>This is the "start a full backup operation" entry point called by the scheduled job.
+     *
+     * @return Whether ongoing work will continue.  The return value here will be passed
+     *         along as the return value to the scheduled job's onStartJob() callback.
+     */
+    @Override
+    public boolean beginFullBackup(FullBackupJob scheduledJob) {
+        long now = System.currentTimeMillis();
+        FullBackupEntry entry = null;
+        long latency = MIN_FULL_BACKUP_INTERVAL;
+
+        if (!mEnabled || !mProvisioned) {
+            // Backups are globally disabled, so don't proceed.  We also don't reschedule
+            // the job driving automatic backups; that job will be scheduled again when
+            // the user enables backup.
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "beginFullBackup but e=" + mEnabled
+                        + " p=" + mProvisioned + "; ignoring");
+            }
+            return false;
+        }
+
+        // Don't run the backup if we're in battery saver mode, but reschedule
+        // to try again in the not-so-distant future.
+        final PowerSaveState result =
+                mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP);
+        if (result.batterySaverEnabled) {
+            if (DEBUG) Slog.i(TAG, "Deferring scheduled full backups in battery saver mode");
+            FullBackupJob.schedule(mContext, KeyValueBackupJob.BATCH_INTERVAL);
+            return false;
+        }
+
+        if (DEBUG_SCHEDULING) {
+            Slog.i(TAG, "Beginning scheduled full backup operation");
+        }
+
+        // Great; we're able to run full backup jobs now.  See if we have any work to do.
+        synchronized (mQueueLock) {
+            if (mRunningFullBackupTask != null) {
+                Slog.e(TAG, "Backup triggered but one already/still running!");
+                return false;
+            }
+
+            // At this point we think that we have work to do, but possibly not right now.
+            // Any exit without actually running backups will also require that we
+            // reschedule the job.
+            boolean runBackup = true;
+            boolean headBusy;
+
+            do {
+                // Recheck each time, because culling due to ineligibility may
+                // have emptied the queue.
+                if (mFullBackupQueue.size() == 0) {
+                    // no work to do so just bow out
+                    if (DEBUG) {
+                        Slog.i(TAG, "Backup queue empty; doing nothing");
+                    }
+                    runBackup = false;
+                    break;
+                }
+
+                headBusy = false;
+
+                if (!fullBackupAllowable(mTransportManager.getCurrentTransportBinder())) {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Preconditions not met; not running full backup");
+                    }
+                    runBackup = false;
+                    // Typically this means we haven't run a key/value backup yet.  Back off
+                    // full-backup operations by the key/value job's run interval so that
+                    // next time we run, we are likely to be able to make progress.
+                    latency = KeyValueBackupJob.BATCH_INTERVAL;
+                }
+
+                if (runBackup) {
+                    entry = mFullBackupQueue.get(0);
+                    long timeSinceRun = now - entry.lastBackup;
+                    runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
+                    if (!runBackup) {
+                        // It's too early to back up the next thing in the queue, so bow out
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Device ready but too early to back up next app");
+                        }
+                        // Wait until the next app in the queue falls due for a full data backup
+                        latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+                        break;  // we know we aren't doing work yet, so bail.
+                    }
+
+                    try {
+                        PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+                        if (!AppBackupUtils.appGetsFullBackup(appInfo)) {
+                            // The head app isn't supposed to get full-data backups [any more];
+                            // so we cull it and force a loop around to consider the new head
+                            // app.
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Culling package " + entry.packageName
+                                        + " in full-backup queue but not eligible");
+                            }
+                            mFullBackupQueue.remove(0);
+                            headBusy = true; // force the while() condition
+                            continue;
+                        }
+
+                        final int privFlags = appInfo.applicationInfo.privateFlags;
+                        headBusy = (privFlags & PRIVATE_FLAG_BACKUP_IN_FOREGROUND) == 0
+                                && mActivityManager.isAppForeground(appInfo.applicationInfo.uid);
+
+                        if (headBusy) {
+                            final long nextEligible = System.currentTimeMillis()
+                                    + BUSY_BACKOFF_MIN_MILLIS
+                                    + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
+                            if (DEBUG_SCHEDULING) {
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                Slog.i(TAG, "Full backup time but " + entry.packageName
+                                        + " is busy; deferring to "
+                                        + sdf.format(new Date(nextEligible)));
+                            }
+                            // This relocates the app's entry from the head of the queue to
+                            // its order-appropriate position further down, so upon looping
+                            // a new candidate will be considered at the head.
+                            enqueueFullBackup(entry.packageName,
+                                    nextEligible - MIN_FULL_BACKUP_INTERVAL);
+                        }
+                    } catch (NameNotFoundException nnf) {
+                        // So, we think we want to back this up, but it turns out the package
+                        // in question is no longer installed.  We want to drop it from the
+                        // queue entirely and move on, but if there's nothing else in the queue
+                        // we should bail entirely.  headBusy cannot have been set to true yet.
+                        runBackup = (mFullBackupQueue.size() > 1);
+                    } catch (RemoteException e) {
+                        // Cannot happen; the Activity Manager is in the same process
+                    }
+                }
+            } while (headBusy);
+
+            if (!runBackup) {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Nothing pending full backup; rescheduling +" + latency);
+                }
+                final long deferTime = latency;     // pin for the closure
+                mBackupHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        FullBackupJob.schedule(mContext, deferTime);
+                    }
+                });
+                return false;
+            }
+
+            // Okay, the top thing is ready for backup now.  Do it.
+            mFullBackupQueue.remove(0);
+            CountDownLatch latch = new CountDownLatch(1);
+            String[] pkg = new String[]{entry.packageName};
+            mRunningFullBackupTask = new PerformFullTransportBackupTask(this, null, pkg, true,
+                    scheduledJob, latch, null, null, false /* userInitiated */);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            mWakelock.acquire();
+            (new Thread(mRunningFullBackupTask)).start();
+        }
+
+        return true;
+    }
+
+    // The job scheduler says our constraints don't hold any more,
+    // so tear down any ongoing backup task right away.
+    @Override
+    public void endFullBackup() {
+        synchronized (mQueueLock) {
+            if (mRunningFullBackupTask != null) {
+                if (DEBUG_SCHEDULING) {
+                    Slog.i(TAG, "Telling running backup to stop");
+                }
+                mRunningFullBackupTask.handleCancel(true);
+            }
+        }
+    }
+
+    // Used by both incremental and full restore
+    public void restoreWidgetData(String packageName, byte[] widgetData) {
+        // Apply the restored widget state and generate the ID update for the app
+        // TODO: http://b/22388012
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Incorporating restored widget data");
+        }
+        AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, UserHandle.USER_SYSTEM);
+    }
+
+    // *****************************
+    // NEW UNIFIED RESTORE IMPLEMENTATION
+    // *****************************
+
+    public void dataChangedImpl(String packageName) {
+        HashSet<String> targets = dataChangedTargets(packageName);
+        dataChangedImpl(packageName, targets);
+    }
+
+    private void dataChangedImpl(String packageName, HashSet<String> targets) {
+        // Record that we need a backup pass for the caller.  Since multiple callers
+        // may share a uid, we need to note all candidates within that uid and schedule
+        // a backup pass for each of them.
+        if (targets == null) {
+            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+                    + " uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        synchronized (mQueueLock) {
+            // Note that this client has made data changes that need to be backed up
+            if (targets.contains(packageName)) {
+                // Add the caller to the set of pending backups.  If there is
+                // one already there, then overwrite it, but no harm done.
+                BackupRequest req = new BackupRequest(packageName);
+                if (mPendingBackups.put(packageName, req) == null) {
+                    if (MORE_DEBUG) Slog.d(TAG, "Now staging backup of " + packageName);
+
+                    // Journal this request in case of crash.  The put()
+                    // operation returned null when this package was not already
+                    // in the set; we want to avoid touching the disk redundantly.
+                    writeToJournalLocked(packageName);
+                }
+            }
+        }
+
+        // ...and schedule a backup pass if necessary
+        KeyValueBackupJob.schedule(mContext);
+    }
+
+    // Note: packageName is currently unused, but may be in the future
+    private HashSet<String> dataChangedTargets(String packageName) {
+        // If the caller does not hold the BACKUP permission, it can only request a
+        // backup of its own data.
+        if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
+                Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
+            synchronized (mBackupParticipants) {
+                return mBackupParticipants.get(Binder.getCallingUid());
+            }
+        }
+
+        // a caller with full permission can ask to back up any participating app
+        HashSet<String> targets = new HashSet<>();
+        if (PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
+            targets.add(PACKAGE_MANAGER_SENTINEL);
+        } else {
+            synchronized (mBackupParticipants) {
+                int N = mBackupParticipants.size();
+                for (int i = 0; i < N; i++) {
+                    HashSet<String> s = mBackupParticipants.valueAt(i);
+                    if (s != null) {
+                        targets.addAll(s);
+                    }
+                }
+            }
+        }
+        return targets;
+    }
+
+    private void writeToJournalLocked(String str) {
+        RandomAccessFile out = null;
+        try {
+            if (mJournal == null) mJournal = File.createTempFile("journal", null, mJournalDir);
+            out = new RandomAccessFile(mJournal, "rws");
+            out.seek(out.length());
+            out.writeUTF(str);
+        } catch (IOException e) {
+            Slog.e(TAG, "Can't write " + str + " to backup journal", e);
+            mJournal = null;
+        } finally {
+            try {
+                if (out != null) out.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    // ----- IBackupManager binder interface -----
+
+    @Override
+    public void dataChanged(final String packageName) {
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            // TODO: http://b/22388012
+            // App is running under a non-owner user profile.  For now, we do not back
+            // up data from secondary user profiles.
+            // TODO: backups for all user profiles although don't add backup for profiles
+            // without adding admin control in DevicePolicyManager.
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "dataChanged(" + packageName + ") ignored because it's user "
+                        + callingUserHandle);
+            }
+            return;
+        }
+
+        final HashSet<String> targets = dataChangedTargets(packageName);
+        if (targets == null) {
+            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+                    + " uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        mBackupHandler.post(new Runnable() {
+            public void run() {
+                dataChangedImpl(packageName, targets);
+            }
+        });
+    }
+
+    // Clear the given package's backup data from the current transport
+    @Override
+    public void clearBackupData(String transportName, String packageName) {
+        if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
+        PackageInfo info;
+        try {
+            info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+        } catch (NameNotFoundException e) {
+            Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
+            return;
+        }
+
+        // If the caller does not hold the BACKUP permission, it can only request a
+        // wipe of its own backed-up data.
+        HashSet<String> apps;
+        if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
+                Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
+            apps = mBackupParticipants.get(Binder.getCallingUid());
+        } else {
+            // a caller with full permission can ask to back up any participating app
+            // !!! TODO: allow data-clear of ANY app?
+            if (MORE_DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
+            apps = new HashSet<>();
+            int N = mBackupParticipants.size();
+            for (int i = 0; i < N; i++) {
+                HashSet<String> s = mBackupParticipants.valueAt(i);
+                if (s != null) {
+                    apps.addAll(s);
+                }
+            }
+        }
+
+        // Is the given app an available participant?
+        if (apps.contains(packageName)) {
+            // found it; fire off the clear request
+            if (MORE_DEBUG) Slog.v(TAG, "Found the app - running clear process");
+            mBackupHandler.removeMessages(MSG_RETRY_CLEAR);
+            synchronized (mQueueLock) {
+                final IBackupTransport transport =
+                        mTransportManager.getTransportBinder(transportName);
+                if (transport == null) {
+                    // transport is currently unavailable -- make sure to retry
+                    Message msg = mBackupHandler.obtainMessage(MSG_RETRY_CLEAR,
+                            new ClearRetryParams(transportName, packageName));
+                    mBackupHandler.sendMessageDelayed(msg, TRANSPORT_RETRY_INTERVAL);
+                    return;
+                }
+                long oldId = Binder.clearCallingIdentity();
+                mWakelock.acquire();
+                Message msg = mBackupHandler.obtainMessage(MSG_RUN_CLEAR,
+                        new ClearParams(transport, info));
+                mBackupHandler.sendMessage(msg);
+                Binder.restoreCallingIdentity(oldId);
+            }
+        }
+    }
+
+    // Run a backup pass immediately for any applications that have declared
+    // that they have pending updates.
+    @Override
+    public void backupNow() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
+
+        final PowerSaveState result =
+                mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
+        if (result.batterySaverEnabled) {
+            if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
+            KeyValueBackupJob.schedule(mContext);   // try again in several hours
+        } else {
+            if (DEBUG) Slog.v(TAG, "Scheduling immediate backup pass");
+            synchronized (mQueueLock) {
+                // Fire the intent that kicks off the whole shebang...
+                try {
+                    mRunBackupIntent.send();
+                } catch (PendingIntent.CanceledException e) {
+                    // should never happen
+                    Slog.e(TAG, "run-backup intent cancelled!");
+                }
+
+                // ...and cancel any pending scheduled job, because we've just superseded it
+                KeyValueBackupJob.cancel(mContext);
+            }
+        }
+    }
+
+    public boolean deviceIsProvisioned() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        return (Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0);
+    }
+
+    // Run a backup pass for the given packages, writing the resulting data stream
+    // to the supplied file descriptor.  This method is synchronous and does not return
+    // to the caller until the backup has been completed.
+    //
+    // This is the variant used by 'adb backup'; it requires on-screen confirmation
+    // by the user because it can be used to offload data over untrusted USB.
+    @Override
+    public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
+            boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
+            boolean compress, boolean doKeyValue, String[] pkgList) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbBackup");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Backup supported only for the device owner");
+        }
+
+        // Validate
+        if (!doAllApps) {
+            if (!includeShared) {
+                // If we're backing up shared data (sdcard or equivalent), then we can run
+                // without any supplied app names.  Otherwise, we'd be doing no work, so
+                // report the error.
+                if (pkgList == null || pkgList.length == 0) {
+                    throw new IllegalArgumentException(
+                            "Backup requested but neither shared nor any apps named");
+                }
+            }
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            // Doesn't make sense to do a full backup prior to setup
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Backup not supported before setup");
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.v(TAG, "Requesting backup: apks=" + includeApks + " obb=" + includeObbs
+                        + " shared=" + includeShared + " all=" + doAllApps + " system="
+                        + includeSystem + " includekeyvalue=" + doKeyValue + " pkgs=" + pkgList);
+            }
+            Slog.i(TAG, "Beginning adb backup...");
+
+            AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
+                    includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
+                    pkgList);
+            final int token = generateRandomIntegerToken();
+            synchronized (mAdbBackupRestoreConfirmations) {
+                mAdbBackupRestoreConfirmations.put(token, params);
+            }
+
+            // start up the confirmation UI
+            if (DEBUG) Slog.d(TAG, "Starting backup confirmation UI, token=" + token);
+            if (!startConfirmationUi(token, FullBackup.FULL_BACKUP_INTENT_ACTION)) {
+                Slog.e(TAG, "Unable to launch backup confirmation UI");
+                mAdbBackupRestoreConfirmations.delete(token);
+                return;
+            }
+
+            // make sure the screen is lit for the user interaction
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
+
+            // start the confirmation countdown
+            startConfirmationTimeout(token, params);
+
+            // wait for the backup to be performed
+            if (DEBUG) Slog.d(TAG, "Waiting for backup completion...");
+            waitForCompletion(params);
+        } finally {
+            try {
+                fd.close();
+            } catch (IOException e) {
+                // just eat it
+            }
+            Binder.restoreCallingIdentity(oldId);
+            Slog.d(TAG, "Adb backup processing complete.");
+        }
+    }
+
+    @Override
+    public void fullTransportBackup(String[] pkgNames) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+                "fullTransportBackup");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Restore supported only for the device owner");
+        }
+
+        if (!fullBackupAllowable(mTransportManager.getCurrentTransportBinder())) {
+            Slog.i(TAG, "Full backup not currently possible -- key/value backup not yet run?");
+        } else {
+            if (DEBUG) {
+                Slog.d(TAG, "fullTransportBackup()");
+            }
+
+            final long oldId = Binder.clearCallingIdentity();
+            try {
+                CountDownLatch latch = new CountDownLatch(1);
+                PerformFullTransportBackupTask task = new PerformFullTransportBackupTask(this, null,
+                        pkgNames, false, null, latch, null, null, false /* userInitiated */);
+                // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+                mWakelock.acquire();
+                (new Thread(task, "full-transport-master")).start();
+                do {
+                    try {
+                        latch.await();
+                        break;
+                    } catch (InterruptedException e) {
+                        // Just go back to waiting for the latch to indicate completion
+                    }
+                } while (true);
+
+                // We just ran a backup on these packages, so kick them to the end of the queue
+                final long now = System.currentTimeMillis();
+                for (String pkg : pkgNames) {
+                    enqueueFullBackup(pkg, now);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(oldId);
+            }
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG, "Done with full transport backup.");
+        }
+    }
+
+    @Override
+    public void adbRestore(ParcelFileDescriptor fd) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
+
+        final int callingUserHandle = UserHandle.getCallingUserId();
+        // TODO: http://b/22388012
+        if (callingUserHandle != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Restore supported only for the device owner");
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+
+        try {
+            // Check whether the device has been provisioned -- we don't handle
+            // full restores prior to completing the setup process.
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Full restore not permitted before setup");
+                return;
+            }
+
+            Slog.i(TAG, "Beginning restore...");
+
+            AdbRestoreParams params = new AdbRestoreParams(fd);
+            final int token = generateRandomIntegerToken();
+            synchronized (mAdbBackupRestoreConfirmations) {
+                mAdbBackupRestoreConfirmations.put(token, params);
+            }
+
+            // start up the confirmation UI
+            if (DEBUG) Slog.d(TAG, "Starting restore confirmation UI, token=" + token);
+            if (!startConfirmationUi(token, FullBackup.FULL_RESTORE_INTENT_ACTION)) {
+                Slog.e(TAG, "Unable to launch restore confirmation");
+                mAdbBackupRestoreConfirmations.delete(token);
+                return;
+            }
+
+            // make sure the screen is lit for the user interaction
+            mPowerManager.userActivity(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    0);
+
+            // start the confirmation countdown
+            startConfirmationTimeout(token, params);
+
+            // wait for the restore to be performed
+            if (DEBUG) Slog.d(TAG, "Waiting for restore completion...");
+            waitForCompletion(params);
+        } finally {
+            try {
+                fd.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Error trying to close fd after adb restore: " + e);
+            }
+            Binder.restoreCallingIdentity(oldId);
+            Slog.i(TAG, "adb restore processing complete.");
+        }
+    }
+
+    private boolean startConfirmationUi(int token, String action) {
+        try {
+            Intent confIntent = new Intent(action);
+            confIntent.setClassName("com.android.backupconfirm",
+                    "com.android.backupconfirm.BackupRestoreConfirmation");
+            confIntent.putExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, token);
+            confIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivityAsUser(confIntent, UserHandle.SYSTEM);
+        } catch (ActivityNotFoundException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private void startConfirmationTimeout(int token, AdbParams params) {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Posting conf timeout msg after "
+                    + TIMEOUT_FULL_CONFIRMATION + " millis");
+        }
+        Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT,
+                token, 0, params);
+        mBackupHandler.sendMessageDelayed(msg, TIMEOUT_FULL_CONFIRMATION);
+    }
+
+    private void waitForCompletion(AdbParams params) {
+        synchronized (params.latch) {
+            while (params.latch.get() == false) {
+                try {
+                    params.latch.wait();
+                } catch (InterruptedException e) { /* never interrupted */ }
+            }
+        }
+    }
+
+    public void signalAdbBackupRestoreCompletion(AdbParams params) {
+        synchronized (params.latch) {
+            params.latch.set(true);
+            params.latch.notifyAll();
+        }
+    }
+
+    // Confirm that the previously-requested full backup/restore operation can proceed.  This
+    // is used to require a user-facing disclosure about the operation.
+    @Override
+    public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
+            String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
+        if (DEBUG) {
+            Slog.d(TAG, "acknowledgeAdbBackupOrRestore : token=" + token
+                    + " allow=" + allow);
+        }
+
+        // TODO: possibly require not just this signature-only permission, but even
+        // require that the specific designated confirmation-UI app uid is the caller?
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+                "acknowledgeAdbBackupOrRestore");
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+
+            AdbParams params;
+            synchronized (mAdbBackupRestoreConfirmations) {
+                params = mAdbBackupRestoreConfirmations.get(token);
+                if (params != null) {
+                    mBackupHandler.removeMessages(MSG_FULL_CONFIRMATION_TIMEOUT, params);
+                    mAdbBackupRestoreConfirmations.delete(token);
+
+                    if (allow) {
+                        final int verb = params instanceof AdbBackupParams
+                                ? MSG_RUN_ADB_BACKUP
+                                : MSG_RUN_ADB_RESTORE;
+
+                        params.observer = observer;
+                        params.curPassword = curPassword;
+
+                        params.encryptPassword = encPpassword;
+
+                        if (MORE_DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
+                        mWakelock.acquire();
+                        Message msg = mBackupHandler.obtainMessage(verb, params);
+                        mBackupHandler.sendMessage(msg);
+                    } else {
+                        Slog.w(TAG, "User rejected full backup/restore operation");
+                        // indicate completion without having actually transferred any data
+                        signalAdbBackupRestoreCompletion(params);
+                    }
+                } else {
+                    Slog.w(TAG, "Attempted to ack full backup/restore with invalid token");
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    private static boolean backupSettingMigrated(int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        return enableFile.exists();
+    }
+
+    private static boolean readBackupEnableState(int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        if (enableFile.exists()) {
+            try (FileInputStream fin = new FileInputStream(enableFile)) {
+                int state = fin.read();
+                return state != 0;
+            } catch (IOException e) {
+                // can't read the file; fall through to assume disabled
+                Slog.e(TAG, "Cannot read enable state; assuming disabled");
+            }
+        } else {
+            if (DEBUG) {
+                Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
+            }
+        }
+        return false;
+    }
+
+    private static void writeBackupEnableState(boolean enable, int userId) {
+        File base = new File(Environment.getDataDirectory(), "backup");
+        File enableFile = new File(base, BACKUP_ENABLE_FILE);
+        File stage = new File(base, BACKUP_ENABLE_FILE + "-stage");
+        FileOutputStream fout = null;
+        try {
+            fout = new FileOutputStream(stage);
+            fout.write(enable ? 1 : 0);
+            fout.close();
+            stage.renameTo(enableFile);
+            // will be synced immediately by the try-with-resources call to close()
+        } catch (IOException | RuntimeException e) {
+            // Whoops; looks like we're doomed.  Roll everything out, disabled,
+            // including the legacy state.
+            Slog.e(TAG, "Unable to record backup enable state; reverting to disabled: "
+                    + e.getMessage());
+
+            final ContentResolver r = sInstance.mContext.getContentResolver();
+            Settings.Secure.putStringForUser(r,
+                    Settings.Secure.BACKUP_ENABLED, null, userId);
+            enableFile.delete();
+            stage.delete();
+        } finally {
+            IoUtils.closeQuietly(fout);
+        }
+    }
+
+    // Enable/disable backups
+    @Override
+    public void setBackupEnabled(boolean enable) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupEnabled");
+
+        Slog.i(TAG, "Backup enabled => " + enable);
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            boolean wasEnabled = mEnabled;
+            synchronized (this) {
+                writeBackupEnableState(enable, UserHandle.USER_SYSTEM);
+                mEnabled = enable;
+            }
+
+            synchronized (mQueueLock) {
+                if (enable && !wasEnabled && mProvisioned) {
+                    // if we've just been enabled, start scheduling backup passes
+                    KeyValueBackupJob.schedule(mContext);
+                    scheduleNextFullBackupJob(0);
+                } else if (!enable) {
+                    // No longer enabled, so stop running backups
+                    if (MORE_DEBUG) Slog.i(TAG, "Opting out of backup");
+
+                    KeyValueBackupJob.cancel(mContext);
+
+                    // This also constitutes an opt-out, so we wipe any data for
+                    // this device from the backend.  We start that process with
+                    // an alarm in order to guarantee wakelock states.
+                    if (wasEnabled && mProvisioned) {
+                        // NOTE: we currently flush every registered transport, not just
+                        // the currently-active one.
+                        String[] allTransports = mTransportManager.getBoundTransportNames();
+                        // build the set of transports for which we are posting an init
+                        for (String transport : allTransports) {
+                            recordInitPendingLocked(true, transport);
+                        }
+                        mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
+                                mRunInitIntent);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    // Enable/disable automatic restore of app data at install time
+    @Override
+    public void setAutoRestore(boolean doAutoRestore) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setAutoRestore");
+
+        Slog.i(TAG, "Auto restore => " + doAutoRestore);
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.BACKUP_AUTO_RESTORE, doAutoRestore ? 1 : 0);
+                mAutoRestore = doAutoRestore;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    // Mark the backup service as having been provisioned
+    @Override
+    public void setBackupProvisioned(boolean available) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "setBackupProvisioned");
+        /*
+         * This is now a no-op; provisioning is simply the device's own setup state.
+         */
+    }
+
+    // Report whether the backup mechanism is currently enabled
+    @Override
+    public boolean isBackupEnabled() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "isBackupEnabled");
+        return mEnabled;    // no need to synchronize just to read it
+    }
+
+    // Report the name of the currently active transport
+    @Override
+    public String getCurrentTransport() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getCurrentTransport");
+        String currentTransport = mTransportManager.getCurrentTransportName();
+        if (MORE_DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + currentTransport);
+        return currentTransport;
+    }
+
+    // Report all known, available backup transports
+    @Override
+    public String[] listAllTransports() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "listAllTransports");
+
+        return mTransportManager.getBoundTransportNames();
+    }
+
+    @Override
+    public ComponentName[] listAllTransportComponents() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "listAllTransportComponents");
+        return mTransportManager.getAllTransportCompenents();
+    }
+
+    @Override
+    public String[] getTransportWhitelist() {
+        // No permission check, intentionally.
+        Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
+        String[] whitelistedTransports = new String[whitelistedComponents.size()];
+        int i = 0;
+        for (ComponentName component : whitelistedComponents) {
+            whitelistedTransports[i] = component.flattenToShortString();
+            i++;
+        }
+        return whitelistedTransports;
+    }
+
+    // Select which transport to use for the next backup operation.
+    @Override
+    public String selectBackupTransport(String transport) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "selectBackupTransport");
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            String prevTransport = mTransportManager.selectTransport(transport);
+            Settings.Secure.putString(mContext.getContentResolver(),
+                    Settings.Secure.BACKUP_TRANSPORT, transport);
+            Slog.v(TAG, "selectBackupTransport() set " + mTransportManager.getCurrentTransportName()
+                    + " returning " + prevTransport);
+            return prevTransport;
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    @Override
+    public void selectBackupTransportAsync(final ComponentName transport,
+            final ISelectBackupTransportCallback listener) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "selectBackupTransportAsync");
+
+        final long oldId = Binder.clearCallingIdentity();
+
+        Slog.v(TAG, "selectBackupTransportAsync() called with transport " +
+                transport.flattenToShortString());
+
+        mTransportManager.ensureTransportReady(transport, new SelectBackupTransportCallback() {
+            @Override
+            public void onSuccess(String transportName) {
+                mTransportManager.selectTransport(transportName);
+                Settings.Secure.putString(mContext.getContentResolver(),
+                        Settings.Secure.BACKUP_TRANSPORT,
+                        mTransportManager.getCurrentTransportName());
+                Slog.v(TAG, "Transport successfully selected: " + transport.flattenToShortString());
+                try {
+                    listener.onSuccess(transportName);
+                } catch (RemoteException e) {
+                    // Nothing to do here.
+                }
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Slog.v(TAG, "Failed to select transport: " + transport.flattenToShortString());
+                try {
+                    listener.onFailure(reason);
+                } catch (RemoteException e) {
+                    // Nothing to do here.
+                }
+            }
+        });
+
+        Binder.restoreCallingIdentity(oldId);
+    }
+
+    // Supply the configuration Intent for the given transport.  If the name is not one
+    // of the available transports, or if the transport does not supply any configuration
+    // UI, the method returns null.
+    @Override
+    public Intent getConfigurationIntent(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getConfigurationIntent");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final Intent intent = transport.configurationIntent();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "getConfigurationIntent() returning config intent "
+                            + intent);
+                }
+                return intent;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get configuration intent from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the configuration summary string for the given transport.  If the name is
+    // not one of the available transports, or if the transport does not supply any
+    // summary / destination string, the method can return null.
+    //
+    // This string is used VERBATIM as the summary text of the relevant Settings item!
+    @Override
+    public String getDestinationString(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDestinationString");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final String text = transport.currentDestinationString();
+                if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
+                return text;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get string from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the manage-data intent for the given transport.
+    @Override
+    public Intent getDataManagementIntent(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDataManagementIntent");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final Intent intent = transport.dataManagementIntent();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "getDataManagementIntent() returning intent "
+                            + intent);
+                }
+                return intent;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get management intent from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Supply the menu label for affordances that fire the manage-data intent
+    // for the given transport.
+    @Override
+    public String getDataManagementLabel(String transportName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "getDataManagementLabel");
+
+        final IBackupTransport transport = mTransportManager.getTransportBinder(transportName);
+        if (transport != null) {
+            try {
+                final String text = transport.dataManagementLabel();
+                if (MORE_DEBUG) Slog.d(TAG, "getDataManagementLabel() returning " + text);
+                return text;
+            } catch (Exception e) {
+                /* fall through to return null */
+                Slog.e(TAG, "Unable to get management label from transport: " + e.getMessage());
+            }
+        }
+
+        return null;
+    }
+
+    // Callback: a requested backup agent has been instantiated.  This should only
+    // be called from the Activity Manager.
+    @Override
+    public void agentConnected(String packageName, IBinder agentBinder) {
+        synchronized (mAgentConnectLock) {
+            if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+                Slog.d(TAG, "agentConnected pkg=" + packageName + " agent=" + agentBinder);
+                IBackupAgent agent = IBackupAgent.Stub.asInterface(agentBinder);
+                mConnectedAgent = agent;
+                mConnecting = false;
+            } else {
+                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                        + " claiming agent connected");
+            }
+            mAgentConnectLock.notifyAll();
+        }
+    }
+
+    // Callback: a backup agent has failed to come up, or has unexpectedly quit.
+    // If the agent failed to come up in the first place, the agentBinder argument
+    // will be null.  This should only be called from the Activity Manager.
+    @Override
+    public void agentDisconnected(String packageName) {
+        // TODO: handle backup being interrupted
+        synchronized (mAgentConnectLock) {
+            if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+                mConnectedAgent = null;
+                mConnecting = false;
+            } else {
+                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                        + " claiming agent disconnected");
+            }
+            mAgentConnectLock.notifyAll();
+        }
+    }
+
+    // An application being installed will need a restore pass, then the Package Manager
+    // will need to be told when the restore is finished.
+    @Override
+    public void restoreAtInstall(String packageName, int token) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
+                    + " attemping install-time restore");
+            return;
+        }
+
+        boolean skip = false;
+
+        long restoreSet = getAvailableRestoreToken(packageName);
+        if (DEBUG) {
+            Slog.v(TAG, "restoreAtInstall pkg=" + packageName
+                    + " token=" + Integer.toHexString(token)
+                    + " restoreSet=" + Long.toHexString(restoreSet));
+        }
+        if (restoreSet == 0) {
+            if (MORE_DEBUG) Slog.i(TAG, "No restore set");
+            skip = true;
+        }
+
+        // Do we have a transport to fetch data for us?
+        IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+        if (transport == null) {
+            if (DEBUG) Slog.w(TAG, "No transport");
+            skip = true;
+        }
+
+        if (!mAutoRestore) {
+            if (DEBUG) {
+                Slog.w(TAG, "Non-restorable state: auto=" + mAutoRestore);
+            }
+            skip = true;
+        }
+
+        if (!skip) {
+            try {
+                // okay, we're going to attempt a restore of this package from this restore set.
+                // The eventual message back into the Package Manager to run the post-install
+                // steps for 'token' will be issued from the restore handling code.
+
+                // This can throw and so *must* happen before the wakelock is acquired
+                String dirName = transport.transportDirName();
+
+                mWakelock.acquire();
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Restore at install of " + packageName);
+                }
+                Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
+                msg.obj = new RestoreParams(transport, dirName, null, null,
+                        restoreSet, packageName, token);
+                mBackupHandler.sendMessage(msg);
+            } catch (Exception e) {
+                // Calling into the transport broke; back off and proceed with the installation.
+                Slog.e(TAG, "Unable to contact transport: " + e.getMessage());
+                skip = true;
+            }
+        }
+
+        if (skip) {
+            // Auto-restore disabled or no way to attempt a restore; just tell the Package
+            // Manager to proceed with the post-install handling for this package.
+            if (DEBUG) Slog.v(TAG, "Finishing install immediately");
+            try {
+                mPackageManagerBinder.finishPackageInstall(token, false);
+            } catch (RemoteException e) { /* can't happen */ }
+        }
+    }
+
+    // Hand off a restore session
+    @Override
+    public IRestoreSession beginRestoreSession(String packageName, String transport) {
+        if (DEBUG) {
+            Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
+                    + " transport=" + transport);
+        }
+
+        boolean needPermission = true;
+        if (transport == null) {
+            transport = mTransportManager.getCurrentTransportName();
+
+            if (packageName != null) {
+                PackageInfo app = null;
+                try {
+                    app = mPackageManager.getPackageInfo(packageName, 0);
+                } catch (NameNotFoundException nnf) {
+                    Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
+                    throw new IllegalArgumentException("Package " + packageName + " not found");
+                }
+
+                if (app.applicationInfo.uid == Binder.getCallingUid()) {
+                    // So: using the current active transport, and the caller has asked
+                    // that its own package will be restored.  In this narrow use case
+                    // we do not require the caller to hold the permission.
+                    needPermission = false;
+                }
+            }
+        }
+
+        if (needPermission) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                    "beginRestoreSession");
+        } else {
+            if (DEBUG) Slog.d(TAG, "restoring self on current transport; no permission needed");
+        }
+
+        synchronized (this) {
+            if (mActiveRestoreSession != null) {
+                Slog.i(TAG, "Restore session requested but one already active");
+                return null;
+            }
+            if (mBackupRunning) {
+                Slog.i(TAG, "Restore session requested but currently running backups");
+                return null;
+            }
+            mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport);
+            mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
+                    TIMEOUT_RESTORE_INTERVAL);
+        }
+        return mActiveRestoreSession;
+    }
+
+    public void clearRestoreSession(ActiveRestoreSession currentSession) {
+        synchronized (this) {
+            if (currentSession != mActiveRestoreSession) {
+                Slog.e(TAG, "ending non-current restore session");
+            } else {
+                if (DEBUG) Slog.v(TAG, "Clearing restore session and halting timeout");
+                mActiveRestoreSession = null;
+                mBackupHandler.removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+            }
+        }
+    }
+
+    // Note that a currently-active backup agent has notified us that it has
+    // completed the given outstanding asynchronous backup/restore operation.
+    @Override
+    public void opComplete(int token, long result) {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
+        }
+        Operation op = null;
+        synchronized (mCurrentOpLock) {
+            op = mCurrentOperations.get(token);
+            if (op != null) {
+                if (op.state == OP_TIMEOUT) {
+                    // The operation already timed out, and this is a late response.  Tidy up
+                    // and ignore it; we've already dealt with the timeout.
+                    op = null;
+                    mCurrentOperations.delete(token);
+                } else if (op.state == OP_ACKNOWLEDGED) {
+                    if (DEBUG) {
+                        Slog.w(TAG, "Received duplicate ack for token=" +
+                                Integer.toHexString(token));
+                    }
+                    op = null;
+                    mCurrentOperations.remove(token);
+                } else if (op.state == OP_PENDING) {
+                    // Can't delete op from mCurrentOperations. waitUntilOperationComplete can be
+                    // called after we we receive this call.
+                    op.state = OP_ACKNOWLEDGED;
+                }
+            }
+            mCurrentOpLock.notifyAll();
+        }
+
+        // The completion callback, if any, is invoked on the handler
+        if (op != null && op.callback != null) {
+            Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(op.callback, result);
+            Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult);
+            mBackupHandler.sendMessage(msg);
+        }
+    }
+
+    // We also avoid backups of 'disabled' apps
+    private static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) {
+        switch (pm.getApplicationEnabledSetting(app.packageName)) {
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public boolean isAppEligibleForBackup(String packageName) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+                "isAppEligibleForBackup");
+        try {
+            PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+                    PackageManager.GET_SIGNATURES);
+            if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo) ||
+                    AppBackupUtils.appIsStopped(packageInfo.applicationInfo) ||
+                    appIsDisabled(packageInfo.applicationInfo, mPackageManager)) {
+                return false;
+            }
+            IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
+            if (transport != null) {
+                try {
+                    return transport.isAppEligibleForBackup(packageInfo,
+                            AppBackupUtils.appGetsFullBackup(packageInfo));
+                } catch (Exception e) {
+                    Slog.e(TAG, "Unable to ask about eligibility: " + e.getMessage());
+                }
+            }
+            // If transport is not present we couldn't tell that the package is not eligible.
+            return true;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+
+        long identityToken = Binder.clearCallingIdentity();
+        try {
+            if (args != null) {
+                for (String arg : args) {
+                    if ("-h".equals(arg)) {
+                        pw.println("'dumpsys backup' optional arguments:");
+                        pw.println("  -h       : this help text");
+                        pw.println("  a[gents] : dump information about defined backup agents");
+                        return;
+                    } else if ("agents".startsWith(arg)) {
+                        dumpAgents(pw);
+                        return;
+                    }
+                }
+            }
+            dumpInternal(pw);
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+    }
+
+    private void dumpAgents(PrintWriter pw) {
+        List<PackageInfo> agentPackages = allAgentPackages();
+        pw.println("Defined backup agents:");
+        for (PackageInfo pkg : agentPackages) {
+            pw.print("  ");
+            pw.print(pkg.packageName);
+            pw.println(':');
+            pw.print("      ");
+            pw.println(pkg.applicationInfo.backupAgentName);
+        }
+    }
+
+    private void dumpInternal(PrintWriter pw) {
+        synchronized (mQueueLock) {
+            pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
+                    + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
+                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
+            pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
+            if (mBackupRunning) pw.println("Backup currently running");
+            pw.println("Last backup pass started: " + mLastBackupPass
+                    + " (now = " + System.currentTimeMillis() + ')');
+            pw.println("  next scheduled: " + KeyValueBackupJob.nextScheduled());
+
+            pw.println("Transport whitelist:");
+            for (ComponentName transport : mTransportManager.getTransportWhitelist()) {
+                pw.print("    ");
+                pw.println(transport.flattenToShortString());
+            }
+
+            pw.println("Available transports:");
+            final String[] transports = listAllTransports();
+            if (transports != null) {
+                for (String t : listAllTransports()) {
+                    pw.println((t.equals(mTransportManager.getCurrentTransportName()) ? "  * "
+                            : "    ") + t);
+                    try {
+                        IBackupTransport transport = mTransportManager.getTransportBinder(t);
+                        File dir = new File(mBaseStateDir, transport.transportDirName());
+                        pw.println("       destination: " + transport.currentDestinationString());
+                        pw.println("       intent: " + transport.configurationIntent());
+                        for (File f : dir.listFiles()) {
+                            pw.println(
+                                    "       " + f.getName() + " - " + f.length() + " state bytes");
+                        }
+                    } catch (Exception e) {
+                        Slog.e(TAG, "Error in transport", e);
+                        pw.println("        Error: " + e);
+                    }
+                }
+            }
+
+            pw.println("Pending init: " + mPendingInits.size());
+            for (String s : mPendingInits) {
+                pw.println("    " + s);
+            }
+
+            if (DEBUG_BACKUP_TRACE) {
+                synchronized (mBackupTrace) {
+                    if (!mBackupTrace.isEmpty()) {
+                        pw.println("Most recent backup trace:");
+                        for (String s : mBackupTrace) {
+                            pw.println("   " + s);
+                        }
+                    }
+                }
+            }
+
+            pw.print("Ancestral: ");
+            pw.println(Long.toHexString(mAncestralToken));
+            pw.print("Current:   ");
+            pw.println(Long.toHexString(mCurrentToken));
+
+            int N = mBackupParticipants.size();
+            pw.println("Participants:");
+            for (int i = 0; i < N; i++) {
+                int uid = mBackupParticipants.keyAt(i);
+                pw.print("  uid: ");
+                pw.println(uid);
+                HashSet<String> participants = mBackupParticipants.valueAt(i);
+                for (String app : participants) {
+                    pw.println("    " + app);
+                }
+            }
+
+            pw.println("Ancestral packages: "
+                    + (mAncestralPackages == null ? "none" : mAncestralPackages.size()));
+            if (mAncestralPackages != null) {
+                for (String pkg : mAncestralPackages) {
+                    pw.println("    " + pkg);
+                }
+            }
+
+            pw.println("Ever backed up: " + mEverStoredApps.size());
+            for (String pkg : mEverStoredApps) {
+                pw.println("    " + pkg);
+            }
+
+            pw.println("Pending key/value backup: " + mPendingBackups.size());
+            for (BackupRequest req : mPendingBackups.values()) {
+                pw.println("    " + req);
+            }
+
+            pw.println("Full backup queue:" + mFullBackupQueue.size());
+            for (FullBackupEntry entry : mFullBackupQueue) {
+                pw.print("    ");
+                pw.print(entry.lastBackup);
+                pw.print(" : ");
+                pw.println(entry.packageName);
+            }
+        }
+    }
+
+
+    @Override
+    public IBackupManager getBackupManagerBinder() {
+        return mBackupManagerBinder;
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index aafa88a..9e7a29e 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -34,6 +34,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Slog;
 
 import com.android.internal.util.DumpUtils;
@@ -43,6 +44,22 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 
+
+/**
+ * A proxy to BackupManagerService implementation.
+ *
+ * This is an external interface to the BackupManagerService which is being accessed via published
+ * binder (see BackupManagerService$Lifecycle). This lets us turn down the heavy implementation
+ * object on the fly without disturbing binders that have been cached somewhere in the system.
+ *
+ * This is where it is decided whether backup subsystem is available. It can be disabled with the
+ * following two methods:
+ *
+ * <ul>
+ * <li> Temporarily - create a file named Trampoline.BACKUP_SUPPRESS_FILENAME, or
+ * <li> Product level - set Trampoline.BACKUP_DISABLE_PROPERTY system property to true.
+ * </ul>
+ */
 public class Trampoline extends IBackupManager.Stub {
     static final String TAG = "BackupManagerService";
     static final boolean DEBUG_TRAMPOLINE = false;
@@ -56,14 +73,49 @@
     final Context mContext;
     final File mSuppressFile;   // existence testing & creating synchronized on 'this'
     final boolean mGlobalDisable;
-    volatile BackupManagerService mService;
+    volatile BackupManagerServiceInterface mService;
 
     public Trampoline(Context context) {
         mContext = context;
-        File dir = new File(Environment.getDataDirectory(), "backup");
-        dir.mkdirs();
-        mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME);
-        mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
+        mGlobalDisable = isBackupDisabled();
+        mSuppressFile = getSuppressFile();
+        mSuppressFile.getParentFile().mkdirs();
+    }
+
+    protected BackupManagerServiceInterface createService() {
+        if (isRefactoredServiceEnabled()) {
+            Slog.i(TAG, "Instantiating RefactoredBackupManagerService");
+            return createRefactoredBackupManagerService();
+        }
+
+        Slog.i(TAG, "Instantiating BackupManagerService");
+        return createBackupManagerService();
+    }
+
+    protected boolean isBackupDisabled() {
+        return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
+    }
+
+    protected boolean isRefactoredServiceEnabled() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.BACKUP_REFACTORED_SERVICE_DISABLED, 1) == 0;
+    }
+
+    protected int binderGetCallingUid() {
+        return Binder.getCallingUid();
+    }
+
+    protected File getSuppressFile() {
+        return new File(new File(Environment.getDataDirectory(), "backup"),
+                BACKUP_SUPPRESS_FILENAME);
+    }
+
+    protected BackupManagerServiceInterface createRefactoredBackupManagerService() {
+        return new RefactoredBackupManagerService(mContext, this);
+    }
+
+    protected BackupManagerServiceInterface createBackupManagerService() {
+        return new BackupManagerService(mContext, this);
     }
 
     // internal control API
@@ -79,7 +131,7 @@
 
             synchronized (this) {
                 if (!mSuppressFile.exists()) {
-                    mService = new BackupManagerService(mContext, this);
+                    mService = createService();
                 } else {
                     Slog.i(TAG, "Backup inactive in user " + whichUser);
                 }
@@ -89,7 +141,7 @@
 
     public void setBackupServiceActive(final int userHandle, boolean makeActive) {
         // Only the DPM should be changing the active state of backup
-        final int caller = Binder.getCallingUid();
+        final int caller = binderGetCallingUid();
         if (caller != Process.SYSTEM_UID
                 && caller != Process.ROOT_UID) {
             throw new SecurityException("No permission to configure backup activity");
@@ -106,7 +158,7 @@
                     Slog.i(TAG, "Making backup "
                             + (makeActive ? "" : "in") + "active in user " + userHandle);
                     if (makeActive) {
-                        mService = new BackupManagerService(mContext, this);
+                        mService = createService();
                         mSuppressFile.delete();
                     } else {
                         mService = null;
@@ -140,7 +192,7 @@
     // IBackupManager binder API
     @Override
     public void dataChanged(String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.dataChanged(packageName);
         }
@@ -149,7 +201,7 @@
     @Override
     public void clearBackupData(String transportName, String packageName)
             throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.clearBackupData(transportName, packageName);
         }
@@ -157,7 +209,7 @@
 
     @Override
     public void agentConnected(String packageName, IBinder agent) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.agentConnected(packageName, agent);
         }
@@ -165,7 +217,7 @@
 
     @Override
     public void agentDisconnected(String packageName) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.agentDisconnected(packageName);
         }
@@ -173,7 +225,7 @@
 
     @Override
     public void restoreAtInstall(String packageName, int token) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.restoreAtInstall(packageName, token);
         }
@@ -181,7 +233,7 @@
 
     @Override
     public void setBackupEnabled(boolean isEnabled) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setBackupEnabled(isEnabled);
         }
@@ -189,7 +241,7 @@
 
     @Override
     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setAutoRestore(doAutoRestore);
         }
@@ -197,7 +249,7 @@
 
     @Override
     public void setBackupProvisioned(boolean isProvisioned) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.setBackupProvisioned(isProvisioned);
         }
@@ -205,25 +257,25 @@
 
     @Override
     public boolean isBackupEnabled() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.isBackupEnabled() : false;
     }
 
     @Override
     public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false;
     }
 
     @Override
     public boolean hasBackupPassword() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.hasBackupPassword() : false;
     }
 
     @Override
     public void backupNow() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.backupNow();
         }
@@ -234,7 +286,7 @@
             boolean includeShared, boolean doWidgets, boolean allApps,
             boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)
                     throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.adbBackup(fd, includeApks, includeObbs, includeShared, doWidgets,
                     allApps, allIncludesSystem, doCompress, doKeyValue, packageNames);
@@ -243,7 +295,7 @@
 
     @Override
     public void fullTransportBackup(String[] packageNames) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.fullTransportBackup(packageNames);
         }
@@ -251,7 +303,7 @@
 
     @Override
     public void adbRestore(ParcelFileDescriptor fd) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.adbRestore(fd);
         }
@@ -261,7 +313,7 @@
     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
             String encryptionPassword, IFullBackupRestoreObserver observer)
                     throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.acknowledgeAdbBackupOrRestore(token, allow,
                     curPassword, encryptionPassword, observer);
@@ -270,38 +322,38 @@
 
     @Override
     public String getCurrentTransport() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getCurrentTransport() : null;
     }
 
     @Override
     public String[] listAllTransports() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.listAllTransports() : null;
     }
 
     @Override
     public ComponentName[] listAllTransportComponents() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.listAllTransportComponents() : null;
     }
 
     @Override
     public String[] getTransportWhitelist() {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getTransportWhitelist() : null;
     }
 
     @Override
     public String selectBackupTransport(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.selectBackupTransport(transport) : null;
     }
 
     @Override
     public void selectBackupTransportAsync(ComponentName transport,
             ISelectBackupTransportCallback listener) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.selectBackupTransportAsync(transport, listener);
         } else {
@@ -309,7 +361,7 @@
                 try {
                     listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                 } catch (RemoteException ex) {
-                    // Ignore
+                    // ignore
                 }
             }
         }
@@ -317,38 +369,38 @@
 
     @Override
     public Intent getConfigurationIntent(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getConfigurationIntent(transport) : null;
     }
 
     @Override
     public String getDestinationString(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDestinationString(transport) : null;
     }
 
     @Override
     public Intent getDataManagementIntent(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDataManagementIntent(transport) : null;
     }
 
     @Override
     public String getDataManagementLabel(String transport) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getDataManagementLabel(transport) : null;
     }
 
     @Override
     public IRestoreSession beginRestoreSession(String packageName, String transportID)
             throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null;
     }
 
     @Override
     public void opComplete(int token, long result) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.opComplete(token, result);
         }
@@ -356,20 +408,20 @@
 
     @Override
     public long getAvailableRestoreToken(String packageName) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.getAvailableRestoreToken(packageName) : 0;
     }
 
     @Override
     public boolean isAppEligibleForBackup(String packageName) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.isAppEligibleForBackup(packageName) : false;
     }
 
     @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc == null) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
@@ -378,7 +430,7 @@
 
     @Override
     public void cancelBackups() throws RemoteException {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.cancelBackups();
         }
@@ -388,7 +440,7 @@
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.dump(fd, pw, args);
         } else {
@@ -399,12 +451,12 @@
     // Full backup/restore entry points - non-Binder; called directly
     // by the full-backup scheduled job
     /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         return (svc != null) ? svc.beginFullBackup(scheduledJob) : false;
     }
 
     /* package */ void endFullBackup() {
-        BackupManagerService svc = mService;
+        BackupManagerServiceInterface svc = mService;
         if (svc != null) {
             svc.endFullBackup();
         }
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index da1f32c..fb2982e 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -53,7 +53,7 @@
 /**
  * Handles in-memory bookkeeping of all BackupTransport objects.
  */
-class TransportManager {
+public class TransportManager {
 
     private static final String TAG = "BackupTransportManager";
 
@@ -149,7 +149,7 @@
         }
     }
 
-    IBackupTransport getTransportBinder(String transportName) {
+    public IBackupTransport getTransportBinder(String transportName) {
         synchronized (mTransportLock) {
             ComponentName component = mBoundTransports.get(transportName);
             if (component == null) {
@@ -165,11 +165,11 @@
         }
     }
 
-    IBackupTransport getCurrentTransportBinder() {
+    public IBackupTransport getCurrentTransportBinder() {
         return getTransportBinder(mCurrentTransportName);
     }
 
-    String getTransportName(IBackupTransport binder) {
+    public String getTransportName(IBackupTransport binder) {
         synchronized (mTransportLock) {
             for (TransportConnection conn : mValidTransports.values()) {
                 if (conn.getBinder() == binder) {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
new file mode 100644
index 0000000..3bf77e8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -0,0 +1,364 @@
+/*
+ * 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.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupTransport;
+import android.app.backup.FullBackup;
+import android.app.backup.FullBackupDataOutput;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.os.Environment.UserEnvironment;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import android.util.StringBuilderPrinter;
+
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.FullBackupUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Core logic for performing one package's full backup, gathering the tarball from the
+ * application and emitting it to the designated OutputStream.
+ */
+public class FullBackupEngine {
+
+    private RefactoredBackupManagerService backupManagerService;
+    OutputStream mOutput;
+    FullBackupPreflight mPreflightHook;
+    BackupRestoreTask mTimeoutMonitor;
+    IBackupAgent mAgent;
+    File mFilesDir;
+    File mManifestFile;
+    File mMetadataFile;
+    boolean mIncludeApks;
+    PackageInfo mPkg;
+    private final long mQuota;
+    private final int mOpToken;
+
+    class FullBackupRunner implements Runnable {
+
+        PackageInfo mPackage;
+        byte[] mWidgetData;
+        IBackupAgent mAgent;
+        ParcelFileDescriptor mPipe;
+        int mToken;
+        boolean mSendApk;
+        boolean mWriteManifest;
+
+        FullBackupRunner(PackageInfo pack, IBackupAgent agent, ParcelFileDescriptor pipe,
+                int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
+                throws IOException {
+            mPackage = pack;
+            mWidgetData = widgetData;
+            mAgent = agent;
+            mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
+            mToken = token;
+            mSendApk = sendApk;
+            mWriteManifest = writeManifest;
+        }
+
+        @Override
+        public void run() {
+            try {
+                FullBackupDataOutput output = new FullBackupDataOutput(mPipe);
+
+                if (mWriteManifest) {
+                    final boolean writeWidgetData = mWidgetData != null;
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
+                    }
+                    FullBackupUtils
+                            .writeAppManifest(mPackage, backupManagerService.getPackageManager(),
+                                    mManifestFile, mSendApk,
+                                    writeWidgetData);
+                    FullBackup.backupToTar(mPackage.packageName, null, null,
+                            mFilesDir.getAbsolutePath(),
+                            mManifestFile.getAbsolutePath(),
+                            output);
+                    mManifestFile.delete();
+
+                    // We only need to write a metadata file if we have widget data to stash
+                    if (writeWidgetData) {
+                        writeMetadata(mPackage, mMetadataFile, mWidgetData);
+                        FullBackup.backupToTar(mPackage.packageName, null, null,
+                                mFilesDir.getAbsolutePath(),
+                                mMetadataFile.getAbsolutePath(),
+                                output);
+                        mMetadataFile.delete();
+                    }
+                }
+
+                if (mSendApk) {
+                    writeApkToBackup(mPackage, output);
+                }
+
+                final boolean isSharedStorage =
+                        mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                final long timeout = isSharedStorage ?
+                        TIMEOUT_SHARED_BACKUP_INTERVAL :
+                        TIMEOUT_FULL_BACKUP_INTERVAL;
+
+                if (DEBUG) {
+                    Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
+                }
+                backupManagerService
+                        .prepareOperationTimeout(mToken,
+                                timeout,
+                                mTimeoutMonitor /* in parent class */,
+                                OP_TYPE_BACKUP_WAIT);
+                mAgent.doFullBackup(mPipe, mQuota, mToken,
+                        backupManagerService.getBackupManagerBinder());
+            } catch (IOException e) {
+                Slog.e(TAG, "Error running full backup for " + mPackage.packageName);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote agent vanished during full backup of " + mPackage.packageName);
+            } finally {
+                try {
+                    mPipe.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    public FullBackupEngine(RefactoredBackupManagerService backupManagerService,
+            OutputStream output,
+            FullBackupPreflight preflightHook, PackageInfo pkg,
+            boolean alsoApks, BackupRestoreTask timeoutMonitor, long quota, int opToken) {
+        this.backupManagerService = backupManagerService;
+        mOutput = output;
+        mPreflightHook = preflightHook;
+        mPkg = pkg;
+        mIncludeApks = alsoApks;
+        mTimeoutMonitor = timeoutMonitor;
+        mFilesDir = new File("/data/system");
+        mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
+        mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
+        mQuota = quota;
+        mOpToken = opToken;
+    }
+
+    public int preflightCheck() throws RemoteException {
+        if (mPreflightHook == null) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "No preflight check");
+            }
+            return BackupTransport.TRANSPORT_OK;
+        }
+        if (initializeAgent()) {
+            int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "preflight returned " + result);
+            }
+            return result;
+        } else {
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+            return BackupTransport.AGENT_ERROR;
+        }
+    }
+
+    public int backupOnePackage() throws RemoteException {
+        int result = BackupTransport.AGENT_ERROR;
+
+        if (initializeAgent()) {
+            ParcelFileDescriptor[] pipes = null;
+            try {
+                pipes = ParcelFileDescriptor.createPipe();
+
+                ApplicationInfo app = mPkg.applicationInfo;
+                final boolean isSharedStorage =
+                        mPkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                final boolean sendApk = mIncludeApks
+                        && !isSharedStorage
+                        && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
+                        && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
+                        (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+
+                // TODO: http://b/22388012
+                byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(mPkg.packageName,
+                        UserHandle.USER_SYSTEM);
+
+                FullBackupRunner runner = new FullBackupRunner(mPkg, mAgent, pipes[1],
+                        mOpToken, sendApk, !isSharedStorage, widgetBlob);
+                pipes[1].close();   // the runner has dup'd it
+                pipes[1] = null;
+                Thread t = new Thread(runner, "app-data-runner");
+                t.start();
+
+                // Now pull data from the app and stuff it into the output
+                FullBackupUtils.routeSocketDataToOutput(pipes[0], mOutput);
+
+                if (!backupManagerService.waitUntilOperationComplete(mOpToken)) {
+                    Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
+                } else {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
+                    }
+                    result = BackupTransport.TRANSPORT_OK;
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
+                result = BackupTransport.AGENT_ERROR;
+            } finally {
+                try {
+                    // flush after every package
+                    mOutput.flush();
+                    if (pipes != null) {
+                        if (pipes[0] != null) {
+                            pipes[0].close();
+                        }
+                        if (pipes[1] != null) {
+                            pipes[1].close();
+                        }
+                    }
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error bringing down backup stack");
+                    result = BackupTransport.TRANSPORT_ERROR;
+                }
+            }
+        } else {
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+        }
+        tearDown();
+        return result;
+    }
+
+    public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+        if (initializeAgent()) {
+            try {
+                mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
+            }
+        }
+    }
+
+    private boolean initializeAgent() {
+        if (mAgent == null) {
+            if (MORE_DEBUG) {
+                Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
+            }
+            mAgent = backupManagerService.bindToAgentSynchronous(mPkg.applicationInfo,
+                    ApplicationThreadConstants.BACKUP_MODE_FULL);
+        }
+        return mAgent != null;
+    }
+
+    private void writeApkToBackup(PackageInfo pkg, FullBackupDataOutput output) {
+        // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
+        // TODO: handle backing up split APKs
+        final String appSourceDir = pkg.applicationInfo.getBaseCodePath();
+        final String apkDir = new File(appSourceDir).getParent();
+        FullBackup.backupToTar(pkg.packageName, FullBackup.APK_TREE_TOKEN, null,
+                apkDir, appSourceDir, output);
+
+        // TODO: migrate this to SharedStorageBackup, since AID_SYSTEM
+        // doesn't have access to external storage.
+
+        // Save associated .obb content if it exists and we did save the apk
+        // check for .obb and save those too
+        // TODO: http://b/22388012
+        final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_SYSTEM);
+        final File obbDir = userEnv.buildExternalStorageAppObbDirs(pkg.packageName)[0];
+        if (obbDir != null) {
+            if (MORE_DEBUG) {
+                Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
+            }
+            File[] obbFiles = obbDir.listFiles();
+            if (obbFiles != null) {
+                final String obbDirName = obbDir.getAbsolutePath();
+                for (File obb : obbFiles) {
+                    FullBackup.backupToTar(pkg.packageName, FullBackup.OBB_TREE_TOKEN, null,
+                            obbDirName, obb.getAbsolutePath(), output);
+                }
+            }
+        }
+    }
+
+    // Widget metadata format. All header entries are strings ending in LF:
+    //
+    // Version 1 header:
+    //     BACKUP_METADATA_VERSION, currently "1"
+    //     package name
+    //
+    // File data (all integers are binary in network byte order)
+    // *N: 4 : integer token identifying which metadata blob
+    //     4 : integer size of this blob = N
+    //     N : raw bytes of this metadata blob
+    //
+    // Currently understood blobs (always in network byte order):
+    //
+    //     widgets : metadata token = 0x01FFED01 (BACKUP_WIDGET_METADATA_TOKEN)
+    //
+    // Unrecognized blobs are *ignored*, not errors.
+    private void writeMetadata(PackageInfo pkg, File destination, byte[] widgetData)
+            throws IOException {
+        StringBuilder b = new StringBuilder(512);
+        StringBuilderPrinter printer = new StringBuilderPrinter(b);
+        printer.println(Integer.toString(BACKUP_METADATA_VERSION));
+        printer.println(pkg.packageName);
+
+        FileOutputStream fout = new FileOutputStream(destination);
+        BufferedOutputStream bout = new BufferedOutputStream(fout);
+        DataOutputStream out = new DataOutputStream(bout);
+        bout.write(b.toString().getBytes());    // bypassing DataOutputStream
+
+        if (widgetData != null && widgetData.length > 0) {
+            out.writeInt(BACKUP_WIDGET_METADATA_TOKEN);
+            out.writeInt(widgetData.length);
+            out.write(widgetData);
+        }
+        bout.flush();
+        out.close();
+
+        // As with the manifest file, guarantee idempotence of the archive metadata
+        // for the widget block by using a fixed mtime on the transient file.
+        destination.setLastModified(0);
+    }
+
+    private void tearDown() {
+        if (mPkg != null) {
+            backupManagerService.tearDownAgentAndKill(mPkg.applicationInfo);
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java
new file mode 100644
index 0000000..a62f1c0
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEntry.java
@@ -0,0 +1,39 @@
+/*
+ * 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.backup.fullbackup;
+
+public class FullBackupEntry implements Comparable<FullBackupEntry> {
+
+    public String packageName;
+    public long lastBackup;
+
+    public FullBackupEntry(String pkg, long when) {
+        packageName = pkg;
+        lastBackup = when;
+    }
+
+    @Override
+    public int compareTo(FullBackupEntry other) {
+        if (lastBackup < other.lastBackup) {
+            return -1;
+        } else if (lastBackup > other.lastBackup) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
new file mode 100644
index 0000000..da8a66a
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -0,0 +1,155 @@
+/*
+ * 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.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.app.backup.IBackupManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.backup.IObbBackupService;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.FullBackupUtils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Full backup/restore to a file/socket.
+ */
+public class FullBackupObbConnection implements ServiceConnection {
+
+    private RefactoredBackupManagerService backupManagerService;
+    volatile IObbBackupService mService;
+
+    public FullBackupObbConnection(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+        mService = null;
+    }
+
+    public void establish() {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Initiating bind of OBB service on " + this);
+        }
+        Intent obbIntent = new Intent().setComponent(new ComponentName(
+                "com.android.sharedstoragebackup",
+                "com.android.sharedstoragebackup.ObbBackupService"));
+        backupManagerService.getContext().bindServiceAsUser(
+                obbIntent, this, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+    }
+
+    public void tearDown() {
+        backupManagerService.getContext().unbindService(this);
+    }
+
+    public boolean backupObbs(PackageInfo pkg, OutputStream out) {
+        boolean success = false;
+        waitForConnection();
+
+        ParcelFileDescriptor[] pipes = null;
+        try {
+            pipes = ParcelFileDescriptor.createPipe();
+            int token = backupManagerService.generateRandomIntegerToken();
+            backupManagerService.prepareOperationTimeout(
+                    token, TIMEOUT_FULL_BACKUP_INTERVAL, null, OP_TYPE_BACKUP_WAIT);
+            mService.backupObbs(pkg.packageName, pipes[1], token,
+                    backupManagerService.getBackupManagerBinder());
+            FullBackupUtils.routeSocketDataToOutput(pipes[0], out);
+            success = backupManagerService.waitUntilOperationComplete(token);
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to back up OBBs for " + pkg, e);
+        } finally {
+            try {
+                out.flush();
+                if (pipes != null) {
+                    if (pipes[0] != null) {
+                        pipes[0].close();
+                    }
+                    if (pipes[1] != null) {
+                        pipes[1].close();
+                    }
+                }
+            } catch (IOException e) {
+                Slog.w(TAG, "I/O error closing down OBB backup", e);
+            }
+        }
+        return success;
+    }
+
+    public void restoreObbFile(String pkgName, ParcelFileDescriptor data,
+            long fileSize, int type, String path, long mode, long mtime,
+            int token, IBackupManager callbackBinder) {
+        waitForConnection();
+
+        try {
+            mService.restoreObbFile(pkgName, data, fileSize, type, path, mode, mtime,
+                    token, callbackBinder);
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to restore OBBs for " + pkgName, e);
+        }
+    }
+
+    private void waitForConnection() {
+        synchronized (this) {
+            while (mService == null) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "...waiting for OBB service binding...");
+                }
+                try {
+                    this.wait();
+                } catch (InterruptedException e) { /* never interrupted */ }
+            }
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Connected to OBB service; continuing");
+            }
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        synchronized (this) {
+            mService = IObbBackupService.Stub.asInterface(service);
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection " + mService + " connected on " + this);
+            }
+            this.notifyAll();
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        synchronized (this) {
+            mService = null;
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection disconnected on " + this);
+            }
+            this.notifyAll();
+        }
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java
new file mode 100644
index 0000000..f12587f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupPreflight.java
@@ -0,0 +1,39 @@
+/*
+ * 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.backup.fullbackup;
+
+import android.app.IBackupAgent;
+import android.content.pm.PackageInfo;
+
+/**
+ * Callout from the engine to an interested participant that might need to communicate with the
+ * agent prior to asking it to move data.
+ */
+public interface FullBackupPreflight {
+
+    /**
+     * Perform the preflight operation necessary for the given package.
+     *
+     * @param pkg The name of the package being proposed for full-data backup
+     * @param agent Live BackupAgent binding to the target app's agent
+     * @return BackupTransport.TRANSPORT_OK to proceed with the backup operation, or one of the
+     * other BackupTransport.* error codes as appropriate
+     */
+    int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
+
+    long getExpectedSizeOrErrorCode();
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
new file mode 100644
index 0000000..37961f9
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
@@ -0,0 +1,70 @@
+/*
+ * 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.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Generic driver skeleton for full backup operations.
+ */
+public abstract class FullBackupTask implements Runnable {
+
+    IFullBackupRestoreObserver mObserver;
+
+    FullBackupTask(IFullBackupRestoreObserver observer) {
+        mObserver = observer;
+    }
+
+    // wrappers for observer use
+    final void sendStartBackup() {
+        if (mObserver != null) {
+            try {
+                mObserver.onStartBackup();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: startBackup");
+                mObserver = null;
+            }
+        }
+    }
+
+    final void sendOnBackupPackage(String name) {
+        if (mObserver != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                mObserver.onBackupPackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: backupPackage");
+                mObserver = null;
+            }
+        }
+    }
+
+    final void sendEndBackup() {
+        if (mObserver != null) {
+            try {
+                mObserver.onEndBackup();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full backup observer went away: endBackup");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
new file mode 100644
index 0000000..007d930
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -0,0 +1,499 @@
+/*
+ * 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.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.KeyValueAdbBackupEngine;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.PasswordUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Full backup task variant used for adb backup.
+ */
+public class PerformAdbBackupTask extends FullBackupTask implements BackupRestoreTask {
+
+    private RefactoredBackupManagerService backupManagerService;
+    FullBackupEngine mBackupEngine;
+    final AtomicBoolean mLatch;
+
+    ParcelFileDescriptor mOutputFile;
+    DeflaterOutputStream mDeflater;
+    boolean mIncludeApks;
+    boolean mIncludeObbs;
+    boolean mIncludeShared;
+    boolean mDoWidgets;
+    boolean mAllApps;
+    boolean mIncludeSystem;
+    boolean mCompress;
+    boolean mKeyValue;
+    ArrayList<String> mPackages;
+    PackageInfo mCurrentTarget;
+    String mCurrentPassword;
+    String mEncryptPassword;
+    private final int mCurrentOpToken;
+
+    public PerformAdbBackupTask(RefactoredBackupManagerService backupManagerService,
+            ParcelFileDescriptor fd, IFullBackupRestoreObserver observer,
+            boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets,
+            String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
+            boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
+        super(observer);
+        this.backupManagerService = backupManagerService;
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+        mLatch = latch;
+
+        mOutputFile = fd;
+        mIncludeApks = includeApks;
+        mIncludeObbs = includeObbs;
+        mIncludeShared = includeShared;
+        mDoWidgets = doWidgets;
+        mAllApps = doAllApps;
+        mIncludeSystem = doSystem;
+        mPackages = (packages == null)
+                ? new ArrayList<String>()
+                : new ArrayList<>(Arrays.asList(packages));
+        mCurrentPassword = curPassword;
+        // when backing up, if there is a current backup password, we require that
+        // the user use a nonempty encryption password as well.  if one is supplied
+        // in the UI we use that, but if the UI was left empty we fall back to the
+        // current backup password (which was supplied by the user as well).
+        if (encryptPassword == null || "".equals(encryptPassword)) {
+            mEncryptPassword = curPassword;
+        } else {
+            mEncryptPassword = encryptPassword;
+        }
+        if (MORE_DEBUG) {
+            Slog.w(TAG, "Encrypting backup with passphrase=" + mEncryptPassword);
+        }
+        mCompress = doCompress;
+        mKeyValue = doKeyValue;
+    }
+
+    void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
+        for (String pkgName : pkgNames) {
+            if (!set.containsKey(pkgName)) {
+                try {
+                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
+                            pkgName,
+                            PackageManager.GET_SIGNATURES);
+                    set.put(pkgName, info);
+                } catch (NameNotFoundException e) {
+                    Slog.w(TAG, "Unknown package " + pkgName + ", skipping");
+                }
+            }
+        }
+    }
+
+    private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
+            OutputStream ofstream) throws Exception {
+        // User key will be used to encrypt the master key.
+        byte[] newUserSalt = backupManagerService
+                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+        SecretKey userKey = PasswordUtils
+                .buildPasswordKey(PBKDF_CURRENT, mEncryptPassword,
+                        newUserSalt,
+                        PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+        // the master key is random for each backup
+        byte[] masterPw = new byte[256 / 8];
+        backupManagerService.getRng().nextBytes(masterPw);
+        byte[] checksumSalt = backupManagerService
+                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
+
+        // primary encryption of the datastream with the random key
+        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        SecretKeySpec masterKeySpec = new SecretKeySpec(masterPw, "AES");
+        c.init(Cipher.ENCRYPT_MODE, masterKeySpec);
+        OutputStream finalOutput = new CipherOutputStream(ofstream, c);
+
+        // line 4: name of encryption algorithm
+        headerbuf.append(PasswordUtils.ENCRYPTION_ALGORITHM_NAME);
+        headerbuf.append('\n');
+        // line 5: user password salt [hex]
+        headerbuf.append(PasswordUtils.byteArrayToHex(newUserSalt));
+        headerbuf.append('\n');
+        // line 6: master key checksum salt [hex]
+        headerbuf.append(PasswordUtils.byteArrayToHex(checksumSalt));
+        headerbuf.append('\n');
+        // line 7: number of PBKDF2 rounds used [decimal]
+        headerbuf.append(PasswordUtils.PBKDF2_HASH_ROUNDS);
+        headerbuf.append('\n');
+
+        // line 8: IV of the user key [hex]
+        Cipher mkC = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        mkC.init(Cipher.ENCRYPT_MODE, userKey);
+
+        byte[] IV = mkC.getIV();
+        headerbuf.append(PasswordUtils.byteArrayToHex(IV));
+        headerbuf.append('\n');
+
+        // line 9: master IV + key blob, encrypted by the user key [hex].  Blob format:
+        //    [byte] IV length = Niv
+        //    [array of Niv bytes] IV itself
+        //    [byte] master key length = Nmk
+        //    [array of Nmk bytes] master key itself
+        //    [byte] MK checksum hash length = Nck
+        //    [array of Nck bytes] master key checksum hash
+        //
+        // The checksum is the (master key + checksum salt), run through the
+        // stated number of PBKDF2 rounds
+        IV = c.getIV();
+        byte[] mk = masterKeySpec.getEncoded();
+        byte[] checksum = PasswordUtils
+                .makeKeyChecksum(PBKDF_CURRENT,
+                        masterKeySpec.getEncoded(),
+                        checksumSalt, PasswordUtils.PBKDF2_HASH_ROUNDS);
+
+        ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length
+                + checksum.length + 3);
+        DataOutputStream mkOut = new DataOutputStream(blob);
+        mkOut.writeByte(IV.length);
+        mkOut.write(IV);
+        mkOut.writeByte(mk.length);
+        mkOut.write(mk);
+        mkOut.writeByte(checksum.length);
+        mkOut.write(checksum);
+        mkOut.flush();
+        byte[] encryptedMk = mkC.doFinal(blob.toByteArray());
+        headerbuf.append(PasswordUtils.byteArrayToHex(encryptedMk));
+        headerbuf.append('\n');
+
+        return finalOutput;
+    }
+
+    private void finalizeBackup(OutputStream out) {
+        try {
+            // A standard 'tar' EOF sequence: two 512-byte blocks of all zeroes.
+            byte[] eof = new byte[512 * 2]; // newly allocated == zero filled
+            out.write(eof);
+        } catch (IOException e) {
+            Slog.w(TAG, "Error attempting to finalize backup stream");
+        }
+    }
+
+    @Override
+    public void run() {
+        String includeKeyValue = mKeyValue ? ", including key-value backups" : "";
+        Slog.i(TAG, "--- Performing adb backup" + includeKeyValue + " ---");
+
+        TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<>();
+        FullBackupObbConnection obbConnection = new FullBackupObbConnection(
+                backupManagerService);
+        obbConnection.establish();  // we'll want this later
+
+        sendStartBackup();
+
+        // doAllApps supersedes the package set if any
+        if (mAllApps) {
+            List<PackageInfo> allPackages =
+                    backupManagerService.getPackageManager().getInstalledPackages(
+                            PackageManager.GET_SIGNATURES);
+            for (int i = 0; i < allPackages.size(); i++) {
+                PackageInfo pkg = allPackages.get(i);
+                // Exclude system apps if we've been asked to do so
+                if (mIncludeSystem == true
+                        || ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) {
+                    packagesToBackup.put(pkg.packageName, pkg);
+                }
+            }
+        }
+
+        // If we're doing widget state as well, ensure that we have all the involved
+        // host & provider packages in the set
+        if (mDoWidgets) {
+            // TODO: http://b/22388012
+            List<String> pkgs =
+                    AppWidgetBackupBridge.getWidgetParticipants(UserHandle.USER_SYSTEM);
+            if (pkgs != null) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Adding widget participants to backup set:");
+                    StringBuilder sb = new StringBuilder(128);
+                    sb.append("   ");
+                    for (String s : pkgs) {
+                        sb.append(' ');
+                        sb.append(s);
+                    }
+                    Slog.i(TAG, sb.toString());
+                }
+                addPackagesToSet(packagesToBackup, pkgs);
+            }
+        }
+
+        // Now process the command line argument packages, if any. Note that explicitly-
+        // named system-partition packages will be included even if includeSystem was
+        // set to false.
+        if (mPackages != null) {
+            addPackagesToSet(packagesToBackup, mPackages);
+        }
+
+        // Now we cull any inapplicable / inappropriate packages from the set.  This
+        // includes the special shared-storage agent package; we handle that one
+        // explicitly at the end of the backup pass. Packages supporting key-value backup are
+        // added to their own queue, and handled after packages supporting fullbackup.
+        ArrayList<PackageInfo> keyValueBackupQueue = new ArrayList<>();
+        Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator();
+        while (iter.hasNext()) {
+            PackageInfo pkg = iter.next().getValue();
+            if (!AppBackupUtils.appIsEligibleForBackup(pkg.applicationInfo)
+                    || AppBackupUtils.appIsStopped(pkg.applicationInfo)) {
+                iter.remove();
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
+                            + " is not eligible for backup, removing.");
+                }
+            } else if (AppBackupUtils.appIsKeyValueOnly(pkg)) {
+                iter.remove();
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
+                            + " is key-value.");
+                }
+                keyValueBackupQueue.add(pkg);
+            }
+        }
+
+        // flatten the set of packages now so we can explicitly control the ordering
+        ArrayList<PackageInfo> backupQueue =
+                new ArrayList<>(packagesToBackup.values());
+        FileOutputStream ofstream = new FileOutputStream(mOutputFile.getFileDescriptor());
+        OutputStream out = null;
+
+        PackageInfo pkg = null;
+        try {
+            boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);
+
+            // Only allow encrypted backups of encrypted devices
+            if (backupManagerService.deviceIsEncrypted() && !encrypting) {
+                Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
+                return;
+            }
+
+            OutputStream finalOutput = ofstream;
+
+            // Verify that the given password matches the currently-active
+            // backup password, if any
+            if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
+                }
+                return;
+            }
+
+            // Write the global file header.  All strings are UTF-8 encoded; lines end
+            // with a '\n' byte.  Actual backup data begins immediately following the
+            // final '\n'.
+            //
+            // line 1: "ANDROID BACKUP"
+            // line 2: backup file format version, currently "5"
+            // line 3: compressed?  "0" if not compressed, "1" if compressed.
+            // line 4: name of encryption algorithm [currently only "none" or "AES-256"]
+            //
+            // When line 4 is not "none", then additional header data follows:
+            //
+            // line 5: user password salt [hex]
+            // line 6: master key checksum salt [hex]
+            // line 7: number of PBKDF2 rounds to use (same for user & master) [decimal]
+            // line 8: IV of the user key [hex]
+            // line 9: master key blob [hex]
+            //     IV of the master key, master key itself, master key checksum hash
+            //
+            // The master key checksum is the master key plus its checksum salt, run through
+            // 10k rounds of PBKDF2.  This is used to verify that the user has supplied the
+            // correct password for decrypting the archive:  the master key decrypted from
+            // the archive using the user-supplied password is also run through PBKDF2 in
+            // this way, and if the result does not match the checksum as stored in the
+            // archive, then we know that the user-supplied password does not match the
+            // archive's.
+            StringBuilder headerbuf = new StringBuilder(1024);
+
+            headerbuf.append(BACKUP_FILE_HEADER_MAGIC);
+            headerbuf.append(BACKUP_FILE_VERSION); // integer, no trailing \n
+            headerbuf.append(mCompress ? "\n1\n" : "\n0\n");
+
+            try {
+                // Set up the encryption stage if appropriate, and emit the correct header
+                if (encrypting) {
+                    finalOutput = emitAesBackupHeader(headerbuf, finalOutput);
+                } else {
+                    headerbuf.append("none\n");
+                }
+
+                byte[] header = headerbuf.toString().getBytes("UTF-8");
+                ofstream.write(header);
+
+                // Set up the compression stage feeding into the encryption stage (if any)
+                if (mCompress) {
+                    Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
+                    finalOutput = new DeflaterOutputStream(finalOutput, deflater, true);
+                }
+
+                out = finalOutput;
+            } catch (Exception e) {
+                // Should never happen!
+                Slog.e(TAG, "Unable to emit archive header", e);
+                return;
+            }
+
+            // Shared storage if requested
+            if (mIncludeShared) {
+                try {
+                    pkg = backupManagerService.getPackageManager().getPackageInfo(
+                            SHARED_BACKUP_AGENT_PACKAGE, 0);
+                    backupQueue.add(pkg);
+                } catch (NameNotFoundException e) {
+                    Slog.e(TAG, "Unable to find shared-storage backup handler");
+                }
+            }
+
+            // Now actually run the constructed backup sequence for full backup
+            int N = backupQueue.size();
+            for (int i = 0; i < N; i++) {
+                pkg = backupQueue.get(i);
+                if (DEBUG) {
+                    Slog.i(TAG, "--- Performing full backup for package " + pkg.packageName
+                            + " ---");
+                }
+                final boolean isSharedStorage =
+                        pkg.packageName.equals(
+                                SHARED_BACKUP_AGENT_PACKAGE);
+
+                mBackupEngine = new FullBackupEngine(backupManagerService, out,
+                        null, pkg, mIncludeApks, this, Long.MAX_VALUE, mCurrentOpToken);
+                sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
+
+                // Don't need to check preflight result as there is no preflight hook.
+                mCurrentTarget = pkg;
+                mBackupEngine.backupOnePackage();
+
+                // after the app's agent runs to handle its private filesystem
+                // contents, back up any OBB content it has on its behalf.
+                if (mIncludeObbs) {
+                    boolean obbOkay = obbConnection.backupObbs(pkg, out);
+                    if (!obbOkay) {
+                        throw new RuntimeException("Failure writing OBB stack for " + pkg);
+                    }
+                }
+            }
+            // And for key-value backup if enabled
+            if (mKeyValue) {
+                for (PackageInfo keyValuePackage : keyValueBackupQueue) {
+                    if (DEBUG) {
+                        Slog.i(TAG, "--- Performing key-value backup for package "
+                                + keyValuePackage.packageName + " ---");
+                    }
+                    KeyValueAdbBackupEngine kvBackupEngine =
+                            new KeyValueAdbBackupEngine(out, keyValuePackage,
+                                    backupManagerService,
+                                    backupManagerService.getPackageManager(),
+                                    backupManagerService.getBaseStateDir(),
+                                    backupManagerService.getDataDir());
+                    sendOnBackupPackage(keyValuePackage.packageName);
+                    kvBackupEngine.backupOnePackage();
+                }
+            }
+
+            // Done!
+            finalizeBackup(out);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "App died during full backup");
+        } catch (Exception e) {
+            Slog.e(TAG, "Internal exception during full backup", e);
+        } finally {
+            try {
+                if (out != null) {
+                    out.flush();
+                    out.close();
+                }
+                mOutputFile.close();
+            } catch (IOException e) {
+                /* nothing we can do about this */
+            }
+            synchronized (mLatch) {
+                mLatch.set(true);
+                mLatch.notifyAll();
+            }
+            sendEndBackup();
+            obbConnection.tearDown();
+            if (DEBUG) {
+                Slog.d(TAG, "Full backup pass complete.");
+            }
+            backupManagerService.getWakelock().release();
+        }
+    }
+
+    // BackupRestoreTask methods, used for timeout handling
+    @Override
+    public void execute() {
+        // Unused
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        // Unused
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        final PackageInfo target = mCurrentTarget;
+        if (DEBUG) {
+            Slog.w(TAG, "adb backup cancel of " + target);
+        }
+        if (target != null) {
+            backupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
+        }
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
new file mode 100644
index 0000000..0f1e485
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -0,0 +1,855 @@
+/*
+ * 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.backup.fullbackup;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_SCHEDULING;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.app.IBackupAgent;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupProgress;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.FullBackupJob;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.internal.Operation;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Full backup task extension used for transport-oriented operation.
+ *
+ * Flow:
+ * For each requested package:
+ *     - Spin off a new SinglePackageBackupRunner (mBackupRunner) for the current package.
+ *     - Wait until preflight is complete. (mBackupRunner.getPreflightResultBlocking())
+ *     - If preflight data size is within limit, start reading data from agent pipe and writing
+ *       to transport pipe. While there is data to send, call transport.sendBackupData(int) to
+ *       tell the transport how many bytes to expect on its pipe.
+ *     - After sending all data, call transport.finishBackup() if things went well. And
+ *       transport.cancelFullBackup() otherwise.
+ *
+ * Interactions with mCurrentOperations:
+ *     - An entry for this object is added to mCurrentOperations for the entire lifetime of this
+ *       object. Used to cancel the operation.
+ *     - SinglePackageBackupRunner and SinglePackageBackupPreflight will put ephemeral entries
+ *       to get timeouts or operation complete callbacks.
+ *
+ * Handling cancels:
+ *     - The contract we provide is that the task won't interact with the transport after
+ *       handleCancel() is done executing.
+ *     - This task blocks at 3 points: 1. Preflight result check 2. Reading on agent side pipe
+ *       and 3. Get backup result from mBackupRunner.
+ *     - Bubbling up handleCancel to mBackupRunner handles all 3: 1. Calls handleCancel on the
+ *       preflight operation which counts down on the preflight latch. 2. Tears down the agent,
+ *       so read() returns -1. 3. Notifies mCurrentOpLock which unblocks
+ *       mBackupRunner.getBackupResultBlocking().
+ */
+public class PerformFullTransportBackupTask extends FullBackupTask implements BackupRestoreTask {
+    private static final String TAG = "PFTBT";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private final Object mCancelLock = new Object();
+
+    ArrayList<PackageInfo> mPackages;
+    PackageInfo mCurrentPackage;
+    boolean mUpdateSchedule;
+    CountDownLatch mLatch;
+    FullBackupJob mJob;             // if a scheduled job needs to be finished afterwards
+    IBackupObserver mBackupObserver;
+    IBackupManagerMonitor mMonitor;
+    boolean mUserInitiated;
+    private volatile IBackupTransport mTransport;
+    SinglePackageBackupRunner mBackupRunner;
+    private final int mBackupRunnerOpToken;
+
+    // This is true when a backup operation for some package is in progress.
+    private volatile boolean mIsDoingBackup;
+    private volatile boolean mCancelAll;
+    private final int mCurrentOpToken;
+
+    public PerformFullTransportBackupTask(RefactoredBackupManagerService backupManagerService,
+            IFullBackupRestoreObserver observer,
+            String[] whichPackages, boolean updateSchedule,
+            FullBackupJob runningJob, CountDownLatch latch, IBackupObserver backupObserver,
+            IBackupManagerMonitor monitor, boolean userInitiated) {
+        super(observer);
+        this.backupManagerService = backupManagerService;
+        mUpdateSchedule = updateSchedule;
+        mLatch = latch;
+        mJob = runningJob;
+        mPackages = new ArrayList<>(whichPackages.length);
+        mBackupObserver = backupObserver;
+        mMonitor = monitor;
+        mUserInitiated = userInitiated;
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+        mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
+
+        if (backupManagerService.isBackupOperationInProgress()) {
+            if (DEBUG) {
+                Slog.d(TAG, "Skipping full backup. A backup is already in progress.");
+            }
+            mCancelAll = true;
+            return;
+        }
+
+        registerTask();
+
+        for (String pkg : whichPackages) {
+            try {
+                PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(pkg,
+                        PackageManager.GET_SIGNATURES);
+                mCurrentPackage = info;
+                if (!AppBackupUtils.appIsEligibleForBackup(info.applicationInfo)) {
+                    // Cull any packages that have indicated that backups are not permitted,
+                    // that run as system-domain uids but do not define their own backup agents,
+                    // as well as any explicit mention of the 'special' shared-storage agent
+                    // package (we handle that one at the end).
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring ineligible package " + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_INELIGIBLE,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                } else if (!AppBackupUtils.appGetsFullBackup(info)) {
+                    // Cull any packages that are found in the queue but now aren't supposed
+                    // to get full-data backup operations.
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring full-data backup of key/value participant "
+                                + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_KEY_VALUE_PARTICIPANT,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                } else if (AppBackupUtils.appIsStopped(info.applicationInfo)) {
+                    // Cull any packages in the 'stopped' state: they've either just been
+                    // installed or have explicitly been force-stopped by the user.  In both
+                    // cases we do not want to launch them for backup.
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Ignoring stopped package " + pkg);
+                    }
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_STOPPED,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                    BackupObserverUtils.sendBackupOnPackageResult(mBackupObserver, pkg,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                }
+                mPackages.add(info);
+            } catch (NameNotFoundException e) {
+                Slog.i(TAG, "Requested package " + pkg + " not found; ignoring");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_FOUND,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+            }
+        }
+    }
+
+    private void registerTask() {
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken,
+                    new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
+        }
+    }
+
+    public void unregisterTask() {
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    @Override
+    public void execute() {
+        // Nothing to do.
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        synchronized (mCancelLock) {
+            // We only support 'cancelAll = true' case for this task. Cancelling of a single package
+
+            // due to timeout is handled by SinglePackageBackupRunner and
+            // SinglePackageBackupPreflight.
+
+            if (!cancelAll) {
+                Slog.wtf(TAG, "Expected cancelAll to be true.");
+            }
+
+            if (mCancelAll) {
+                Slog.d(TAG, "Ignoring duplicate cancel call.");
+                return;
+            }
+
+            mCancelAll = true;
+            if (mIsDoingBackup) {
+                backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+                try {
+                    mTransport.cancelFullBackup();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Error calling cancelFullBackup() on transport: " + e);
+                    // Can't do much.
+                }
+            }
+        }
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        // Nothing to do.
+    }
+
+    @Override
+    public void run() {
+
+        // data from the app, passed to us for bridging to the transport
+        ParcelFileDescriptor[] enginePipes = null;
+
+        // Pipe through which we write data to the transport
+        ParcelFileDescriptor[] transportPipes = null;
+
+        long backoff = 0;
+        int backupRunStatus = BackupManager.SUCCESS;
+
+        try {
+            if (!backupManagerService.isEnabled() || !backupManagerService.isProvisioned()) {
+                // Backups are globally disabled, so don't proceed.
+                if (DEBUG) {
+                    Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
+                            .isEnabled()
+                            + " provisioned=" + backupManagerService.isProvisioned()
+                            + "; ignoring");
+                }
+                int monitoringEvent;
+                if (!backupManagerService.isEnabled()) {
+                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
+                } else {
+                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
+                }
+                mMonitor = BackupManagerMonitorUtils
+                        .monitorEvent(mMonitor, monitoringEvent, null,
+                                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                null);
+                mUpdateSchedule = false;
+                backupRunStatus = BackupManager.ERROR_BACKUP_NOT_ALLOWED;
+                return;
+            }
+
+            mTransport = backupManagerService.getTransportManager().getCurrentTransportBinder();
+            if (mTransport == null) {
+                Slog.w(TAG, "Transport not present; full data backup not performed");
+                backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_TRANSPORT_NOT_PRESENT,
+                        mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                        null);
+                return;
+            }
+
+            // Set up to send data to the transport
+            final int N = mPackages.size();
+            final byte[] buffer = new byte[8192];
+            for (int i = 0; i < N; i++) {
+                PackageInfo currentPackage = mPackages.get(i);
+                String packageName = currentPackage.packageName;
+                if (DEBUG) {
+                    Slog.i(TAG, "Initiating full-data transport backup of " + packageName
+                            + " token: " + mCurrentOpToken);
+                }
+                EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE, packageName);
+
+                transportPipes = ParcelFileDescriptor.createPipe();
+
+                // Tell the transport the data's coming
+                int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+                int backupPackageStatus;
+                long quota = Long.MAX_VALUE;
+                synchronized (mCancelLock) {
+                    if (mCancelAll) {
+                        break;
+                    }
+                    backupPackageStatus = mTransport.performFullBackup(currentPackage,
+                            transportPipes[0], flags);
+
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                        quota = mTransport.getBackupQuota(currentPackage.packageName,
+                                true /* isFullBackup */);
+                        // Now set up the backup engine / data source end of things
+                        enginePipes = ParcelFileDescriptor.createPipe();
+                        mBackupRunner =
+                                new SinglePackageBackupRunner(enginePipes[1], currentPackage,
+                                        mTransport, quota, mBackupRunnerOpToken);
+                        // The runner dup'd the pipe half, so we close it here
+                        enginePipes[1].close();
+                        enginePipes[1] = null;
+
+                        mIsDoingBackup = true;
+                    }
+                }
+                if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+
+                    // The transport has its own copy of the read end of the pipe,
+                    // so close ours now
+                    transportPipes[0].close();
+                    transportPipes[0] = null;
+
+                    // Spin off the runner to fetch the app's data and pipe it
+                    // into the engine pipes
+                    (new Thread(mBackupRunner, "package-backup-bridge")).start();
+
+                    // Read data off the engine pipe and pass it to the transport
+                    // pipe until we hit EOD on the input stream.  We do not take
+                    // close() responsibility for these FDs into these stream wrappers.
+                    FileInputStream in = new FileInputStream(
+                            enginePipes[0].getFileDescriptor());
+                    FileOutputStream out = new FileOutputStream(
+                            transportPipes[1].getFileDescriptor());
+                    long totalRead = 0;
+                    final long preflightResult = mBackupRunner.getPreflightResultBlocking();
+                    // Preflight result is negative if some error happened on preflight.
+                    if (preflightResult < 0) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Backup error after preflight of package "
+                                    + packageName + ": " + preflightResult
+                                    + ", not running backup.");
+                        }
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                BackupManagerMonitor.LOG_EVENT_ID_ERROR_PREFLIGHT,
+                                mCurrentPackage,
+                                BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                        BackupManagerMonitor.EXTRA_LOG_PREFLIGHT_ERROR,
+                                        preflightResult));
+                        backupPackageStatus = (int) preflightResult;
+                    } else {
+                        int nRead = 0;
+                        do {
+                            nRead = in.read(buffer);
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+                            }
+                            if (nRead > 0) {
+                                out.write(buffer, 0, nRead);
+                                synchronized (mCancelLock) {
+                                    if (!mCancelAll) {
+                                        backupPackageStatus = mTransport.sendBackupData(nRead);
+                                    }
+                                }
+                                totalRead += nRead;
+                                if (mBackupObserver != null && preflightResult > 0) {
+                                    BackupObserverUtils
+                                            .sendBackupOnUpdate(mBackupObserver, packageName,
+                                                    new BackupProgress(preflightResult, totalRead));
+                                }
+                            }
+                        } while (nRead > 0
+                                && backupPackageStatus == BackupTransport.TRANSPORT_OK);
+                        // Despite preflight succeeded, package still can hit quota on flight.
+                        if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                            Slog.w(TAG, "Package hit quota limit in-flight " + packageName
+                                    + ": " + totalRead + " of " + quota);
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                    BackupManagerMonitor.LOG_EVENT_ID_QUOTA_HIT_PREFLIGHT,
+                                    mCurrentPackage,
+                                    BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+                                    null);
+                            mBackupRunner.sendQuotaExceeded(totalRead, quota);
+                        }
+                    }
+
+                    final int backupRunnerResult = mBackupRunner.getBackupResultBlocking();
+
+                    synchronized (mCancelLock) {
+                        mIsDoingBackup = false;
+                        // If mCancelCurrent is true, we have already called cancelFullBackup().
+                        if (!mCancelAll) {
+                            if (backupRunnerResult == BackupTransport.TRANSPORT_OK) {
+                                // If we were otherwise in a good state, now interpret the final
+                                // result based on what finishBackup() returns.  If we're in a
+                                // failure case already, preserve that result and ignore whatever
+                                // finishBackup() reports.
+                                final int finishResult = mTransport.finishBackup();
+                                if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                                    backupPackageStatus = finishResult;
+                                }
+                            } else {
+                                mTransport.cancelFullBackup();
+                            }
+                        }
+                    }
+
+                    // A transport-originated error here means that we've hit an error that the
+                    // runner doesn't know about, so it's still moving data but we're pulling the
+                    // rug out from under it.  Don't ask for its result:  we already know better
+                    // and we'll hang if we block waiting for it, since it relies on us to
+                    // read back the data it's writing into the engine.  Just proceed with
+                    // a graceful failure.  The runner/engine mechanism will tear itself
+                    // down cleanly when we close the pipes from this end.  Transport-level
+                    // errors take precedence over agent/app-specific errors for purposes of
+                    // determining our course of action.
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                        // We still could fail in backup runner thread.
+                        if (backupRunnerResult != BackupTransport.TRANSPORT_OK) {
+                            // If there was an error in runner thread and
+                            // not TRANSPORT_ERROR here, overwrite it.
+                            backupPackageStatus = backupRunnerResult;
+                        }
+                    } else {
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Transport-level failure; cancelling agent work");
+                        }
+                    }
+
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Done delivering backup data: result="
+                                + backupPackageStatus);
+                    }
+
+                    if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                        Slog.e(TAG, "Error " + backupPackageStatus + " backing up "
+                                + packageName);
+                    }
+
+                    // Also ask the transport how long it wants us to wait before
+                    // moving on to the next package, if any.
+                    backoff = mTransport.requestFullBackupTime();
+                    if (DEBUG_SCHEDULING) {
+                        Slog.i(TAG, "Transport suggested backoff=" + backoff);
+                    }
+
+                }
+
+                // Roll this package to the end of the backup queue if we're
+                // in a queue-driven mode (regardless of success/failure)
+                if (mUpdateSchedule) {
+                    backupManagerService.enqueueFullBackup(packageName, System.currentTimeMillis());
+                }
+
+                if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+                    if (DEBUG) {
+                        Slog.i(TAG, "Transport rejected backup of " + packageName
+                                + ", skipping");
+                    }
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
+                            "transport rejected");
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+                    if (DEBUG) {
+                        Slog.i(TAG, "Transport quota exceeded for package: " + packageName);
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
+                                packageName);
+                    }
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_AGENT_FAILURE);
+                    Slog.w(TAG, "Application failure for package: " + packageName);
+                    EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus == BackupManager.ERROR_BACKUP_CANCELLED) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_BACKUP_CANCELLED);
+                    Slog.w(TAG, "Backup cancelled. package=" + packageName +
+                            ", cancelAll=" + mCancelAll);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
+                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    // Do nothing, clean up, and continue looping.
+                } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.ERROR_TRANSPORT_ABORTED);
+                    Slog.w(TAG, "Transport failed; aborting backup: " + backupPackageStatus);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
+                    // Abort entire backup pass.
+                    backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+                    return;
+                } else {
+                    // Success!
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mBackupObserver, packageName,
+                                    BackupManager.SUCCESS);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
+                    backupManagerService.logBackupComplete(packageName);
+                }
+                cleanUpPipes(transportPipes);
+                cleanUpPipes(enginePipes);
+                if (currentPackage.applicationInfo != null) {
+                    Slog.i(TAG, "Unbinding agent in " + packageName);
+                    backupManagerService.addBackupTrace("unbinding " + packageName);
+                    try {
+                        backupManagerService.getActivityManager().unbindBackupAgent(
+                                currentPackage.applicationInfo);
+                    } catch (RemoteException e) { /* can't happen; activity manager is local */ }
+                }
+            }
+        } catch (Exception e) {
+            backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
+            Slog.w(TAG, "Exception trying full transport backup", e);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_EXCEPTION_FULL_BACKUP,
+                    mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_EXCEPTION_FULL_BACKUP,
+                            Log.getStackTraceString(e)));
+
+        } finally {
+
+            if (mCancelAll) {
+                backupRunStatus = BackupManager.ERROR_BACKUP_CANCELLED;
+            }
+
+            if (DEBUG) {
+                Slog.i(TAG, "Full backup completed with status: " + backupRunStatus);
+            }
+            BackupObserverUtils.sendBackupFinished(mBackupObserver, backupRunStatus);
+
+            cleanUpPipes(transportPipes);
+            cleanUpPipes(enginePipes);
+
+            unregisterTask();
+
+            if (mJob != null) {
+                mJob.finishBackupPass();
+            }
+
+            synchronized (backupManagerService.getQueueLock()) {
+                backupManagerService.setRunningFullBackupTask(null);
+            }
+
+            mLatch.countDown();
+
+            // Now that we're actually done with schedule-driven work, reschedule
+            // the next pass based on the new queue state.
+            if (mUpdateSchedule) {
+                backupManagerService.scheduleNextFullBackupJob(backoff);
+            }
+
+            Slog.i(TAG, "Full data backup pass finished.");
+            backupManagerService.getWakelock().release();
+        }
+    }
+
+    void cleanUpPipes(ParcelFileDescriptor[] pipes) {
+        if (pipes != null) {
+            if (pipes[0] != null) {
+                ParcelFileDescriptor fd = pipes[0];
+                pipes[0] = null;
+                try {
+                    fd.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close pipe!");
+                }
+            }
+            if (pipes[1] != null) {
+                ParcelFileDescriptor fd = pipes[1];
+                pipes[1] = null;
+                try {
+                    fd.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Unable to close pipe!");
+                }
+            }
+        }
+    }
+
+    // Run the backup and pipe it back to the given socket -- expects to run on
+    // a standalone thread.  The  runner owns this half of the pipe, and closes
+    // it to indicate EOD to the other end.
+    class SinglePackageBackupPreflight implements BackupRestoreTask, FullBackupPreflight {
+        final AtomicLong mResult = new AtomicLong(BackupTransport.AGENT_ERROR);
+        final CountDownLatch mLatch = new CountDownLatch(1);
+        final IBackupTransport mTransport;
+        final long mQuota;
+        private final int mCurrentOpToken;
+
+        SinglePackageBackupPreflight(IBackupTransport transport, long quota, int currentOpToken) {
+            mTransport = transport;
+            mQuota = quota;
+            mCurrentOpToken = currentOpToken;
+        }
+
+        @Override
+        public int preflightFullBackup(PackageInfo pkg, IBackupAgent agent) {
+            int result;
+            try {
+                backupManagerService.prepareOperationTimeout(
+                        mCurrentOpToken, TIMEOUT_FULL_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+                backupManagerService.addBackupTrace("preflighting");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
+                }
+                agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
+                        backupManagerService.getBackupManagerBinder());
+
+                // Now wait to get our result back.  If this backstop timeout is reached without
+                // the latch being thrown, flow will continue as though a result or "normal"
+                // timeout had been produced.  In case of a real backstop timeout, mResult
+                // will still contain the value it was constructed with, AGENT_ERROR, which
+                // intentionaly falls into the "just report failure" code.
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+
+                long totalSize = mResult.get();
+                // If preflight timed out, mResult will contain error code as int.
+                if (totalSize < 0) {
+                    return (int) totalSize;
+                }
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "Got preflight response; size=" + totalSize);
+                }
+
+                result = mTransport.checkFullBackupSize(totalSize);
+                if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Package hit quota limit on preflight " +
+                                pkg.packageName + ": " + totalSize + " of " + mQuota);
+                    }
+                    agent.doQuotaExceeded(totalSize, mQuota);
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Exception preflighting " + pkg.packageName + ": " + e.getMessage());
+                result = BackupTransport.AGENT_ERROR;
+            }
+            return result;
+        }
+
+        @Override
+        public void execute() {
+            // Unused.
+        }
+
+        @Override
+        public void operationComplete(long result) {
+            // got the callback, and our preflightFullBackup() method is waiting for the result
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Preflight op complete, result=" + result);
+            }
+            mResult.set(result);
+            mLatch.countDown();
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Preflight cancelled; failing");
+            }
+            mResult.set(BackupTransport.AGENT_ERROR);
+            mLatch.countDown();
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+
+        @Override
+        public long getExpectedSizeOrErrorCode() {
+            try {
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                return mResult.get();
+            } catch (InterruptedException e) {
+                return BackupTransport.NO_MORE_DATA;
+            }
+        }
+    }
+
+    class SinglePackageBackupRunner implements Runnable, BackupRestoreTask {
+        final ParcelFileDescriptor mOutput;
+        final PackageInfo mTarget;
+        final SinglePackageBackupPreflight mPreflight;
+        final CountDownLatch mPreflightLatch;
+        final CountDownLatch mBackupLatch;
+        private final int mCurrentOpToken;
+        private final int mEphemeralToken;
+        private FullBackupEngine mEngine;
+        private volatile int mPreflightResult;
+        private volatile int mBackupResult;
+        private final long mQuota;
+        private volatile boolean mIsCancelled;
+
+        SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
+                IBackupTransport transport, long quota, int currentOpToken) throws IOException {
+            mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
+            mTarget = target;
+            mCurrentOpToken = currentOpToken;
+            mEphemeralToken = backupManagerService.generateRandomIntegerToken();
+            mPreflight = new SinglePackageBackupPreflight(transport, quota, mEphemeralToken);
+            mPreflightLatch = new CountDownLatch(1);
+            mBackupLatch = new CountDownLatch(1);
+            mPreflightResult = BackupTransport.AGENT_ERROR;
+            mBackupResult = BackupTransport.AGENT_ERROR;
+            mQuota = quota;
+            registerTask();
+        }
+
+        void registerTask() {
+            synchronized (backupManagerService.getCurrentOpLock()) {
+                backupManagerService.getCurrentOperations().put(
+                        mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
+            }
+        }
+
+        void unregisterTask() {
+            synchronized (backupManagerService.getCurrentOpLock()) {
+                backupManagerService.getCurrentOperations().remove(mCurrentOpToken);
+            }
+        }
+
+        @Override
+        public void run() {
+            FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
+            mEngine = new FullBackupEngine(backupManagerService, out, mPreflight, mTarget, false,
+                    this, mQuota, mCurrentOpToken);
+            try {
+                try {
+                    if (!mIsCancelled) {
+                        mPreflightResult = mEngine.preflightCheck();
+                    }
+                } finally {
+                    mPreflightLatch.countDown();
+                }
+                // If there is no error on preflight, continue backup.
+                if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                    if (!mIsCancelled) {
+                        mBackupResult = mEngine.backupOnePackage();
+                    }
+                }
+            } catch (Exception e) {
+                Slog.e(TAG, "Exception during full package backup of " + mTarget.packageName);
+            } finally {
+                unregisterTask();
+                mBackupLatch.countDown();
+                try {
+                    mOutput.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Error closing transport pipe in runner");
+                }
+            }
+        }
+
+        public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+            mEngine.sendQuotaExceeded(backupDataBytes, quotaBytes);
+        }
+
+        // If preflight succeeded, returns positive number - preflight size,
+        // otherwise return negative error code.
+        long getPreflightResultBlocking() {
+            try {
+                mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                if (mIsCancelled) {
+                    return BackupManager.ERROR_BACKUP_CANCELLED;
+                }
+                if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                    return mPreflight.getExpectedSizeOrErrorCode();
+                } else {
+                    return mPreflightResult;
+                }
+            } catch (InterruptedException e) {
+                return BackupTransport.AGENT_ERROR;
+            }
+        }
+
+        int getBackupResultBlocking() {
+            try {
+                mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                if (mIsCancelled) {
+                    return BackupManager.ERROR_BACKUP_CANCELLED;
+                }
+                return mBackupResult;
+            } catch (InterruptedException e) {
+                return BackupTransport.AGENT_ERROR;
+            }
+        }
+
+
+        // BackupRestoreTask interface: specifically, timeout detection
+
+        @Override
+        public void execute() { /* intentionally empty */ }
+
+        @Override
+        public void operationComplete(long result) { /* intentionally empty */ }
+
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            if (DEBUG) {
+                Slog.w(TAG, "Full backup cancel of " + mTarget.packageName);
+            }
+
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_FULL_BACKUP_CANCEL,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            mIsCancelled = true;
+            // Cancel tasks spun off by this task.
+            backupManagerService.handleCancel(mEphemeralToken, cancelAll);
+            backupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
+            // Free up everyone waiting on this task and its children.
+            mPreflightLatch.countDown();
+            mBackupLatch.countDown();
+            // We are done with this operation.
+            backupManagerService.removeOperation(mCurrentOpToken);
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
new file mode 100644
index 0000000..886d1f8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -0,0 +1,416 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+
+import android.app.AlarmManager;
+import android.app.backup.RestoreSet;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.EventLog;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.PerformAdbBackupTask;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.params.AdbBackupParams;
+import com.android.server.backup.params.AdbParams;
+import com.android.server.backup.params.AdbRestoreParams;
+import com.android.server.backup.params.BackupParams;
+import com.android.server.backup.params.ClearParams;
+import com.android.server.backup.params.ClearRetryParams;
+import com.android.server.backup.params.RestoreGetSetsParams;
+import com.android.server.backup.params.RestoreParams;
+import com.android.server.backup.restore.PerformAdbRestoreTask;
+import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * Asynchronous backup/restore handler thread.
+ */
+public class BackupHandler extends Handler {
+
+    public static final int MSG_RUN_BACKUP = 1;
+    public static final int MSG_RUN_ADB_BACKUP = 2;
+    public static final int MSG_RUN_RESTORE = 3;
+    public static final int MSG_RUN_CLEAR = 4;
+    public static final int MSG_RUN_INITIALIZE = 5;
+    public static final int MSG_RUN_GET_RESTORE_SETS = 6;
+    public static final int MSG_RESTORE_SESSION_TIMEOUT = 8;
+    public static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
+    public static final int MSG_RUN_ADB_RESTORE = 10;
+    public static final int MSG_RETRY_INIT = 11;
+    public static final int MSG_RETRY_CLEAR = 12;
+    public static final int MSG_WIDGET_BROADCAST = 13;
+    public static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14;
+    public static final int MSG_REQUEST_BACKUP = 15;
+    public static final int MSG_SCHEDULE_BACKUP_PACKAGE = 16;
+    public static final int MSG_BACKUP_OPERATION_TIMEOUT = 17;
+    public static final int MSG_RESTORE_OPERATION_TIMEOUT = 18;
+    // backup task state machine tick
+    public static final int MSG_BACKUP_RESTORE_STEP = 20;
+    public static final int MSG_OP_COMPLETE = 21;
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public BackupHandler(
+            RefactoredBackupManagerService backupManagerService, Looper looper) {
+        super(looper);
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void handleMessage(Message msg) {
+
+        switch (msg.what) {
+            case MSG_RUN_BACKUP: {
+                backupManagerService.setLastBackupPass(System.currentTimeMillis());
+
+                IBackupTransport transport =
+                        backupManagerService.getTransportManager().getCurrentTransportBinder();
+                if (transport == null) {
+                    Slog.v(TAG, "Backup requested but no transport available");
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.setBackupRunning(false);
+                    }
+                    backupManagerService.getWakelock().release();
+                    break;
+                }
+
+                // snapshot the pending-backup set and work on that
+                ArrayList<BackupRequest> queue = new ArrayList<>();
+                File oldJournal = backupManagerService.getJournal();
+                synchronized (backupManagerService.getQueueLock()) {
+                    // Do we have any work to do?  Construct the work queue
+                    // then release the synchronization lock to actually run
+                    // the backup.
+                    if (backupManagerService.getPendingBackups().size() > 0) {
+                        for (BackupRequest b : backupManagerService.getPendingBackups().values()) {
+                            queue.add(b);
+                        }
+                        if (DEBUG) {
+                            Slog.v(TAG, "clearing pending backups");
+                        }
+                        backupManagerService.getPendingBackups().clear();
+
+                        // Start a new backup-queue journal file too
+                        backupManagerService.setJournal(null);
+
+                    }
+                }
+
+                // At this point, we have started a new journal file, and the old
+                // file identity is being passed to the backup processing task.
+                // When it completes successfully, that old journal file will be
+                // deleted.  If we crash prior to that, the old journal is parsed
+                // at next boot and the journaled requests fulfilled.
+                boolean staged = true;
+                if (queue.size() > 0) {
+                    // Spin up a backup state sequence and set it running
+                    try {
+                        String dirName = transport.transportDirName();
+                        PerformBackupTask pbt = new PerformBackupTask(
+                                backupManagerService, transport, dirName, queue,
+                                oldJournal, null, null, Collections.<String>emptyList(), false,
+                                false /* nonIncremental */);
+                        Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
+                        sendMessage(pbtMessage);
+                    } catch (Exception e) {
+                        // unable to ask the transport its dir name -- transient failure, since
+                        // the above check succeeded.  Try again next time.
+                        Slog.e(TAG, "Transport became unavailable attempting backup"
+                                + " or error initializing backup task", e);
+                        staged = false;
+                    }
+                } else {
+                    Slog.v(TAG, "Backup requested but nothing pending");
+                    staged = false;
+                }
+
+                if (!staged) {
+                    // if we didn't actually hand off the wakelock, rewind until next time
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.setBackupRunning(false);
+                    }
+                    backupManagerService.getWakelock().release();
+                }
+                break;
+            }
+
+            case MSG_BACKUP_RESTORE_STEP: {
+                try {
+                    BackupRestoreTask task = (BackupRestoreTask) msg.obj;
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Got next step for " + task + ", executing");
+                    }
+                    task.execute();
+                } catch (ClassCastException e) {
+                    Slog.e(TAG, "Invalid backup task in flight, obj=" + msg.obj);
+                }
+                break;
+            }
+
+            case MSG_OP_COMPLETE: {
+                try {
+                    Pair<BackupRestoreTask, Long> taskWithResult =
+                            (Pair<BackupRestoreTask, Long>) msg.obj;
+                    taskWithResult.first.operationComplete(taskWithResult.second);
+                } catch (ClassCastException e) {
+                    Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
+                }
+                break;
+            }
+
+            case MSG_RUN_ADB_BACKUP: {
+                // TODO: refactor full backup to be a looper-based state machine
+                // similar to normal backup/restore.
+                AdbBackupParams params = (AdbBackupParams) msg.obj;
+                PerformAdbBackupTask task = new PerformAdbBackupTask(backupManagerService,
+                        params.fd,
+                        params.observer, params.includeApks, params.includeObbs,
+                        params.includeShared, params.doWidgets, params.curPassword,
+                        params.encryptPassword, params.allApps, params.includeSystem,
+                        params.doCompress, params.includeKeyValue, params.packages, params.latch);
+                (new Thread(task, "adb-backup")).start();
+                break;
+            }
+
+            case MSG_RUN_FULL_TRANSPORT_BACKUP: {
+                PerformFullTransportBackupTask task = (PerformFullTransportBackupTask) msg.obj;
+                (new Thread(task, "transport-backup")).start();
+                break;
+            }
+
+            case MSG_RUN_RESTORE: {
+                RestoreParams params = (RestoreParams) msg.obj;
+                Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
+
+                PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(backupManagerService,
+                        params.transport,
+                        params.observer, params.monitor, params.token, params.pkgInfo,
+                        params.pmToken, params.isSystemRestore, params.filterSet);
+
+                synchronized (backupManagerService.getPendingRestores()) {
+                    if (backupManagerService.isRestoreInProgress()) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Restore in progress, queueing.");
+                        }
+                        backupManagerService.getPendingRestores().add(task);
+                        // This task will be picked up and executed when the the currently running
+                        // restore task finishes.
+                    } else {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Starting restore.");
+                        }
+                        backupManagerService.setRestoreInProgress(true);
+                        Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
+                        sendMessage(restoreMsg);
+                    }
+                }
+                break;
+            }
+
+            case MSG_RUN_ADB_RESTORE: {
+                // TODO: refactor full restore to be a looper-based state machine
+                // similar to normal backup/restore.
+                AdbRestoreParams params = (AdbRestoreParams) msg.obj;
+                PerformAdbRestoreTask task = new PerformAdbRestoreTask(backupManagerService,
+                        params.fd,
+                        params.curPassword, params.encryptPassword,
+                        params.observer, params.latch);
+                (new Thread(task, "adb-restore")).start();
+                break;
+            }
+
+            case MSG_RUN_CLEAR: {
+                ClearParams params = (ClearParams) msg.obj;
+                (new PerformClearTask(backupManagerService, params.transport,
+                        params.packageInfo)).run();
+                break;
+            }
+
+            case MSG_RETRY_CLEAR: {
+                // reenqueues if the transport remains unavailable
+                ClearRetryParams params = (ClearRetryParams) msg.obj;
+                backupManagerService.clearBackupData(params.transportName, params.packageName);
+                break;
+            }
+
+            case MSG_RUN_INITIALIZE: {
+                HashSet<String> queue;
+
+                // Snapshot the pending-init queue and work on that
+                synchronized (backupManagerService.getQueueLock()) {
+                    queue = new HashSet<>(backupManagerService.getPendingInits());
+                    backupManagerService.getPendingInits().clear();
+                }
+
+                (new PerformInitializeTask(backupManagerService, queue)).run();
+                break;
+            }
+
+            case MSG_RETRY_INIT: {
+                synchronized (backupManagerService.getQueueLock()) {
+                    backupManagerService.recordInitPendingLocked(msg.arg1 != 0, (String) msg.obj);
+                    backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
+                            System.currentTimeMillis(),
+                            backupManagerService.getRunInitIntent());
+                }
+                break;
+            }
+
+            case MSG_RUN_GET_RESTORE_SETS: {
+                // Like other async operations, this is entered with the wakelock held
+                RestoreSet[] sets = null;
+                RestoreGetSetsParams params = (RestoreGetSetsParams) msg.obj;
+                try {
+                    sets = params.transport.getAvailableRestoreSets();
+                    // cache the result in the active session
+                    synchronized (params.session) {
+                        params.session.mRestoreSets = sets;
+                    }
+                    if (sets == null) {
+                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                    }
+                } catch (Exception e) {
+                    Slog.e(TAG, "Error from transport getting set list: " + e.getMessage());
+                } finally {
+                    if (params.observer != null) {
+                        try {
+                            params.observer.restoreSetsAvailable(sets);
+                        } catch (RemoteException re) {
+                            Slog.e(TAG, "Unable to report listing to observer");
+                        } catch (Exception e) {
+                            Slog.e(TAG, "Restore observer threw: " + e.getMessage());
+                        }
+                    }
+
+                    // Done: reset the session timeout clock
+                    removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
+
+                    backupManagerService.getWakelock().release();
+                }
+                break;
+            }
+
+            case MSG_BACKUP_OPERATION_TIMEOUT:
+            case MSG_RESTORE_OPERATION_TIMEOUT: {
+                Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1));
+                backupManagerService.handleCancel(msg.arg1, false);
+                break;
+            }
+
+            case MSG_RESTORE_SESSION_TIMEOUT: {
+                synchronized (backupManagerService) {
+                    if (backupManagerService.getActiveRestoreSession() != null) {
+                        // Client app left the restore session dangling.  We know that it
+                        // can't be in the middle of an actual restore operation because
+                        // the timeout is suspended while a restore is in progress.  Clean
+                        // up now.
+                        Slog.w(TAG, "Restore session timed out; aborting");
+                        backupManagerService.getActiveRestoreSession().markTimedOut();
+                        post(backupManagerService.getActiveRestoreSession().new EndRestoreRunnable(
+                                backupManagerService,
+                                backupManagerService.getActiveRestoreSession()));
+                    }
+                }
+                break;
+            }
+
+            case MSG_FULL_CONFIRMATION_TIMEOUT: {
+                synchronized (backupManagerService.getAdbBackupRestoreConfirmations()) {
+                    AdbParams params = backupManagerService.getAdbBackupRestoreConfirmations().get(
+                            msg.arg1);
+                    if (params != null) {
+                        Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation");
+
+                        // Release the waiter; timeout == completion
+                        backupManagerService.signalAdbBackupRestoreCompletion(params);
+
+                        // Remove the token from the set
+                        backupManagerService.getAdbBackupRestoreConfirmations().delete(msg.arg1);
+
+                        // Report a timeout to the observer, if any
+                        if (params.observer != null) {
+                            try {
+                                params.observer.onTimeout();
+                            } catch (RemoteException e) {
+                            /* don't care if the app has gone away */
+                            }
+                        }
+                    } else {
+                        Slog.d(TAG, "couldn't find params for token " + msg.arg1);
+                    }
+                }
+                break;
+            }
+
+            case MSG_WIDGET_BROADCAST: {
+                final Intent intent = (Intent) msg.obj;
+                backupManagerService.getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+                break;
+            }
+
+            case MSG_REQUEST_BACKUP: {
+                BackupParams params = (BackupParams) msg.obj;
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer);
+                }
+                ArrayList<BackupRequest> kvQueue = new ArrayList<>();
+                for (String packageName : params.kvPackages) {
+                    kvQueue.add(new BackupRequest(packageName));
+                }
+                backupManagerService.setBackupRunning(true);
+                backupManagerService.getWakelock().acquire();
+
+                PerformBackupTask pbt = new PerformBackupTask(
+                        backupManagerService,
+                        params.transport, params.dirName,
+                        kvQueue, null, params.observer, params.monitor, params.fullPackages, true,
+                        params.nonIncrementalBackup);
+                Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
+                sendMessage(pbtMessage);
+                break;
+            }
+
+            case MSG_SCHEDULE_BACKUP_PACKAGE: {
+                String pkgName = (String) msg.obj;
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
+                }
+                backupManagerService.dataChangedImpl(pkgName);
+                break;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupRequest.java b/services/backup/java/com/android/server/backup/internal/BackupRequest.java
new file mode 100644
index 0000000..20c3cc4
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupRequest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.backup.internal;
+
+/**
+ * Set of backup services that have pending changes.
+ */
+public class BackupRequest {
+
+    public String packageName;
+
+    public BackupRequest(String pkgName) {
+        packageName = pkgName;
+    }
+
+    public String toString() {
+        return "BackupRequest{pkg=" + packageName + "}";
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupState.java b/services/backup/java/com/android/server/backup/internal/BackupState.java
new file mode 100644
index 0000000..4d42c24
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupState.java
@@ -0,0 +1,10 @@
+package com.android.server.backup.internal;
+
+/**
+ * Current state of the backup.
+ */
+enum BackupState {
+    INITIAL,
+    RUNNING_QUEUE,
+    FINAL
+}
diff --git a/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java b/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java
new file mode 100644
index 0000000..d82c865
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/ClearDataObserver.java
@@ -0,0 +1,37 @@
+/*
+ * 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.backup.internal;
+
+import android.content.pm.IPackageDataObserver;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class ClearDataObserver extends IPackageDataObserver.Stub {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public ClearDataObserver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onRemoveCompleted(String packageName, boolean succeeded) {
+        synchronized (backupManagerService.getClearDataLock()) {
+            backupManagerService.setClearingData(false);
+            backupManagerService.getClearDataLock().notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/Operation.java b/services/backup/java/com/android/server/backup/internal/Operation.java
new file mode 100644
index 0000000..fd5ad92
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/Operation.java
@@ -0,0 +1,32 @@
+/*
+ * 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.backup.internal;
+
+import com.android.server.backup.BackupRestoreTask;
+
+public class Operation {
+
+    public int state;
+    public final BackupRestoreTask callback;
+    public final int type;
+
+    public Operation(int initialState, BackupRestoreTask callbackObj, int type) {
+        state = initialState;
+        callback = callbackObj;
+        this.type = type;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
new file mode 100644
index 0000000..a996e2d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -0,0 +1,1118 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_BACKUP_TRACE;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_BACKUP_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SELinux;
+import android.os.UserHandle;
+import android.os.WorkSource;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.KeyValueBackupJob;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This class handles the process of backing up a given list of key/value backup packages.
+ * Also takes in a list of pending dolly backups and kicks them off when key/value backups
+ * are done.
+ *
+ * Flow:
+ * If required, backup @pm@.
+ * For each pending key/value backup package:
+ *     - Bind to agent.
+ *     - Call agent.doBackup()
+ *     - Wait either for cancel/timeout or operationComplete() callback from the agent.
+ * Start task to perform dolly backups.
+ *
+ * There are three entry points into this class:
+ *     - execute() [Called from the handler thread]
+ *     - operationComplete(long result) [Called from the handler thread]
+ *     - handleCancel(boolean cancelAll) [Can be called from any thread]
+ * These methods synchronize on mCancelLock.
+ *
+ * Interaction with mCurrentOperations:
+ *     - An entry for this task is put into mCurrentOperations for the entire lifetime of the
+ *       task. This is useful to cancel the task if required.
+ *     - An ephemeral entry is put into mCurrentOperations each time we are waiting on for
+ *       response from a backup agent. This is used to plumb timeouts and completion callbacks.
+ */
+public class PerformBackupTask implements BackupRestoreTask {
+    private static final String TAG = "PerformBackupTask";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private final Object mCancelLock = new Object();
+
+    IBackupTransport mTransport;
+    ArrayList<BackupRequest> mQueue;
+    ArrayList<BackupRequest> mOriginalQueue;
+    File mStateDir;
+    File mJournal;
+    BackupState mCurrentState;
+    List<String> mPendingFullBackups;
+    IBackupObserver mObserver;
+    IBackupManagerMonitor mMonitor;
+
+    private final PerformFullTransportBackupTask mFullBackupTask;
+    private final int mCurrentOpToken;
+    private volatile int mEphemeralOpToken;
+
+    // carried information about the current in-flight operation
+    IBackupAgent mAgentBinder;
+    PackageInfo mCurrentPackage;
+    File mSavedStateName;
+    File mBackupDataName;
+    File mNewStateName;
+    ParcelFileDescriptor mSavedState;
+    ParcelFileDescriptor mBackupData;
+    ParcelFileDescriptor mNewState;
+    int mStatus;
+    boolean mFinished;
+    final boolean mUserInitiated;
+    final boolean mNonIncremental;
+
+    private volatile boolean mCancelAll;
+
+    public PerformBackupTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, String dirName,
+            ArrayList<BackupRequest> queue, File journal, IBackupObserver observer,
+            IBackupManagerMonitor monitor, List<String> pendingFullBackups,
+            boolean userInitiated, boolean nonIncremental) {
+        this.backupManagerService = backupManagerService;
+        mTransport = transport;
+        mOriginalQueue = queue;
+        mQueue = new ArrayList<>();
+        mJournal = journal;
+        mObserver = observer;
+        mMonitor = monitor;
+        mPendingFullBackups = pendingFullBackups;
+        mUserInitiated = userInitiated;
+        mNonIncremental = nonIncremental;
+
+        mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
+        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
+
+        mFinished = false;
+
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            if (backupManagerService.isBackupOperationInProgress()) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Skipping backup since one is already in progress.");
+                }
+                mCancelAll = true;
+                mFullBackupTask = null;
+                mCurrentState = BackupState.FINAL;
+                backupManagerService.addBackupTrace("Skipped. Backup already in progress.");
+            } else {
+                mCurrentState = BackupState.INITIAL;
+                CountDownLatch latch = new CountDownLatch(1);
+                String[] fullBackups =
+                        mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+                mFullBackupTask =
+                        new PerformFullTransportBackupTask(backupManagerService,
+                                /*fullBackupRestoreObserver*/
+                                null,
+                                fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
+                                latch,
+                                mObserver, mMonitor, mUserInitiated);
+
+                registerTask();
+                backupManagerService.addBackupTrace("STATE => INITIAL");
+            }
+        }
+    }
+
+    /**
+     * Put this task in the repository of running tasks.
+     */
+    private void registerTask() {
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
+        }
+    }
+
+    /**
+     * Remove this task from repository of running tasks.
+     */
+    private void unregisterTask() {
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    // Main entry point: perform one chunk of work, updating the state as appropriate
+    // and reposting the next chunk to the primary backup handler thread.
+    @Override
+    @GuardedBy("mCancelLock")
+    public void execute() {
+        synchronized (mCancelLock) {
+            switch (mCurrentState) {
+                case INITIAL:
+                    beginBackup();
+                    break;
+
+                case RUNNING_QUEUE:
+                    invokeNextAgent();
+                    break;
+
+                case FINAL:
+                    if (!mFinished) {
+                        finalizeBackup();
+                    } else {
+                        Slog.e(TAG, "Duplicate finish");
+                    }
+                    mFinished = true;
+                    break;
+            }
+        }
+    }
+
+    // We're starting a backup pass.  Initialize the transport and send
+    // the PM metadata blob if we haven't already.
+    void beginBackup() {
+        if (DEBUG_BACKUP_TRACE) {
+            backupManagerService.clearBackupTrace();
+            StringBuilder b = new StringBuilder(256);
+            b.append("beginBackup: [");
+            for (BackupRequest req : mOriginalQueue) {
+                b.append(' ');
+                b.append(req.packageName);
+            }
+            b.append(" ]");
+            backupManagerService.addBackupTrace(b.toString());
+        }
+
+        mAgentBinder = null;
+        mStatus = BackupTransport.TRANSPORT_OK;
+
+        // Sanity check: if the queue is empty we have no work to do.
+        if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
+            Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
+            backupManagerService.addBackupTrace("queue empty at begin");
+            BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
+            executeNextState(BackupState.FINAL);
+            return;
+        }
+
+        // We need to retain the original queue contents in case of transport
+        // failure, but we want a working copy that we can manipulate along
+        // the way.
+        mQueue = (ArrayList<BackupRequest>) mOriginalQueue.clone();
+
+        // When the transport is forcing non-incremental key/value payloads, we send the
+        // metadata only if it explicitly asks for it.
+        boolean skipPm = mNonIncremental;
+
+        // The app metadata pseudopackage might also be represented in the
+        // backup queue if apps have been added/removed since the last time
+        // we performed a backup.  Drop it from the working queue now that
+        // we're committed to evaluating it for backup regardless.
+        for (int i = 0; i < mQueue.size(); i++) {
+            if (PACKAGE_MANAGER_SENTINEL.equals(
+                    mQueue.get(i).packageName)) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Metadata in queue; eliding");
+                }
+                mQueue.remove(i);
+                skipPm = false;
+                break;
+            }
+        }
+
+        if (DEBUG) {
+            Slog.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
+        }
+
+        File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+        try {
+            final String transportName = mTransport.transportDirName();
+            EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
+
+            // If we haven't stored package manager metadata yet, we must init the transport.
+            if (mStatus == BackupTransport.TRANSPORT_OK && pmState.length() <= 0) {
+                Slog.i(TAG, "Initializing (wiping) backup state and transport storage");
+                backupManagerService.addBackupTrace("initializing transport " + transportName);
+                backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
+                mStatus = mTransport.initializeDevice();
+
+                backupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
+                } else {
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
+                    Slog.e(TAG, "Transport error in initializeDevice()");
+                }
+            }
+
+            if (skipPm) {
+                Slog.d(TAG, "Skipping backup of package metadata.");
+                executeNextState(BackupState.RUNNING_QUEUE);
+            } else {
+                // The package manager doesn't have a proper <application> etc, but since
+                // it's running here in the system process we can just set up its agent
+                // directly and use a synthetic BackupRequest.  We always run this pass
+                // because it's cheap and this way we guarantee that we don't get out of
+                // step even if we're selecting among various transports at run time.
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
+                            backupManagerService.getPackageManager());
+                    mStatus = invokeAgentForBackup(
+                            PACKAGE_MANAGER_SENTINEL,
+                            IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
+                    backupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
+
+                    // Because the PMBA is a local instance, it has already executed its
+                    // backup callback and returned.  Blow away the lingering (spurious)
+                    // pending timeout message for it.
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_BACKUP_OPERATION_TIMEOUT);
+                }
+            }
+
+            if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+                // The backend reports that our dataset has been wiped.  Note this in
+                // the event log; the no-success code below will reset the backup
+                // state as well.
+                EventLog.writeEvent(EventLogTags.BACKUP_RESET, mTransport.transportDirName());
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Error in backup thread", e);
+            backupManagerService.addBackupTrace("Exception in backup thread: " + e);
+            mStatus = BackupTransport.TRANSPORT_ERROR;
+        } finally {
+            // If we've succeeded so far, invokeAgentForBackup() will have run the PM
+            // metadata and its completion/timeout callback will continue the state
+            // machine chain.  If it failed that won't happen; we handle that now.
+            backupManagerService.addBackupTrace("exiting prelim: " + mStatus);
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                // if things went wrong at this point, we need to
+                // restage everything and try again later.
+                backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
+                // In case of any other error, it's backup transport error.
+                BackupObserverUtils.sendBackupFinished(mObserver,
+                        BackupManager.ERROR_TRANSPORT_ABORTED);
+                executeNextState(BackupState.FINAL);
+            }
+        }
+    }
+
+    // Transport has been initialized and the PM metadata submitted successfully
+    // if that was warranted.  Now we process the single next thing in the queue.
+    void invokeNextAgent() {
+        mStatus = BackupTransport.TRANSPORT_OK;
+        backupManagerService.addBackupTrace("invoke q=" + mQueue.size());
+
+        // Sanity check that we have work to do.  If not, skip to the end where
+        // we reestablish the wakelock invariants etc.
+        if (mQueue.isEmpty()) {
+            if (MORE_DEBUG) Slog.i(TAG, "queue now empty");
+            executeNextState(BackupState.FINAL);
+            return;
+        }
+
+        // pop the entry we're going to process on this step
+        BackupRequest request = mQueue.get(0);
+        mQueue.remove(0);
+
+        Slog.d(TAG, "starting key/value backup of " + request);
+        backupManagerService.addBackupTrace("launch agent for " + request.packageName);
+
+        // Verify that the requested app exists; it might be something that
+        // requested a backup but was then uninstalled.  The request was
+        // journalled and rather than tamper with the journal it's safer
+        // to sanity-check here.  This also gives us the classname of the
+        // package's backup agent.
+        try {
+            mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
+                    request.packageName,
+                    PackageManager.GET_SIGNATURES);
+            if (!AppBackupUtils.appIsEligibleForBackup(
+                    mCurrentPackage.applicationInfo)) {
+                // The manifest has changed but we had a stale backup request pending.
+                // This won't happen again because the app won't be requesting further
+                // backups.
+                Slog.i(TAG, "Package " + request.packageName
+                        + " no longer supports backup; skipping");
+                backupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
+                // Shouldn't happen in case of requested backup, as pre-check was done in
+                // #requestBackup(), except to app update done concurrently
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
+                // It's possible that this app *formerly* was enqueued for key/value backup,
+                // but has since been updated and now only supports the full-data path.
+                // Don't proceed with a key/value backup for it in this case.
+                Slog.i(TAG, "Package " + request.packageName
+                        + " requests full-data rather than key/value; skipping");
+                backupManagerService.addBackupTrace(
+                        "skipping - fullBackupOnly, completion is noop");
+                // Shouldn't happen in case of requested backup, as pre-check was done in
+                // #requestBackup()
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            if (AppBackupUtils.appIsStopped(mCurrentPackage.applicationInfo)) {
+                // The app has been force-stopped or cleared or just installed,
+                // and not yet launched out of that state, so just as it won't
+                // receive broadcasts, we won't run it for backup.
+                backupManagerService.addBackupTrace("skipping - stopped");
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver,
+                        mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                executeNextState(BackupState.RUNNING_QUEUE);
+                return;
+            }
+
+            IBackupAgent agent = null;
+            try {
+                backupManagerService.getWakelock().setWorkSource(
+                        new WorkSource(mCurrentPackage.applicationInfo.uid));
+                agent = backupManagerService.bindToAgentSynchronous(mCurrentPackage.applicationInfo,
+                        ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+                backupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
+                if (agent != null) {
+                    mAgentBinder = agent;
+                    mStatus = invokeAgentForBackup(request.packageName, agent, mTransport);
+                    // at this point we'll either get a completion callback from the
+                    // agent, or a timeout message on the main handler.  either way, we're
+                    // done here as long as we're successful so far.
+                } else {
+                    // Timeout waiting for the agent
+                    mStatus = BackupTransport.AGENT_ERROR;
+                }
+            } catch (SecurityException ex) {
+                // Try for the next one.
+                Slog.d(TAG, "error in bind/backup", ex);
+                mStatus = BackupTransport.AGENT_ERROR;
+                backupManagerService.addBackupTrace("agent SE");
+            }
+        } catch (NameNotFoundException e) {
+            Slog.d(TAG, "Package does not exist; skipping");
+            backupManagerService.addBackupTrace("no such package");
+            mStatus = BackupTransport.AGENT_UNKNOWN;
+        } finally {
+            backupManagerService.getWakelock().setWorkSource(null);
+
+            // If there was an agent error, no timeout/completion handling will occur.
+            // That means we need to direct to the next state ourselves.
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                BackupState nextState = BackupState.RUNNING_QUEUE;
+                mAgentBinder = null;
+
+                // An agent-level failure means we reenqueue this one agent for
+                // a later retry, but otherwise proceed normally.
+                if (mStatus == BackupTransport.AGENT_ERROR) {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Agent failure for " + request.packageName
+                                + " - restaging");
+                    }
+                    backupManagerService.dataChangedImpl(request.packageName);
+                    mStatus = BackupTransport.TRANSPORT_OK;
+                    if (mQueue.isEmpty()) nextState = BackupState.FINAL;
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                    BackupManager.ERROR_AGENT_FAILURE);
+                } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
+                    // Failed lookup of the app, so we couldn't bring up an agent, but
+                    // we're otherwise fine.  Just drop it and go on to the next as usual.
+                    mStatus = BackupTransport.TRANSPORT_OK;
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                    BackupManager.ERROR_PACKAGE_NOT_FOUND);
+                } else {
+                    // Transport-level failure means we reenqueue everything
+                    revertAndEndBackup();
+                    nextState = BackupState.FINAL;
+                }
+
+                executeNextState(nextState);
+            } else {
+                // success case
+                backupManagerService.addBackupTrace("expecting completion/timeout callback");
+            }
+        }
+    }
+
+    void finalizeBackup() {
+        backupManagerService.addBackupTrace("finishing");
+
+        // Mark packages that we didn't backup (because backup was cancelled, etc.) as needing
+        // backup.
+        for (BackupRequest req : mQueue) {
+            backupManagerService.dataChangedImpl(req.packageName);
+        }
+
+        // Either backup was successful, in which case we of course do not need
+        // this pass's journal any more; or it failed, in which case we just
+        // re-enqueued all of these packages in the current active journal.
+        // Either way, we no longer need this pass's journal.
+        if (mJournal != null && !mJournal.delete()) {
+            Slog.e(TAG, "Unable to remove backup journal file " + mJournal);
+        }
+
+        // If everything actually went through and this is the first time we've
+        // done a backup, we can now record what the current backup dataset token
+        // is.
+        if ((backupManagerService.getCurrentToken() == 0) && (mStatus
+                == BackupTransport.TRANSPORT_OK)) {
+            backupManagerService.addBackupTrace("success; recording token");
+            try {
+                backupManagerService.setCurrentToken(mTransport.getCurrentRestoreSet());
+                backupManagerService.writeRestoreTokens();
+            } catch (Exception e) {
+                // nothing for it at this point, unfortunately, but this will be
+                // recorded the next time we fully succeed.
+                Slog.e(TAG, "Transport threw reporting restore set: " + e.getMessage());
+                backupManagerService.addBackupTrace("transport threw returning token");
+            }
+        }
+
+        // Set up the next backup pass - at this point we can set mBackupRunning
+        // to false to allow another pass to fire, because we're done with the
+        // state machine sequence and the wakelock is refcounted.
+        synchronized (backupManagerService.getQueueLock()) {
+            backupManagerService.setBackupRunning(false);
+            if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+                // Make sure we back up everything and perform the one-time init
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Server requires init; rerunning");
+                }
+                backupManagerService.addBackupTrace("init required; rerunning");
+                try {
+                    final String name = backupManagerService.getTransportManager().getTransportName(
+                            mTransport);
+                    if (name != null) {
+                        backupManagerService.getPendingInits().add(name);
+                    } else {
+                        if (DEBUG) {
+                            Slog.w(TAG, "Couldn't find name of transport " + mTransport
+                                    + " for init");
+                        }
+                    }
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failed to query transport name for init: " + e.getMessage());
+                    // swallow it and proceed; we don't rely on this
+                }
+                clearMetadata();
+                backupManagerService.backupNow();
+            }
+        }
+
+        backupManagerService.clearBackupTrace();
+
+        unregisterTask();
+
+        if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
+                mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
+            Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            backupManagerService.getWakelock().acquire();
+            (new Thread(mFullBackupTask, "full-transport-requested")).start();
+        } else if (mCancelAll) {
+            if (mFullBackupTask != null) {
+                mFullBackupTask.unregisterTask();
+            }
+            BackupObserverUtils.sendBackupFinished(mObserver,
+                    BackupManager.ERROR_BACKUP_CANCELLED);
+        } else {
+            mFullBackupTask.unregisterTask();
+            switch (mStatus) {
+                case BackupTransport.TRANSPORT_OK:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.SUCCESS);
+                    break;
+                case BackupTransport.TRANSPORT_NOT_INITIALIZED:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    break;
+                case BackupTransport.TRANSPORT_ERROR:
+                default:
+                    BackupObserverUtils.sendBackupFinished(mObserver,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    break;
+            }
+        }
+        Slog.i(TAG, "K/V backup pass finished.");
+        // Only once we're entirely finished do we release the wakelock for k/v backup.
+        backupManagerService.getWakelock().release();
+    }
+
+    // Remove the PM metadata state. This will generate an init on the next pass.
+    void clearMetadata() {
+        final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+        if (pmState.exists()) pmState.delete();
+    }
+
+    // Invoke an agent's doBackup() and start a timeout message spinning on the main
+    // handler in case it doesn't get back to us.
+    int invokeAgentForBackup(String packageName, IBackupAgent agent,
+            IBackupTransport transport) {
+        if (DEBUG) {
+            Slog.d(TAG, "invokeAgentForBackup on " + packageName);
+        }
+        backupManagerService.addBackupTrace("invoking " + packageName);
+
+        File blankStateName = new File(mStateDir, "blank_state");
+        mSavedStateName = new File(mStateDir, packageName);
+        mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".data");
+        mNewStateName = new File(mStateDir, packageName + ".new");
+        if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
+
+        mSavedState = null;
+        mBackupData = null;
+        mNewState = null;
+
+        boolean callingAgent = false;
+        mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+        try {
+            // Look up the package info & signatures.  This is first so that if it
+            // throws an exception, there's no file setup yet that would need to
+            // be unraveled.
+            if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) {
+                // The metadata 'package' is synthetic; construct one and make
+                // sure our global state is pointed at it
+                mCurrentPackage = new PackageInfo();
+                mCurrentPackage.packageName = packageName;
+            }
+
+            // In a full backup, we pass a null ParcelFileDescriptor as
+            // the saved-state "file". For key/value backups we pass the old state if
+            // an incremental backup is required, and a blank state otherwise.
+            mSavedState = ParcelFileDescriptor.open(
+                    mNonIncremental ? blankStateName : mSavedStateName,
+                    ParcelFileDescriptor.MODE_READ_ONLY |
+                            ParcelFileDescriptor.MODE_CREATE);  // Make an empty file if necessary
+
+            mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            if (!SELinux.restorecon(mBackupDataName)) {
+                Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataName);
+            }
+
+            mNewState = ParcelFileDescriptor.open(mNewStateName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            final long quota = mTransport.getBackupQuota(packageName, false /* isFullBackup */);
+            callingAgent = true;
+
+            // Initiate the target's backup pass
+            backupManagerService.addBackupTrace("setting timeout");
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+            backupManagerService.addBackupTrace("calling agent doBackup()");
+
+            agent.doBackup(mSavedState, mBackupData, mNewState, quota, mEphemeralOpToken,
+                    backupManagerService.getBackupManagerBinder());
+        } catch (Exception e) {
+            Slog.e(TAG, "Error invoking for backup on " + packageName + ". " + e);
+            backupManagerService.addBackupTrace("exception: " + e);
+            EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName,
+                    e.toString());
+            errorCleanup();
+            return callingAgent ? BackupTransport.AGENT_ERROR
+                    : BackupTransport.TRANSPORT_ERROR;
+        } finally {
+            if (mNonIncremental) {
+                blankStateName.delete();
+            }
+        }
+
+        // At this point the agent is off and running.  The next thing to happen will
+        // either be a callback from the agent, at which point we'll process its data
+        // for transport, or a timeout.  Either way the next phase will happen in
+        // response to the TimeoutHandler interface callbacks.
+        backupManagerService.addBackupTrace("invoke success");
+        return BackupTransport.TRANSPORT_OK;
+    }
+
+    public void failAgent(IBackupAgent agent, String message) {
+        try {
+            agent.fail(message);
+        } catch (Exception e) {
+            Slog.w(TAG, "Error conveying failure to " + mCurrentPackage.packageName);
+        }
+    }
+
+    // SHA-1 a byte array and return the result in hex
+    private String SHA1Checksum(byte[] input) {
+        final byte[] checksum;
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            checksum = md.digest(input);
+        } catch (NoSuchAlgorithmException e) {
+            Slog.e(TAG, "Unable to use SHA-1!");
+            return "00";
+        }
+
+        StringBuffer sb = new StringBuffer(checksum.length * 2);
+        for (int i = 0; i < checksum.length; i++) {
+            sb.append(Integer.toHexString(checksum[i]));
+        }
+        return sb.toString();
+    }
+
+    private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
+            throws IOException {
+        // TODO: http://b/22388012
+        byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName,
+                UserHandle.USER_SYSTEM);
+        // has the widget state changed since last time?
+        final File widgetFile = new File(mStateDir, pkgName + "_widget");
+        final boolean priorStateExists = widgetFile.exists();
+
+        if (MORE_DEBUG) {
+            if (priorStateExists || widgetState != null) {
+                Slog.i(TAG, "Checking widget update: state=" + (widgetState != null)
+                        + " prior=" + priorStateExists);
+            }
+        }
+
+        if (!priorStateExists && widgetState == null) {
+            // no prior state, no new state => nothing to do
+            return;
+        }
+
+        // if the new state is not null, we might need to compare checksums to
+        // determine whether to update the widget blob in the archive.  If the
+        // widget state *is* null, we know a priori at this point that we simply
+        // need to commit a deletion for it.
+        String newChecksum = null;
+        if (widgetState != null) {
+            newChecksum = SHA1Checksum(widgetState);
+            if (priorStateExists) {
+                final String priorChecksum;
+                try (
+                        FileInputStream fin = new FileInputStream(widgetFile);
+                        DataInputStream in = new DataInputStream(fin)
+                ) {
+                    priorChecksum = in.readUTF();
+                }
+                if (Objects.equals(newChecksum, priorChecksum)) {
+                    // Same checksum => no state change => don't rewrite the widget data
+                    return;
+                }
+            }
+        } // else widget state *became* empty, so we need to commit a deletion
+
+        BackupDataOutput out = new BackupDataOutput(fd);
+        if (widgetState != null) {
+            try (
+                    FileOutputStream fout = new FileOutputStream(widgetFile);
+                    DataOutputStream stateOut = new DataOutputStream(fout)
+            ) {
+                stateOut.writeUTF(newChecksum);
+            }
+
+            out.writeEntityHeader(KEY_WIDGET_STATE, widgetState.length);
+            out.writeEntityData(widgetState, widgetState.length);
+        } else {
+            // Widget state for this app has been removed; commit a deletion
+            out.writeEntityHeader(KEY_WIDGET_STATE, -1);
+            widgetFile.delete();
+        }
+    }
+
+    @Override
+    @GuardedBy("mCancelLock")
+    public void operationComplete(long unusedResult) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        synchronized (mCancelLock) {
+            // The agent reported back to us!
+            if (mFinished) {
+                Slog.d(TAG, "operationComplete received after task finished.");
+                return;
+            }
+
+            if (mBackupData == null) {
+                // This callback was racing with our timeout, so we've cleaned up the
+                // agent state already and are on to the next thing.  We have nothing
+                // further to do here: agent state having been cleared means that we've
+                // initiated the appropriate next operation.
+                final String pkg = (mCurrentPackage != null)
+                        ? mCurrentPackage.packageName : "[none]";
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Callback after agent teardown: " + pkg);
+                }
+                backupManagerService.addBackupTrace("late opComplete; curPkg = " + pkg);
+                return;
+            }
+
+            final String pkgName = mCurrentPackage.packageName;
+            final long filepos = mBackupDataName.length();
+            FileDescriptor fd = mBackupData.getFileDescriptor();
+            try {
+                // If it's a 3rd party app, see whether they wrote any protected keys
+                // and complain mightily if they are attempting shenanigans.
+                if (mCurrentPackage.applicationInfo != null &&
+                        (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+                                == 0) {
+                    ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataName,
+                            ParcelFileDescriptor.MODE_READ_ONLY);
+                    BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
+                    try {
+                        while (in.readNextHeader()) {
+                            final String key = in.getKey();
+                            if (key != null && key.charAt(0) >= 0xff00) {
+                                // Not okay: crash them and bail.
+                                failAgent(mAgentBinder, "Illegal backup key: " + key);
+                                backupManagerService
+                                        .addBackupTrace("illegal key " + key + " from " + pkgName);
+                                EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
+                                        "bad key");
+                                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                                        BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
+                                        mCurrentPackage,
+                                        BackupManagerMonitor
+                                                .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                        BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                                BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
+                                                key));
+                                backupManagerService.getBackupHandler().removeMessages(
+                                        MSG_BACKUP_OPERATION_TIMEOUT);
+                                BackupObserverUtils
+                                        .sendBackupOnPackageResult(mObserver, pkgName,
+                                                BackupManager.ERROR_AGENT_FAILURE);
+                                errorCleanup();
+                                // agentErrorCleanup() implicitly executes next state properly
+                                return;
+                            }
+                            in.skipEntityData();
+                        }
+                    } finally {
+                        if (readFd != null) {
+                            readFd.close();
+                        }
+                    }
+                }
+
+                // Piggyback the widget state payload, if any
+                writeWidgetPayloadIfAppropriate(fd, pkgName);
+            } catch (IOException e) {
+                // Hard disk error; recovery/failure policy TBD.  For now roll back,
+                // but we may want to consider this a transport-level failure (i.e.
+                // we're in such a bad state that we can't contemplate doing backup
+                // operations any more during this pass).
+                Slog.w(TAG, "Unable to save widget state for " + pkgName);
+                try {
+                    Os.ftruncate(fd, filepos);
+                } catch (ErrnoException ee) {
+                    Slog.w(TAG, "Unable to roll back!");
+                }
+            }
+
+            // Spin the data off to the transport and proceed with the next stage.
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "operationComplete(): sending data to transport for "
+                        + pkgName);
+            }
+            backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_OPERATION_TIMEOUT);
+            clearAgentState();
+            backupManagerService.addBackupTrace("operation complete");
+
+            ParcelFileDescriptor backupData = null;
+            mStatus = BackupTransport.TRANSPORT_OK;
+            long size = 0;
+            try {
+                size = mBackupDataName.length();
+                if (size > 0) {
+                    if (mStatus == BackupTransport.TRANSPORT_OK) {
+                        backupData = ParcelFileDescriptor.open(mBackupDataName,
+                                ParcelFileDescriptor.MODE_READ_ONLY);
+                        backupManagerService.addBackupTrace("sending data to transport");
+                        int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+                        mStatus = mTransport.performBackup(mCurrentPackage, backupData, flags);
+                    }
+
+                    // TODO - We call finishBackup() for each application backed up, because
+                    // we need to know now whether it succeeded or failed.  Instead, we should
+                    // hold off on finishBackup() until the end, which implies holding off on
+                    // renaming *all* the output state files (see below) until that happens.
+
+                    backupManagerService.addBackupTrace("data delivered: " + mStatus);
+                    if (mStatus == BackupTransport.TRANSPORT_OK) {
+                        backupManagerService.addBackupTrace("finishing op on transport");
+                        mStatus = mTransport.finishBackup();
+                        backupManagerService.addBackupTrace("finished: " + mStatus);
+                    } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                        backupManagerService.addBackupTrace("transport rejected package");
+                    }
+                } else {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "no backup data written; not calling transport");
+                    }
+                    backupManagerService.addBackupTrace("no data to send");
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            null);
+                }
+
+                if (mStatus == BackupTransport.TRANSPORT_OK) {
+                    // After successful transport, delete the now-stale data
+                    // and juggle the files so that next time we supply the agent
+                    // with the new state file it just created.
+                    mBackupDataName.delete();
+                    mNewStateName.renameTo(mSavedStateName);
+                    BackupObserverUtils
+                            .sendBackupOnPackageResult(mObserver, pkgName, BackupManager.SUCCESS);
+                    EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
+                    backupManagerService.logBackupComplete(pkgName);
+                } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                    // The transport has rejected backup of this specific package.  Roll it
+                    // back but proceed with running the rest of the queue.
+                    mBackupDataName.delete();
+                    mNewStateName.delete();
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+                    EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+                } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+                    EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
+                } else {
+                    // Actual transport-level failure to communicate the data to the backend
+                    BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+                }
+            } catch (Exception e) {
+                BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+                        BackupManager.ERROR_TRANSPORT_ABORTED);
+                Slog.e(TAG, "Transport error backing up " + pkgName, e);
+                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+            } finally {
+                try {
+                    if (backupData != null) backupData.close();
+                } catch (IOException e) {
+                }
+            }
+
+            final BackupState nextState;
+            if (mStatus == BackupTransport.TRANSPORT_OK
+                    || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                // Success or single-package rejection.  Proceed with the next app if any,
+                // otherwise we're done.
+                nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+            } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+                            " hit quota limit on k/v backup");
+                }
+                if (mAgentBinder != null) {
+                    try {
+                        long quota = mTransport.getBackupQuota(mCurrentPackage.packageName,
+                                false);
+                        mAgentBinder.doQuotaExceeded(size, quota);
+                    } catch (Exception e) {
+                        Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
+                    }
+                }
+                nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+            } else {
+                // Any other error here indicates a transport-level failure.  That means
+                // we need to halt everything and reschedule everything for next time.
+                revertAndEndBackup();
+                nextState = BackupState.FINAL;
+            }
+
+            executeNextState(nextState);
+        }
+    }
+
+
+    @Override
+    @GuardedBy("mCancelLock")
+    public void handleCancel(boolean cancelAll) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        synchronized (mCancelLock) {
+            if (mFinished) {
+                // We have already cancelled this operation.
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Ignoring stale cancel. cancelAll=" + cancelAll);
+                }
+                return;
+            }
+            mCancelAll = cancelAll;
+            final String logPackageName = (mCurrentPackage != null)
+                    ? mCurrentPackage.packageName
+                    : "no_package_yet";
+            Slog.i(TAG, "Cancel backing up " + logPackageName);
+            EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName);
+            backupManagerService.addBackupTrace(
+                    "cancel of " + logPackageName + ", cancelAll=" + cancelAll);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL,
+                            mCancelAll));
+            errorCleanup();
+            if (!cancelAll) {
+                // The current agent either timed out or was cancelled running doBackup().
+                // Restage it for the next time we run a backup pass.
+                // !!! TODO: keep track of failure counts per agent, and blacklist those which
+                // fail repeatedly (i.e. have proved themselves to be buggy).
+                executeNextState(
+                        mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE);
+                backupManagerService.dataChangedImpl(mCurrentPackage.packageName);
+            } else {
+                finalizeBackup();
+            }
+        }
+    }
+
+    void revertAndEndBackup() {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Reverting backup queue - restaging everything");
+        }
+        backupManagerService.addBackupTrace("transport error; reverting");
+
+        // We want to reset the backup schedule based on whatever the transport suggests
+        // by way of retry/backoff time.
+        long delay;
+        try {
+            delay = mTransport.requestBackupTime();
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e.getMessage());
+            delay = 0;  // use the scheduler's default
+        }
+        KeyValueBackupJob.schedule(backupManagerService.getContext(), delay);
+
+        for (BackupRequest request : mOriginalQueue) {
+            backupManagerService.dataChangedImpl(request.packageName);
+        }
+
+    }
+
+    void errorCleanup() {
+        mBackupDataName.delete();
+        mNewStateName.delete();
+        clearAgentState();
+    }
+
+    // Cleanup common to both success and failure cases
+    void clearAgentState() {
+        try {
+            if (mSavedState != null) mSavedState.close();
+        } catch (IOException e) {
+        }
+        try {
+            if (mBackupData != null) mBackupData.close();
+        } catch (IOException e) {
+        }
+        try {
+            if (mNewState != null) mNewState.close();
+        } catch (IOException e) {
+        }
+        synchronized (backupManagerService.getCurrentOpLock()) {
+            // Current-operation callback handling requires the validity of these various
+            // bits of internal state as an invariant of the operation still being live.
+            // This means we make sure to clear all of the state in unison inside the lock.
+            backupManagerService.getCurrentOperations().remove(mEphemeralOpToken);
+            mSavedState = mBackupData = mNewState = null;
+        }
+
+        // If this was a pseudopackage there's no associated Activity Manager state
+        if (mCurrentPackage.applicationInfo != null) {
+            backupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
+            try {  // unbind even on timeout, just in case
+                backupManagerService.getActivityManager().unbindBackupAgent(
+                        mCurrentPackage.applicationInfo);
+            } catch (RemoteException e) { /* can't happen; activity manager is local */ }
+        }
+    }
+
+    void executeNextState(BackupState nextState) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, " => executing next step on "
+                    + this + " nextState=" + nextState);
+        }
+        backupManagerService.addBackupTrace("executeNextState => " + nextState);
+        mCurrentState = nextState;
+        Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                MSG_BACKUP_RESTORE_STEP, this);
+        backupManagerService.getBackupHandler().sendMessage(msg);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformClearTask.java b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
new file mode 100644
index 0000000..7af01ea
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
@@ -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
+ */
+
+package com.android.server.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.PackageInfo;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.File;
+
+public class PerformClearTask implements Runnable {
+
+    private RefactoredBackupManagerService backupManagerService;
+    IBackupTransport mTransport;
+    PackageInfo mPackage;
+
+    PerformClearTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, PackageInfo packageInfo) {
+        this.backupManagerService = backupManagerService;
+        mTransport = transport;
+        mPackage = packageInfo;
+    }
+
+    public void run() {
+        try {
+            // Clear the on-device backup state to ensure a full backup next time
+            File stateDir = new File(backupManagerService.getBaseStateDir(),
+                    mTransport.transportDirName());
+            File stateFile = new File(stateDir, mPackage.packageName);
+            stateFile.delete();
+
+            // Tell the transport to remove all the persistent storage for the app
+            // TODO - need to handle failures
+            mTransport.clearBackupData(mPackage);
+        } catch (Exception e) {
+            Slog.e(TAG, "Transport threw clearing data for " + mPackage + ": " + e.getMessage());
+        } finally {
+            try {
+                // TODO - need to handle failures
+                mTransport.finishBackup();
+            } catch (Exception e) {
+                // Nothing we can do here, alas
+                Slog.e(TAG, "Unable to mark clear operation finished: " + e.getMessage());
+            }
+
+            // Last but not least, release the cpu
+            backupManagerService.getWakelock().release();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
new file mode 100644
index 0000000..5a75b66
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
@@ -0,0 +1,100 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.AlarmManager;
+import android.app.backup.BackupTransport;
+import android.os.SystemClock;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.EventLogTags;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.File;
+import java.util.HashSet;
+
+public class PerformInitializeTask implements Runnable {
+
+    private RefactoredBackupManagerService backupManagerService;
+    HashSet<String> mQueue;
+
+    PerformInitializeTask(RefactoredBackupManagerService backupManagerService,
+            HashSet<String> transportNames) {
+        this.backupManagerService = backupManagerService;
+        mQueue = transportNames;
+    }
+
+    public void run() {
+        try {
+            for (String transportName : mQueue) {
+                IBackupTransport transport =
+                        backupManagerService.getTransportManager().getTransportBinder(
+                                transportName);
+                if (transport == null) {
+                    Slog.e(TAG, "Requested init for " + transportName + " but not found");
+                    continue;
+                }
+
+                Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName);
+                EventLog.writeEvent(EventLogTags.BACKUP_START, transport.transportDirName());
+                long startRealtime = SystemClock.elapsedRealtime();
+                int status = transport.initializeDevice();
+
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    status = transport.finishBackup();
+                }
+
+                // Okay, the wipe really happened.  Clean up our local bookkeeping.
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    Slog.i(TAG, "Device init successful");
+                    int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
+                    EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
+                    backupManagerService
+                            .resetBackupState(new File(backupManagerService.getBaseStateDir(),
+                                    transport.transportDirName()));
+                    EventLog.writeEvent(EventLogTags.BACKUP_SUCCESS, 0, millis);
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.recordInitPendingLocked(false, transportName);
+                    }
+                } else {
+                    // If this didn't work, requeue this one and try again
+                    // after a suitable interval
+                    Slog.e(TAG, "Transport error in initializeDevice()");
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
+                    synchronized (backupManagerService.getQueueLock()) {
+                        backupManagerService.recordInitPendingLocked(true, transportName);
+                    }
+                    // do this via another alarm to make sure of the wakelock states
+                    long delay = transport.requestBackupTime();
+                    Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay);
+                    backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
+                            System.currentTimeMillis() + delay,
+                            backupManagerService.getRunInitIntent());
+                }
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Unexpected error performing init", e);
+        } finally {
+            // Done; release the wakelock
+            backupManagerService.getWakelock().release();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
new file mode 100644
index 0000000..e92b8be
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
@@ -0,0 +1,61 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.util.Slog;
+
+import com.android.server.backup.KeyValueBackupJob;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class ProvisionedObserver extends ContentObserver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public ProvisionedObserver(
+            RefactoredBackupManagerService backupManagerService, Handler handler) {
+        super(handler);
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onChange(boolean selfChange) {
+        final boolean wasProvisioned = backupManagerService.isProvisioned();
+        final boolean isProvisioned = backupManagerService.deviceIsProvisioned();
+        // latch: never unprovision
+        backupManagerService.setProvisioned(wasProvisioned || isProvisioned);
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
+                    + " is=" + isProvisioned + " now=" + backupManagerService.isProvisioned());
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            if (backupManagerService.isProvisioned() && !wasProvisioned
+                    && backupManagerService.isEnabled()) {
+                // we're now good to go, so start the backup alarms
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Now provisioned, so starting backups");
+                }
+                KeyValueBackupJob.schedule(backupManagerService.getContext());
+                backupManagerService.scheduleNextFullBackupJob(0);
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
new file mode 100644
index 0000000..f1fa7eb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
@@ -0,0 +1,87 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_BACKUP_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_BACKUP;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class RunBackupReceiver extends BroadcastReceiver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public RunBackupReceiver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onReceive(Context context, Intent intent) {
+        if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
+            synchronized (backupManagerService.getQueueLock()) {
+                if (backupManagerService.getPendingInits().size() > 0) {
+                    // If there are pending init operations, we process those
+                    // and then settle into the usual periodic backup schedule.
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Init pending at scheduled backup");
+                    }
+                    try {
+                        backupManagerService.getAlarmManager().cancel(
+                                backupManagerService.getRunInitIntent());
+                        backupManagerService.getRunInitIntent().send();
+                    } catch (PendingIntent.CanceledException ce) {
+                        Slog.e(TAG, "Run init intent cancelled");
+                        // can't really do more than bail here
+                    }
+                } else {
+                    // Don't run backups now if we're disabled or not yet
+                    // fully set up.
+                    if (backupManagerService.isEnabled() && backupManagerService.isProvisioned()) {
+                        if (!backupManagerService.isBackupRunning()) {
+                            if (DEBUG) {
+                                Slog.v(TAG, "Running a backup pass");
+                            }
+
+                            // Acquire the wakelock and pass it to the backup thread.  it will
+                            // be released once backup concludes.
+                            backupManagerService.setBackupRunning(true);
+                            backupManagerService.getWakelock().acquire();
+
+                            Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                                    MSG_RUN_BACKUP);
+                            backupManagerService.getBackupHandler().sendMessage(msg);
+                        } else {
+                            Slog.i(TAG, "Backup time but one already running");
+                        }
+                    } else {
+                        Slog.w(TAG, "Backup pass but e=" + backupManagerService.isEnabled() + " p="
+                                + backupManagerService.isProvisioned());
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
new file mode 100644
index 0000000..1621a91
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
@@ -0,0 +1,57 @@
+/*
+ * 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.backup.internal;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_INITIALIZE_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_INITIALIZE;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+public class RunInitializeReceiver extends BroadcastReceiver {
+
+    private RefactoredBackupManagerService backupManagerService;
+
+    public RunInitializeReceiver(RefactoredBackupManagerService backupManagerService) {
+        this.backupManagerService = backupManagerService;
+    }
+
+    public void onReceive(Context context, Intent intent) {
+        if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
+            synchronized (backupManagerService.getQueueLock()) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Running a device init");
+                }
+
+                // Acquire the wakelock and pass it to the init thread.  it will
+                // be released once init concludes.
+                backupManagerService.getWakelock().acquire();
+
+                Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                        MSG_RUN_INITIALIZE);
+                backupManagerService.getBackupHandler().sendMessage(msg);
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbBackupParams.java b/services/backup/java/com/android/server/backup/params/AdbBackupParams.java
new file mode 100644
index 0000000..5c1ba24
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbBackupParams.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 com.android.server.backup.params;
+
+import android.os.ParcelFileDescriptor;
+
+public class AdbBackupParams extends AdbParams {
+
+    public boolean includeApks;
+    public boolean includeObbs;
+    public boolean includeShared;
+    public boolean doWidgets;
+    public boolean allApps;
+    public boolean includeSystem;
+    public boolean doCompress;
+    public boolean includeKeyValue;
+    public String[] packages;
+
+    public AdbBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveObbs,
+            boolean saveShared, boolean alsoWidgets, boolean doAllApps, boolean doSystem,
+            boolean compress, boolean doKeyValue, String[] pkgList) {
+        fd = output;
+        includeApks = saveApks;
+        includeObbs = saveObbs;
+        includeShared = saveShared;
+        doWidgets = alsoWidgets;
+        allApps = doAllApps;
+        includeSystem = doSystem;
+        doCompress = compress;
+        includeKeyValue = doKeyValue;
+        packages = pkgList;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbParams.java b/services/backup/java/com/android/server/backup/params/AdbParams.java
new file mode 100644
index 0000000..392f40d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbParams.java
@@ -0,0 +1,38 @@
+/*
+ * 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.backup.params;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.ParcelFileDescriptor;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Parameters used by adbBackup() and adbRestore().
+ */
+public class AdbParams {
+
+    public ParcelFileDescriptor fd;
+    public final AtomicBoolean latch;
+    public IFullBackupRestoreObserver observer;
+    public String curPassword;     // filled in by the confirmation step
+    public String encryptPassword;
+
+    AdbParams() {
+        latch = new AtomicBoolean(false);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/AdbRestoreParams.java b/services/backup/java/com/android/server/backup/params/AdbRestoreParams.java
new file mode 100644
index 0000000..0142fe0
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/AdbRestoreParams.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.server.backup.params;
+
+import android.os.ParcelFileDescriptor;
+
+public class AdbRestoreParams extends AdbParams {
+
+    public AdbRestoreParams(ParcelFileDescriptor input) {
+        fd = input;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/BackupParams.java b/services/backup/java/com/android/server/backup/params/BackupParams.java
new file mode 100644
index 0000000..4fd7ddb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/BackupParams.java
@@ -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
+ */
+
+package com.android.server.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+
+import com.android.internal.backup.IBackupTransport;
+
+import java.util.ArrayList;
+
+public class BackupParams {
+
+    public IBackupTransport transport;
+    public String dirName;
+    public ArrayList<String> kvPackages;
+    public ArrayList<String> fullPackages;
+    public IBackupObserver observer;
+    public IBackupManagerMonitor monitor;
+    public boolean userInitiated;
+    public boolean nonIncrementalBackup;
+
+    public BackupParams(IBackupTransport transport, String dirName, ArrayList<String> kvPackages,
+            ArrayList<String> fullPackages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, boolean userInitiated, boolean nonIncrementalBackup) {
+        this.transport = transport;
+        this.dirName = dirName;
+        this.kvPackages = kvPackages;
+        this.fullPackages = fullPackages;
+        this.observer = observer;
+        this.monitor = monitor;
+        this.userInitiated = userInitiated;
+        this.nonIncrementalBackup = nonIncrementalBackup;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/ClearParams.java b/services/backup/java/com/android/server/backup/params/ClearParams.java
new file mode 100644
index 0000000..d744efc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/ClearParams.java
@@ -0,0 +1,32 @@
+/*
+ * 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.backup.params;
+
+import android.content.pm.PackageInfo;
+
+import com.android.internal.backup.IBackupTransport;
+
+public class ClearParams {
+
+    public IBackupTransport transport;
+    public PackageInfo packageInfo;
+
+    public ClearParams(IBackupTransport _transport, PackageInfo _info) {
+        transport = _transport;
+        packageInfo = _info;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/ClearRetryParams.java b/services/backup/java/com/android/server/backup/params/ClearRetryParams.java
new file mode 100644
index 0000000..fcf66e4
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/ClearRetryParams.java
@@ -0,0 +1,28 @@
+/*
+ * 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.backup.params;
+
+public class ClearRetryParams {
+
+    public String transportName;
+    public String packageName;
+
+    public ClearRetryParams(String transport, String pkg) {
+        transportName = transport;
+        packageName = pkg;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java b/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java
new file mode 100644
index 0000000..bff476b
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/RestoreGetSetsParams.java
@@ -0,0 +1,39 @@
+/*
+ * 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.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.restore.ActiveRestoreSession;
+
+public class RestoreGetSetsParams {
+
+    public IBackupTransport transport;
+    public ActiveRestoreSession session;
+    public IRestoreObserver observer;
+    public IBackupManagerMonitor monitor;
+
+    public RestoreGetSetsParams(IBackupTransport _transport, ActiveRestoreSession _session,
+            IRestoreObserver _observer, IBackupManagerMonitor _monitor) {
+        transport = _transport;
+        session = _session;
+        observer = _observer;
+        monitor = _monitor;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/params/RestoreParams.java b/services/backup/java/com/android/server/backup/params/RestoreParams.java
new file mode 100644
index 0000000..93ce00d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/params/RestoreParams.java
@@ -0,0 +1,103 @@
+/*
+ * 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.backup.params;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.content.pm.PackageInfo;
+
+import com.android.internal.backup.IBackupTransport;
+
+public class RestoreParams {
+
+    public IBackupTransport transport;
+    public String dirName;
+    public IRestoreObserver observer;
+    public IBackupManagerMonitor monitor;
+    public long token;
+    public PackageInfo pkgInfo;
+    public int pmToken; // in post-install restore, the PM's token for this transaction
+    public boolean isSystemRestore;
+    public String[] filterSet;
+
+    /**
+     * Restore a single package; no kill after restore
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token, PackageInfo _pkg) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = _pkg;
+        pmToken = 0;
+        isSystemRestore = false;
+        filterSet = null;
+    }
+
+    /**
+     * Restore at install: PM token needed, kill after restore
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token, String _pkgName, int _pmToken) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = _pmToken;
+        isSystemRestore = false;
+        filterSet = new String[]{_pkgName};
+    }
+
+    /**
+     * Restore everything possible.  This is the form that Setup Wizard or similar
+     * restore UXes use.
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = 0;
+        isSystemRestore = true;
+        filterSet = null;
+    }
+
+    /**
+     * Restore some set of packages.  Leave this one up to the caller to specify
+     * whether it's to be considered a system-level restore.
+     */
+    public RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+            IBackupManagerMonitor _monitor, long _token,
+            String[] _filterSet, boolean _isSystemRestore) {
+        transport = _transport;
+        dirName = _dirName;
+        observer = _obs;
+        monitor = _monitor;
+        token = _token;
+        pkgInfo = null;
+        pmToken = 0;
+        isSystemRestore = _isSystemRestore;
+        filterSet = _filterSet;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
new file mode 100644
index 0000000..8d8a013
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -0,0 +1,407 @@
+/*
+ * 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.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
+import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.app.backup.IRestoreSession;
+import android.app.backup.RestoreSet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
+import android.os.Message;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.params.RestoreGetSetsParams;
+import com.android.server.backup.params.RestoreParams;
+
+/**
+ * Restore session.
+ */
+public class ActiveRestoreSession extends IRestoreSession.Stub {
+
+    private static final String TAG = "RestoreSession";
+
+    private RefactoredBackupManagerService backupManagerService;
+    private String mPackageName;
+    private IBackupTransport mRestoreTransport = null;
+    public RestoreSet[] mRestoreSets = null;
+    boolean mEnded = false;
+    boolean mTimedOut = false;
+
+    public ActiveRestoreSession(RefactoredBackupManagerService backupManagerService,
+            String packageName, String transport) {
+        this.backupManagerService = backupManagerService;
+        mPackageName = packageName;
+        mRestoreTransport = backupManagerService.getTransportManager().getTransportBinder(
+                transport);
+    }
+
+    public void markTimedOut() {
+        mTimedOut = true;
+    }
+
+    // --- Binder interface ---
+    public synchronized int getAvailableRestoreSets(IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "getAvailableRestoreSets");
+        if (observer == null) {
+            throw new IllegalArgumentException("Observer must not be null");
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            if (mRestoreTransport == null) {
+                Slog.w(TAG, "Null transport getting restore sets");
+                return -1;
+            }
+
+            // We know we're doing legit work now, so halt the timeout
+            // until we're done.  It gets started again when the result
+            // comes in.
+            backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+            // spin off the transport request to our service thread
+            backupManagerService.getWakelock().acquire();
+            Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                    MSG_RUN_GET_RESTORE_SETS,
+                    new RestoreGetSetsParams(mRestoreTransport, this, observer,
+                            monitor));
+            backupManagerService.getBackupHandler().sendMessage(msg);
+            return 0;
+        } catch (Exception e) {
+            Slog.e(TAG, "Error in getAvailableRestoreSets", e);
+            return -1;
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+    }
+
+    public synchronized int restoreAll(long token, IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "performRestore");
+
+        if (DEBUG) {
+            Slog.d(TAG, "restoreAll token=" + Long.toHexString(token)
+                    + " observer=" + observer);
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mRestoreTransport == null || mRestoreSets == null) {
+            Slog.e(TAG, "Ignoring restoreAll() with no restore set");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            Slog.e(TAG, "Ignoring restoreAll() on single-package session");
+            return -1;
+        }
+
+        String dirName;
+        try {
+            dirName = mRestoreTransport.transportDirName();
+        } catch (Exception e) {
+            // Transport went AWOL; fail.
+            Slog.e(TAG, "Unable to get transport dir for restore: " + e.getMessage());
+            return -1;
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            for (int i = 0; i < mRestoreSets.length; i++) {
+                if (token == mRestoreSets[i].token) {
+                    // Real work, so stop the session timeout until we finalize the restore
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_RESTORE_SESSION_TIMEOUT);
+
+                    long oldId = Binder.clearCallingIdentity();
+                    backupManagerService.getWakelock().acquire();
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "restoreAll() kicking off");
+                    }
+                    Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                            MSG_RUN_RESTORE);
+                    msg.obj = new RestoreParams(mRestoreTransport, dirName,
+                            observer, monitor, token);
+                    backupManagerService.getBackupHandler().sendMessage(msg);
+                    Binder.restoreCallingIdentity(oldId);
+                    return 0;
+                }
+            }
+        }
+
+        Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found");
+        return -1;
+    }
+
+    // Restores of more than a single package are treated as 'system' restores
+    public synchronized int restoreSome(long token, IRestoreObserver observer,
+            IBackupManagerMonitor monitor, String[] packages) {
+        backupManagerService.getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.BACKUP,
+                "performRestore");
+
+        if (DEBUG) {
+            StringBuilder b = new StringBuilder(128);
+            b.append("restoreSome token=");
+            b.append(Long.toHexString(token));
+            b.append(" observer=");
+            b.append(observer.toString());
+            b.append(" monitor=");
+            if (monitor == null) {
+                b.append("null");
+            } else {
+                b.append(monitor.toString());
+            }
+            b.append(" packages=");
+            if (packages == null) {
+                b.append("null");
+            } else {
+                b.append('{');
+                boolean first = true;
+                for (String s : packages) {
+                    if (!first) {
+                        b.append(", ");
+                    } else {
+                        first = false;
+                    }
+                    b.append(s);
+                }
+                b.append('}');
+            }
+            Slog.d(TAG, b.toString());
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mRestoreTransport == null || mRestoreSets == null) {
+            Slog.e(TAG, "Ignoring restoreAll() with no restore set");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            Slog.e(TAG, "Ignoring restoreAll() on single-package session");
+            return -1;
+        }
+
+        String dirName;
+        try {
+            dirName = mRestoreTransport.transportDirName();
+        } catch (Exception e) {
+            // Transport went AWOL; fail.
+            Slog.e(TAG, "Unable to get transport name for restoreSome: " + e.getMessage());
+            return -1;
+        }
+
+        synchronized (backupManagerService.getQueueLock()) {
+            for (int i = 0; i < mRestoreSets.length; i++) {
+                if (token == mRestoreSets[i].token) {
+                    // Stop the session timeout until we finalize the restore
+                    backupManagerService.getBackupHandler().removeMessages(
+                            MSG_RESTORE_SESSION_TIMEOUT);
+
+                    long oldId = Binder.clearCallingIdentity();
+                    backupManagerService.getWakelock().acquire();
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "restoreSome() of " + packages.length + " packages");
+                    }
+                    Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                            MSG_RUN_RESTORE);
+                    msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, monitor,
+                            token, packages, packages.length > 1);
+                    backupManagerService.getBackupHandler().sendMessage(msg);
+                    Binder.restoreCallingIdentity(oldId);
+                    return 0;
+                }
+            }
+        }
+
+        Slog.w(TAG, "Restore token " + Long.toHexString(token) + " not found");
+        return -1;
+    }
+
+    public synchronized int restorePackage(String packageName, IRestoreObserver observer,
+            IBackupManagerMonitor monitor) {
+        if (DEBUG) {
+            Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer
+                    + "monitor=" + monitor);
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return -1;
+        }
+
+        if (mPackageName != null) {
+            if (!mPackageName.equals(packageName)) {
+                Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName
+                        + " on session for package " + mPackageName);
+                return -1;
+            }
+        }
+
+        PackageInfo app = null;
+        try {
+            app = backupManagerService.getPackageManager().getPackageInfo(packageName, 0);
+        } catch (NameNotFoundException nnf) {
+            Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
+            return -1;
+        }
+
+        // If the caller is not privileged and is not coming from the target
+        // app's uid, throw a permission exception back to the caller.
+        int perm = backupManagerService.getContext().checkPermission(
+                android.Manifest.permission.BACKUP,
+                Binder.getCallingPid(), Binder.getCallingUid());
+        if ((perm == PackageManager.PERMISSION_DENIED) &&
+                (app.applicationInfo.uid != Binder.getCallingUid())) {
+            Slog.w(TAG, "restorePackage: bad packageName=" + packageName
+                    + " or calling uid=" + Binder.getCallingUid());
+            throw new SecurityException("No permission to restore other packages");
+        }
+
+        // So far so good; we're allowed to try to restore this package.
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            // Check whether there is data for it in the current dataset, falling back
+            // to the ancestral dataset if not.
+            long token = backupManagerService.getAvailableRestoreToken(packageName);
+            if (DEBUG) {
+                Slog.v(TAG, "restorePackage pkg=" + packageName
+                        + " token=" + Long.toHexString(token));
+            }
+
+            // If we didn't come up with a place to look -- no ancestral dataset and
+            // the app has never been backed up from this device -- there's nothing
+            // to do but return failure.
+            if (token == 0) {
+                if (DEBUG) {
+                    Slog.w(TAG, "No data available for this package; not restoring");
+                }
+                return -1;
+            }
+
+            String dirName;
+            try {
+                dirName = mRestoreTransport.transportDirName();
+            } catch (Exception e) {
+                // Transport went AWOL; fail.
+                Slog.e(TAG, "Unable to get transport dir for restorePackage: " + e.getMessage());
+                return -1;
+            }
+
+            // Stop the session timeout until we finalize the restore
+            backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+            // Ready to go:  enqueue the restore request and claim success
+            backupManagerService.getWakelock().acquire();
+            if (MORE_DEBUG) {
+                Slog.d(TAG, "restorePackage() : " + packageName);
+            }
+            Message msg = backupManagerService.getBackupHandler().obtainMessage(MSG_RUN_RESTORE);
+            msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, monitor,
+                    token, app);
+            backupManagerService.getBackupHandler().sendMessage(msg);
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+        return 0;
+    }
+
+    // Posted to the handler to tear down a restore session in a cleanly synchronized way
+    public class EndRestoreRunnable implements Runnable {
+
+        RefactoredBackupManagerService mBackupManager;
+        ActiveRestoreSession mSession;
+
+        public EndRestoreRunnable(RefactoredBackupManagerService manager,
+                ActiveRestoreSession session) {
+            mBackupManager = manager;
+            mSession = session;
+        }
+
+        public void run() {
+            // clean up the session's bookkeeping
+            synchronized (mSession) {
+                mSession.mRestoreTransport = null;
+                mSession.mEnded = true;
+            }
+
+            // clean up the BackupManagerImpl side of the bookkeeping
+            // and cancel any pending timeout message
+            mBackupManager.clearRestoreSession(mSession);
+        }
+    }
+
+    public synchronized void endRestoreSession() {
+        if (DEBUG) {
+            Slog.d(TAG, "endRestoreSession");
+        }
+
+        if (mTimedOut) {
+            Slog.i(TAG, "Session already timed out");
+            return;
+        }
+
+        if (mEnded) {
+            throw new IllegalStateException("Restore session already ended");
+        }
+
+        backupManagerService.getBackupHandler().post(
+                new EndRestoreRunnable(backupManagerService, this));
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
new file mode 100644
index 0000000..6353d1f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -0,0 +1,79 @@
+/*
+ * 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.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
+import android.util.Slog;
+
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Used for synchronizing doRestoreFinished during adb restore.
+ */
+public class AdbRestoreFinishedLatch implements BackupRestoreTask {
+
+    private static final String TAG = "AdbRestoreFinishedLatch";
+    private RefactoredBackupManagerService backupManagerService;
+    final CountDownLatch mLatch;
+    private final int mCurrentOpToken;
+
+    public AdbRestoreFinishedLatch(RefactoredBackupManagerService backupManagerService,
+            int currentOpToken) {
+        this.backupManagerService = backupManagerService;
+        mLatch = new CountDownLatch(1);
+        mCurrentOpToken = currentOpToken;
+    }
+
+    void await() {
+        boolean latched = false;
+        try {
+            latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Slog.w(TAG, "Interrupted!");
+        }
+    }
+
+    @Override
+    public void execute() {
+        // Unused
+    }
+
+    @Override
+    public void operationComplete(long result) {
+        if (MORE_DEBUG) {
+            Slog.w(TAG, "adb onRestoreFinished() complete");
+        }
+        mLatch.countDown();
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        if (DEBUG) {
+            Slog.w(TAG, "adb onRestoreFinished() timed out");
+        }
+        mLatch.countDown();
+        backupManagerService.removeOperation(mCurrentOpToken);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
new file mode 100644
index 0000000..888dcd7e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -0,0 +1,634 @@
+/*
+ * 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.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.KeyValueAdbRestoreEngine;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.FullBackupObbConnection;
+import com.android.server.backup.utils.BytesReadListener;
+import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
+import com.android.server.backup.utils.RestoreUtils;
+import com.android.server.backup.utils.TarBackupReader;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Full restore engine, used by both adb restore and transport-based full restore.
+ */
+public class FullRestoreEngine extends RestoreEngine {
+
+    private final RefactoredBackupManagerService mBackupManagerService;
+    // Task in charge of monitoring timeouts
+    private final BackupRestoreTask mMonitorTask;
+
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
+
+    // Dedicated observer, if any
+    private IFullBackupRestoreObserver mObserver;
+
+    final IBackupManagerMonitor mMonitor;
+
+    // Where we're delivering the file data as we go
+    private IBackupAgent mAgent;
+
+    // Are we permitted to only deliver a specific package's metadata?
+    final PackageInfo mOnlyPackage;
+
+    final boolean mAllowApks;
+    private final boolean mAllowObbs;
+
+    // Which package are we currently handling data for?
+    private String mAgentPackage;
+
+    // Info for working with the target app process
+    private ApplicationInfo mTargetApp;
+
+    // Machinery for restoring OBBs
+    private FullBackupObbConnection mObbConnection = null;
+
+    // possible handling states for a given package in the restore dataset
+    private final HashMap<String, RestorePolicy> mPackagePolicies
+            = new HashMap<>();
+
+    // installer package names for each encountered app, derived from the manifests
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
+
+    // Signatures for a given package found in its manifest file
+    private final HashMap<String, Signature[]> mManifestSignatures
+            = new HashMap<>();
+
+    // Packages we've already wiped data on when restoring their first file
+    private final HashSet<String> mClearedPackages = new HashSet<>();
+
+    // How much data have we moved?
+    private long mBytes;
+
+    // Working buffer
+    final byte[] mBuffer;
+
+    // Pipes for moving data
+    private ParcelFileDescriptor[] mPipes = null;
+
+    // Widget blob to be restored out-of-band
+    private byte[] mWidgetData = null;
+
+    final int mEphemeralOpToken;
+
+    public FullRestoreEngine(RefactoredBackupManagerService backupManagerService,
+            BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
+            IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
+            boolean allowObbs, int ephemeralOpToken) {
+        mBackupManagerService = backupManagerService;
+        mEphemeralOpToken = ephemeralOpToken;
+        mMonitorTask = monitorTask;
+        mObserver = observer;
+        mMonitor = monitor;
+        mOnlyPackage = onlyPackage;
+        mAllowApks = allowApks;
+        mAllowObbs = allowObbs;
+        mBuffer = new byte[32 * 1024];
+        mBytes = 0;
+    }
+
+    public IBackupAgent getAgent() {
+        return mAgent;
+    }
+
+    public byte[] getWidgetData() {
+        return mWidgetData;
+    }
+
+    public boolean restoreOneFile(InputStream instream, boolean mustKillAgent, byte[] buffer,
+            PackageInfo onlyPackage, boolean allowApks, int token, IBackupManagerMonitor monitor) {
+        if (!isRunning()) {
+            Slog.w(TAG, "Restore engine used after halting");
+            return false;
+        }
+
+        BytesReadListener bytesReadListener = new BytesReadListener() {
+            @Override
+            public void onBytesRead(long bytesRead) {
+                mBytes += bytesRead;
+            }
+        };
+
+        TarBackupReader tarBackupReader = new TarBackupReader(instream,
+                bytesReadListener, monitor);
+
+        FileMetadata info;
+        try {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Reading tar header for restoring file");
+            }
+            info = tarBackupReader.readTarHeaders();
+            if (info != null) {
+                if (MORE_DEBUG) {
+                    info.dump();
+                }
+
+                final String pkg = info.packageName;
+                if (!pkg.equals(mAgentPackage)) {
+                    // In the single-package case, it's a semantic error to expect
+                    // one app's data but see a different app's on the wire
+                    if (onlyPackage != null) {
+                        if (!pkg.equals(onlyPackage.packageName)) {
+                            Slog.w(TAG, "Expected data for " + onlyPackage + " but saw " + pkg);
+                            setResult(RestoreEngine.TRANSPORT_FAILURE);
+                            setRunning(false);
+                            return false;
+                        }
+                    }
+
+                    // okay, change in package; set up our various
+                    // bookkeeping if we haven't seen it yet
+                    if (!mPackagePolicies.containsKey(pkg)) {
+                        mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                    }
+
+                    // Clean up the previous agent relationship if necessary,
+                    // and let the observer know we're considering a new app.
+                    if (mAgent != null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
+                        }
+                        // Now we're really done
+                        tearDownPipes();
+                        tearDownAgent(mTargetApp);
+                        mTargetApp = null;
+                        mAgentPackage = null;
+                    }
+                }
+
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks, info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
+                    mPackageInstallers.put(pkg, info.installerPackageName);
+                    // We've read only the manifest content itself at this point,
+                    // so consume the footer before looping around to the next
+                    // input file
+                    tarBackupReader.skipTarPadding(info.size);
+                    mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
+                    // Metadata blobs!
+                    tarBackupReader.readMetadata(info);
+
+                    // The following only exist because we want to keep refactoring as safe as
+                    // possible, without changing too much.
+                    // TODO: Refactor, so that there are no funny things like this.
+                    // This is read during TarBackupReader.readMetadata().
+                    mWidgetData = tarBackupReader.getWidgetData();
+                    // This can be nulled during TarBackupReader.readMetadata().
+                    monitor = tarBackupReader.getMonitor();
+
+                    tarBackupReader.skipTarPadding(info.size);
+                } else {
+                    // Non-manifest, so it's actual file data.  Is this a package
+                    // we're ignoring?
+                    boolean okay = true;
+                    RestorePolicy policy = mPackagePolicies.get(pkg);
+                    switch (policy) {
+                        case IGNORE:
+                            okay = false;
+                            break;
+
+                        case ACCEPT_IF_APK:
+                            // If we're in accept-if-apk state, then the first file we
+                            // see MUST be the apk.
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
+                                }
+                                // Try to install the app.
+                                String installerName = mPackageInstallers.get(pkg);
+                                boolean isSuccessfullyInstalled = RestoreUtils.installApk(
+                                        instream, mBackupManagerService.getPackageManager(),
+                                        mInstallObserver, mDeleteObserver, mManifestSignatures,
+                                        mPackagePolicies, info, installerName,
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
+                                // good to go; promote to ACCEPT
+                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
+                                        ? RestorePolicy.ACCEPT
+                                        : RestorePolicy.IGNORE);
+                                // At this point we've consumed this file entry
+                                // ourselves, so just strip the tar footer and
+                                // go on to the next file in the input stream
+                                tarBackupReader.skipTarPadding(info.size);
+                                return true;
+                            } else {
+                                // File data before (or without) the apk.  We can't
+                                // handle it coherently in this case so ignore it.
+                                mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                                okay = false;
+                            }
+                            break;
+
+                        case ACCEPT:
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
+                                }
+                                // we can take the data without the apk, so we
+                                // *want* to do so.  skip the apk by declaring this
+                                // one file not-okay without changing the restore
+                                // policy for the package.
+                                okay = false;
+                            }
+                            break;
+
+                        default:
+                            // Something has gone dreadfully wrong when determining
+                            // the restore policy from the manifest.  Ignore the
+                            // rest of this package's data.
+                            Slog.e(TAG, "Invalid policy from manifest");
+                            okay = false;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                            break;
+                    }
+
+                    // Is it a *file* we need to drop or is it not a canonical path?
+                    if (!isRestorableFile(info) || !isCanonicalFilePath(info.path)) {
+                        okay = false;
+                    }
+
+                    // If the policy is satisfied, go ahead and set up to pipe the
+                    // data to the agent.
+                    if (MORE_DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
+                    }
+                    if (okay && mAgent == null) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
+                        }
+
+                        try {
+                            mTargetApp =
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
+                                            pkg, 0);
+
+                            // If we haven't sent any data to this app yet, we probably
+                            // need to clear it first.  Check that.
+                            if (!mClearedPackages.contains(pkg)) {
+                                // apps with their own backup agents are
+                                // responsible for coherently managing a full
+                                // restore.
+                                if (mTargetApp.backupAgentName == null) {
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
+                                                "Clearing app data preparatory to full restore");
+                                    }
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
+                                } else {
+                                    if (MORE_DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
+                                                + mTargetApp.backupAgentName + ") => no clear");
+                                    }
+                                }
+                                mClearedPackages.add(pkg);
+                            } else {
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
+                                }
+                            }
+
+                            // All set; now set up the IPC and launch the agent
+                            setUpPipes();
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
+                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
+                            mAgentPackage = pkg;
+                        } catch (IOException e) {
+                            // fall through to error handling
+                        } catch (NameNotFoundException e) {
+                            // fall through to error handling
+                        }
+
+                        if (mAgent == null) {
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
+                            okay = false;
+                            tearDownPipes();
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Sanity check: make sure we never give data to the wrong app.  This
+                    // should never happen but a little paranoia here won't go amiss.
+                    if (okay && !pkg.equals(mAgentPackage)) {
+                        Slog.e(TAG, "Restoring data for " + pkg
+                                + " but agent is for " + mAgentPackage);
+                        okay = false;
+                    }
+
+                    // At this point we have an agent ready to handle the full
+                    // restore data as well as a pipe for sending data to
+                    // that agent.  Tell the agent to start reading from the
+                    // pipe.
+                    if (okay) {
+                        boolean agentSuccess = true;
+                        long toCopy = info.size;
+                        final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                        final long timeout = isSharedStorage ?
+                                TIMEOUT_SHARED_BACKUP_INTERVAL :
+                                TIMEOUT_RESTORE_INTERVAL;
+                        try {
+                            mBackupManagerService.prepareOperationTimeout(token,
+                                    timeout,
+                                    mMonitorTask,
+                                    OP_TYPE_RESTORE_WAIT);
+
+                            if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                mObbConnection.restoreObbFile(pkg, mPipes[0],
+                                        info.size, info.type, info.path, info.mode,
+                                        info.mtime, token,
+                                        mBackupManagerService.getBackupManagerBinder());
+                            } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
+                                // This is only possible during adb restore.
+                                // TODO: Refactor to clearly separate the flows.
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                KeyValueAdbRestoreEngine restoreEngine =
+                                        new KeyValueAdbRestoreEngine(
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
+                                                mAgent, token);
+                                new Thread(restoreEngine, "restore-key-value-runner").start();
+                            } else {
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
+                                }
+                                // fire up the app's agent listening on the socket.  If
+                                // the agent is running in the system process we can't
+                                // just invoke it asynchronously, so we provide a thread
+                                // for it here.
+                                if (mTargetApp.processName.equals("system")) {
+                                    Slog.d(TAG, "system process agent - spinning a thread");
+                                    RestoreFileRunnable runner = new RestoreFileRunnable(
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
+                                    new Thread(runner, "restore-sys-runner").start();
+                                } else {
+                                    mAgent.doRestoreFile(mPipes[0], info.size, info.type,
+                                            info.domain, info.path, info.mode, info.mtime,
+                                            token, mBackupManagerService.getBackupManagerBinder());
+                                }
+                            }
+                        } catch (IOException e) {
+                            // couldn't dup the socket for a process-local restore
+                            Slog.d(TAG, "Couldn't establish restore");
+                            agentSuccess = false;
+                            okay = false;
+                        } catch (RemoteException e) {
+                            // whoops, remote entity went away.  We'll eat the content
+                            // ourselves, then, and not copy it over.
+                            Slog.e(TAG, "Agent crashed during full restore");
+                            agentSuccess = false;
+                            okay = false;
+                        }
+
+                        // Copy over the data if the agent is still good
+                        if (okay) {
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  copying to restore agent: " + toCopy + " bytes");
+                            }
+                            boolean pipeOkay = true;
+                            FileOutputStream pipe = new FileOutputStream(
+                                    mPipes[1].getFileDescriptor());
+                            while (toCopy > 0) {
+                                int toRead = (toCopy > buffer.length)
+                                        ? buffer.length : (int) toCopy;
+                                int nRead = instream.read(buffer, 0, toRead);
+                                if (nRead >= 0) {
+                                    mBytes += nRead;
+                                }
+                                if (nRead <= 0) {
+                                    break;
+                                }
+                                toCopy -= nRead;
+
+                                // send it to the output pipe as long as things
+                                // are still good
+                                if (pipeOkay) {
+                                    try {
+                                        pipe.write(buffer, 0, nRead);
+                                    } catch (IOException e) {
+                                        Slog.e(TAG, "Failed to write to restore pipe: "
+                                                + e.getMessage());
+                                        pipeOkay = false;
+                                    }
+                                }
+                            }
+
+                            // done sending that file!  Now we just need to consume
+                            // the delta from info.size to the end of block.
+                            tarBackupReader.skipTarPadding(info.size);
+
+                            // and now that we've sent it all, wait for the remote
+                            // side to acknowledge receipt
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
+                        }
+
+                        // okay, if the remote end failed at any point, deal with
+                        // it by ignoring the rest of the restore on it
+                        if (!agentSuccess) {
+                            Slog.w(TAG, "Agent failure restoring " + pkg + "; ending restore");
+                            mBackupManagerService.getBackupHandler().removeMessages(
+                                    MSG_RESTORE_OPERATION_TIMEOUT);
+                            tearDownPipes();
+                            tearDownAgent(mTargetApp);
+                            mAgent = null;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+
+                            // If this was a single-package restore, we halt immediately
+                            // with an agent error under these circumstances
+                            if (onlyPackage != null) {
+                                setResult(RestoreEngine.TARGET_FAILURE);
+                                setRunning(false);
+                                return false;
+                            }
+                        }
+                    }
+
+                    // Problems setting up the agent communication, an explicitly
+                    // dropped file, or an already-ignored package: skip to the
+                    // next stream entry by reading and discarding this file.
+                    if (!okay) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
+                        }
+                        long bytesToConsume = (info.size + 511) & ~511;
+                        while (bytesToConsume > 0) {
+                            int toRead = (bytesToConsume > buffer.length)
+                                    ? buffer.length : (int) bytesToConsume;
+                            long nRead = instream.read(buffer, 0, toRead);
+                            if (nRead >= 0) {
+                                mBytes += nRead;
+                            }
+                            if (nRead <= 0) {
+                                break;
+                            }
+                            bytesToConsume -= nRead;
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read: " + e.getMessage());
+            }
+            setResult(RestoreEngine.TRANSPORT_FAILURE);
+            info = null;
+        }
+
+        // If we got here we're either running smoothly or we've finished
+        if (info == null) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "No [more] data for this package; tearing down");
+            }
+            tearDownPipes();
+            setRunning(false);
+            if (mustKillAgent) {
+                tearDownAgent(mTargetApp);
+            }
+        }
+        return (info != null);
+    }
+
+    private void setUpPipes() throws IOException {
+        mPipes = ParcelFileDescriptor.createPipe();
+    }
+
+    private void tearDownPipes() {
+        // Teardown might arise from the inline restore processing or from the asynchronous
+        // timeout mechanism, and these might race.  Make sure we don't try to close and
+        // null out the pipes twice.
+        synchronized (this) {
+            if (mPipes != null) {
+                try {
+                    mPipes[0].close();
+                    mPipes[0] = null;
+                    mPipes[1].close();
+                    mPipes[1] = null;
+                } catch (IOException e) {
+                    Slog.w(TAG, "Couldn't close agent pipes", e);
+                }
+                mPipes = null;
+            }
+        }
+    }
+
+    private void tearDownAgent(ApplicationInfo app) {
+        if (mAgent != null) {
+            mBackupManagerService.tearDownAgentAndKill(app);
+            mAgent = null;
+        }
+    }
+
+    void handleTimeout() {
+        tearDownPipes();
+        setResult(RestoreEngine.TARGET_FAILURE);
+        setRunning(false);
+    }
+
+    private static boolean isRestorableFile(FileMetadata info) {
+        if (FullBackup.CACHE_TREE_TOKEN.equals(info.domain)) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Dropping cache file path " + info.path);
+            }
+            return false;
+        }
+
+        if (FullBackup.ROOT_TREE_TOKEN.equals(info.domain)) {
+            // It's possible this is "no-backup" dir contents in an archive stream
+            // produced on a device running a version of the OS that predates that
+            // API.  Respect the no-backup intention and don't let the data get to
+            // the app.
+            if (info.path.startsWith("no_backup/")) {
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Dropping no_backup file path " + info.path);
+                }
+                return false;
+            }
+        }
+
+        // Otherwise we think this file is good to go
+        return true;
+    }
+
+    private static boolean isCanonicalFilePath(String path) {
+        if (path.contains("..") || path.contains("//")) {
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    void sendOnRestorePackage(String name) {
+        if (mObserver != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                mObserver.onRestorePackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: restorePackage");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
new file mode 100644
index 0000000..d5c62af
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -0,0 +1,848 @@
+/*
+ * 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.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_FALLBACK;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.KeyValueAdbRestoreEngine;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.fullbackup.FullBackupObbConnection;
+import com.android.server.backup.utils.BytesReadListener;
+import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
+import com.android.server.backup.utils.PasswordUtils;
+import com.android.server.backup.utils.RestoreUtils;
+import com.android.server.backup.utils.TarBackupReader;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.zip.InflaterInputStream;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class PerformAdbRestoreTask implements Runnable {
+
+    private final RefactoredBackupManagerService mBackupManagerService;
+    private final ParcelFileDescriptor mInputFile;
+    private final String mCurrentPassword;
+    private final String mDecryptPassword;
+    private final AtomicBoolean mLatchObject;
+    private final PackageManagerBackupAgent mPackageManagerBackupAgent;
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
+
+    private IFullBackupRestoreObserver mObserver;
+    private IBackupAgent mAgent;
+    private String mAgentPackage;
+    private ApplicationInfo mTargetApp;
+    private FullBackupObbConnection mObbConnection = null;
+    private ParcelFileDescriptor[] mPipes = null;
+    private byte[] mWidgetData = null;
+
+    private long mBytes;
+
+    // Runner that can be placed on a separate thread to do in-process invocation
+    // of the "restore finished" API asynchronously.  Used by adb restore.
+    private static class RestoreFinishedRunnable implements Runnable {
+
+        private final IBackupAgent mAgent;
+        private final int mToken;
+        private final RefactoredBackupManagerService mBackupManagerService;
+
+        RestoreFinishedRunnable(IBackupAgent agent, int token,
+                RefactoredBackupManagerService backupManagerService) {
+            mAgent = agent;
+            mToken = token;
+            mBackupManagerService = backupManagerService;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mAgent.doRestoreFinished(mToken, mBackupManagerService.getBackupManagerBinder());
+            } catch (RemoteException e) {
+                // never happens; this is used only for local binder calls
+            }
+        }
+    }
+
+    // possible handling states for a given package in the restore dataset
+    private final HashMap<String, RestorePolicy> mPackagePolicies
+            = new HashMap<>();
+
+    // installer package names for each encountered app, derived from the manifests
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
+
+    // Signatures for a given package found in its manifest file
+    private final HashMap<String, Signature[]> mManifestSignatures
+            = new HashMap<>();
+
+    // Packages we've already wiped data on when restoring their first file
+    private final HashSet<String> mClearedPackages = new HashSet<>();
+
+    public PerformAdbRestoreTask(RefactoredBackupManagerService backupManagerService,
+            ParcelFileDescriptor fd, String curPassword, String decryptPassword,
+            IFullBackupRestoreObserver observer, AtomicBoolean latch) {
+        this.mBackupManagerService = backupManagerService;
+        mInputFile = fd;
+        mCurrentPassword = curPassword;
+        mDecryptPassword = decryptPassword;
+        mObserver = observer;
+        mLatchObject = latch;
+        mAgent = null;
+        mPackageManagerBackupAgent = new PackageManagerBackupAgent(
+                backupManagerService.getPackageManager());
+        mAgentPackage = null;
+        mTargetApp = null;
+        mObbConnection = new FullBackupObbConnection(backupManagerService);
+
+        // Which packages we've already wiped data on.  We prepopulate this
+        // with a whitelist of packages known to be unclearable.
+        mClearedPackages.add("android");
+        mClearedPackages.add(SETTINGS_PACKAGE);
+    }
+
+    @Override
+    public void run() {
+        Slog.i(TAG, "--- Performing full-dataset restore ---");
+        mObbConnection.establish();
+        mObserver = FullBackupRestoreObserverUtils.sendStartRestore(mObserver);
+
+        // Are we able to restore shared-storage data?
+        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            mPackagePolicies.put(SHARED_BACKUP_AGENT_PACKAGE, RestorePolicy.ACCEPT);
+        }
+
+        FileInputStream rawInStream = null;
+        try {
+            if (!mBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
+                }
+                return;
+            }
+
+            mBytes = 0;
+
+            rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
+
+            InputStream tarInputStream = parseBackupFileHeaderAndReturnTarStream(rawInStream,
+                    mDecryptPassword);
+            if (tarInputStream == null) {
+                // There was an error reading the backup file, which is already handled and logged.
+                // Just abort.
+                return;
+            }
+
+            byte[] buffer = new byte[32 * 1024];
+            boolean didRestore;
+            do {
+                didRestore = restoreOneFile(tarInputStream, false /* mustKillAgent */, buffer,
+                        null /* onlyPackage */, true /* allowApks */,
+                        mBackupManagerService.generateRandomIntegerToken(), null /* monitor */);
+            } while (didRestore);
+
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to read restore input");
+        } finally {
+            tearDownPipes();
+            tearDownAgent(mTargetApp, true);
+
+            try {
+                if (rawInStream != null) {
+                    rawInStream.close();
+                }
+                mInputFile.close();
+            } catch (IOException e) {
+                Slog.w(TAG, "Close of restore data pipe threw", e);
+                /* nothing we can do about this */
+            }
+            synchronized (mLatchObject) {
+                mLatchObject.set(true);
+                mLatchObject.notifyAll();
+            }
+            mObbConnection.tearDown();
+            mObserver = FullBackupRestoreObserverUtils.sendEndRestore(mObserver);
+            Slog.d(TAG, "Full restore pass complete.");
+            mBackupManagerService.getWakelock().release();
+        }
+    }
+
+    private static void readFullyOrThrow(InputStream in, byte[] buffer) throws IOException {
+        int offset = 0;
+        while (offset < buffer.length) {
+            int bytesRead = in.read(buffer, offset, buffer.length - offset);
+            if (bytesRead <= 0) {
+                throw new IOException("Couldn't fully read data");
+            }
+            offset += bytesRead;
+        }
+    }
+
+    @VisibleForTesting
+    public static InputStream parseBackupFileHeaderAndReturnTarStream(
+            InputStream rawInputStream,
+            String decryptPassword)
+            throws IOException {
+        // First, parse out the unencrypted/uncompressed header
+        boolean compressed = false;
+        InputStream preCompressStream = rawInputStream;
+
+        boolean okay = false;
+        final int headerLen = BACKUP_FILE_HEADER_MAGIC.length();
+        byte[] streamHeader = new byte[headerLen];
+        readFullyOrThrow(rawInputStream, streamHeader);
+        byte[] magicBytes = BACKUP_FILE_HEADER_MAGIC.getBytes(
+                "UTF-8");
+        if (Arrays.equals(magicBytes, streamHeader)) {
+            // okay, header looks good.  now parse out the rest of the fields.
+            String s = readHeaderLine(rawInputStream);
+            final int archiveVersion = Integer.parseInt(s);
+            if (archiveVersion <= BACKUP_FILE_VERSION) {
+                // okay, it's a version we recognize.  if it's version 1, we may need
+                // to try two different PBKDF2 regimes to compare checksums.
+                final boolean pbkdf2Fallback = (archiveVersion == 1);
+
+                s = readHeaderLine(rawInputStream);
+                compressed = (Integer.parseInt(s) != 0);
+                s = readHeaderLine(rawInputStream);
+                if (s.equals("none")) {
+                    // no more header to parse; we're good to go
+                    okay = true;
+                } else if (decryptPassword != null && decryptPassword.length() > 0) {
+                    preCompressStream = decodeAesHeaderAndInitialize(
+                            decryptPassword, s, pbkdf2Fallback,
+                            rawInputStream);
+                    if (preCompressStream != null) {
+                        okay = true;
+                    }
+                } else {
+                    Slog.w(TAG, "Archive is encrypted but no password given");
+                }
+            } else {
+                Slog.w(TAG, "Wrong header version: " + s);
+            }
+        } else {
+            Slog.w(TAG, "Didn't read the right header magic");
+        }
+
+        if (!okay) {
+            Slog.w(TAG, "Invalid restore data; aborting.");
+            return null;
+        }
+
+        // okay, use the right stream layer based on compression
+        return compressed ? new InflaterInputStream(preCompressStream) : preCompressStream;
+    }
+
+    private static String readHeaderLine(InputStream in) throws IOException {
+        int c;
+        StringBuilder buffer = new StringBuilder(80);
+        while ((c = in.read()) >= 0) {
+            if (c == '\n') {
+                break;   // consume and discard the newlines
+            }
+            buffer.append((char) c);
+        }
+        return buffer.toString();
+    }
+
+    private static InputStream attemptMasterKeyDecryption(String decryptPassword, String algorithm,
+            byte[] userSalt, byte[] ckSalt,
+            int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
+            boolean doLog) {
+        InputStream result = null;
+
+        try {
+            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            SecretKey userKey = PasswordUtils
+                    .buildPasswordKey(algorithm, decryptPassword, userSalt,
+                            rounds);
+            byte[] IV = PasswordUtils.hexToByteArray(userIvHex);
+            IvParameterSpec ivSpec = new IvParameterSpec(IV);
+            c.init(Cipher.DECRYPT_MODE,
+                    new SecretKeySpec(userKey.getEncoded(), "AES"),
+                    ivSpec);
+            byte[] mkCipher = PasswordUtils.hexToByteArray(masterKeyBlobHex);
+            byte[] mkBlob = c.doFinal(mkCipher);
+
+            // first, the master key IV
+            int offset = 0;
+            int len = mkBlob[offset++];
+            IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
+            offset += len;
+            // then the master key itself
+            len = mkBlob[offset++];
+            byte[] mk = Arrays.copyOfRange(mkBlob,
+                    offset, offset + len);
+            offset += len;
+            // and finally the master key checksum hash
+            len = mkBlob[offset++];
+            byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
+                    offset, offset + len);
+
+            // now validate the decrypted master key against the checksum
+            byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, mk, ckSalt,
+                    rounds);
+            if (Arrays.equals(calculatedCk, mkChecksum)) {
+                ivSpec = new IvParameterSpec(IV);
+                c.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec(mk, "AES"),
+                        ivSpec);
+                // Only if all of the above worked properly will 'result' be assigned
+                result = new CipherInputStream(rawInStream, c);
+            } else if (doLog) {
+                Slog.w(TAG, "Incorrect password");
+            }
+        } catch (InvalidAlgorithmParameterException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed parameter spec unavailable!", e);
+            }
+        } catch (BadPaddingException e) {
+            // This case frequently occurs when the wrong password is used to decrypt
+            // the master key.  Use the identical "incorrect password" log text as is
+            // used in the checksum failure log in order to avoid providing additional
+            // information to an attacker.
+            if (doLog) {
+                Slog.w(TAG, "Incorrect password");
+            }
+        } catch (IllegalBlockSizeException e) {
+            if (doLog) {
+                Slog.w(TAG, "Invalid block size in master key");
+            }
+        } catch (NoSuchAlgorithmException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed decryption algorithm unavailable!");
+            }
+        } catch (NoSuchPaddingException e) {
+            if (doLog) {
+                Slog.e(TAG, "Needed padding mechanism unavailable!");
+            }
+        } catch (InvalidKeyException e) {
+            if (doLog) {
+                Slog.w(TAG, "Illegal password; aborting");
+            }
+        }
+
+        return result;
+    }
+
+    private static InputStream decodeAesHeaderAndInitialize(String decryptPassword,
+            String encryptionName,
+            boolean pbkdf2Fallback,
+            InputStream rawInStream) {
+        InputStream result = null;
+        try {
+            if (encryptionName.equals(PasswordUtils.ENCRYPTION_ALGORITHM_NAME)) {
+
+                String userSaltHex = readHeaderLine(rawInStream); // 5
+                byte[] userSalt = PasswordUtils.hexToByteArray(userSaltHex);
+
+                String ckSaltHex = readHeaderLine(rawInStream); // 6
+                byte[] ckSalt = PasswordUtils.hexToByteArray(ckSaltHex);
+
+                int rounds = Integer.parseInt(readHeaderLine(rawInStream)); // 7
+                String userIvHex = readHeaderLine(rawInStream); // 8
+
+                String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
+
+                // decrypt the master key blob
+                result = attemptMasterKeyDecryption(decryptPassword, PBKDF_CURRENT,
+                        userSalt, ckSalt, rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
+                if (result == null && pbkdf2Fallback) {
+                    result = attemptMasterKeyDecryption(
+                            decryptPassword, PBKDF_FALLBACK, userSalt, ckSalt,
+                            rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
+                }
+            } else {
+                Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
+            }
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Can't parse restore data header");
+        } catch (IOException e) {
+            Slog.w(TAG, "Can't read input header");
+        }
+
+        return result;
+    }
+
+    boolean restoreOneFile(InputStream instream, boolean mustKillAgent, byte[] buffer,
+            PackageInfo onlyPackage, boolean allowApks, int token, IBackupManagerMonitor monitor) {
+        BytesReadListener bytesReadListener = new BytesReadListener() {
+            @Override
+            public void onBytesRead(long bytesRead) {
+                mBytes += bytesRead;
+            }
+        };
+        TarBackupReader tarBackupReader = new TarBackupReader(instream,
+                bytesReadListener, monitor);
+        FileMetadata info;
+        try {
+            info = tarBackupReader.readTarHeaders();
+            if (info != null) {
+                if (MORE_DEBUG) {
+                    info.dump();
+                }
+
+                final String pkg = info.packageName;
+                if (!pkg.equals(mAgentPackage)) {
+                    // okay, change in package; set up our various
+                    // bookkeeping if we haven't seen it yet
+                    if (!mPackagePolicies.containsKey(pkg)) {
+                        mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                    }
+
+                    // Clean up the previous agent relationship if necessary,
+                    // and let the observer know we're considering a new app.
+                    if (mAgent != null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
+                        }
+                        // Now we're really done
+                        tearDownPipes();
+                        tearDownAgent(mTargetApp, true);
+                        mTargetApp = null;
+                        mAgentPackage = null;
+                    }
+                }
+
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks,
+                            info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
+                    mPackageInstallers.put(pkg, info.installerPackageName);
+                    // We've read only the manifest content itself at this point,
+                    // so consume the footer before looping around to the next
+                    // input file
+                    tarBackupReader.skipTarPadding(info.size);
+                    mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
+                    // Metadata blobs!
+                    tarBackupReader.readMetadata(info);
+
+                    // The following only exist because we want to keep refactoring as safe as
+                    // possible, without changing too much.
+                    // TODO: Refactor, so that there are no funny things like this.
+                    // This is read during TarBackupReader.readMetadata().
+                    mWidgetData = tarBackupReader.getWidgetData();
+                    // This can be nulled during TarBackupReader.readMetadata().
+                    monitor = tarBackupReader.getMonitor();
+
+                    tarBackupReader.skipTarPadding(info.size);
+                } else {
+                    // Non-manifest, so it's actual file data.  Is this a package
+                    // we're ignoring?
+                    boolean okay = true;
+                    RestorePolicy policy = mPackagePolicies.get(pkg);
+                    switch (policy) {
+                        case IGNORE:
+                            okay = false;
+                            break;
+
+                        case ACCEPT_IF_APK:
+                            // If we're in accept-if-apk state, then the first file we
+                            // see MUST be the apk.
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
+                                }
+                                // Try to install the app.
+                                String installerName = mPackageInstallers.get(pkg);
+                                boolean isSuccessfullyInstalled = RestoreUtils.installApk(
+                                        instream, mBackupManagerService.getPackageManager(),
+                                        mInstallObserver, mDeleteObserver, mManifestSignatures,
+                                        mPackagePolicies, info, installerName,
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
+                                // good to go; promote to ACCEPT
+                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
+                                        ? RestorePolicy.ACCEPT
+                                        : RestorePolicy.IGNORE);
+                                // At this point we've consumed this file entry
+                                // ourselves, so just strip the tar footer and
+                                // go on to the next file in the input stream
+                                tarBackupReader.skipTarPadding(info.size);
+                                return true;
+                            } else {
+                                // File data before (or without) the apk.  We can't
+                                // handle it coherently in this case so ignore it.
+                                mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                                okay = false;
+                            }
+                            break;
+
+                        case ACCEPT:
+                            if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
+                                }
+                                // we can take the data without the apk, so we
+                                // *want* to do so.  skip the apk by declaring this
+                                // one file not-okay without changing the restore
+                                // policy for the package.
+                                okay = false;
+                            }
+                            break;
+
+                        default:
+                            // Something has gone dreadfully wrong when determining
+                            // the restore policy from the manifest.  Ignore the
+                            // rest of this package's data.
+                            Slog.e(TAG, "Invalid policy from manifest");
+                            okay = false;
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                            break;
+                    }
+
+                    // The path needs to be canonical
+                    if (!isCanonicalFilePath(info.path)) {
+                        okay = false;
+                    }
+
+                    // If the policy is satisfied, go ahead and set up to pipe the
+                    // data to the agent.
+                    if (DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
+                    }
+                    if (okay && mAgent == null) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
+                        }
+
+                        try {
+                            mTargetApp =
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
+                                            pkg, 0);
+
+                            // If we haven't sent any data to this app yet, we probably
+                            // need to clear it first.  Check that.
+                            if (!mClearedPackages.contains(pkg)) {
+                                // apps with their own backup agents are
+                                // responsible for coherently managing a full
+                                // restore.
+                                if (mTargetApp.backupAgentName == null) {
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
+                                                "Clearing app data preparatory to full restore");
+                                    }
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
+                                } else {
+                                    if (DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
+                                                + mTargetApp.backupAgentName + ") => no clear");
+                                    }
+                                }
+                                mClearedPackages.add(pkg);
+                            } else {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
+                                }
+                            }
+
+                            // All set; now set up the IPC and launch the agent
+                            setUpPipes();
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
+                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
+                            mAgentPackage = pkg;
+                        } catch (IOException e) {
+                            // fall through to error handling
+                        } catch (NameNotFoundException e) {
+                            // fall through to error handling
+                        }
+
+                        if (mAgent == null) {
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
+                            okay = false;
+                            tearDownPipes();
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Sanity check: make sure we never give data to the wrong app.  This
+                    // should never happen but a little paranoia here won't go amiss.
+                    if (okay && !pkg.equals(mAgentPackage)) {
+                        Slog.e(TAG, "Restoring data for " + pkg
+                                + " but agent is for " + mAgentPackage);
+                        okay = false;
+                    }
+
+                    // At this point we have an agent ready to handle the full
+                    // restore data as well as a pipe for sending data to
+                    // that agent.  Tell the agent to start reading from the
+                    // pipe.
+                    if (okay) {
+                        boolean agentSuccess = true;
+                        long toCopy = info.size;
+                        try {
+                            mBackupManagerService.prepareOperationTimeout(
+                                    token, TIMEOUT_RESTORE_INTERVAL, null, OP_TYPE_RESTORE_WAIT);
+
+                            if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                mObbConnection.restoreObbFile(pkg, mPipes[0],
+                                        info.size, info.type, info.path, info.mode,
+                                        info.mtime, token,
+                                        mBackupManagerService.getBackupManagerBinder());
+                            } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
+                                }
+                                KeyValueAdbRestoreEngine restoreEngine =
+                                        new KeyValueAdbRestoreEngine(
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
+                                                mAgent, token);
+                                new Thread(restoreEngine, "restore-key-value-runner").start();
+                            } else {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
+                                }
+                                // fire up the app's agent listening on the socket.  If
+                                // the agent is running in the system process we can't
+                                // just invoke it asynchronously, so we provide a thread
+                                // for it here.
+                                if (mTargetApp.processName.equals("system")) {
+                                    Slog.d(TAG, "system process agent - spinning a thread");
+                                    RestoreFileRunnable runner = new RestoreFileRunnable(
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
+                                    new Thread(runner, "restore-sys-runner").start();
+                                } else {
+                                    mAgent.doRestoreFile(mPipes[0], info.size, info.type,
+                                            info.domain, info.path, info.mode, info.mtime,
+                                            token, mBackupManagerService.getBackupManagerBinder());
+                                }
+                            }
+                        } catch (IOException e) {
+                            // couldn't dup the socket for a process-local restore
+                            Slog.d(TAG, "Couldn't establish restore");
+                            agentSuccess = false;
+                            okay = false;
+                        } catch (RemoteException e) {
+                            // whoops, remote entity went away.  We'll eat the content
+                            // ourselves, then, and not copy it over.
+                            Slog.e(TAG, "Agent crashed during full restore");
+                            agentSuccess = false;
+                            okay = false;
+                        }
+
+                        // Copy over the data if the agent is still good
+                        if (okay) {
+                            boolean pipeOkay = true;
+                            FileOutputStream pipe = new FileOutputStream(
+                                    mPipes[1].getFileDescriptor());
+                            while (toCopy > 0) {
+                                int toRead = (toCopy > buffer.length)
+                                        ? buffer.length : (int) toCopy;
+                                int nRead = instream.read(buffer, 0, toRead);
+                                if (nRead >= 0) {
+                                    mBytes += nRead;
+                                }
+                                if (nRead <= 0) {
+                                    break;
+                                }
+                                toCopy -= nRead;
+
+                                // send it to the output pipe as long as things
+                                // are still good
+                                if (pipeOkay) {
+                                    try {
+                                        pipe.write(buffer, 0, nRead);
+                                    } catch (IOException e) {
+                                        Slog.e(TAG, "Failed to write to restore pipe", e);
+                                        pipeOkay = false;
+                                    }
+                                }
+                            }
+
+                            // done sending that file!  Now we just need to consume
+                            // the delta from info.size to the end of block.
+                            tarBackupReader.skipTarPadding(info.size);
+
+                            // and now that we've sent it all, wait for the remote
+                            // side to acknowledge receipt
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
+                        }
+
+                        // okay, if the remote end failed at any point, deal with
+                        // it by ignoring the rest of the restore on it
+                        if (!agentSuccess) {
+                            if (DEBUG) {
+                                Slog.d(TAG, "Agent failure restoring " + pkg + "; now ignoring");
+                            }
+                            mBackupManagerService.getBackupHandler().removeMessages(
+                                    MSG_RESTORE_OPERATION_TIMEOUT);
+                            tearDownPipes();
+                            tearDownAgent(mTargetApp, false);
+                            mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
+                        }
+                    }
+
+                    // Problems setting up the agent communication, or an already-
+                    // ignored package: skip to the next tar stream entry by
+                    // reading and discarding this file.
+                    if (!okay) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
+                        }
+                        long bytesToConsume = (info.size + 511) & ~511;
+                        while (bytesToConsume > 0) {
+                            int toRead = (bytesToConsume > buffer.length)
+                                    ? buffer.length : (int) bytesToConsume;
+                            long nRead = instream.read(buffer, 0, toRead);
+                            if (nRead >= 0) {
+                                mBytes += nRead;
+                            }
+                            if (nRead <= 0) {
+                                break;
+                            }
+                            bytesToConsume -= nRead;
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read", e);
+            }
+            // treat as EOF
+            info = null;
+        }
+
+        return (info != null);
+    }
+
+    private static boolean isCanonicalFilePath(String path) {
+        if (path.contains("..") || path.contains("//")) {
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    private void setUpPipes() throws IOException {
+        mPipes = ParcelFileDescriptor.createPipe();
+    }
+
+    private void tearDownPipes() {
+        if (mPipes != null) {
+            try {
+                mPipes[0].close();
+                mPipes[0] = null;
+                mPipes[1].close();
+                mPipes[1] = null;
+            } catch (IOException e) {
+                Slog.w(TAG, "Couldn't close agent pipes", e);
+            }
+            mPipes = null;
+        }
+    }
+
+    private void tearDownAgent(ApplicationInfo app, boolean doRestoreFinished) {
+        if (mAgent != null) {
+            try {
+                // In the adb restore case, we do restore-finished here
+                if (doRestoreFinished) {
+                    final int token = mBackupManagerService.generateRandomIntegerToken();
+                    final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(
+                            mBackupManagerService, token);
+                    mBackupManagerService.prepareOperationTimeout(
+                            token, TIMEOUT_FULL_BACKUP_INTERVAL, latch, OP_TYPE_RESTORE_WAIT);
+                    if (mTargetApp.processName.equals("system")) {
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "system agent - restoreFinished on thread");
+                        }
+                        Runnable runner = new RestoreFinishedRunnable(mAgent, token,
+                                mBackupManagerService);
+                        new Thread(runner, "restore-sys-finished-runner").start();
+                    } else {
+                        mAgent.doRestoreFinished(token,
+                                mBackupManagerService.getBackupManagerBinder());
+                    }
+
+                    latch.await();
+                }
+
+                mBackupManagerService.tearDownAgentAndKill(app);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Lost app trying to shut down");
+            }
+            mAgent = null;
+        }
+    }
+
+}
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
new file mode 100644
index 0000000..21d5dc2
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -0,0 +1,1324 @@
+/*
+ * 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.backup.restore;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_RESTORE_FINISHED_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+
+import android.app.ApplicationThreadConstants;
+import android.app.IBackupAgent;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.app.backup.RestoreDescription;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.internal.backup.IBackupTransport;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupUtils;
+import com.android.server.backup.PackageManagerBackupAgent;
+import com.android.server.backup.PackageManagerBackupAgent.Metadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.utils.AppBackupUtils;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PerformUnifiedRestoreTask implements BackupRestoreTask {
+
+    private RefactoredBackupManagerService backupManagerService;
+    // Transport we're working with to do the restore
+    private IBackupTransport mTransport;
+
+    // Where per-transport saved state goes
+    File mStateDir;
+
+    // Restore observer; may be null
+    private IRestoreObserver mObserver;
+
+    // BackuoManagerMonitor; may be null
+    private IBackupManagerMonitor mMonitor;
+
+    // Token identifying the dataset to the transport
+    private long mToken;
+
+    // When this is a restore-during-install, this is the token identifying the
+    // operation to the Package Manager, and we must ensure that we let it know
+    // when we're finished.
+    private int mPmToken;
+
+    // When this is restore-during-install, we need to tell the package manager
+    // whether we actually launched the app, because this affects notifications
+    // around externally-visible state transitions.
+    private boolean mDidLaunch;
+
+    // Is this a whole-system restore, i.e. are we establishing a new ancestral
+    // dataset to base future restore-at-install operations from?
+    private boolean mIsSystemRestore;
+
+    // If this is a single-package restore, what package are we interested in?
+    private PackageInfo mTargetPackage;
+
+    // In all cases, the calculated list of packages that we are trying to restore
+    private List<PackageInfo> mAcceptSet;
+
+    // Our bookkeeping about the ancestral dataset
+    private PackageManagerBackupAgent mPmAgent;
+
+    // Currently-bound backup agent for restore + restoreFinished purposes
+    private IBackupAgent mAgent;
+
+    // What sort of restore we're doing now
+    private RestoreDescription mRestoreDescription;
+
+    // The package we're currently restoring
+    private PackageInfo mCurrentPackage;
+
+    // Widget-related data handled as part of this restore operation
+    private byte[] mWidgetData;
+
+    // Number of apps restored in this pass
+    private int mCount;
+
+    // When did we start?
+    private long mStartRealtime;
+
+    // State machine progress
+    private UnifiedRestoreState mState;
+
+    // How are things going?
+    private int mStatus;
+
+    // Done?
+    private boolean mFinished;
+
+    // Key/value: bookkeeping about staged data and files for agent access
+    private File mBackupDataName;
+    private File mStageName;
+    private File mSavedStateName;
+    private File mNewStateName;
+    ParcelFileDescriptor mBackupData;
+    ParcelFileDescriptor mNewState;
+
+    private final int mEphemeralOpToken;
+
+    // Invariant: mWakelock is already held, and this task is responsible for
+    // releasing it at the end of the restore operation.
+    public PerformUnifiedRestoreTask(RefactoredBackupManagerService backupManagerService,
+            IBackupTransport transport, IRestoreObserver observer,
+            IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
+            int pmToken, boolean isFullSystemRestore, String[] filterSet) {
+        this.backupManagerService = backupManagerService;
+        mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+        mState = UnifiedRestoreState.INITIAL;
+        mStartRealtime = SystemClock.elapsedRealtime();
+
+        mTransport = transport;
+        mObserver = observer;
+        mMonitor = monitor;
+        mToken = restoreSetToken;
+        mPmToken = pmToken;
+        mTargetPackage = targetPackage;
+        mIsSystemRestore = isFullSystemRestore;
+        mFinished = false;
+        mDidLaunch = false;
+
+        if (targetPackage != null) {
+            // Single package restore
+            mAcceptSet = new ArrayList<>();
+            mAcceptSet.add(targetPackage);
+        } else {
+            // Everything possible, or a target set
+            if (filterSet == null) {
+                // We want everything and a pony
+                List<PackageInfo> apps =
+                        PackageManagerBackupAgent.getStorableApplications(
+                                backupManagerService.getPackageManager());
+                filterSet = packagesToNames(apps);
+                if (DEBUG) {
+                    Slog.i(TAG, "Full restore; asking about " + filterSet.length + " apps");
+                }
+            }
+
+            mAcceptSet = new ArrayList<>(filterSet.length);
+
+            // Pro tem, we insist on moving the settings provider package to last place.
+            // Keep track of whether it's in the list, and bump it down if so.  We also
+            // want to do the system package itself first if it's called for.
+            boolean hasSystem = false;
+            boolean hasSettings = false;
+            for (int i = 0; i < filterSet.length; i++) {
+                try {
+                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
+                            filterSet[i], 0);
+                    if ("android".equals(info.packageName)) {
+                        hasSystem = true;
+                        continue;
+                    }
+                    if (SETTINGS_PACKAGE.equals(info.packageName)) {
+                        hasSettings = true;
+                        continue;
+                    }
+
+                    if (AppBackupUtils.appIsEligibleForBackup(
+                            info.applicationInfo)) {
+                        mAcceptSet.add(info);
+                    }
+                } catch (NameNotFoundException e) {
+                    // requested package name doesn't exist; ignore it
+                }
+            }
+            if (hasSystem) {
+                try {
+                    mAcceptSet.add(0,
+                            backupManagerService.getPackageManager().getPackageInfo("android", 0));
+                } catch (NameNotFoundException e) {
+                    // won't happen; we know a priori that it's valid
+                }
+            }
+            if (hasSettings) {
+                try {
+                    mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfo(
+                            SETTINGS_PACKAGE, 0));
+                } catch (NameNotFoundException e) {
+                    // this one is always valid too
+                }
+            }
+        }
+
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size());
+            for (PackageInfo info : mAcceptSet) {
+                Slog.v(TAG, "   " + info.packageName);
+            }
+        }
+    }
+
+    private String[] packagesToNames(List<PackageInfo> apps) {
+        final int N = apps.size();
+        String[] names = new String[N];
+        for (int i = 0; i < N; i++) {
+            names[i] = apps.get(i).packageName;
+        }
+        return names;
+    }
+
+    // Execute one tick of whatever state machine the task implements
+    @Override
+    public void execute() {
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "*** Executing restore step " + mState);
+        }
+        switch (mState) {
+            case INITIAL:
+                startRestore();
+                break;
+
+            case RUNNING_QUEUE:
+                dispatchNextRestore();
+                break;
+
+            case RESTORE_KEYVALUE:
+                restoreKeyValue();
+                break;
+
+            case RESTORE_FULL:
+                restoreFull();
+                break;
+
+            case RESTORE_FINISHED:
+                restoreFinished();
+                break;
+
+            case FINAL:
+                if (!mFinished) {
+                    finalizeRestore();
+                } else {
+                    Slog.e(TAG, "Duplicate finish");
+                }
+                mFinished = true;
+                break;
+        }
+    }
+
+    /*
+     * SKETCH OF OPERATION
+     *
+     * create one of these PerformUnifiedRestoreTask objects, telling it which
+     * dataset & transport to address, and then parameters within the restore
+     * operation: single target package vs many, etc.
+     *
+     * 1. transport.startRestore(token, list-of-packages).  If we need @pm@  it is
+     * always placed first and the settings provider always placed last [for now].
+     *
+     * 1a [if we needed @pm@ then nextRestorePackage() and restore the PMBA inline]
+     *
+     *   [ state change => RUNNING_QUEUE ]
+     *
+     * NOW ITERATE:
+     *
+     * { 3. t.nextRestorePackage()
+     *   4. does the metadata for this package allow us to restore it?
+     *      does the on-disk app permit us to restore it? [re-check allowBackup etc]
+     *   5. is this a key/value dataset?  => key/value agent restore
+     *       [ state change => RESTORE_KEYVALUE ]
+     *       5a. spin up agent
+     *       5b. t.getRestoreData() to stage it properly
+     *       5c. call into agent to perform restore
+     *       5d. tear down agent
+     *       [ state change => RUNNING_QUEUE ]
+     *
+     *   6. else it's a stream dataset:
+     *       [ state change => RESTORE_FULL ]
+     *       6a. instantiate the engine for a stream restore: engine handles agent lifecycles
+     *       6b. spin off engine runner on separate thread
+     *       6c. ITERATE getNextFullRestoreDataChunk() and copy data to engine runner socket
+     *       [ state change => RUNNING_QUEUE ]
+     * }
+     *
+     *   [ state change => FINAL ]
+     *
+     * 7. t.finishRestore(), release wakelock, etc.
+     *
+     *
+     */
+
+    // state INITIAL : set up for the restore and read the metadata if necessary
+    private void startRestore() {
+        sendStartRestore(mAcceptSet.size());
+
+        // If we're starting a full-system restore, set up to begin widget ID remapping
+        if (mIsSystemRestore) {
+            // TODO: http://b/22388012
+            AppWidgetBackupBridge.restoreStarting(UserHandle.USER_SYSTEM);
+        }
+
+        try {
+            String transportDir = mTransport.transportDirName();
+            mStateDir = new File(backupManagerService.getBaseStateDir(), transportDir);
+
+            // Fetch the current metadata from the dataset first
+            PackageInfo pmPackage = new PackageInfo();
+            pmPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+            mAcceptSet.add(0, pmPackage);
+
+            PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]);
+            mStatus = mTransport.startRestore(mToken, packages);
+            if (mStatus != BackupTransport.TRANSPORT_OK) {
+                Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            RestoreDescription desc = mTransport.nextRestorePackage();
+            if (desc == null) {
+                Slog.e(TAG, "No restore metadata available; halting");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_NO_RESTORE_METADATA_AVAILABLE,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+            if (!PACKAGE_MANAGER_SENTINEL.equals(
+                    desc.getPackageName())) {
+                Slog.e(TAG, "Required package metadata but got "
+                        + desc.getPackageName());
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_NO_PM_METADATA_RECEIVED,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // Pull the Package Manager metadata from the restore set first
+            mCurrentPackage = new PackageInfo();
+            mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+            mPmAgent = new PackageManagerBackupAgent(backupManagerService.getPackageManager(),
+                    null);
+            mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "initiating restore for PMBA");
+            }
+            initiateOneRestore(mCurrentPackage, 0);
+            // The PM agent called operationComplete() already, because our invocation
+            // of it is process-local and therefore synchronous.  That means that the
+            // next-state message (RUNNING_QUEUE) is already enqueued.  Only if we're
+            // unable to proceed with running the queue do we remove that pending
+            // message and jump straight to the FINAL state.  Because this was
+            // synchronous we also know that we should cancel the pending timeout
+            // message.
+            backupManagerService.getBackupHandler().removeMessages(
+                    MSG_RESTORE_OPERATION_TIMEOUT);
+
+            // Verify that the backup set includes metadata.  If not, we can't do
+            // signature/version verification etc, so we simply do not proceed with
+            // the restore operation.
+            if (!mPmAgent.hasMetadata()) {
+                Slog.e(TAG, "PM agent has no metadata, so not restoring");
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                        PACKAGE_MANAGER_SENTINEL,
+                        "Package manager restore metadata missing");
+                mStatus = BackupTransport.TRANSPORT_ERROR;
+                backupManagerService.getBackupHandler().removeMessages(
+                        MSG_BACKUP_RESTORE_STEP, this);
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // Success; cache the metadata and continue as expected with the
+            // next state already enqueued
+
+        } catch (Exception e) {
+            // If we lost the transport at any time, halt
+            Slog.e(TAG, "Unable to contact transport for restore: " + e.getMessage());
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_LOST_TRANSPORT,
+                    null,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            mStatus = BackupTransport.TRANSPORT_ERROR;
+            backupManagerService.getBackupHandler().removeMessages(
+                    MSG_BACKUP_RESTORE_STEP, this);
+            executeNextState(UnifiedRestoreState.FINAL);
+            return;
+        }
+    }
+
+    // state RUNNING_QUEUE : figure out what the next thing to be restored is,
+    // and fire the appropriate next step
+    private void dispatchNextRestore() {
+        UnifiedRestoreState nextState = UnifiedRestoreState.FINAL;
+        try {
+            mRestoreDescription = mTransport.nextRestorePackage();
+            final String pkgName = (mRestoreDescription != null)
+                    ? mRestoreDescription.getPackageName() : null;
+            if (pkgName == null) {
+                Slog.e(TAG, "Failure getting next package name");
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                nextState = UnifiedRestoreState.FINAL;
+                return;
+            } else if (mRestoreDescription == RestoreDescription.NO_MORE_PACKAGES) {
+                // Yay we've reached the end cleanly
+                if (DEBUG) {
+                    Slog.v(TAG, "No more packages; finishing restore");
+                }
+                int millis = (int) (SystemClock.elapsedRealtime() - mStartRealtime);
+                EventLog.writeEvent(EventLogTags.RESTORE_SUCCESS, mCount, millis);
+                nextState = UnifiedRestoreState.FINAL;
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.i(TAG, "Next restore package: " + mRestoreDescription);
+            }
+            sendOnRestorePackage(pkgName);
+
+            Metadata metaInfo = mPmAgent.getRestoredMetadata(pkgName);
+            if (metaInfo == null) {
+                Slog.e(TAG, "No metadata for " + pkgName);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
+                        "Package metadata missing");
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+
+            try {
+                mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
+                        pkgName, PackageManager.GET_SIGNATURES);
+            } catch (NameNotFoundException e) {
+                // Whoops, we thought we could restore this package but it
+                // turns out not to be present.  Skip it.
+                Slog.e(TAG, "Package not present: " + pkgName);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT,
+                        mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
+                        "Package missing on device");
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+
+            if (metaInfo.versionCode > mCurrentPackage.versionCode) {
+                // Data is from a "newer" version of the app than we have currently
+                // installed.  If the app has not declared that it is prepared to
+                // handle this case, we do not attempt the restore.
+                if ((mCurrentPackage.applicationInfo.flags
+                        & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
+                    String message = "Source version " + metaInfo.versionCode
+                            + " > installed version " + mCurrentPackage.versionCode;
+                    Slog.w(TAG, "Package " + pkgName + ": " + message);
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                            metaInfo.versionCode);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, false);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                    EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                            pkgName, message);
+                    nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                    return;
+                } else {
+                    if (DEBUG) {
+                        Slog.v(TAG, "Source version " + metaInfo.versionCode
+                                + " > installed version " + mCurrentPackage.versionCode
+                                + " but restoreAnyVersion");
+                    }
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                            metaInfo.versionCode);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, true);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                            BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
+                            mCurrentPackage,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                }
+            }
+
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Package " + pkgName
+                        + " restore version [" + metaInfo.versionCode
+                        + "] is compatible with installed version ["
+                        + mCurrentPackage.versionCode + "]");
+            }
+
+            // Reset per-package preconditions and fire the appropriate next state
+            mWidgetData = null;
+            final int type = mRestoreDescription.getDataType();
+            if (type == RestoreDescription.TYPE_KEY_VALUE) {
+                nextState = UnifiedRestoreState.RESTORE_KEYVALUE;
+            } else if (type == RestoreDescription.TYPE_FULL_STREAM) {
+                nextState = UnifiedRestoreState.RESTORE_FULL;
+            } else {
+                // Unknown restore type; ignore this package and move on
+                Slog.e(TAG, "Unrecognized restore type " + type);
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                return;
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Can't get next restore target from transport; halting: "
+                    + e.getMessage());
+            EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+            nextState = UnifiedRestoreState.FINAL;
+            return;
+        } finally {
+            executeNextState(nextState);
+        }
+    }
+
+    // state RESTORE_KEYVALUE : restore one package via key/value API set
+    private void restoreKeyValue() {
+        // Initiating the restore will pass responsibility for the state machine's
+        // progress to the agent callback, so we do not always execute the
+        // next state here.
+        final String packageName = mCurrentPackage.packageName;
+        // Validate some semantic requirements that apply in this way
+        // only to the key/value restore API flow
+        if (mCurrentPackage.applicationInfo.backupAgentName == null
+                || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) {
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Data exists for package " + packageName
+                        + " but app has no agent; skipping");
+            }
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_APP_HAS_NO_AGENT, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Package has no agent");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName);
+        if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
+            Slog.w(TAG, "Signature mismatch restoring " + packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Signature mismatch");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        // Good to go!  Set up and bind the agent...
+        mAgent = backupManagerService.bindToAgentSynchronous(
+                mCurrentPackage.applicationInfo,
+                ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+        if (mAgent == null) {
+            Slog.w(TAG, "Can't find backup agent for " + packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
+                    "Restore agent missing");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+            return;
+        }
+
+        // Whatever happens next, we've launched the target app now; remember that.
+        mDidLaunch = true;
+
+        // And then finally start the restore on this agent
+        try {
+            initiateOneRestore(mCurrentPackage, metaInfo.versionCode);
+            ++mCount;
+        } catch (Exception e) {
+            Slog.e(TAG, "Error when attempting restore: " + e.toString());
+            keyValueAgentErrorCleanup();
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // Guts of a key/value restore operation
+    void initiateOneRestore(PackageInfo app, int appVersionCode) {
+        final String packageName = app.packageName;
+
+        if (DEBUG) {
+            Slog.d(TAG, "initiateOneRestore packageName=" + packageName);
+        }
+
+        // !!! TODO: get the dirs from the transport
+        mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".restore");
+        mStageName = new File(backupManagerService.getDataDir(), packageName + ".stage");
+        mNewStateName = new File(mStateDir, packageName + ".new");
+        mSavedStateName = new File(mStateDir, packageName);
+
+        // don't stage the 'android' package where the wallpaper data lives.  this is
+        // an optimization: we know there's no widget data hosted/published by that
+        // package, and this way we avoid doing a spurious copy of MB-sized wallpaper
+        // data following the download.
+        boolean staging = !packageName.equals("android");
+        ParcelFileDescriptor stage;
+        File downloadFile = (staging) ? mStageName : mBackupDataName;
+
+        try {
+            // Run the transport's restore pass
+            stage = ParcelFileDescriptor.open(downloadFile,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            if (mTransport.getRestoreData(stage) != BackupTransport.TRANSPORT_OK) {
+                // Transport-level failure, so we wind everything up and
+                // terminate the restore operation.
+                Slog.e(TAG, "Error getting restore data for " + packageName);
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                stage.close();
+                downloadFile.delete();
+                executeNextState(UnifiedRestoreState.FINAL);
+                return;
+            }
+
+            // We have the data from the transport. Now we extract and strip
+            // any per-package metadata (typically widget-related information)
+            // if appropriate
+            if (staging) {
+                stage.close();
+                stage = ParcelFileDescriptor.open(downloadFile,
+                        ParcelFileDescriptor.MODE_READ_ONLY);
+
+                mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                        ParcelFileDescriptor.MODE_READ_WRITE |
+                                ParcelFileDescriptor.MODE_CREATE |
+                                ParcelFileDescriptor.MODE_TRUNCATE);
+
+                BackupDataInput in = new BackupDataInput(stage.getFileDescriptor());
+                BackupDataOutput out = new BackupDataOutput(mBackupData.getFileDescriptor());
+                byte[] buffer = new byte[8192]; // will grow when needed
+                while (in.readNextHeader()) {
+                    final String key = in.getKey();
+                    final int size = in.getDataSize();
+
+                    // is this a special key?
+                    if (key.equals(KEY_WIDGET_STATE)) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Restoring widget state for " + packageName);
+                        }
+                        mWidgetData = new byte[size];
+                        in.readEntityData(mWidgetData, 0, size);
+                    } else {
+                        if (size > buffer.length) {
+                            buffer = new byte[size];
+                        }
+                        in.readEntityData(buffer, 0, size);
+                        out.writeEntityHeader(key, size);
+                        out.writeEntityData(buffer, size);
+                    }
+                }
+
+                mBackupData.close();
+            }
+
+            // Okay, we have the data.  Now have the agent do the restore.
+            stage.close();
+
+            mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                    ParcelFileDescriptor.MODE_READ_ONLY);
+
+            mNewState = ParcelFileDescriptor.open(mNewStateName,
+                    ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+            // Kick off the restore, checking for hung agents.  The timeout or
+            // the operationComplete() callback will schedule the next step,
+            // so we do not do that here.
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_RESTORE_INTERVAL, this, OP_TYPE_RESTORE_WAIT);
+            mAgent.doRestore(mBackupData, appVersionCode, mNewState,
+                    mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
+        } catch (Exception e) {
+            Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                    packageName, e.toString());
+            keyValueAgentErrorCleanup();    // clears any pending timeout messages as well
+
+            // After a restore failure we go back to running the queue.  If there
+            // are no more packages to be restored that will be handled by the
+            // next step.
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // state RESTORE_FULL : restore one package via streaming engine
+    private void restoreFull() {
+        // None of this can run on the work looper here, so we spin asynchronous
+        // work like this:
+        //
+        //   StreamFeederThread: read data from mTransport.getNextFullRestoreDataChunk()
+        //                       write it into the pipe to the engine
+        //   EngineThread: FullRestoreEngine thread communicating with the target app
+        //
+        // When finished, StreamFeederThread executes next state as appropriate on the
+        // backup looper, and the overall unified restore task resumes
+        try {
+            StreamFeederThread feeder = new StreamFeederThread();
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Spinning threads for stream restore of "
+                        + mCurrentPackage.packageName);
+            }
+            new Thread(feeder, "unified-stream-feeder").start();
+
+            // At this point the feeder is responsible for advancing the restore
+            // state, so we're done here.
+        } catch (IOException e) {
+            // Unable to instantiate the feeder thread -- we need to bail on the
+            // current target.  We haven't asked the transport for data yet, though,
+            // so we can do that simply by going back to running the restore queue.
+            Slog.e(TAG, "Unable to construct pipes for stream restore!");
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    // state RESTORE_FINISHED : provide the "no more data" signpost callback at the end
+    private void restoreFinished() {
+        try {
+            backupManagerService
+                    .prepareOperationTimeout(mEphemeralOpToken,
+                            TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
+                            OP_TYPE_RESTORE_WAIT);
+            mAgent.doRestoreFinished(mEphemeralOpToken,
+                    backupManagerService.getBackupManagerBinder());
+            // If we get this far, the callback or timeout will schedule the
+            // next restore state, so we're done
+        } catch (Exception e) {
+            final String packageName = mCurrentPackage.packageName;
+            Slog.e(TAG, "Unable to finalize restore of " + packageName);
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                    packageName, e.toString());
+            keyValueAgentErrorCleanup();
+            executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+        }
+    }
+
+    class StreamFeederThread extends RestoreEngine implements Runnable, BackupRestoreTask {
+
+        final String TAG = "StreamFeederThread";
+        FullRestoreEngine mEngine;
+        EngineThread mEngineThread;
+
+        // pipe through which we read data from the transport. [0] read, [1] write
+        ParcelFileDescriptor[] mTransportPipes;
+
+        // pipe through which the engine will read data.  [0] read, [1] write
+        ParcelFileDescriptor[] mEnginePipes;
+
+        private final int mEphemeralOpToken;
+
+        public StreamFeederThread() throws IOException {
+            mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+            mTransportPipes = ParcelFileDescriptor.createPipe();
+            mEnginePipes = ParcelFileDescriptor.createPipe();
+            setRunning(true);
+        }
+
+        @Override
+        public void run() {
+            UnifiedRestoreState nextState = UnifiedRestoreState.RUNNING_QUEUE;
+            int status = BackupTransport.TRANSPORT_OK;
+
+            EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE,
+                    mCurrentPackage.packageName);
+
+            mEngine = new FullRestoreEngine(backupManagerService, this, null,
+                    mMonitor, mCurrentPackage, false, false, mEphemeralOpToken);
+            mEngineThread = new EngineThread(mEngine, mEnginePipes[0]);
+
+            ParcelFileDescriptor eWriteEnd = mEnginePipes[1];
+            ParcelFileDescriptor tReadEnd = mTransportPipes[0];
+            ParcelFileDescriptor tWriteEnd = mTransportPipes[1];
+
+            int bufferSize = 32 * 1024;
+            byte[] buffer = new byte[bufferSize];
+            FileOutputStream engineOut = new FileOutputStream(eWriteEnd.getFileDescriptor());
+            FileInputStream transportIn = new FileInputStream(tReadEnd.getFileDescriptor());
+
+            // spin up the engine and start moving data to it
+            new Thread(mEngineThread, "unified-restore-engine").start();
+
+            try {
+                while (status == BackupTransport.TRANSPORT_OK) {
+                    // have the transport write some of the restoring data to us
+                    int result = mTransport.getNextFullRestoreDataChunk(tWriteEnd);
+                    if (result > 0) {
+                        // The transport wrote this many bytes of restore data to the
+                        // pipe, so pass it along to the engine.
+                        if (MORE_DEBUG) {
+                            Slog.v(TAG, "  <- transport provided chunk size " + result);
+                        }
+                        if (result > bufferSize) {
+                            bufferSize = result;
+                            buffer = new byte[bufferSize];
+                        }
+                        int toCopy = result;
+                        while (toCopy > 0) {
+                            int n = transportIn.read(buffer, 0, toCopy);
+                            engineOut.write(buffer, 0, n);
+                            toCopy -= n;
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  -> wrote " + n + " to engine, left=" + toCopy);
+                            }
+                        }
+                    } else if (result == BackupTransport.NO_MORE_DATA) {
+                        // Clean finish.  Wind up and we're done!
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Got clean full-restore EOF for "
+                                    + mCurrentPackage.packageName);
+                        }
+                        status = BackupTransport.TRANSPORT_OK;
+                        break;
+                    } else {
+                        // Transport reported some sort of failure; the fall-through
+                        // handling will deal properly with that.
+                        Slog.e(TAG, "Error " + result + " streaming restore for "
+                                + mCurrentPackage.packageName);
+                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                        status = result;
+                    }
+                }
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "Done copying to engine, falling through");
+                }
+            } catch (IOException e) {
+                // We lost our ability to communicate via the pipes.  That's worrying
+                // but potentially recoverable; abandon this package's restore but
+                // carry on with the next restore target.
+                Slog.e(TAG, "Unable to route data for restore");
+                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                        mCurrentPackage.packageName, "I/O error on pipes");
+                status = BackupTransport.AGENT_ERROR;
+            } catch (Exception e) {
+                // The transport threw; terminate the whole operation.  Closing
+                // the sockets will wake up the engine and it will then tidy up the
+                // remote end.
+                Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
+                EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+                status = BackupTransport.TRANSPORT_ERROR;
+            } finally {
+                // Close the transport pipes and *our* end of the engine pipe,
+                // but leave the engine thread's end open so that it properly
+                // hits EOF and winds up its operations.
+                IoUtils.closeQuietly(mEnginePipes[1]);
+                IoUtils.closeQuietly(mTransportPipes[0]);
+                IoUtils.closeQuietly(mTransportPipes[1]);
+
+                // Don't proceed until the engine has wound up operations
+                mEngineThread.waitForResult();
+
+                // Now we're really done with this one too
+                IoUtils.closeQuietly(mEnginePipes[0]);
+
+                // In all cases we want to remember whether we launched
+                // the target app as part of our work so far.
+                mDidLaunch = (mEngine.getAgent() != null);
+
+                // If we hit a transport-level error, we are done with everything;
+                // if we hit an agent error we just go back to running the queue.
+                if (status == BackupTransport.TRANSPORT_OK) {
+                    // Clean finish means we issue the restore-finished callback
+                    nextState = UnifiedRestoreState.RESTORE_FINISHED;
+
+                    // the engine bound the target's agent, so recover that binding
+                    // to use for the callback.
+                    mAgent = mEngine.getAgent();
+
+                    // and the restored widget data, if any
+                    mWidgetData = mEngine.getWidgetData();
+                } else {
+                    // Something went wrong somewhere.  Whether it was at the transport
+                    // level is immaterial; we need to tell the transport to bail
+                    try {
+                        mTransport.abortFullRestore();
+                    } catch (Exception e) {
+                        // transport itself is dead; make sure we handle this as a
+                        // fatal error
+                        Slog.e(TAG, "Transport threw from abortFullRestore: " + e.getMessage());
+                        status = BackupTransport.TRANSPORT_ERROR;
+                    }
+
+                    // We also need to wipe the current target's data, as it's probably
+                    // in an incoherent state.
+                    backupManagerService.clearApplicationDataSynchronous(
+                            mCurrentPackage.packageName);
+
+                    // Schedule the next state based on the nature of our failure
+                    if (status == BackupTransport.TRANSPORT_ERROR) {
+                        nextState = UnifiedRestoreState.FINAL;
+                    } else {
+                        nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                    }
+                }
+                executeNextState(nextState);
+                setRunning(false);
+            }
+        }
+
+        // BackupRestoreTask interface, specifically for timeout handling
+
+        @Override
+        public void execute() { /* intentionally empty */ }
+
+        @Override
+        public void operationComplete(long result) { /* intentionally empty */ }
+
+        // The app has timed out handling a restoring file
+        @Override
+        public void handleCancel(boolean cancelAll) {
+            backupManagerService.removeOperation(mEphemeralOpToken);
+            if (DEBUG) {
+                Slog.w(TAG, "Full-data restore target timed out; shutting down");
+            }
+
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_TIMEOUT,
+                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+            mEngineThread.handleTimeout();
+
+            IoUtils.closeQuietly(mEnginePipes[1]);
+            mEnginePipes[1] = null;
+            IoUtils.closeQuietly(mEnginePipes[0]);
+            mEnginePipes[0] = null;
+        }
+    }
+
+    class EngineThread implements Runnable {
+
+        FullRestoreEngine mEngine;
+        FileInputStream mEngineStream;
+
+        EngineThread(FullRestoreEngine engine, ParcelFileDescriptor engineSocket) {
+            mEngine = engine;
+            engine.setRunning(true);
+            // We *do* want this FileInputStream to own the underlying fd, so that
+            // when we are finished with it, it closes this end of the pipe in a way
+            // that signals its other end.
+            mEngineStream = new FileInputStream(engineSocket.getFileDescriptor(), true);
+        }
+
+        public boolean isRunning() {
+            return mEngine.isRunning();
+        }
+
+        public int waitForResult() {
+            return mEngine.waitForResult();
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (mEngine.isRunning()) {
+                    // Tell it to be sure to leave the agent instance up after finishing
+                    mEngine.restoreOneFile(mEngineStream, false, mEngine.mBuffer,
+                            mEngine.mOnlyPackage, mEngine.mAllowApks, mEngine.mEphemeralOpToken,
+                            mEngine.mMonitor);
+                }
+            } finally {
+                // Because mEngineStream adopted its underlying FD, this also
+                // closes this end of the pipe.
+                IoUtils.closeQuietly(mEngineStream);
+            }
+        }
+
+        public void handleTimeout() {
+            IoUtils.closeQuietly(mEngineStream);
+            mEngine.handleTimeout();
+        }
+    }
+
+    // state FINAL : tear everything down and we're done.
+    private void finalizeRestore() {
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "finishing restore mObserver=" + mObserver);
+        }
+
+        try {
+            mTransport.finishRestore();
+        } catch (Exception e) {
+            Slog.e(TAG, "Error finishing restore", e);
+        }
+
+        // Tell the observer we're done
+        if (mObserver != null) {
+            try {
+                mObserver.restoreFinished(mStatus);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Restore observer died at restoreFinished");
+            }
+        }
+
+        // Clear any ongoing session timeout.
+        backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
+
+        // If we have a PM token, we must under all circumstances be sure to
+        // handshake when we've finished.
+        if (mPmToken > 0) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "finishing PM token " + mPmToken);
+            }
+            try {
+                backupManagerService.getPackageManagerBinder().finishPackageInstall(mPmToken,
+                        mDidLaunch);
+            } catch (RemoteException e) { /* can't happen */ }
+        } else {
+            // We were invoked via an active restore session, not by the Package
+            // Manager, so start up the session timeout again.
+            backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
+                    MSG_RESTORE_SESSION_TIMEOUT,
+                    TIMEOUT_RESTORE_INTERVAL);
+        }
+
+        // Kick off any work that may be needed regarding app widget restores
+        // TODO: http://b/22388012
+        AppWidgetBackupBridge.restoreFinished(UserHandle.USER_SYSTEM);
+
+        // If this was a full-system restore, record the ancestral
+        // dataset information
+        if (mIsSystemRestore && mPmAgent != null) {
+            backupManagerService.setAncestralPackages(mPmAgent.getRestoredPackages());
+            backupManagerService.setAncestralToken(mToken);
+            backupManagerService.writeRestoreTokens();
+        }
+
+        // done; we can finally release the wakelock and be legitimately done.
+        Slog.i(TAG, "Restore complete.");
+
+        synchronized (backupManagerService.getPendingRestores()) {
+            if (backupManagerService.getPendingRestores().size() > 0) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Starting next pending restore.");
+                }
+                PerformUnifiedRestoreTask task = backupManagerService.getPendingRestores().remove();
+                backupManagerService.getBackupHandler().sendMessage(
+                        backupManagerService.getBackupHandler().obtainMessage(
+                                MSG_BACKUP_RESTORE_STEP, task));
+
+            } else {
+                backupManagerService.setRestoreInProgress(false);
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "No pending restores.");
+                }
+            }
+        }
+
+        backupManagerService.getWakelock().release();
+    }
+
+    void keyValueAgentErrorCleanup() {
+        // If the agent fails restore, it might have put the app's data
+        // into an incoherent state.  For consistency we wipe its data
+        // again in this case before continuing with normal teardown
+        backupManagerService.clearApplicationDataSynchronous(mCurrentPackage.packageName);
+        keyValueAgentCleanup();
+    }
+
+    // TODO: clean up naming; this is now used at finish by both k/v and stream restores
+    void keyValueAgentCleanup() {
+        mBackupDataName.delete();
+        mStageName.delete();
+        try {
+            if (mBackupData != null) {
+                mBackupData.close();
+            }
+        } catch (IOException e) {
+        }
+        try {
+            if (mNewState != null) {
+                mNewState.close();
+            }
+        } catch (IOException e) {
+        }
+        mBackupData = mNewState = null;
+
+        // if everything went okay, remember the recorded state now
+        //
+        // !!! TODO: the restored data could be migrated on the server
+        // side into the current dataset.  In that case the new state file
+        // we just created would reflect the data already extant in the
+        // backend, so there'd be nothing more to do.  Until that happens,
+        // however, we need to make sure that we record the data to the
+        // current backend dataset.  (Yes, this means shipping the data over
+        // the wire in both directions.  That's bad, but consistency comes
+        // first, then efficiency.)  Once we introduce server-side data
+        // migration to the newly-restored device's dataset, we will change
+        // the following from a discard of the newly-written state to the
+        // "correct" operation of renaming into the canonical state blob.
+        mNewStateName.delete();                      // TODO: remove; see above comment
+        //mNewStateName.renameTo(mSavedStateName);   // TODO: replace with this
+
+        // If this wasn't the PM pseudopackage, tear down the agent side
+        if (mCurrentPackage.applicationInfo != null) {
+            // unbind and tidy up even on timeout or failure
+            try {
+                backupManagerService.getActivityManager().unbindBackupAgent(
+                        mCurrentPackage.applicationInfo);
+
+                // The agent was probably running with a stub Application object,
+                // which isn't a valid run mode for the main app logic.  Shut
+                // down the app so that next time it's launched, it gets the
+                // usual full initialization.  Note that this is only done for
+                // full-system restores: when a single app has requested a restore,
+                // it is explicitly not killed following that operation.
+                //
+                // We execute this kill when these conditions hold:
+                //    1. it's not a system-uid process,
+                //    2. the app did not request its own restore (mTargetPackage == null), and
+                // either
+                //    3a. the app is a full-data target (TYPE_FULL_STREAM) or
+                //     b. the app does not state android:killAfterRestore="false" in its manifest
+                final int appFlags = mCurrentPackage.applicationInfo.flags;
+                final boolean killAfterRestore =
+                        (mCurrentPackage.applicationInfo.uid >= Process.FIRST_APPLICATION_UID)
+                                && ((mRestoreDescription.getDataType()
+                                == RestoreDescription.TYPE_FULL_STREAM)
+                                || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0));
+
+                if (mTargetPackage == null && killAfterRestore) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Restore complete, killing host process of "
+                                + mCurrentPackage.applicationInfo.processName);
+                    }
+                    backupManagerService.getActivityManager().killApplicationProcess(
+                            mCurrentPackage.applicationInfo.processName,
+                            mCurrentPackage.applicationInfo.uid);
+                }
+            } catch (RemoteException e) {
+                // can't happen; we run in the same process as the activity manager
+            }
+        }
+
+        // The caller is responsible for reestablishing the state machine; our
+        // responsibility here is to clear the decks for whatever comes next.
+        backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_OPERATION_TIMEOUT, this);
+    }
+
+    @Override
+    public void operationComplete(long unusedResult) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "operationComplete() during restore: target="
+                    + mCurrentPackage.packageName
+                    + " state=" + mState);
+        }
+
+        final UnifiedRestoreState nextState;
+        switch (mState) {
+            case INITIAL:
+                // We've just (manually) restored the PMBA.  It doesn't need the
+                // additional restore-finished callback so we bypass that and go
+                // directly to running the queue.
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                break;
+
+            case RESTORE_KEYVALUE:
+            case RESTORE_FULL: {
+                // Okay, we've just heard back from the agent that it's done with
+                // the restore itself.  We now have to send the same agent its
+                // doRestoreFinished() callback, so roll into that state.
+                nextState = UnifiedRestoreState.RESTORE_FINISHED;
+                break;
+            }
+
+            case RESTORE_FINISHED: {
+                // Okay, we're done with this package.  Tidy up and go on to the next
+                // app in the queue.
+                int size = (int) mBackupDataName.length();
+                EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE,
+                        mCurrentPackage.packageName, size);
+
+                // Just go back to running the restore queue
+                keyValueAgentCleanup();
+
+                // If there was widget state associated with this app, get the OS to
+                // incorporate it into current bookeeping and then pass that along to
+                // the app as part of the restore-time work.
+                if (mWidgetData != null) {
+                    backupManagerService.restoreWidgetData(mCurrentPackage.packageName,
+                            mWidgetData);
+                }
+
+                nextState = UnifiedRestoreState.RUNNING_QUEUE;
+                break;
+            }
+
+            default: {
+                // Some kind of horrible semantic error; we're in an unexpected state.
+                // Back off hard and wind up.
+                Slog.e(TAG, "Unexpected restore callback into state " + mState);
+                keyValueAgentErrorCleanup();
+                nextState = UnifiedRestoreState.FINAL;
+                break;
+            }
+        }
+
+        executeNextState(nextState);
+    }
+
+    // A call to agent.doRestore() or agent.doRestoreFinished() has timed out
+    @Override
+    public void handleCancel(boolean cancelAll) {
+        backupManagerService.removeOperation(mEphemeralOpToken);
+        Slog.e(TAG, "Timeout restoring application " + mCurrentPackage.packageName);
+        mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+                BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_RESTORE_TIMEOUT,
+                mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
+        EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                mCurrentPackage.packageName, "restore timeout");
+        // Handle like an agent that threw on invocation: wipe it and go on to the next
+        keyValueAgentErrorCleanup();
+        executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
+    }
+
+    void executeNextState(UnifiedRestoreState nextState) {
+        if (MORE_DEBUG) {
+            Slog.i(TAG, " => executing next step on "
+                    + this + " nextState=" + nextState);
+        }
+        mState = nextState;
+        Message msg = backupManagerService.getBackupHandler().obtainMessage(
+                MSG_BACKUP_RESTORE_STEP, this);
+        backupManagerService.getBackupHandler().sendMessage(msg);
+    }
+
+    // restore observer support
+    void sendStartRestore(int numPackages) {
+        if (mObserver != null) {
+            try {
+                mObserver.restoreStarting(numPackages);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Restore observer went away: startRestore");
+                mObserver = null;
+            }
+        }
+    }
+
+    void sendOnRestorePackage(String name) {
+        if (mObserver != null) {
+            if (mObserver != null) {
+                try {
+                    mObserver.onUpdate(mCount, name);
+                } catch (RemoteException e) {
+                    Slog.d(TAG, "Restore observer died in onUpdate");
+                    mObserver = null;
+                }
+            }
+        }
+    }
+
+    void sendEndRestore() {
+        if (mObserver != null) {
+            try {
+                mObserver.restoreFinished(mStatus);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Restore observer went away: endRestore");
+                mObserver = null;
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java b/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java
new file mode 100644
index 0000000..12be84c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreDeleteObserver.java
@@ -0,0 +1,69 @@
+/*
+ * 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.backup.restore;
+
+import android.content.pm.IPackageDeleteObserver;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Synchronous implementation of IPackageDeleteObserver.Stub.
+ *
+ * Allows the caller to synchronously wait for package deleted event.
+ */
+public class RestoreDeleteObserver extends IPackageDeleteObserver.Stub {
+
+    @GuardedBy("mDone")
+    private final AtomicBoolean mDone = new AtomicBoolean();
+
+    public RestoreDeleteObserver() {
+    }
+
+    /**
+     * Resets the observer to prepare for another removal.
+     */
+    public void reset() {
+        synchronized (mDone) {
+            mDone.set(false);
+        }
+    }
+
+    /**
+     * Synchronously waits for completion.
+     */
+    public void waitForCompletion() {
+        synchronized (mDone) {
+            while (mDone.get() == false) {
+                try {
+                    mDone.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    @Override
+    public void packageDeleted(String packageName, int returnCode) throws RemoteException {
+        synchronized (mDone) {
+            mDone.set(true);
+            mDone.notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreEngine.java b/services/backup/java/com/android/server/backup/restore/RestoreEngine.java
new file mode 100644
index 0000000..b2fdbb8
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreEngine.java
@@ -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
+ */
+
+package com.android.server.backup.restore;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Restore infrastructure.
+ */
+public abstract class RestoreEngine {
+
+    private static final String TAG = "RestoreEngine";
+
+    public static final int SUCCESS = 0;
+    public static final int TARGET_FAILURE = -2;
+    public static final int TRANSPORT_FAILURE = -3;
+
+    private AtomicBoolean mRunning = new AtomicBoolean(false);
+    private AtomicInteger mResult = new AtomicInteger(SUCCESS);
+
+    public boolean isRunning() {
+        return mRunning.get();
+    }
+
+    public void setRunning(boolean stillRunning) {
+        synchronized (mRunning) {
+            mRunning.set(stillRunning);
+            mRunning.notifyAll();
+        }
+    }
+
+    public int waitForResult() {
+        synchronized (mRunning) {
+            while (isRunning()) {
+                try {
+                    mRunning.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        return getResult();
+    }
+
+    public int getResult() {
+        return mResult.get();
+    }
+
+    public void setResult(int result) {
+        mResult.set(result);
+    }
+
+    // TODO: abstract restore state and APIs
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java b/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java
new file mode 100644
index 0000000..6c9a222
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreFileRunnable.java
@@ -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
+ */
+
+package com.android.server.backup.restore;
+
+import android.app.IBackupAgent;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import java.io.IOException;
+
+/**
+ * Runner that can be placed in a separate thread to do in-process invocations of the full restore
+ * API asynchronously. Used by adb restore.
+ */
+class RestoreFileRunnable implements Runnable {
+
+    private final IBackupAgent mAgent;
+    private final FileMetadata mInfo;
+    private final ParcelFileDescriptor mSocket;
+    private final int mToken;
+    private final RefactoredBackupManagerService mBackupManagerService;
+
+    RestoreFileRunnable(RefactoredBackupManagerService backupManagerService, IBackupAgent agent,
+            FileMetadata info, ParcelFileDescriptor socket, int token) throws IOException {
+        mAgent = agent;
+        mInfo = info;
+        mToken = token;
+
+        // This class is used strictly for process-local binder invocations.  The
+        // semantics of ParcelFileDescriptor differ in this case; in particular, we
+        // do not automatically get a 'dup'ed descriptor that we can can continue
+        // to use asynchronously from the caller.  So, we make sure to dup it ourselves
+        // before proceeding to do the restore.
+        mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
+        this.mBackupManagerService = backupManagerService;
+    }
+
+    @Override
+    public void run() {
+        try {
+            mAgent.doRestoreFile(mSocket, mInfo.size, mInfo.type,
+                    mInfo.domain, mInfo.path, mInfo.mode, mInfo.mtime,
+                    mToken, mBackupManagerService.getBackupManagerBinder());
+        } catch (RemoteException e) {
+            // never happens; this is used strictly for local binder calls
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java b/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java
new file mode 100644
index 0000000..3d506f1
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestoreInstallObserver.java
@@ -0,0 +1,89 @@
+/*
+ * 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.backup.restore;
+
+import android.app.PackageInstallObserver;
+import android.os.Bundle;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Synchronous implementation of PackageInstallObserver.
+ *
+ * Allows the caller to synchronously wait for package install event.
+ */
+public class RestoreInstallObserver extends PackageInstallObserver {
+
+    @GuardedBy("mDone")
+    private final AtomicBoolean mDone = new AtomicBoolean();
+
+    private String mPackageName;
+    private int mResult;
+
+    public RestoreInstallObserver() {
+    }
+
+    /**
+     * Resets the observer to prepare for another installation.
+     */
+    public void reset() {
+        synchronized (mDone) {
+            mDone.set(false);
+        }
+    }
+
+    /**
+     * Synchronously waits for completion.
+     */
+    public void waitForCompletion() {
+        synchronized (mDone) {
+            while (mDone.get() == false) {
+                try {
+                    mDone.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns result code.
+     */
+    public int getResult() {
+        return mResult;
+    }
+
+    /**
+     * Returns installed package name.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    @Override
+    public void onPackageInstalled(String packageName, int returnCode,
+            String msg, Bundle extras) {
+        synchronized (mDone) {
+            mResult = returnCode;
+            mPackageName = packageName;
+            mDone.set(true);
+            mDone.notifyAll();
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/restore/RestorePolicy.java b/services/backup/java/com/android/server/backup/restore/RestorePolicy.java
new file mode 100644
index 0000000..db25472
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/RestorePolicy.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.server.backup.restore;
+
+/**
+ * Full restore from a file/socket.
+ */
+public enum RestorePolicy {
+    IGNORE,
+    ACCEPT,
+    ACCEPT_IF_APK
+}
diff --git a/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java b/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java
new file mode 100644
index 0000000..f5bff5e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/restore/UnifiedRestoreState.java
@@ -0,0 +1,29 @@
+/*
+ * 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.backup.restore;
+
+/**
+ * States of the unified-restore state machine.
+ */
+public enum UnifiedRestoreState {
+    INITIAL,
+    RUNNING_QUEUE,
+    RESTORE_KEYVALUE,
+    RESTORE_FULL,
+    RESTORE_FINISHED,
+    FINAL
+}
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
new file mode 100644
index 0000000..c033d98
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -0,0 +1,149 @@
+/*
+ * 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.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Process;
+import android.util.Slog;
+
+/**
+ * Utility methods wrapping operations on ApplicationInfo and PackageInfo.
+ */
+public class AppBackupUtils {
+    /**
+     * Returns whether app is eligible for backup.
+     *
+     * High level policy: apps are generally ineligible for backup if certain conditions apply. The
+     * conditions are:
+     *
+     * <ol>
+     *     <li>their manifest states android:allowBackup="false"
+     *     <li>they run as a system-level uid but do not supply their own backup agent
+     *     <li>it is the special shared-storage backup package used for 'adb backup'
+     * </ol>
+     */
+    public static boolean appIsEligibleForBackup(ApplicationInfo app) {
+        // 1. their manifest states android:allowBackup="false"
+        if ((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+            return false;
+        }
+
+        // 2. they run as a system-level uid but do not supply their own backup agent
+        if ((app.uid < Process.FIRST_APPLICATION_UID) && (app.backupAgentName == null)) {
+            return false;
+        }
+
+        // 3. it is the special shared-storage backup package used for 'adb backup'
+        if (app.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks if the app is in a stopped state, that means it won't receive broadcasts.
+     */
+    public static boolean appIsStopped(ApplicationInfo app) {
+        return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
+    }
+
+    /**
+     * Returns whether the app can get full backup. Does *not* check overall backup eligibility
+     * policy!
+     */
+    public static boolean appGetsFullBackup(PackageInfo pkg) {
+        if (pkg.applicationInfo.backupAgentName != null) {
+            // If it has an agent, it gets full backups only if it says so
+            return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0;
+        }
+
+        // No agent or fullBackupOnly="true" means we do indeed perform full-data backups for it
+        return true;
+    }
+
+    /**
+     * Returns whether the app is only capable of doing key/value. We say it's not if it allows full
+     * backup, and it is otherwise.
+     */
+    public static boolean appIsKeyValueOnly(PackageInfo pkg) {
+        return !appGetsFullBackup(pkg);
+    }
+
+    /**
+     * Old style: directly match the stored vs on device signature blocks.
+     */
+    // TODO(b/37977154): Resolve questionable policies.
+    public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) {
+        if (target == null) {
+            return false;
+        }
+
+        // If the target resides on the system partition, we allow it to restore
+        // data from the like-named package in a restore set even if the signatures
+        // do not match.  (Unlike general applications, those flashed to the system
+        // partition will be signed with the device's platform certificate, so on
+        // different phones the same system app will have different signatures.)
+        if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "System app " + target.packageName + " - skipping sig check");
+            }
+            return true;
+        }
+
+        // Allow unsigned apps, but not signed on one device and unsigned on the other
+        // TODO(b/37977154): is this the right policy?
+        Signature[] deviceSigs = target.signatures;
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs);
+        }
+        if ((storedSigs == null || storedSigs.length == 0)
+                && (deviceSigs == null || deviceSigs.length == 0)) {
+            return true;
+        }
+        // TODO(b/37977154): This allows empty stored signature, is this right?
+        if (storedSigs == null || deviceSigs == null) {
+            return false;
+        }
+
+        // TODO(b/37977154): this demands that every stored signature match one
+        // that is present on device, and does not demand the converse.
+        // Is this this right policy?
+        int nStored = storedSigs.length;
+        int nDevice = deviceSigs.length;
+
+        for (int i = 0; i < nStored; i++) {
+            boolean match = false;
+            for (int j = 0; j < nDevice; j++) {
+                if (storedSigs[i].equals(deviceSigs[j])) {
+                    match = true;
+                    break;
+                }
+            }
+            if (!match) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
new file mode 100644
index 0000000..734fa1d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -0,0 +1,124 @@
+/*
+ * 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.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.PackageInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with BackupManagerMonitor.
+ */
+public class BackupManagerMonitorUtils {
+    /**
+     * Notifies monitor about the event.
+     *
+     * Calls {@link IBackupManagerMonitor#onEvent(Bundle)} with a bundle representing current event.
+     *
+     * @param monitor - implementation of {@link IBackupManagerMonitor} to notify.
+     * @param id - event id.
+     * @param pkg - package event is related to.
+     * @param category - event category.
+     * @param extras - additional event data.
+     * @return <code>monitor</code> if call succeeded and <code>null</code> otherwise.
+     */
+    public static IBackupManagerMonitor monitorEvent(IBackupManagerMonitor monitor, int id,
+            PackageInfo pkg, int category, Bundle extras) {
+        if (monitor != null) {
+            try {
+                Bundle bundle = new Bundle();
+                bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, id);
+                bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, category);
+                if (pkg != null) {
+                    bundle.putString(EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            pkg.packageName);
+                    bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION,
+                            pkg.versionCode);
+                }
+                if (extras != null) {
+                    bundle.putAll(extras);
+                }
+                monitor.onEvent(bundle);
+                return monitor;
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "backup manager monitor went away");
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, String value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putString(key, value);
+        return extras;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, long value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putLong(key, value);
+        return extras;
+    }
+
+    /**
+     * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
+     * be created.
+     *
+     * @param extras - bundle where to add key-value to, if null a new bundle will be created.
+     * @param key - key.
+     * @param value - value.
+     * @return extras if it was not null and new bundle otherwise.
+     */
+    public static Bundle putMonitoringExtra(Bundle extras, String key, boolean value) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putBoolean(key, value);
+        return extras;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
new file mode 100644
index 0000000..3be1e33
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.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 com.android.server.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupProgress;
+import android.app.backup.IBackupObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with BackupObserver.
+ */
+public class BackupObserverUtils {
+    /**
+     * Wraps {@link IBackupObserver#onUpdate(String, BackupProgress)} to handle RemoteException,
+     * so that the caller doesn't have to.
+     */
+    public static void sendBackupOnUpdate(IBackupObserver observer, String packageName,
+            BackupProgress progress) {
+        if (observer != null) {
+            try {
+                observer.onUpdate(packageName, progress);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onUpdate");
+                }
+            }
+        }
+    }
+
+    /**
+     * Wraps {@link IBackupObserver#onResult(String, int)} to handle RemoteException, so that the
+     * caller doesn't have to.
+     */
+    public static void sendBackupOnPackageResult(IBackupObserver observer, String packageName,
+            int status) {
+        if (observer != null) {
+            try {
+                observer.onResult(packageName, status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onResult");
+                }
+            }
+        }
+    }
+
+    /**
+     * Wraps {@link IBackupObserver#backupFinished(int)} to handle RemoteException, so that the
+     * caller doesn't have to.
+     */
+    public static void sendBackupFinished(IBackupObserver observer, int status) {
+        if (observer != null) {
+            try {
+                observer.backupFinished(status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: backupFinished");
+                }
+            }
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/BytesReadListener.java b/services/backup/java/com/android/server/backup/utils/BytesReadListener.java
new file mode 100644
index 0000000..34d85ff
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/BytesReadListener.java
@@ -0,0 +1,28 @@
+/*
+ * 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.backup.utils;
+
+/**
+ * Listener for bytes reading.
+ */
+public interface BytesReadListener {
+    /**
+     * Will be called on each read operation.
+     * @param bytesRead - number of bytes read with the most recent read operation.
+     */
+    void onBytesRead(long bytesRead);
+}
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
new file mode 100644
index 0000000..089109e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
@@ -0,0 +1,88 @@
+/*
+ * 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.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Utility methods to communicate with FullBackupRestoreObserver.
+ */
+public class FullBackupRestoreObserverUtils {
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onStartRestore()} to handle RemoteException, so that
+     * the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendStartRestore(IFullBackupRestoreObserver observer) {
+        if (observer != null) {
+            try {
+                observer.onStartRestore();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: startRestore");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onRestorePackage(String)} to handle RemoteException,
+     * so that the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @param name - package name.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendOnRestorePackage(
+            IFullBackupRestoreObserver observer, String name) {
+        if (observer != null) {
+            try {
+                // TODO: use a more user-friendly name string
+                observer.onRestorePackage(name);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: restorePackage");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+
+    /**
+     * Wraps {@link IFullBackupRestoreObserver#onEndRestore()} ()} to handle RemoteException, so
+     * that the caller doesn't have to.
+     *
+     * @param observer - IFullBackupRestoreObserver to communicate with.
+     * @return observer if the call worked and null if there was a communication problem.
+     */
+    public static IFullBackupRestoreObserver sendEndRestore(IFullBackupRestoreObserver observer) {
+        if (observer != null) {
+            try {
+                observer.onEndRestore();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "full restore observer went away: endRestore");
+                observer = null;
+            }
+        }
+        return observer;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
new file mode 100644
index 0000000..b3e20dc
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -0,0 +1,127 @@
+/*
+ * 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.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.util.Slog;
+import android.util.StringBuilderPrinter;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Low-level utility methods for full backup.
+ */
+public class FullBackupUtils {
+    /**
+     * Reads data from pipe and writes it to the stream in chunks of up to 32KB.
+     *
+     * @param inPipe - pipe to read the data from.
+     * @param out - stream to write the data to.
+     * @throws IOException - in case of an error.
+     */
+    public static void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
+            throws IOException {
+        // We do not take close() responsibility for the pipe FD
+        FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
+        DataInputStream in = new DataInputStream(raw);
+
+        byte[] buffer = new byte[32 * 1024];
+        int chunkTotal;
+        while ((chunkTotal = in.readInt()) > 0) {
+            while (chunkTotal > 0) {
+                int toRead = (chunkTotal > buffer.length) ? buffer.length : chunkTotal;
+                int nRead = in.read(buffer, 0, toRead);
+                if (nRead < 0) {
+                    Slog.e(TAG, "Unexpectedly reached end of file while reading data");
+                    throw new EOFException();
+                }
+                out.write(buffer, 0, nRead);
+                chunkTotal -= nRead;
+            }
+        }
+    }
+
+    /**
+     * Writes app manifest to the given manifest file.
+     *
+     * @param pkg - app package, which manifest to write.
+     * @param packageManager - {@link PackageManager} instance.
+     * @param manifestFile - target manifest file.
+     * @param withApk - whether include apk or not.
+     * @param withWidgets - whether to write widgets data.
+     * @throws IOException - in case of an error.
+     */
+    // TODO: withWidgets is not used, decide whether it is needed.
+    public static void writeAppManifest(PackageInfo pkg, PackageManager packageManager,
+            File manifestFile, boolean withApk, boolean withWidgets) throws IOException {
+        // Manifest format. All data are strings ending in LF:
+        //     BACKUP_MANIFEST_VERSION, currently 1
+        //
+        // Version 1:
+        //     package name
+        //     package's versionCode
+        //     platform versionCode
+        //     getInstallerPackageName() for this package (maybe empty)
+        //     boolean: "1" if archive includes .apk; any other string means not
+        //     number of signatures == N
+        // N*:    signature byte array in ascii format per Signature.toCharsString()
+        StringBuilder builder = new StringBuilder(4096);
+        StringBuilderPrinter printer = new StringBuilderPrinter(builder);
+
+        printer.println(Integer.toString(BACKUP_MANIFEST_VERSION));
+        printer.println(pkg.packageName);
+        printer.println(Integer.toString(pkg.versionCode));
+        printer.println(Integer.toString(Build.VERSION.SDK_INT));
+
+        String installerName = packageManager.getInstallerPackageName(pkg.packageName);
+        printer.println((installerName != null) ? installerName : "");
+
+        printer.println(withApk ? "1" : "0");
+        if (pkg.signatures == null) {
+            printer.println("0");
+        } else {
+            printer.println(Integer.toString(pkg.signatures.length));
+            for (Signature sig : pkg.signatures) {
+                printer.println(sig.toCharsString());
+            }
+        }
+
+        FileOutputStream outstream = new FileOutputStream(manifestFile);
+        outstream.write(builder.toString().getBytes());
+        outstream.close();
+
+        // We want the manifest block in the archive stream to be idempotent:
+        // each time we generate a backup stream for the app, we want the manifest
+        // block to be identical.  The underlying tar mechanism sees it as a file,
+        // though, and will propagate its mtime, causing the tar header to vary.
+        // Avoid this problem by pinning the mtime to zero.
+        manifestFile.setLastModified(0);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/PasswordUtils.java b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
new file mode 100644
index 0000000..12fc927
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
@@ -0,0 +1,136 @@
+/*
+ * 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.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.util.Slog;
+
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Passwords related utility methods.
+ */
+public class PasswordUtils {
+    // Configuration of PBKDF2 that we use for generating pw hashes and intermediate keys
+    public static final int PBKDF2_HASH_ROUNDS = 10000;
+    private static final int PBKDF2_KEY_SIZE = 256;     // bits
+    public static final int PBKDF2_SALT_SIZE = 512;    // bits
+    public static final String ENCRYPTION_ALGORITHM_NAME = "AES-256";
+
+    /**
+     * Creates {@link SecretKey} instance from given parameters.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pw - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return {@link SecretKey} instance or null in case of an error.
+     */
+    public static SecretKey buildPasswordKey(String algorithm, String pw, byte[] salt, int rounds) {
+        return buildCharArrayKey(algorithm, pw.toCharArray(), salt, rounds);
+    }
+
+    /**
+     * Generates {@link SecretKey} instance from given parameters and returns it's hex
+     * representation.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pw - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return Hex representation of the generated key, or null if generation failed.
+     */
+    public static String buildPasswordHash(String algorithm, String pw, byte[] salt, int rounds) {
+        SecretKey key = buildPasswordKey(algorithm, pw, salt, rounds);
+        if (key != null) {
+            return byteArrayToHex(key.getEncoded());
+        }
+        return null;
+    }
+
+    /**
+     * Creates hex string representation of the byte array.
+     */
+    public static String byteArrayToHex(byte[] data) {
+        StringBuilder buf = new StringBuilder(data.length * 2);
+        for (int i = 0; i < data.length; i++) {
+            buf.append(Byte.toHexString(data[i], true));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Creates byte array from it's hex string representation.
+     */
+    public static byte[] hexToByteArray(String digits) {
+        final int bytes = digits.length() / 2;
+        if (2 * bytes != digits.length()) {
+            throw new IllegalArgumentException("Hex string must have an even number of digits");
+        }
+
+        byte[] result = new byte[bytes];
+        for (int i = 0; i < digits.length(); i += 2) {
+            result[i / 2] = (byte) Integer.parseInt(digits.substring(i, i + 2), 16);
+        }
+        return result;
+    }
+
+    /**
+     * Generates {@link SecretKey} instance from given parameters and returns it's checksum.
+     *
+     * Current implementation returns the key in its primary encoding format.
+     *
+     * @param algorithm - key generation algorithm.
+     * @param pwBytes - password.
+     * @param salt - salt.
+     * @param rounds - number of rounds to run in key generation.
+     * @return Hex representation of the generated key, or null if generation failed.
+     */
+    public static byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt,
+            int rounds) {
+        char[] mkAsChar = new char[pwBytes.length];
+        for (int i = 0; i < pwBytes.length; i++) {
+            mkAsChar[i] = (char) pwBytes[i];
+        }
+
+        Key checksum = buildCharArrayKey(algorithm, mkAsChar, salt, rounds);
+        return checksum.getEncoded();
+    }
+
+    private static SecretKey buildCharArrayKey(String algorithm, char[] pwArray, byte[] salt,
+            int rounds) {
+        try {
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
+            KeySpec
+                    ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE);
+            return keyFactory.generateSecret(ks);
+        } catch (InvalidKeySpecException e) {
+            Slog.e(TAG, "Invalid key spec for PBKDF2!");
+        } catch (NoSuchAlgorithmException e) {
+            Slog.e(TAG, "PBKDF2 unavailable!");
+        }
+        return null;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
new file mode 100644
index 0000000..ee4201e
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -0,0 +1,178 @@
+/*
+ * 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.backup.utils;
+
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.net.Uri;
+import android.os.Process;
+import android.util.Slog;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.restore.RestoreDeleteObserver;
+import com.android.server.backup.restore.RestoreInstallObserver;
+import com.android.server.backup.restore.RestorePolicy;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+/**
+ * Utility methods used by {@link com.android.server.backup.restore.PerformAdbRestoreTask} and
+ * {@link com.android.server.backup.restore.FullRestoreEngine}.
+ */
+public class RestoreUtils {
+    /**
+     * Reads apk contents from input stream and installs the apk.
+     *
+     * @param instream - input stream to read apk data from.
+     * @param packageManager - {@link PackageManager} instance.
+     * @param installObserver - {@link RestoreInstallObserver} instance.
+     * @param deleteObserver - {@link RestoreDeleteObserver} instance.
+     * @param manifestSignatures - manifest signatures.
+     * @param packagePolicies - package policies.
+     * @param info - backup file info.
+     * @param installerPackage - installer package.
+     * @param bytesReadListener - listener to be called for counting bytes read.
+     * @param dataDir - directory where to create apk file.
+     * @return true if apk was successfully read and installed and false otherwise.
+     */
+    // TODO: Refactor to get rid of unneeded params.
+    public static boolean installApk(InputStream instream, PackageManager packageManager,
+            RestoreInstallObserver installObserver, RestoreDeleteObserver deleteObserver,
+            HashMap<String, Signature[]> manifestSignatures,
+            HashMap<String, RestorePolicy> packagePolicies,
+            FileMetadata info,
+            String installerPackage, BytesReadListener bytesReadListener,
+            File dataDir) {
+        boolean okay = true;
+
+        if (DEBUG) {
+            Slog.d(TAG, "Installing from backup: " + info.packageName);
+        }
+
+        // The file content is an .apk file.  Copy it out to a staging location and
+        // attempt to install it.
+        File apkFile = new File(dataDir, info.packageName);
+        try {
+            FileOutputStream apkStream = new FileOutputStream(apkFile);
+            byte[] buffer = new byte[32 * 1024];
+            long size = info.size;
+            while (size > 0) {
+                long toRead = (buffer.length < size) ? buffer.length : size;
+                int didRead = instream.read(buffer, 0, (int) toRead);
+                if (didRead >= 0) {
+                    bytesReadListener.onBytesRead(didRead);
+                }
+                apkStream.write(buffer, 0, didRead);
+                size -= didRead;
+            }
+            apkStream.close();
+
+            // make sure the installer can read it
+            apkFile.setReadable(true, false);
+
+            // Now install it
+            Uri packageUri = Uri.fromFile(apkFile);
+            installObserver.reset();
+            // TODO: PackageManager.installPackage() is deprecated, refactor.
+            packageManager.installPackage(packageUri, installObserver,
+                    PackageManager.INSTALL_REPLACE_EXISTING | PackageManager.INSTALL_FROM_ADB,
+                    installerPackage);
+            installObserver.waitForCompletion();
+
+            if (installObserver.getResult() != PackageManager.INSTALL_SUCCEEDED) {
+                // The only time we continue to accept install of data even if the
+                // apk install failed is if we had already determined that we could
+                // accept the data regardless.
+                if (packagePolicies.get(info.packageName) != RestorePolicy.ACCEPT) {
+                    okay = false;
+                }
+            } else {
+                // Okay, the install succeeded.  Make sure it was the right app.
+                boolean uninstall = false;
+                if (!installObserver.getPackageName().equals(info.packageName)) {
+                    Slog.w(TAG, "Restore stream claimed to include apk for "
+                            + info.packageName + " but apk was really "
+                            + installObserver.getPackageName());
+                    // delete the package we just put in place; it might be fraudulent
+                    okay = false;
+                    uninstall = true;
+                } else {
+                    try {
+                        PackageInfo pkg = packageManager.getPackageInfo(
+                                info.packageName,
+                                PackageManager.GET_SIGNATURES);
+                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
+                                == 0) {
+                            Slog.w(TAG, "Restore stream contains apk of package "
+                                    + info.packageName
+                                    + " but it disallows backup/restore");
+                            okay = false;
+                        } else {
+                            // So far so good -- do the signatures match the manifest?
+                            Signature[] sigs = manifestSignatures.get(info.packageName);
+                            if (AppBackupUtils.signaturesMatch(sigs, pkg)) {
+                                // If this is a system-uid app without a declared backup agent,
+                                // don't restore any of the file data.
+                                if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
+                                        && (pkg.applicationInfo.backupAgentName == null)) {
+                                    Slog.w(TAG, "Installed app " + info.packageName
+                                            + " has restricted uid and no agent");
+                                    okay = false;
+                                }
+                            } else {
+                                Slog.w(TAG, "Installed app " + info.packageName
+                                        + " signatures do not match restore manifest");
+                                okay = false;
+                                uninstall = true;
+                            }
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Slog.w(TAG, "Install of package " + info.packageName
+                                + " succeeded but now not found");
+                        okay = false;
+                    }
+                }
+
+                // If we're not okay at this point, we need to delete the package
+                // that we just installed.
+                if (uninstall) {
+                    deleteObserver.reset();
+                    packageManager.deletePackage(
+                            installObserver.getPackageName(),
+                            deleteObserver, 0);
+                    deleteObserver.waitForCompletion();
+                }
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to transcribe restored apk for install");
+            okay = false;
+        } finally {
+            apkFile.delete();
+        }
+
+        return okay;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
new file mode 100644
index 0000000..2910ba2
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -0,0 +1,798 @@
+/*
+ * 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.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_MANIFEST_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_OLD_VERSION;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_POLICY_ALLOW_APKS;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_EXPECTED_DIFFERENT_PACKAGE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_MISSING_SIGNATURE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
+import android.app.backup.BackupAgent;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.FullBackup;
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Slog;
+
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.restore.RestorePolicy;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility methods to read backup tar file.
+ */
+public class TarBackupReader {
+    private static final int TAR_HEADER_OFFSET_TYPE_CHAR = 156;
+    private static final int TAR_HEADER_LENGTH_PATH = 100;
+    private static final int TAR_HEADER_OFFSET_PATH = 0;
+    private static final int TAR_HEADER_LENGTH_PATH_PREFIX = 155;
+    private static final int TAR_HEADER_OFFSET_PATH_PREFIX = 345;
+    private static final int TAR_HEADER_LENGTH_MODE = 8;
+    private static final int TAR_HEADER_OFFSET_MODE = 100;
+    private static final int TAR_HEADER_LENGTH_MODTIME = 12;
+    private static final int TAR_HEADER_OFFSET_MODTIME = 136;
+    private static final int TAR_HEADER_LENGTH_FILESIZE = 12;
+    private static final int TAR_HEADER_OFFSET_FILESIZE = 124;
+    private static final int TAR_HEADER_LONG_RADIX = 8;
+
+    private final InputStream mInputStream;
+    private final BytesReadListener mBytesReadListener;
+
+    private IBackupManagerMonitor mMonitor;
+
+    // Widget blob to be restored out-of-band.
+    private byte[] mWidgetData = null;
+
+    public TarBackupReader(InputStream inputStream, BytesReadListener bytesReadListener,
+            IBackupManagerMonitor monitor) {
+        mInputStream = inputStream;
+        mBytesReadListener = bytesReadListener;
+        mMonitor = monitor;
+    }
+
+    /**
+     * Consumes a tar file header block [sequence] and accumulates the relevant metadata.
+     */
+    public FileMetadata readTarHeaders() throws IOException {
+        byte[] block = new byte[512];
+        FileMetadata info = null;
+
+        boolean gotHeader = readTarHeader(block);
+        if (gotHeader) {
+            try {
+                // okay, presume we're okay, and extract the various metadata
+                info = new FileMetadata();
+                info.size = extractRadix(block,
+                        TAR_HEADER_OFFSET_FILESIZE,
+                        TAR_HEADER_LENGTH_FILESIZE,
+                        TAR_HEADER_LONG_RADIX);
+                info.mtime = extractRadix(block,
+                        TAR_HEADER_OFFSET_MODTIME,
+                        TAR_HEADER_LENGTH_MODTIME,
+                        TAR_HEADER_LONG_RADIX);
+                info.mode = extractRadix(block,
+                        TAR_HEADER_OFFSET_MODE,
+                        TAR_HEADER_LENGTH_MODE,
+                        TAR_HEADER_LONG_RADIX);
+
+                info.path = extractString(block,
+                        TAR_HEADER_OFFSET_PATH_PREFIX,
+                        TAR_HEADER_LENGTH_PATH_PREFIX);
+                String path = extractString(block,
+                        TAR_HEADER_OFFSET_PATH,
+                        TAR_HEADER_LENGTH_PATH);
+                if (path.length() > 0) {
+                    if (info.path.length() > 0) {
+                        info.path += '/';
+                    }
+                    info.path += path;
+                }
+
+                // tar link indicator field: 1 byte at offset 156 in the header.
+                int typeChar = block[TAR_HEADER_OFFSET_TYPE_CHAR];
+                if (typeChar == 'x') {
+                    // pax extended header, so we need to read that
+                    gotHeader = readPaxExtendedHeader(info);
+                    if (gotHeader) {
+                        // and after a pax extended header comes another real header -- read
+                        // that to find the real file type
+                        gotHeader = readTarHeader(block);
+                    }
+                    if (!gotHeader) {
+                        throw new IOException("Bad or missing pax header");
+                    }
+
+                    typeChar = block[TAR_HEADER_OFFSET_TYPE_CHAR];
+                }
+
+                switch (typeChar) {
+                    case '0':
+                        info.type = BackupAgent.TYPE_FILE;
+                        break;
+                    case '5': {
+                        info.type = BackupAgent.TYPE_DIRECTORY;
+                        if (info.size != 0) {
+                            Slog.w(TAG, "Directory entry with nonzero size in header");
+                            info.size = 0;
+                        }
+                        break;
+                    }
+                    case 0: {
+                        // presume EOF
+                        if (MORE_DEBUG) {
+                            Slog.w(TAG, "Saw type=0 in tar header block, info=" + info);
+                        }
+                        return null;
+                    }
+                    default: {
+                        Slog.e(TAG, "Unknown tar entity type: " + typeChar);
+                        throw new IOException("Unknown entity type " + typeChar);
+                    }
+                }
+
+                // Parse out the path
+                //
+                // first: apps/shared/unrecognized
+                if (FullBackup.SHARED_PREFIX.regionMatches(0,
+                        info.path, 0, FullBackup.SHARED_PREFIX.length())) {
+                    // File in shared storage.  !!! TODO: implement this.
+                    info.path = info.path.substring(FullBackup.SHARED_PREFIX.length());
+                    info.packageName = SHARED_BACKUP_AGENT_PACKAGE;
+                    info.domain = FullBackup.SHARED_STORAGE_TOKEN;
+                    if (DEBUG) {
+                        Slog.i(TAG, "File in shared storage: " + info.path);
+                    }
+                } else if (FullBackup.APPS_PREFIX.regionMatches(0,
+                        info.path, 0, FullBackup.APPS_PREFIX.length())) {
+                    // App content!  Parse out the package name and domain
+
+                    // strip the apps/ prefix
+                    info.path = info.path.substring(FullBackup.APPS_PREFIX.length());
+
+                    // extract the package name
+                    int slash = info.path.indexOf('/');
+                    if (slash < 0) {
+                        throw new IOException("Illegal semantic path in " + info.path);
+                    }
+                    info.packageName = info.path.substring(0, slash);
+                    info.path = info.path.substring(slash + 1);
+
+                    // if it's a manifest or metadata payload we're done, otherwise parse
+                    // out the domain into which the file will be restored
+                    if (!info.path.equals(BACKUP_MANIFEST_FILENAME) &&
+                            !info.path.equals(BACKUP_METADATA_FILENAME)) {
+                        slash = info.path.indexOf('/');
+                        if (slash < 0) {
+                            throw new IOException("Illegal semantic path in non-manifest "
+                                    + info.path);
+                        }
+                        info.domain = info.path.substring(0, slash);
+                        info.path = info.path.substring(slash + 1);
+                    }
+                }
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Slog.e(TAG, "Parse error in header: " + e.getMessage());
+                    if (MORE_DEBUG) {
+                        hexLog(block);
+                    }
+                }
+                throw e;
+            }
+        }
+        return info;
+    }
+
+    /**
+     * Tries to read exactly the given number of bytes into a buffer at the stated offset.
+     *
+     * @param in - input stream to read bytes from..
+     * @param buffer - where to write bytes to.
+     * @param offset - offset in buffer to write bytes to.
+     * @param size - number of bytes to read.
+     * @return number of bytes actually read.
+     * @throws IOException in case of an error.
+     */
+    private static int readExactly(InputStream in, byte[] buffer, int offset, int size)
+            throws IOException {
+        if (size <= 0) {
+            throw new IllegalArgumentException("size must be > 0");
+        }
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "  ... readExactly(" + size + ") called");
+        }
+        int soFar = 0;
+        while (soFar < size) {
+            int nRead = in.read(buffer, offset + soFar, size - soFar);
+            if (nRead <= 0) {
+                if (MORE_DEBUG) {
+                    Slog.w(TAG, "- wanted exactly " + size + " but got only " + soFar);
+                }
+                break;
+            }
+            soFar += nRead;
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "   + got " + nRead + "; now wanting " + (size - soFar));
+            }
+        }
+        return soFar;
+    }
+
+    /**
+     * Reads app manifest, filling version and hasApk fields in the metadata, and returns array of
+     * signatures.
+     *
+     * @param info - file metadata.
+     * @return array of signatures or null, in case of an error.
+     * @throws IOException in case of an error.
+     */
+    public Signature[] readAppManifestAndReturnSignatures(FileMetadata info)
+            throws IOException {
+        // Fail on suspiciously large manifest files
+        if (info.size > 64 * 1024) {
+            throw new IOException("Restore manifest too big; corrupt? size=" + info.size);
+        }
+
+        byte[] buffer = new byte[(int) info.size];
+        if (MORE_DEBUG) {
+            Slog.i(TAG,
+                    "   readAppManifestAndReturnSignatures() looking for " + info.size + " bytes");
+        }
+        if (readExactly(mInputStream, buffer, 0, (int) info.size) == info.size) {
+            mBytesReadListener.onBytesRead(info.size);
+        } else {
+            throw new IOException("Unexpected EOF in manifest");
+        }
+
+        String[] str = new String[1];
+        int offset = 0;
+
+        try {
+            offset = extractLine(buffer, offset, str);
+            int version = Integer.parseInt(str[0]);
+            if (version == BACKUP_MANIFEST_VERSION) {
+                offset = extractLine(buffer, offset, str);
+                String manifestPackage = str[0];
+                // TODO: handle <original-package>
+                if (manifestPackage.equals(info.packageName)) {
+                    offset = extractLine(buffer, offset, str);
+                    info.version = Integer.parseInt(str[0]);  // app version
+                    offset = extractLine(buffer, offset, str);
+                    // This is the platform version, which we don't use, but we parse it
+                    // as a safety against corruption in the manifest.
+                    Integer.parseInt(str[0]);
+                    offset = extractLine(buffer, offset, str);
+                    info.installerPackageName = (str[0].length() > 0) ? str[0] : null;
+                    offset = extractLine(buffer, offset, str);
+                    info.hasApk = str[0].equals("1");
+                    offset = extractLine(buffer, offset, str);
+                    int numSigs = Integer.parseInt(str[0]);
+                    if (numSigs > 0) {
+                        Signature[] sigs = new Signature[numSigs];
+                        for (int i = 0; i < numSigs; i++) {
+                            offset = extractLine(buffer, offset, str);
+                            sigs[i] = new Signature(str[0]);
+                        }
+                        return sigs;
+                    } else {
+                        Slog.i(TAG, "Missing signature on backed-up package " + info.packageName);
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                mMonitor,
+                                LOG_EVENT_ID_MISSING_SIGNATURE,
+                                null,
+                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                BackupManagerMonitorUtils.putMonitoringExtra(null,
+                                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
+                    }
+                } else {
+                    Slog.i(TAG, "Expected package " + info.packageName
+                            + " but restore manifest claims " + manifestPackage);
+                    Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                    monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                            monitoringExtras,
+                            EXTRA_LOG_MANIFEST_PACKAGE_NAME, manifestPackage);
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                            mMonitor,
+                            LOG_EVENT_ID_EXPECTED_DIFFERENT_PACKAGE,
+                            null,
+                            LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            monitoringExtras);
+                }
+            } else {
+                Slog.i(TAG, "Unknown restore manifest version " + version
+                        + " for package " + info.packageName);
+                Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                        EXTRA_LOG_EVENT_PACKAGE_VERSION, version);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_VERSION,
+                        null,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+
+            }
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "Corrupt restore manifest for package " + info.packageName);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_CORRUPT_MANIFEST,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            info.packageName));
+        } catch (IllegalArgumentException e) {
+            Slog.w(TAG, e.getMessage());
+        }
+
+        return null;
+    }
+
+    /**
+     * Chooses restore policy.
+     *
+     * @param packageManager - PackageManager instance.
+     * @param allowApks - allow restore set to include apks.
+     * @param info - file metadata.
+     * @param signatures - array of signatures parsed from backup file.
+     * @return a restore policy constant.
+     */
+    public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
+            boolean allowApks, FileMetadata info, Signature[] signatures) {
+        if (signatures == null) {
+            return RestorePolicy.IGNORE;
+        }
+
+        RestorePolicy policy = RestorePolicy.IGNORE;
+
+        // Okay, got the manifest info we need...
+        try {
+            PackageInfo pkgInfo = packageManager.getPackageInfo(
+                    info.packageName, PackageManager.GET_SIGNATURES);
+            // Fall through to IGNORE if the app explicitly disallows backup
+            final int flags = pkgInfo.applicationInfo.flags;
+            if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+                // Restore system-uid-space packages only if they have
+                // defined a custom backup agent
+                if ((pkgInfo.applicationInfo.uid
+                        >= Process.FIRST_APPLICATION_UID)
+                        || (pkgInfo.applicationInfo.backupAgentName != null)) {
+                    // Verify signatures against any installed version; if they
+                    // don't match, then we fall though and ignore the data.  The
+                    // signatureMatch() method explicitly ignores the signature
+                    // check for packages installed on the system partition, because
+                    // such packages are signed with the platform cert instead of
+                    // the app developer's cert, so they're different on every
+                    // device.
+                    if (AppBackupUtils.signaturesMatch(signatures, pkgInfo)) {
+                        if ((pkgInfo.applicationInfo.flags
+                                & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
+                            Slog.i(TAG, "Package has restoreAnyVersion; taking data");
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_RESTORE_ANY_VERSION,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                            policy = RestorePolicy.ACCEPT;
+                        } else if (pkgInfo.versionCode >= info.version) {
+                            Slog.i(TAG, "Sig + version match; taking data");
+                            policy = RestorePolicy.ACCEPT;
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_VERSIONS_MATCH,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                        } else {
+                            // The data is from a newer version of the app than
+                            // is presently installed.  That means we can only
+                            // use it if the matching apk is also supplied.
+                            if (allowApks) {
+                                Slog.i(TAG, "Data version " + info.version
+                                        + " is newer than installed "
+                                        + "version "
+                                        + pkgInfo.versionCode
+                                        + " - requiring apk");
+                                policy = RestorePolicy.ACCEPT_IF_APK;
+                            } else {
+                                Slog.i(TAG, "Data requires newer version "
+                                        + info.version + "; ignoring");
+                                mMonitor = BackupManagerMonitorUtils
+                                        .monitorEvent(mMonitor,
+                                                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER,
+                                                pkgInfo,
+                                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                                BackupManagerMonitorUtils
+                                                        .putMonitoringExtra(
+                                                                null,
+                                                                EXTRA_LOG_OLD_VERSION,
+                                                                info.version));
+
+                                policy = RestorePolicy.IGNORE;
+                            }
+                        }
+                    } else {
+                        Slog.w(TAG, "Restore manifest signatures do not match "
+                                + "installed application for "
+                                + info.packageName);
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                mMonitor,
+                                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH,
+                                pkgInfo,
+                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                null);
+                    }
+                } else {
+                    Slog.w(TAG, "Package " + info.packageName
+                            + " is system level with no agent");
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                            mMonitor,
+                            LOG_EVENT_ID_SYSTEM_APP_NO_AGENT,
+                            pkgInfo,
+                            LOG_EVENT_CATEGORY_AGENT,
+                            null);
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG,
+                            "Restore manifest from " + info.packageName + " but allowBackup=false");
+                }
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE,
+                        pkgInfo,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // Okay, the target app isn't installed.  We can process
+            // the restore properly only if the dataset provides the
+            // apk file and we can successfully install it.
+            if (allowApks) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + info.packageName
+                            + " not installed; requiring apk in dataset");
+                }
+                policy = RestorePolicy.ACCEPT_IF_APK;
+            } else {
+                policy = RestorePolicy.IGNORE;
+            }
+            Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    null,
+                    EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    monitoringExtras,
+                    EXTRA_LOG_POLICY_ALLOW_APKS, allowApks);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_APK_NOT_INSTALLED,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        }
+
+        if (policy == RestorePolicy.ACCEPT_IF_APK && !info.hasApk) {
+            Slog.i(TAG, "Cannot restore package " + info.packageName
+                    + " without the matching .apk");
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
+        }
+
+        return policy;
+    }
+
+    // Given an actual file content size, consume the post-content padding mandated
+    // by the tar format.
+    public void skipTarPadding(long size) throws IOException {
+        long partial = (size + 512) % 512;
+        if (partial > 0) {
+            final int needed = 512 - (int) partial;
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Skipping tar padding: " + needed + " bytes");
+            }
+            byte[] buffer = new byte[needed];
+            if (readExactly(mInputStream, buffer, 0, needed) == needed) {
+                mBytesReadListener.onBytesRead(needed);
+            } else {
+                throw new IOException("Unexpected EOF in padding");
+            }
+        }
+    }
+
+    /**
+     * Read a widget metadata file, returning the restored blob.
+     */
+    public void readMetadata(FileMetadata info) throws IOException {
+        // Fail on suspiciously large widget dump files
+        if (info.size > 64 * 1024) {
+            throw new IOException("Metadata too big; corrupt? size=" + info.size);
+        }
+
+        byte[] buffer = new byte[(int) info.size];
+        if (readExactly(mInputStream, buffer, 0, (int) info.size) == info.size) {
+            mBytesReadListener.onBytesRead(info.size);
+        } else {
+            throw new IOException("Unexpected EOF in widget data");
+        }
+
+        String[] str = new String[1];
+        int offset = extractLine(buffer, 0, str);
+        int version = Integer.parseInt(str[0]);
+        if (version == BACKUP_MANIFEST_VERSION) {
+            offset = extractLine(buffer, offset, str);
+            final String pkg = str[0];
+            if (info.packageName.equals(pkg)) {
+                // Data checks out -- the rest of the buffer is a concatenation of
+                // binary blobs as described in the comment at writeAppWidgetData()
+                ByteArrayInputStream bin = new ByteArrayInputStream(buffer,
+                        offset, buffer.length - offset);
+                DataInputStream in = new DataInputStream(bin);
+                while (bin.available() > 0) {
+                    int token = in.readInt();
+                    int size = in.readInt();
+                    if (size > 64 * 1024) {
+                        throw new IOException("Datum " + Integer.toHexString(token)
+                                + " too big; corrupt? size=" + info.size);
+                    }
+                    switch (token) {
+                        case BACKUP_WIDGET_METADATA_TOKEN: {
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Got widget metadata for " + info.packageName);
+                            }
+                            mWidgetData = new byte[size];
+                            in.read(mWidgetData);
+                            break;
+                        }
+                        default: {
+                            if (DEBUG) {
+                                Slog.i(TAG, "Ignoring metadata blob " + Integer.toHexString(token)
+                                        + " for " + info.packageName);
+                            }
+                            in.skipBytes(size);
+                            break;
+                        }
+                    }
+                }
+            } else {
+                Slog.w(TAG,
+                        "Metadata mismatch: package " + info.packageName + " but widget data for "
+                                + pkg);
+
+                Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
+                        EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+                monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                        BackupManagerMonitor.EXTRA_LOG_WIDGET_PACKAGE_NAME, pkg);
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        BackupManagerMonitor.LOG_EVENT_ID_WIDGET_METADATA_MISMATCH,
+                        null,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+            }
+        } else {
+            Slog.w(TAG, "Unsupported metadata version " + version);
+
+            Bundle monitoringExtras = BackupManagerMonitorUtils
+                    .putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
+                            info.packageName);
+            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
+                    EXTRA_LOG_EVENT_PACKAGE_VERSION, version);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    BackupManagerMonitor.LOG_EVENT_ID_WIDGET_UNKNOWN_VERSION,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        }
+    }
+
+    /**
+     * Builds a line from a byte buffer starting at 'offset'.
+     *
+     * @param buffer - where to read a line from.
+     * @param offset - offset in buffer to read a line from.
+     * @param outStr - an output parameter, the result will be put in outStr.
+     * @return the index of the next unconsumed data in the buffer.
+     * @throws IOException in case of an error.
+     */
+    private static int extractLine(byte[] buffer, int offset, String[] outStr) throws IOException {
+        final int end = buffer.length;
+        if (offset >= end) {
+            throw new IOException("Incomplete data");
+        }
+
+        int pos;
+        for (pos = offset; pos < end; pos++) {
+            byte c = buffer[pos];
+            // at LF we declare end of line, and return the next char as the
+            // starting point for the next time through
+            if (c == '\n') {
+                break;
+            }
+        }
+        outStr[0] = new String(buffer, offset, pos - offset);
+        pos++;  // may be pointing an extra byte past the end but that's okay
+        return pos;
+    }
+
+    private boolean readTarHeader(byte[] block) throws IOException {
+        final int got = readExactly(mInputStream, block, 0, 512);
+        if (got == 0) {
+            return false;     // Clean EOF
+        }
+        if (got < 512) {
+            throw new IOException("Unable to read full block header");
+        }
+        mBytesReadListener.onBytesRead(512);
+        return true;
+    }
+
+    // overwrites 'info' fields based on the pax extended header
+    private boolean readPaxExtendedHeader(FileMetadata info)
+            throws IOException {
+        // We should never see a pax extended header larger than this
+        if (info.size > 32 * 1024) {
+            Slog.w(TAG, "Suspiciously large pax header size " + info.size + " - aborting");
+            throw new IOException("Sanity failure: pax header size " + info.size);
+        }
+
+        // read whole blocks, not just the content size
+        int numBlocks = (int) ((info.size + 511) >> 9);
+        byte[] data = new byte[numBlocks * 512];
+        if (readExactly(mInputStream, data, 0, data.length) < data.length) {
+            throw new IOException("Unable to read full pax header");
+        }
+        mBytesReadListener.onBytesRead(data.length);
+
+        final int contentSize = (int) info.size;
+        int offset = 0;
+        do {
+            // extract the line at 'offset'
+            int eol = offset + 1;
+            while (eol < contentSize && data[eol] != ' ') {
+                eol++;
+            }
+            if (eol >= contentSize) {
+                // error: we just hit EOD looking for the end of the size field
+                throw new IOException("Invalid pax data");
+            }
+            // eol points to the space between the count and the key
+            int linelen = (int) extractRadix(data, offset, eol - offset, 10);
+            int key = eol + 1;  // start of key=value
+            eol = offset + linelen - 1; // trailing LF
+            int value;
+            for (value = key + 1; data[value] != '=' && value <= eol; value++) {
+                ;
+            }
+            if (value > eol) {
+                throw new IOException("Invalid pax declaration");
+            }
+
+            // pax requires that key/value strings be in UTF-8
+            String keyStr = new String(data, key, value - key, "UTF-8");
+            // -1 to strip the trailing LF
+            String valStr = new String(data, value + 1, eol - value - 1, "UTF-8");
+
+            if ("path".equals(keyStr)) {
+                info.path = valStr;
+            } else if ("size".equals(keyStr)) {
+                info.size = Long.parseLong(valStr);
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG, "Unhandled pax key: " + key);
+                }
+            }
+
+            offset += linelen;
+        } while (offset < contentSize);
+
+        return true;
+    }
+
+    private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
+            throws IOException {
+        long value = 0;
+        final int end = offset + maxChars;
+        for (int i = offset; i < end; i++) {
+            final byte b = data[i];
+            // Numeric fields in tar can terminate with either NUL or SPC
+            if (b == 0 || b == ' ') {
+                break;
+            }
+            if (b < '0' || b > ('0' + radix - 1)) {
+                throw new IOException("Invalid number in header: '" + (char) b
+                        + "' for radix " + radix);
+            }
+            value = radix * value + (b - '0');
+        }
+        return value;
+    }
+
+    private static String extractString(byte[] data, int offset, int maxChars) throws IOException {
+        final int end = offset + maxChars;
+        int eos = offset;
+        // tar string fields terminate early with a NUL
+        while (eos < end && data[eos] != 0) {
+            eos++;
+        }
+        return new String(data, offset, eos - offset, "US-ASCII");
+    }
+
+    private static void hexLog(byte[] block) {
+        int offset = 0;
+        int todo = block.length;
+        StringBuilder buf = new StringBuilder(64);
+        while (todo > 0) {
+            buf.append(String.format("%04x   ", offset));
+            int numThisLine = (todo > 16) ? 16 : todo;
+            for (int i = 0; i < numThisLine; i++) {
+                buf.append(String.format("%02x ", block[offset + i]));
+            }
+            Slog.i("hexdump", buf.toString());
+            buf.setLength(0);
+            todo -= numThisLine;
+            offset += numThisLine;
+        }
+    }
+
+    public IBackupManagerMonitor getMonitor() {
+        return mMonitor;
+    }
+
+    public byte[] getWidgetData() {
+        return mWidgetData;
+    }
+}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 4810f4f..f47b0d3 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -383,7 +383,7 @@
                                     findDeviceCallback,
                                     getServiceCallback());
                 } catch (RemoteException e) {
-                    throw new RuntimeException(e);
+                    Log.e(LOG_TAG, "Error while initiating device discovery", e);
                 }
             }
 
diff --git a/services/core/Android.mk b/services/core/Android.mk
index f61fd550..5ec5370 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -31,9 +31,12 @@
     time_zone_distro \
     time_zone_distro_installer \
     android.hidl.base-V1.0-java \
+    android.hardware.weaver-V1.0-java \
     android.hardware.biometrics.fingerprint-V2.1-java \
+    android.hardware.oemlock-V1.0-java \
     android.hardware.tetheroffload.control-V1.0-java \
     android.hardware.vibrator-V1.0-java \
+    android.hardware.configstore-V1.0-java
 
 ifneq ($(INCREMENTAL_BUILDS),)
     LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a378d02..a15992d 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -31,7 +31,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PermissionInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
@@ -154,6 +158,20 @@
     long mAllowWhileIdleMinTime;
     int mNumTimeChanged;
 
+    // Bookkeeping about the identity of the "System UI" package, determined at runtime.
+
+    /**
+     * This permission must be defined by the canonical System UI package,
+     * with protection level "signature".
+     */
+    private static final String SYSTEM_UI_SELF_PERMISSION =
+            "android.permission.systemui.IDENTITY";
+
+    /**
+     * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid.
+     */
+    int mSystemUiUid;
+
     /**
      * The current set of user whitelisted apps for device idle mode, meaning these are allowed
      * to freely schedule alarms.
@@ -961,6 +979,25 @@
             }
         }
 
+        // Determine SysUI's uid
+        final PackageManager packMan = getContext().getPackageManager();
+        try {
+            PermissionInfo sysUiPerm = packMan.getPermissionInfo(SYSTEM_UI_SELF_PERMISSION, 0);
+            ApplicationInfo sysUi = packMan.getApplicationInfo(sysUiPerm.packageName, 0);
+            if ((sysUi.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+                mSystemUiUid = sysUi.uid;
+            } else {
+                Slog.e(TAG, "SysUI permission " + SYSTEM_UI_SELF_PERMISSION
+                        + " defined by non-privileged app " + sysUi.packageName
+                        + " - ignoring");
+            }
+        } catch (NameNotFoundException e) {
+        }
+
+        if (mSystemUiUid <= 0) {
+            Slog.wtf(TAG, "SysUI package not found!");
+        }
+
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
 
@@ -1335,6 +1372,7 @@
             // This means we will allow these alarms to go off as normal even while idle, with no
             // timing restrictions.
             } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
+                    || callingUid == mSystemUiUid
                     || Arrays.binarySearch(mDeviceIdleUserWhitelist,
                             UserHandle.getAppId(callingUid)) >= 0)) {
                 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 1a5ec61..c8e6e2e 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -2445,6 +2445,28 @@
         }
     }
 
+    @Override
+    public boolean isOperationActive(int code, int uid, String packageName) {
+        verifyIncomingUid(uid);
+        verifyIncomingOp(code);
+        String resolvedPackageName = resolvePackageName(uid, packageName);
+        if (resolvedPackageName == null) {
+            return false;
+        }
+        synchronized (this) {
+            for (int i = mClients.size() - 1; i >= 0; i--) {
+                final ClientState client = mClients.valueAt(i);
+                if (client.mStartedOps == null) continue;
+
+                for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
+                    final Op op = client.mStartedOps.get(j);
+                    if (op.op == code && op.uid == uid) return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private void removeUidsForUserLocked(int userHandle) {
         for (int i = mUidStates.size() - 1; i >= 0; --i) {
             final int uid = mUidStates.keyAt(i);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 61057dd..75206e4 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -86,6 +86,8 @@
     private static final int ACTIVE_LOG_MAX_SIZE = 20;
     private static final int CRASH_LOG_MAX_SIZE = 100;
     private static final String REASON_AIRPLANE_MODE = "airplane mode";
+    private static final String REASON_DISALLOWED = "disallowed by system";
+    private static final String REASON_SHARING_DISALLOWED = "sharing disallowed by system";
     private static final String REASON_RESTARTED = "automatic restart";
     private static final String REASON_START_CRASH = "turn-on crash";
     private static final String REASON_SYSTEM_BOOT = "system boot";
@@ -227,25 +229,26 @@
         @Override
         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
                 Bundle prevRestrictions) {
-            if (!UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
-                    UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING)) {
-                return; // No relevant changes, nothing to do.
+
+            if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
+                    UserManager.DISALLOW_BLUETOOTH_SHARING)) {
+                updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+                        UserManager.DISALLOW_BLUETOOTH_SHARING));
             }
 
-            final boolean disallowed = newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
-
-            // DISALLOW_BLUETOOTH is a global restriction that can only be set by DO or PO on the
-            // system user, so we only look at the system user.
-            if (userId == UserHandle.USER_SYSTEM && disallowed && (mEnable || mEnableExternal)) {
-                try {
-                    disable(null /* packageName */, true /* persist */);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception when disabling Bluetooth", e);
+            // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
+            if (userId == UserHandle.USER_SYSTEM &&
+                UserRestrictionsUtils.restrictionsChanged(
+                    prevRestrictions, newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
+                if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
+                        UserManager.DISALLOW_BLUETOOTH)) {
+                    updateOppLauncherComponentState(userId, true); // Sharing disallowed
+                    sendDisableMsg(REASON_DISALLOWED);
+                } else {
+                    updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+                            UserManager.DISALLOW_BLUETOOTH_SHARING));
                 }
             }
-            final boolean sharingDisallowed = disallowed
-                    || newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING);
-            updateOppLauncherComponentState(userId, sharingDisallowed);
         }
     };
 
@@ -2118,7 +2121,8 @@
                 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         try {
             final IPackageManager imp = AppGlobals.getPackageManager();
-            imp.setComponentEnabledSetting(oppLauncherComponent, newState, 0 /* flags */, userId);
+            imp.setComponentEnabledSetting(oppLauncherComponent, newState,
+                    PackageManager.DONT_KILL_APP, userId);
         } catch (Exception e) {
             // The component was not found, do nothing.
         }
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 07c8679..5cebfa5 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -92,12 +92,12 @@
      * Internal state
      */
     private final Context mContext;
+    private final Object mLock = new Object();
     private INetworkManagementService mNetMgr;
     private CommonTimeConfig mCTConfig;
     private String mCurIface;
     private Handler mReconnectHandler = new Handler();
     private Handler mNoInterfaceHandler = new Handler();
-    private Object mLock = new Object();
     private boolean mDetectedAtStartup = false;
     private byte mEffectivePrio = BASE_SERVER_PRIO;
 
@@ -105,15 +105,19 @@
      * Callback handler implementations.
      */
     private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() {
+        @Override
         public void interfaceStatusChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceLinkStateChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceAdded(String iface) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceRemoved(String iface) {
             reevaluateServiceState();
         }
@@ -127,19 +131,11 @@
     };
 
     private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener =
-        new CommonTimeConfig.OnServerDiedListener() {
-            public void onServerDied() {
-                scheduleTimeConfigReconnect();
-            }
-        };
+            () -> scheduleTimeConfigReconnect();
 
-    private Runnable mReconnectRunnable = new Runnable() {
-        public void run() { connectToTimeConfig(); }
-    };
+    private Runnable mReconnectRunnable = () -> connectToTimeConfig();
 
-    private Runnable mNoInterfaceRunnable = new Runnable() {
-        public void run() { handleNoInterfaceTimeout(); }
-    };
+    private Runnable mNoInterfaceRunnable = () -> handleNoInterfaceTimeout();
 
     /*
      * Public interface (constructor, systemReady and dump)
diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java
index 5d4317c..110847d 100644
--- a/services/core/java/com/android/server/ContextHubSystemService.java
+++ b/services/core/java/com/android/server/ContextHubSystemService.java
@@ -16,17 +16,25 @@
 
 package com.android.server;
 
+import com.android.internal.util.ConcurrentUtils;
 import com.android.server.location.ContextHubService;
+import com.android.server.SystemServerInitThreadPool;
 import android.content.Context;
 import android.util.Log;
 
+import java.util.concurrent.Future;
+
 class ContextHubSystemService extends SystemService {
     private static final String TAG = "ContextHubSystemService";
-    private final ContextHubService mContextHubService;
+    private ContextHubService mContextHubService;
+
+    private Future<?> mInit;
 
     public ContextHubSystemService(Context context) {
         super(context);
-        mContextHubService = new ContextHubService(context);
+        mInit = SystemServerInitThreadPool.get().submit(() -> {
+            mContextHubService = new ContextHubService(context);
+        }, "Init ContextHubSystemService");
     }
 
     @Override
@@ -37,6 +45,9 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+            ConcurrentUtils.waitForFutureNoInterrupt(mInit,
+                    "Wait for ContextHubSystemService init");
+            mInit = null;
             publishBinderService(Context.CONTEXTHUB_SERVICE, mContextHubService);
         }
     }
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 830a6ed..a903f3d 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -28,6 +28,8 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
@@ -38,9 +40,12 @@
 import android.util.MutableBoolean;
 import android.util.Slog;
 import android.view.KeyEvent;
+import android.view.WindowManagerInternal;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.LocalServices;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 /**
@@ -52,23 +57,39 @@
  */
 public class GestureLauncherService extends SystemService {
     private static final boolean DBG = false;
+    private static final boolean DBG_CAMERA_LIFT = false;
     private static final String TAG = "GestureLauncherService";
 
     /**
      * Time in milliseconds in which the power button must be pressed twice so it will be considered
      * as a camera launch.
      */
-    private static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+    @VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+
+    /**
+     * Interval in milliseconds in which the power button must be depressed in succession to be
+     * considered part of an extended sequence of taps. Note that this is a looser threshold than
+     * the camera launch gesture, because the purpose of this threshold is to measure the
+     * frequency of consecutive taps, for evaluation for future gestures.
+     */
+    @VisibleForTesting static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500;
 
     /** The listener that receives the gesture event. */
     private final GestureEventListener mGestureListener = new GestureEventListener();
+    private final CameraLiftTriggerEventListener mCameraLiftTriggerListener =
+            new CameraLiftTriggerEventListener();
 
     private Sensor mCameraLaunchSensor;
+    private Sensor mCameraLiftTriggerSensor;
     private Context mContext;
+    private final MetricsLogger mMetricsLogger;
+    private PowerManager mPowerManager;
+    private WindowManagerInternal mWindowManagerInternal;
 
     /** The wake lock held when a gesture is detected. */
     private WakeLock mWakeLock;
-    private boolean mRegistered;
+    private boolean mCameraLaunchRegistered;
+    private boolean mCameraLiftRegistered;
     private int mUserId;
 
     // Below are fields used for event logging only.
@@ -106,10 +127,17 @@
      */
     private boolean mCameraDoubleTapPowerEnabled;
     private long mLastPowerDown;
+    private int mPowerButtonConsecutiveTaps;
 
     public GestureLauncherService(Context context) {
+        this(context, new MetricsLogger());
+    }
+
+    @VisibleForTesting
+    GestureLauncherService(Context context, MetricsLogger metricsLogger) {
         super(context);
         mContext = context;
+        mMetricsLogger = metricsLogger;
     }
 
     public void onStart() {
@@ -124,9 +152,10 @@
                 return;
             }
 
-            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+            mPowerManager = (PowerManager) mContext.getSystemService(
                     Context.POWER_SERVICE);
-            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                     "GestureLauncherService");
             updateCameraRegistered();
             updateCameraDoubleTapPowerEnabled();
@@ -144,6 +173,9 @@
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED),
                 false, mSettingObserver, mUserId);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED),
+                false, mSettingObserver, mUserId);
     }
 
     private void updateCameraRegistered() {
@@ -153,9 +185,16 @@
         } else {
             unregisterCameraLaunchGesture();
         }
+
+        if (isCameraLiftTriggerSettingEnabled(mContext, mUserId)) {
+            registerCameraLiftTrigger(resources);
+        } else {
+            unregisterCameraLiftTrigger();
+        }
     }
 
-    private void updateCameraDoubleTapPowerEnabled() {
+    @VisibleForTesting
+    void updateCameraDoubleTapPowerEnabled() {
         boolean enabled = isCameraDoubleTapPowerSettingEnabled(mContext, mUserId);
         synchronized (this) {
             mCameraDoubleTapPowerEnabled = enabled;
@@ -163,8 +202,8 @@
     }
 
     private void unregisterCameraLaunchGesture() {
-        if (mRegistered) {
-            mRegistered = false;
+        if (mCameraLaunchRegistered) {
+            mCameraLaunchRegistered = false;
             mCameraGestureOnTimeMs = 0L;
             mCameraGestureLastEventTime = 0L;
             mCameraGestureSensor1LastOnTimeMs = 0;
@@ -181,7 +220,7 @@
      * Registers for the camera launch gesture.
      */
     private void registerCameraLaunchGesture(Resources resources) {
-        if (mRegistered) {
+        if (mCameraLaunchRegistered) {
             return;
         }
         mCameraGestureOnTimeMs = SystemClock.elapsedRealtime();
@@ -191,7 +230,7 @@
         int cameraLaunchGestureId = resources.getInteger(
                 com.android.internal.R.integer.config_cameraLaunchGestureSensorType);
         if (cameraLaunchGestureId != -1) {
-            mRegistered = false;
+            mCameraLaunchRegistered = false;
             String sensorName = resources.getString(
                 com.android.internal.R.string.config_cameraLaunchGestureSensorStringType);
             mCameraLaunchSensor = sensorManager.getDefaultSensor(
@@ -203,7 +242,7 @@
             // makes the code more robust.
             if (mCameraLaunchSensor != null) {
                 if (sensorName.equals(mCameraLaunchSensor.getStringType())) {
-                    mRegistered = sensorManager.registerListener(mGestureListener,
+                    mCameraLaunchRegistered = sensorManager.registerListener(mGestureListener,
                             mCameraLaunchSensor, 0);
                 } else {
                     String message = String.format("Wrong configuration. Sensor type and sensor "
@@ -212,12 +251,61 @@
                     throw new RuntimeException(message);
                 }
             }
-            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mRegistered);
+            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mCameraLaunchRegistered);
         } else {
             if (DBG) Slog.d(TAG, "Camera launch sensor is not specified.");
         }
     }
 
+    private void unregisterCameraLiftTrigger() {
+        if (mCameraLiftRegistered) {
+            mCameraLiftRegistered = false;
+
+            SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                    Context.SENSOR_SERVICE);
+            sensorManager.cancelTriggerSensor(mCameraLiftTriggerListener, mCameraLiftTriggerSensor);
+        }
+    }
+
+    /**
+     * Registers for the camera lift trigger.
+     */
+    private void registerCameraLiftTrigger(Resources resources) {
+        if (mCameraLiftRegistered) {
+            return;
+        }
+        SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                Context.SENSOR_SERVICE);
+        int cameraLiftTriggerId = resources.getInteger(
+                com.android.internal.R.integer.config_cameraLiftTriggerSensorType);
+        if (cameraLiftTriggerId != -1) {
+            mCameraLiftRegistered = false;
+            String sensorName = resources.getString(
+                com.android.internal.R.string.config_cameraLiftTriggerSensorStringType);
+            mCameraLiftTriggerSensor = sensorManager.getDefaultSensor(
+                    cameraLiftTriggerId,
+                    true /*wakeUp*/);
+
+            // Compare the camera lift trigger string type to that in the resource file to make
+            // sure we are registering the correct sensor. This is redundant check, it
+            // makes the code more robust.
+            if (mCameraLiftTriggerSensor != null) {
+                if (sensorName.equals(mCameraLiftTriggerSensor.getStringType())) {
+                    mCameraLiftRegistered = sensorManager.requestTriggerSensor(mCameraLiftTriggerListener,
+                            mCameraLiftTriggerSensor);
+                } else {
+                    String message = String.format("Wrong configuration. Sensor type and sensor "
+                            + "string type don't match: %s in resources, %s in the sensor.",
+                            sensorName, mCameraLiftTriggerSensor.getStringType());
+                    throw new RuntimeException(message);
+                }
+            }
+            if (DBG) Slog.d(TAG, "Camera lift trigger sensor registered: " + mCameraLiftRegistered);
+        } else {
+            if (DBG) Slog.d(TAG, "Camera lift trigger sensor is not specified.");
+        }
+    }
+
     public static boolean isCameraLaunchSettingEnabled(Context context, int userId) {
         return isCameraLaunchEnabled(context.getResources())
                 && (Settings.Secure.getIntForUser(context.getContentResolver(),
@@ -230,6 +318,13 @@
                         Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
     }
 
+    public static boolean isCameraLiftTriggerSettingEnabled(Context context, int userId) {
+        return isCameraLiftTriggerEnabled(context.getResources())
+                && (Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED,
+                        Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT, userId) != 0);
+    }
+
     /**
      * Whether to enable the camera launch gesture.
      */
@@ -245,38 +340,55 @@
                 com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled);
     }
 
+    public static boolean isCameraLiftTriggerEnabled(Resources resources) {
+        boolean configSet = resources.getInteger(
+                com.android.internal.R.integer.config_cameraLiftTriggerSensorType) != -1;
+        return configSet;
+    }
+
     /**
      * Whether GestureLauncherService should be enabled according to system properties.
      */
     public static boolean isGestureLauncherEnabled(Resources resources) {
-        return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources);
+        return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources) ||
+                isCameraLiftTriggerEnabled(resources);
     }
 
     public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
             MutableBoolean outLaunched) {
         boolean launched = false;
         boolean intercept = false;
-        long doubleTapInterval;
+        long powerTapInterval;
         synchronized (this) {
-            doubleTapInterval = event.getEventTime() - mLastPowerDown;
+            powerTapInterval = event.getEventTime() - mLastPowerDown;
             if (mCameraDoubleTapPowerEnabled
-                    && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
+                    && powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
                 launched = true;
                 intercept = interactive;
+                mPowerButtonConsecutiveTaps++;
+            } else if (powerTapInterval < POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
+                mPowerButtonConsecutiveTaps++;
+            } else {
+                mPowerButtonConsecutiveTaps = 1;
             }
             mLastPowerDown = event.getEventTime();
         }
+        if (DBG && mPowerButtonConsecutiveTaps > 1) {
+            Slog.i(TAG, Long.valueOf(mPowerButtonConsecutiveTaps) +
+                    " consecutive power button taps detected");
+        }
         if (launched) {
             Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
-                    + doubleTapInterval + "ms");
-            launched = handleCameraLaunchGesture(false /* useWakelock */,
+                    + powerTapInterval + "ms");
+            launched = handleCameraGesture(false /* useWakelock */,
                     StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
             if (launched) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
-                        (int) doubleTapInterval);
+                mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
+                        (int) powerTapInterval);
             }
         }
-        MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);
+        mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonConsecutiveTaps);
+        mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval);
         outLaunched.value = launched;
         return intercept && launched;
     }
@@ -284,17 +396,18 @@
     /**
      * @return true if camera was launched, false otherwise.
      */
-    private boolean handleCameraLaunchGesture(boolean useWakelock, int source) {
+    @VisibleForTesting
+    boolean handleCameraGesture(boolean useWakelock, int source) {
         boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
         if (!userSetupComplete) {
             if (DBG) Slog.d(TAG, String.format(
-                    "userSetupComplete = %s, ignoring camera launch gesture.",
+                    "userSetupComplete = %s, ignoring camera gesture.",
                     userSetupComplete));
             return false;
         }
         if (DBG) Slog.d(TAG, String.format(
-                "userSetupComplete = %s, performing camera launch gesture.",
+                "userSetupComplete = %s, performing camera gesture.",
                 userSetupComplete));
 
         if (useWakelock) {
@@ -332,7 +445,7 @@
     private final class GestureEventListener implements SensorEventListener {
         @Override
         public void onSensorChanged(SensorEvent event) {
-            if (!mRegistered) {
+            if (!mCameraLaunchRegistered) {
               if (DBG) Slog.d(TAG, "Ignoring gesture event because it's unregistered.");
               return;
             }
@@ -342,9 +455,9 @@
                     Slog.d(TAG, String.format("Received a camera launch event: " +
                             "values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2]));
                 }
-                if (handleCameraLaunchGesture(true /* useWakelock */,
+                if (handleCameraGesture(true /* useWakelock */,
                         StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
-                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
+                    mMetricsLogger.action(MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
                     trackCameraLaunchEvent(event);
                 }
                 return;
@@ -401,4 +514,46 @@
             mCameraLaunchLastEventExtra = extra;
         }
     }
+
+    private final class CameraLiftTriggerEventListener extends TriggerEventListener {
+        @Override
+        public void onTrigger(TriggerEvent event) {
+            if (DBG_CAMERA_LIFT) Slog.d(TAG, String.format("onTrigger event - time: %d, name: %s",
+                    event.timestamp, event.sensor.getName()));
+            if (!mCameraLiftRegistered) {
+              if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring camera lift event because it's " +
+                      "unregistered.");
+              return;
+            }
+            if (event.sensor == mCameraLiftTriggerSensor) {
+                Resources resources = mContext.getResources();
+                SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                        Context.SENSOR_SERVICE);
+                boolean keyguardShowingAndNotOccluded =
+                        mWindowManagerInternal.isKeyguardShowingAndNotOccluded();
+                boolean interactive = mPowerManager.isInteractive();
+                if (DBG_CAMERA_LIFT) {
+                    float[] values = event.values;
+                    Slog.d(TAG, String.format("Received a camera lift trigger " +
+                            "event: values=[%.4f], keyguard showing: %b, interactive: %b", values[0],
+                            keyguardShowingAndNotOccluded, interactive));
+                }
+                if (keyguardShowingAndNotOccluded || !interactive) {
+                    if (handleCameraGesture(true /* useWakelock */,
+                            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
+                        MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
+                    }
+                } else {
+                    if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring lift event");
+                }
+
+                mCameraLiftRegistered = sensorManager.requestTriggerSensor(
+                        mCameraLiftTriggerListener, mCameraLiftTriggerSensor);
+
+                if (DBG_CAMERA_LIFT) Slog.d(TAG, "Camera lift trigger sensor re-registered: " +
+                        mCameraLiftRegistered);
+                return;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index bff39b3..192fa3a 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2088,7 +2088,8 @@
     private boolean shouldShowImeSwitcherLocked(int visibility) {
         if (!mShowOngoingImeSwitcherForPhones) return false;
         if (mSwitchingDialog != null) return false;
-        if (isScreenLocked()) return false;
+        if (mWindowManagerInternal.isKeyguardShowingAndNotOccluded()
+                && mKeyguardManager != null && mKeyguardManager.isKeyguardSecure()) return false;
         if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false;
         if (mWindowManagerInternal.isHardKeyboardAvailable()) {
             if (mHardKeyboardBehavior == HardKeyboardBehavior.WIRELESS_AFFORDANCE) {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 3460419..a4e673d 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -243,6 +243,8 @@
 
     private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
 
+    private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
+
     private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
     private IBatchedLocationCallback mGnssBatchingCallback;
     private LinkedCallback mGnssBatchingDeathCallback;
@@ -587,6 +589,7 @@
                     mLocationHandler.getLooper());
             mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider();
             mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider();
+            mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider();
             mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
             mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
             addProviderLocked(gnssProvider);
@@ -3036,6 +3039,12 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
         synchronized (mLock) {
+            if (args.length > 0 && args[0].equals("--gnssmetrics")) {
+                if (mGnssMetricsProvider != null) {
+                    pw.append(mGnssMetricsProvider.getGnssMetricsAsProtoString());
+                }
+                return;
+            }
             pw.println("Current Location Manager state:");
             pw.println("  Location Listeners:");
             for (Receiver receiver : mReceivers.values()) {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
deleted file mode 100644
index 773a1ee..0000000
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ /dev/null
@@ -1,2259 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
-import static android.Manifest.permission.READ_CONTACTS;
-import static android.content.Context.KEYGUARD_SERVICE;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.PasswordMetrics;
-import android.app.backup.BackupManager;
-import android.app.trust.IStrongAuthTracker;
-import android.app.trust.TrustManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceManager;
-import android.os.ShellCallback;
-import android.os.StrictMode;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.DumpUtils;
-import com.android.internal.widget.ICheckCredentialProgressCallback;
-import com.android.internal.widget.ILockSettings;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-import libcore.util.HexEncoding;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * Keeps the lock pattern/password data and related settings for each user. Used by
- * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
- * lockscreen information for secondary users.
- *
- * @hide
- */
-public class LockSettingsService extends ILockSettings.Stub {
-    private static final String TAG = "LockSettingsService";
-    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
-    private static final boolean DEBUG = false;
-
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
-
-    // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
-    private final Object mSeparateChallengeLock = new Object();
-
-    private final Injector mInjector;
-    private final Context mContext;
-    private final Handler mHandler;
-    @VisibleForTesting
-    protected final LockSettingsStorage mStorage;
-    private final LockSettingsStrongAuth mStrongAuth;
-    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
-
-    private final LockPatternUtils mLockPatternUtils;
-    private final NotificationManager mNotificationManager;
-    private final UserManager mUserManager;
-    private final IActivityManager mActivityManager;
-
-    private final KeyStore mKeyStore;
-
-    private boolean mFirstCallToVold;
-    protected IGateKeeperService mGateKeeperService;
-    private SyntheticPasswordManager mSpManager;
-
-    /**
-     * The UIDs that are used for system credential storage in keystore.
-     */
-    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
-            Process.WIFI_UID, Process.VPN_UID,
-            Process.ROOT_UID, Process.SYSTEM_UID };
-
-    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
-    // devices. The most basic of these is to show/hide notifications about missing features until
-    // the user unlocks the account and credential-encrypted storage is available.
-    public static final class Lifecycle extends SystemService {
-        private LockSettingsService mLockSettingsService;
-
-        public Lifecycle(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onStart() {
-            AndroidKeyStoreProvider.install();
-            mLockSettingsService = new LockSettingsService(getContext());
-            publishBinderService("lock_settings", mLockSettingsService);
-        }
-
-        @Override
-        public void onStartUser(int userHandle) {
-            mLockSettingsService.onStartUser(userHandle);
-        }
-
-        @Override
-        public void onUnlockUser(int userHandle) {
-            mLockSettingsService.onUnlockUser(userHandle);
-        }
-
-        @Override
-        public void onCleanupUser(int userHandle) {
-            mLockSettingsService.onCleanupUser(userHandle);
-        }
-    }
-
-    @VisibleForTesting
-    protected static class SynchronizedStrongAuthTracker
-            extends LockPatternUtils.StrongAuthTracker {
-        public SynchronizedStrongAuthTracker(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
-            synchronized (this) {
-                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
-            }
-        }
-
-        @Override
-        public int getStrongAuthForUser(int userId) {
-            synchronized (this) {
-                return super.getStrongAuthForUser(userId);
-            }
-        }
-
-        void register(LockSettingsStrongAuth strongAuth) {
-            strongAuth.registerStrongAuthTracker(this.mStub);
-        }
-    }
-
-    /**
-     * Tie managed profile to primary profile if it is in unified mode and not tied before.
-     *
-     * @param managedUserId Managed profile user Id
-     * @param managedUserPassword Managed profile original password (when it has separated lock).
-     *            NULL when it does not have a separated lock before.
-     */
-    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
-        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
-        // Only for managed profile
-        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
-            return;
-        }
-        // Do not tie managed profile when work challenge is enabled
-        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-            return;
-        }
-        // Do not tie managed profile to parent when it's done already
-        if (mStorage.hasChildProfileLock(managedUserId)) {
-            return;
-        }
-        // Do not tie it to parent when parent does not have a screen lock
-        final int parentId = mUserManager.getProfileParent(managedUserId).id;
-        if (!isUserSecure(parentId)) {
-            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
-            return;
-        }
-        // Do not tie when the parent has no SID (but does have a screen lock).
-        // This can only happen during an upgrade path where SID is yet to be
-        // generated when the user unlocks for the first time.
-        try {
-            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
-            return;
-        }
-        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
-        byte[] randomLockSeed = new byte[] {};
-        try {
-            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
-            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
-            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    managedUserPassword, managedUserId);
-            // We store a private credential for the managed user that's unlocked by the primary
-            // account holder's credential. As such, the user will never be prompted to enter this
-            // password directly, so we always store a password.
-            setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                    DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
-            tieProfileLockToParent(managedUserId, newPassword);
-        } catch (NoSuchAlgorithmException | RemoteException e) {
-            Slog.e(TAG, "Fail to tie managed profile", e);
-            // Nothing client can do to fix this issue, so we do not throw exception out
-        }
-    }
-
-    static class Injector {
-
-        protected Context mContext;
-
-        public Injector(Context context) {
-            mContext = context;
-        }
-
-        public Context getContext() {
-            return mContext;
-        }
-
-        public Handler getHandler() {
-            return new Handler();
-        }
-
-        public LockSettingsStorage getStorage() {
-            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
-            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                @Override
-                public void initialize(SQLiteDatabase db) {
-                    // Get the lockscreen default from a system property, if available
-                    boolean lockScreenDisable = SystemProperties.getBoolean(
-                            "ro.lockscreen.disable.default", false);
-                    if (lockScreenDisable) {
-                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
-                    }
-                }
-            });
-            return storage;
-        }
-
-        public LockSettingsStrongAuth getStrongAuth() {
-            return new LockSettingsStrongAuth(mContext);
-        }
-
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return new SynchronizedStrongAuthTracker(mContext);
-        }
-
-        public IActivityManager getActivityManager() {
-            return ActivityManager.getService();
-        }
-
-        public LockPatternUtils getLockPatternUtils() {
-            return new LockPatternUtils(mContext);
-        }
-
-        public NotificationManager getNotificationManager() {
-            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-        }
-
-        public UserManager getUserManager() {
-            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        }
-
-        public DevicePolicyManager getDevicePolicyManager() {
-            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        }
-
-        public KeyStore getKeyStore() {
-            return KeyStore.getInstance();
-        }
-
-        public IStorageManager getStorageManager() {
-            final IBinder service = ServiceManager.getService("mount");
-            if (service != null) {
-                return IStorageManager.Stub.asInterface(service);
-            }
-            return null;
-        }
-
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return new SyntheticPasswordManager(storage);
-        }
-
-        public int binderGetCallingUid() {
-            return Binder.getCallingUid();
-        }
-    }
-
-    public LockSettingsService(Context context) {
-        this(new Injector(context));
-    }
-
-    @VisibleForTesting
-    protected LockSettingsService(Injector injector) {
-        mInjector = injector;
-        mContext = injector.getContext();
-        mKeyStore = injector.getKeyStore();
-        mHandler = injector.getHandler();
-        mStrongAuth = injector.getStrongAuth();
-        mActivityManager = injector.getActivityManager();
-
-        mLockPatternUtils = injector.getLockPatternUtils();
-        mFirstCallToVold = true;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_ADDED);
-        filter.addAction(Intent.ACTION_USER_STARTING);
-        filter.addAction(Intent.ACTION_USER_REMOVED);
-        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
-                null, null);
-
-        mStorage = injector.getStorage();
-        mNotificationManager = injector.getNotificationManager();
-        mUserManager = injector.getUserManager();
-        mStrongAuthTracker = injector.getStrongAuthTracker();
-        mStrongAuthTracker.register(mStrongAuth);
-
-        mSpManager = injector.getSyntheticPasswordManager(mStorage);
-    }
-
-    /**
-     * If the account is credential-encrypted, show notification requesting the user to unlock the
-     * device.
-     */
-    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
-        final UserInfo user = mUserManager.getUserInfo(userId);
-        if (!user.isManagedProfile()) {
-            // When the user is locked, we communicate it loud-and-clear
-            // on the lockscreen; we only show a notification below for
-            // locked managed profiles.
-            return;
-        }
-
-        final UserHandle userHandle = user.getUserHandle();
-        final boolean isSecure = isUserSecure(userId);
-        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
-            UserInfo parent = mUserManager.getProfileParent(userId);
-            if (parent != null &&
-                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
-                    !mUserManager.isQuietModeEnabled(userHandle)) {
-                // Only show notifications for managed profiles once their parent
-                // user is unlocked.
-                showEncryptionNotificationForProfile(userHandle);
-            }
-        }
-    }
-
-    private void showEncryptionNotificationForProfile(UserHandle user) {
-        Resources r = mContext.getResources();
-        CharSequence title = r.getText(
-                com.android.internal.R.string.user_encrypted_title);
-        CharSequence message = r.getText(
-                com.android.internal.R.string.profile_encrypted_message);
-        CharSequence detail = r.getText(
-                com.android.internal.R.string.profile_encrypted_detail);
-
-        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
-        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
-                user.getIdentifier());
-        if (unlockIntent == null) {
-            return;
-        }
-        unlockIntent.setFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-
-        showEncryptionNotification(user, title, message, detail, intent);
-    }
-
-    private void showEncryptionNotification(UserHandle user, CharSequence title,
-            CharSequence message, CharSequence detail, PendingIntent intent) {
-        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
-
-        // Suppress all notifications on non-FBE devices for now
-        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
-
-        Notification notification =
-                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
-                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
-                        .setWhen(0)
-                        .setOngoing(true)
-                        .setTicker(title)
-                        .setColor(mContext.getColor(
-                                com.android.internal.R.color.system_notification_accent_color))
-                        .setContentTitle(title)
-                        .setContentText(message)
-                        .setSubText(detail)
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setContentIntent(intent)
-                        .build();
-        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            notification, user);
-    }
-
-    private void hideEncryptionNotification(UserHandle userHandle) {
-        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
-        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            userHandle);
-    }
-
-    public void onCleanupUser(int userId) {
-        hideEncryptionNotification(new UserHandle(userId));
-    }
-
-    public void onStartUser(final int userId) {
-        maybeShowEncryptionNotificationForUser(userId);
-    }
-
-    public void onUnlockUser(final int userId) {
-        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
-        // ActivityManager.unlockUser()
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                // Hide notification first, as tie managed profile lock takes time
-                hideEncryptionNotification(new UserHandle(userId));
-
-                // Now we have unlocked the parent user we should show notifications
-                // about any profiles that exist.
-                List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (int i = 0; i < profiles.size(); i++) {
-                    UserInfo profile = profiles.get(i);
-                    final boolean isSecure = isUserSecure(profile.id);
-                    if (isSecure && profile.isManagedProfile()) {
-                        UserHandle userHandle = profile.getUserHandle();
-                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
-                                !mUserManager.isQuietModeEnabled(userHandle)) {
-                            showEncryptionNotificationForProfile(userHandle);
-                        }
-                    }
-                }
-
-                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                    tieManagedProfileLockIfNecessary(userId, null);
-                }
-            }
-        });
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
-                // Notify keystore that a new user was added.
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > UserHandle.USER_SYSTEM) {
-                    removeUser(userHandle, /* unknownUser= */ true);
-                }
-                final KeyStore ks = KeyStore.getInstance();
-                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
-                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
-                ks.onUserAdded(userHandle, parentHandle);
-            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                mStorage.prefetchUser(userHandle);
-            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > 0) {
-                    removeUser(userHandle, /* unknownUser= */ false);
-                }
-            }
-        }
-    };
-
-    @Override // binder interface
-    public void systemReady() {
-        migrateOldData();
-        try {
-            getGateKeeperService();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
-        }
-        // TODO: maybe skip this for split system user mode.
-        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
-    }
-
-    private void migrateOldData() {
-        try {
-            // These Settings moved before multi-user was enabled, so we only have to do it for the
-            // root user.
-            if (getString("migrated", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                for (String validSetting : VALID_SETTINGS) {
-                    String value = Settings.Secure.getString(cr, validSetting);
-                    if (value != null) {
-                        setString(validSetting, value, 0);
-                    }
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated", "true", 0);
-                Slog.i(TAG, "Migrated lock settings to new location");
-            }
-
-            // These Settings changed after multi-user was enabled, hence need to be moved per user.
-            if (getString("migrated_user_specific", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int user = 0; user < users.size(); user++) {
-                    // Migrate owner info
-                    final int userId = users.get(user).id;
-                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
-                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
-                    if (!TextUtils.isEmpty(ownerInfo)) {
-                        setString(OWNER_INFO, ownerInfo, userId);
-                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
-                    }
-
-                    // Migrate owner info enabled. Note there was a bug where older platforms only
-                    // stored this value if the checkbox was toggled at least once. The code detects
-                    // this case by handling the exception.
-                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
-                    boolean enabled;
-                    try {
-                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
-                        enabled = ivalue != 0;
-                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
-                    } catch (SettingNotFoundException e) {
-                        // Setting was never stored. Store it if the string is not empty.
-                        if (!TextUtils.isEmpty(ownerInfo)) {
-                            setLong(OWNER_INFO_ENABLED, 1, userId);
-                        }
-                    }
-                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated_user_specific", "true", 0);
-                Slog.i(TAG, "Migrated per-user lock settings to new location");
-            }
-
-            // Migrates biometric weak such that the fallback mechanism becomes the primary.
-            if (getString("migrated_biometric_weak", null, 0) == null) {
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int i = 0; i < users.size(); i++) {
-                    int userId = users.get(i).id;
-                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                alternateType,
-                                userId);
-                    }
-                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                }
-                setString("migrated_biometric_weak", "true", 0);
-                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
-            }
-
-            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
-            // user was present on the system, so if we're upgrading to M and there is more than one
-            // user we disable the flag to remain consistent.
-            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
-                final List<UserInfo> users = mUserManager.getUsers();
-                final int userCount = users.size();
-                int switchableUsers = 0;
-                for (int i = 0; i < userCount; i++) {
-                    if (users.get(i).supportsSwitchTo()) {
-                        switchableUsers++;
-                    }
-                }
-
-                if (switchableUsers > 1) {
-                    for (int i = 0; i < userCount; i++) {
-                        int id = users.get(i).id;
-
-                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
-                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                        }
-                    }
-                }
-
-                setString("migrated_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen disabled flag");
-            }
-
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                final UserInfo userInfo = users.get(i);
-                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
-                    // When managed profile has a unified lock, the password quality stored has 2
-                    // possibilities only.
-                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
-                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
-                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
-                    // unified lock.
-                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
-                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                        // Only possible when it's upgraded from nyc dp3
-                        Slog.i(TAG, "Migrated tied profile lock type");
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
-                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
-                        // It should not happen
-                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
-                    }
-                }
-                try {
-                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
-                    java.security.KeyStore keyStore =
-                            java.security.KeyStore.getInstance("AndroidKeyStore");
-                    keyStore.load(null);
-                    if (keyStore.containsAlias(alias)) {
-                        keyStore.deleteEntry(alias);
-                    }
-                } catch (KeyStoreException | NoSuchAlgorithmException |
-                        CertificateException | IOException e) {
-                    Slog.e(TAG, "Unable to remove tied profile key", e);
-                }
-            }
-
-            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_WATCH);
-            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
-            // and device management the lockscreen must be re-enabled now for users that upgrade.
-            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
-                final int userCount = users.size();
-                for (int i = 0; i < userCount; i++) {
-                    int id = users.get(i).id;
-                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                }
-                setString("migrated_wear_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
-            }
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to migrate old data", re);
-        }
-    }
-
-    private final void checkWritePermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
-    }
-
-    private final void checkPasswordReadPermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
-    }
-
-    private final void checkReadPermission(String requestedKey, int userId) {
-        final int callingUid = Binder.getCallingUid();
-
-        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + READ_CONTACTS + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-
-        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + PERMISSION + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
-        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
-        synchronized (mSeparateChallengeLock) {
-            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
-        }
-    }
-
-    @Override
-    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
-            String managedUserPassword) throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
-            if (enabled) {
-                mStorage.removeChildProfileLock(userId);
-                removeKeystoreProfileKey(userId);
-            } else {
-                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
-            }
-        }
-    }
-
-    @Override
-    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value ? "1" : "0");
-    }
-
-    @Override
-    public void setLong(String key, long value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, Long.toString(value));
-    }
-
-    @Override
-    public void setString(String key, String value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value);
-    }
-
-    private void setStringUnchecked(String key, int userId, String value) {
-        mStorage.writeKeyValue(key, value, userId);
-        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
-            BackupManager.dataChanged("com.android.providers.settings");
-        }
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ?
-                defaultValue : (value.equals("1") || value.equals("true"));
-    }
-
-    @Override
-    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
-    }
-
-    @Override
-    public String getString(String key, String defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        return getStringUnchecked(key, defaultValue, userId);
-    }
-
-    public String getStringUnchecked(String key, String defaultValue, int userId) {
-        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
-            key = Settings.Secure.LOCK_PATTERN_ENABLED;
-        }
-
-        return mStorage.readKeyValue(key, defaultValue, userId);
-    }
-
-    @Override
-    public boolean havePassword(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPassword(userId);
-    }
-
-    @Override
-    public boolean havePattern(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPattern(userId);
-    }
-
-    private boolean isUserSecure(int userId) {
-        synchronized (mSpManager) {
-            try {
-                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                    long handle = getSyntheticPasswordHandleLocked(userId);
-                    return mSpManager.getCredentialType(handle, userId) !=
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
-                }
-            } catch (RemoteException e) {
-                // fall through
-            }
-        }
-        return mStorage.hasCredential(userId);
-    }
-
-    private void setKeystorePassword(String password, int userHandle) {
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserPasswordChanged(userHandle, password);
-    }
-
-    private void unlockKeystore(String password, int userHandle) {
-        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        final KeyStore ks = KeyStore.getInstance();
-        ks.unlock(userHandle, password);
-    }
-
-    @VisibleForTesting
-    protected String getDecryptedPasswordForTiedProfile(int userId)
-            throws KeyStoreException, UnrecoverableKeyException,
-            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
-            CertificateException, IOException {
-        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
-        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
-                storedData.length);
-        byte[] decryptionResult;
-        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
-        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
-                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
-
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-
-        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
-        decryptionResult = cipher.doFinal(encryptedPassword);
-        return new String(decryptionResult, StandardCharsets.UTF_8);
-    }
-
-    private void unlockChildProfile(int profileHandle) throws RemoteException {
-        try {
-            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            if (e instanceof FileNotFoundException) {
-                Slog.i(TAG, "Child profile key not found");
-            } else {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-    }
-
-    private void unlockUser(int userId, byte[] token, byte[] secret) {
-        // TODO: make this method fully async so we can update UI with progress strings
-        final CountDownLatch latch = new CountDownLatch(1);
-        final IProgressListener listener = new IProgressListener.Stub() {
-            @Override
-            public void onStarted(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser started");
-            }
-
-            @Override
-            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser progress " + progress);
-            }
-
-            @Override
-            public void onFinished(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser finished");
-                latch.countDown();
-            }
-        };
-
-        try {
-            mActivityManager.unlockUser(userId, token, secret, listener);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-
-        try {
-            latch.await(15, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-        try {
-            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
-                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (UserInfo pi : profiles) {
-                    // Unlock managed profile with unified lock
-                    if (pi.isManagedProfile()
-                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                            && mStorage.hasChildProfileLock(pi.id)
-                            && mUserManager.isUserRunning(pi.id)) {
-                        unlockChildProfile(pi.id);
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            Log.d(TAG, "Failed to unlock child profile", e);
-        }
-    }
-
-    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return null;
-        }
-        Map<Integer, String> result = new ArrayMap<Integer, String>();
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (!profile.isManagedProfile()) {
-                continue;
-            }
-            final int managedUserId = profile.id;
-            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                continue;
-            }
-            try {
-                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
-            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
-                    | NoSuchPaddingException | InvalidKeyException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                // ignore
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
-     * depending on the parent user's secure state.
-     *
-     * When clearing tied work challenges, a pre-computed password table for profiles are required,
-     * since changing password for profiles requires existing password, and existing passwords can
-     * only be computed before the parent user's password is cleared.
-     *
-     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
-     * method again on profiles. However the recursion is guaranteed to terminate as this method
-     * terminates when the user is a managed profile.
-     */
-    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
-            Map<Integer, String> profilePasswordMap) throws RemoteException {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return;
-        }
-        final boolean isSecure = isUserSecure(userId);
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (profile.isManagedProfile()) {
-                final int managedUserId = profile.id;
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                    continue;
-                }
-                if (isSecure) {
-                    tieManagedProfileLockIfNecessary(managedUserId, null);
-                } else {
-                    // We use cached work profile password computed before clearing the parent's
-                    // credential, otherwise they get lost
-                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                                profilePasswordMap.get(managedUserId), managedUserId);
-                    } else {
-                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
-                        // Supplying null here would lead to untrusted credential change
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
-                                managedUserId);
-                    }
-                    mStorage.removeChildProfileLock(managedUserId);
-                    removeKeystoreProfileKey(managedUserId);
-                }
-            }
-        }
-    }
-
-    private boolean isManagedProfileWithUnifiedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    private boolean isManagedProfileWithSeparatedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    // This method should be called by LockPatternUtil only, all internal methods in this class
-    // should call setLockCredentialInternal.
-    @Override
-    public void setLockCredential(String credential, int type, String savedCredential, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setLockCredentialInternal(credential, type, savedCredential, userId);
-            setSeparateProfileChallengeEnabled(userId, true, null);
-            notifyPasswordChanged(userId);
-        }
-    }
-
-    private void setLockCredentialInternal(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        // Normalize savedCredential and credential such that empty string is always represented
-        // as null.
-        if (TextUtils.isEmpty(savedCredential)) {
-            savedCredential = null;
-        }
-        if (TextUtils.isEmpty(credential)) {
-            credential = null;
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            if (credential != null) {
-                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
-            }
-            clearUserKeyProtection(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
-            setKeystorePassword(null, userId);
-            fixateNewestUserKeyAuth(userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            notifyActivePasswordMetricsAvailable(null, userId);
-            return;
-        }
-        if (credential == null) {
-            throw new RemoteException("Null credential with mismatched credential type");
-        }
-
-        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            if (savedCredential == null) {
-                try {
-                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
-                } catch (FileNotFoundException e) {
-                    Slog.i(TAG, "Child profile key not found");
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        } else {
-            if (currentHandle.hash == null) {
-                if (savedCredential != null) {
-                    Slog.w(TAG, "Saved credential provided, but none stored");
-                }
-                savedCredential = null;
-            }
-        }
-        synchronized (mSpManager) {
-            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
-                        currentHandle.type, userId);
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
-        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
-                userId);
-        if (enrolledHandle != null) {
-            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
-            mStorage.writeCredentialHash(willStore, userId);
-            // push new secret and auth token to vold
-            GateKeeperResponse gkResponse = getGateKeeperService()
-                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
-            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
-            fixateNewestUserKeyAuth(userId);
-            // Refresh the auth token
-            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-        } else {
-            throw new RemoteException("Failed to enroll " +
-                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
-                            : "pattern"));
-        }
-    }
-
-    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
-        VerifyCredentialResponse response;
-        int responseCode = gateKeeperResponse.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
-        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            byte[] token = gateKeeperResponse.getPayload();
-            if (token == null) {
-                // something's wrong if there's no payload with a challenge
-                Slog.e(TAG, "verifyChallenge response had no associated payload");
-                response = VerifyCredentialResponse.ERROR;
-            } else {
-                response = new VerifyCredentialResponse(token);
-            }
-        } else {
-            response = VerifyCredentialResponse.ERROR;
-        }
-        return response;
-    }
-
-    @VisibleForTesting
-    protected void tieProfileLockToParent(int userId, String password) {
-        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
-        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
-        byte[] encryptionResult;
-        byte[] iv;
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            try {
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .build());
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .setUserAuthenticationRequired(true)
-                                .setUserAuthenticationValidityDurationSeconds(30)
-                                .build());
-                // Key imported, obtain a reference to it.
-                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
-                Cipher cipher = Cipher.getInstance(
-                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                                + KeyProperties.ENCRYPTION_PADDING_NONE);
-                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
-                encryptionResult = cipher.doFinal(randomLockSeed);
-                iv = cipher.getIV();
-            } finally {
-                // The original key can now be discarded.
-                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
-            }
-        } catch (CertificateException | UnrecoverableKeyException
-                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
-                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
-            throw new RuntimeException("Failed to encrypt key", e);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        try {
-            if (iv.length != PROFILE_KEY_IV_SIZE) {
-                throw new RuntimeException("Invalid iv length: " + iv.length);
-            }
-            outputStream.write(iv);
-            outputStream.write(encryptionResult);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to concatenate byte arrays", e);
-        }
-        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
-    }
-
-    private byte[] enrollCredential(byte[] enrolledHandle,
-            String enrolledCredential, String toEnroll, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        byte[] enrolledCredentialBytes = enrolledCredential == null
-                ? null
-                : enrolledCredential.getBytes();
-        byte[] toEnrollBytes = toEnroll == null
-                ? null
-                : toEnroll.getBytes();
-        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
-                enrolledCredentialBytes, toEnrollBytes);
-
-        if (response == null) {
-            return null;
-        }
-
-        byte[] hash = response.getPayload();
-        if (hash != null) {
-            setKeystorePassword(toEnroll, userId);
-        } else {
-            // Should not happen
-            Slog.e(TAG, "Throttled while enrolling a password");
-        }
-        return hash;
-    }
-
-    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
-        addUserKeyAuth(userId, null, key);
-    }
-
-    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
-        if (vcr == null) {
-            throw new RemoteException("Null response verifying a credential we just set");
-        }
-        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            throw new RemoteException("Non-OK response verifying a credential we just set: "
-                    + vcr.getResponseCode());
-        }
-        byte[] token = vcr.getPayload();
-        if (token == null) {
-            throw new RemoteException("Empty payload verifying a credential we just set");
-        }
-        addUserKeyAuth(userId, token, secretFromCredential(credential));
-    }
-
-    private void clearUserKeyProtection(int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
-        addUserKeyAuth(userId, null, null);
-    }
-
-    private static byte[] secretFromCredential(String credential) throws RemoteException {
-        try {
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            // Personalize the hash
-            byte[] personalization = "Android FBE credential hash"
-                    .getBytes(StandardCharsets.UTF_8);
-            // Pad it to the block size of the hash function
-            personalization = Arrays.copyOf(personalization, 128);
-            digest.update(personalization);
-            digest.update(credential.getBytes(StandardCharsets.UTF_8));
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
-        }
-    }
-
-    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
-            throws RemoteException {
-        final UserInfo userInfo = mUserManager.getUserInfo(userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    private void fixateNewestUserKeyAuth(int userId)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.fixateNewestUserKeyAuth(userId);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    @Override
-    public void resetKeyStore(int userId) throws RemoteException {
-        checkWritePermission(userId);
-        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
-        int managedUserId = -1;
-        String managedUserDecryptedPassword = null;
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        for (UserInfo pi : profiles) {
-            // Unlock managed profile with unified lock
-            if (pi.isManagedProfile()
-                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                    && mStorage.hasChildProfileLock(pi.id)) {
-                try {
-                    if (managedUserId == -1) {
-                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
-                        managedUserId = pi.id;
-                    } else {
-                        // Should not happen
-                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
-                                + ", uid2:" + pi.id);
-                    }
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        }
-        try {
-            // Clear all the users credentials could have been installed in for this user.
-            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
-                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
-                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
-                }
-            }
-        } finally {
-            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
-                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
-                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
-            }
-        }
-    }
-
-    @Override
-    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
-            int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, true, challenge, userId,
-                null /* progressCallback */);
-    }
-
-    /**
-     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
-     * format.
-     */
-    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
-            boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (TextUtils.isEmpty(credential)) {
-            throw new IllegalArgumentException("Credential can't be null or empty");
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
-                        credentialType, hasChallenge, challenge, userId, progressCallback);
-                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-                }
-                return response;
-            }
-        }
-        CredentialHash storedHash = mStorage.readCredentialHash(userId);
-        if (storedHash.type != credentialType) {
-            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
-                    + " stored: " + storedHash.type + " passed in: " + credentialType);
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
-                && storedHash.isBaseZeroPattern;
-
-        String credentialToVerify;
-        if (shouldReEnrollBaseZero) {
-            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
-        } else {
-            credentialToVerify = credential;
-        }
-
-        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
-                hasChallenge, challenge, progressCallback);
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-            if (shouldReEnrollBaseZero) {
-                setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId);
-            }
-        }
-
-        return response;
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
-            long challenge, int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        if (!isManagedProfileWithUnifiedLock(userId)) {
-            throw new RemoteException("User id must be managed profile with unified lock");
-        }
-        final int parentProfileId = mUserManager.getProfileParent(userId).id;
-        // Unlock parent by using parent's challenge
-        final VerifyCredentialResponse parentResponse = doVerifyCredential(
-                credential,
-                type,
-                true /* hasChallenge */,
-                challenge,
-                parentProfileId,
-                null /* progressCallback */);
-        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            // Failed, just return parent's response
-            return parentResponse;
-        }
-
-        try {
-            // Unlock work profile, and work profile with unified lock must use password only
-            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    true,
-                    challenge,
-                    userId, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            Slog.e(TAG, "Failed to decrypt child profile key", e);
-            throw new RemoteException("Unable to get tied profile token");
-        }
-    }
-
-    /**
-     * Lowest-level credential verification routine that talks to GateKeeper. If verification
-     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
-     * hash to GK.
-     */
-    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
-            String credential, boolean hasChallenge, long challenge,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
-            // don't need to pass empty credentials to GateKeeper
-            return VerifyCredentialResponse.OK;
-        }
-
-        if (storedHash == null || TextUtils.isEmpty(credential)) {
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        // We're potentially going to be doing a bunch of disk I/O below as part
-        // of unlocking the user, so yell if calling from the main thread.
-        StrictMode.noteDiskRead();
-
-        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
-            final byte[] hash;
-            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
-            } else {
-                hash = mLockPatternUtils.passwordToHash(credential, userId);
-            }
-            if (Arrays.equals(hash, storedHash.hash)) {
-                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
-                } else {
-                    unlockKeystore(credential, userId);
-                }
-                // Users with legacy credentials don't have credential-backed
-                // FBE keys, so just pass through a fake token/secret
-                Slog.i(TAG, "Unlocking user with fake token: " + userId);
-                final byte[] fakeToken = String.valueOf(userId).getBytes();
-                unlockUser(userId, fakeToken, fakeToken);
-
-                // migrate credential to GateKeeper
-                setLockCredentialInternal(credential, storedHash.type, null, userId);
-                if (!hasChallenge) {
-                    notifyActivePasswordMetricsAvailable(credential, userId);
-                    return VerifyCredentialResponse.OK;
-                }
-                // Fall through to get the auth token. Technically this should never happen,
-                // as a user that had a legacy credential would have to unlock their device
-                // before getting to a flow with a challenge, but supporting for consistency.
-            } else {
-                return VerifyCredentialResponse.ERROR;
-            }
-        }
-        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
-                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
-        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
-        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-
-            // credential has matched
-
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(credential, userId);
-            unlockKeystore(credential, userId);
-
-            Slog.i(TAG, "Unlocking user " + userId + " with token length "
-                    + response.getPayload().length);
-            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            if (shouldReEnroll) {
-                setLockCredentialInternal(credential, storedHash.type, credential, userId);
-            } else {
-                // Now that we've cleared of all required GK migration, let's do the final
-                // migration to synthetic password.
-                synchronized (mSpManager) {
-                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
-                                storedHash.hash, credential, storedHash.type, userId);
-                        activateEscrowTokens(auth, userId);
-                    }
-                }
-            }
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
-        final PasswordMetrics metrics;
-        if (password == null) {
-            metrics = new PasswordMetrics();
-        } else {
-            metrics = PasswordMetrics.computeForPassword(password);
-            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
-        }
-
-        // Asynchronous to avoid dead lock
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.setActivePasswordState(metrics, userId);
-        });
-    }
-
-    /**
-     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
-     * reporting the password changed.
-     */
-    private void notifyPasswordChanged(@UserIdInt int userId) {
-        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.reportPasswordChanged(userId);
-        });
-    }
-
-    @Override
-    public boolean checkVoldPassword(int userId) throws RemoteException {
-        if (!mFirstCallToVold) {
-            return false;
-        }
-        mFirstCallToVold = false;
-
-        checkPasswordReadPermission(userId);
-
-        // There's no guarantee that this will safely connect, but if it fails
-        // we will simply show the lock screen when we shouldn't, so relatively
-        // benign. There is an outside chance something nasty would happen if
-        // this service restarted before vold stales out the password in this
-        // case. The nastiness is limited to not showing the lock screen when
-        // we should, within the first minute of decrypting the phone if this
-        // service can't connect to vold, it restarts, and then the new instance
-        // does successfully connect.
-        final IStorageManager service = mInjector.getStorageManager();
-        String password;
-        long identity = Binder.clearCallingIdentity();
-        try {
-            password = service.getPassword();
-            service.clearPassword();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (password == null) {
-            return false;
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        return false;
-    }
-
-    private void removeUser(int userId, boolean unknownUser) {
-        mStorage.removeUser(userId);
-        mStrongAuth.removeUser(userId);
-
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserRemoved(userId);
-
-        try {
-            final IGateKeeperService gk = getGateKeeperService();
-            if (gk != null) {
-                gk.clearSecureUserId(userId);
-            }
-        } catch (RemoteException ex) {
-            Slog.w(TAG, "unable to clear GK secure user id");
-        }
-        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
-            removeKeystoreProfileKey(userId);
-        }
-    }
-
-    private void removeKeystoreProfileKey(int targetUserId) {
-        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
-        try {
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            // We have tried our best to remove all keys
-            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
-        }
-    }
-
-    @Override
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.registerStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.unregisterStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
-    }
-
-    @Override
-    public void userPresent(int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.reportUnlock(userId);
-    }
-
-    @Override
-    public int getStrongAuthForUser(int userId) {
-        checkPasswordReadPermission(userId);
-        return mStrongAuthTracker.getStrongAuthForUser(userId);
-    }
-
-    private boolean isCallerShell() {
-        final int callingUid = Binder.getCallingUid();
-        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
-    }
-
-    private void enforceShell() {
-        if (!isCallerShell()) {
-            throw new SecurityException("Caller must be shell");
-        }
-    }
-
-    @Override
-    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
-            throws RemoteException {
-        enforceShell();
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
-                    this, in, out, err, args, callback, resultReceiver);
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    private static final String[] VALID_SETTINGS = new String[] {
-            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
-            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
-            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
-            LockPatternUtils.LOCKSCREEN_OPTIONS,
-            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
-            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
-            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            Secure.LOCK_PATTERN_ENABLED,
-            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
-            Secure.LOCK_PATTERN_VISIBLE,
-            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
-    };
-
-    // Reading these settings needs the contacts permission
-    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    // Reading these settings needs the same permission as checking the password
-    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            SEPARATE_PROFILE_CHALLENGE_KEY
-    };
-
-    private static final String[] SETTINGS_TO_BACKUP = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
-            mGateKeeperService = null;
-        }
-    }
-
-    protected synchronized IGateKeeperService getGateKeeperService()
-            throws RemoteException {
-        if (mGateKeeperService != null) {
-            return mGateKeeperService;
-        }
-
-        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
-        if (service != null) {
-            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
-            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
-            return mGateKeeperService;
-        }
-
-        Slog.e(TAG, "Unable to acquire GateKeeperService");
-        return null;
-    }
-
-    /**
-     * Precondition: vold and keystore unlocked.
-     *
-     * Create new synthetic password, set up synthetic password blob protected by the supplied
-     * user credential, and make the newly-created SP blob active.
-     *
-     * The invariant under a synthetic password is:
-     * 1. If user credential exists, then both vold and keystore and protected with keys derived
-     *     from the synthetic password.
-     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
-     *     make it consistent with current behaviour. It also allows ActivityManager to call
-     *     unlockUser() with empty secret.
-     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
-     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
-     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
-     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
-     *     credential change, in which case we have no way to derive the existing synthetic password
-     *     and has to create a new one.
-     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
-     *     clears/re-creates his lockscreen PIN.
-     *
-     *
-     * Different cases of calling this method:
-     * 1. credentialHash != null
-     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
-     *     migrated to associate with the new SP.
-     *     This happens during a normal migration case when the user currently has password.
-     *
-     * 2. credentialhash == null and credential == null
-     *     A new SP blob and a new SID will be created, while the user has no credentials.
-     *     This can happens when we are activating an escrow token on a unsecured device, during
-     *     which we want to create the SP structure with an empty user credential.
-     *
-     * 3. credentialhash == null and credential != null
-     *     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,
-            String credential, int credentialType, int userId) throws RemoteException {
-        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
-        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
-                credentialHash, credential, userId);
-        if (auth == null) {
-            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
-            return null;
-        }
-        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        if (credential != null) {
-            if (credentialHash == null) {
-                // Since when initializing SP, we didn't provide an existing password handle
-                // for it to migrate SID, we need to create a new SID for the user.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-            }
-            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-        } else {
-            clearUserKeyProtection(userId);
-            setKeystorePassword(null, userId);
-            getGateKeeperService().clearSecureUserId(userId);
-        }
-        fixateNewestUserKeyAuth(userId);
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
-        return auth;
-    }
-
-    private long getSyntheticPasswordHandleLocked(int userId) {
-        try {
-            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
-        } catch (RemoteException e) {
-            return SyntheticPasswordManager.DEFAULT_HANDLE;
-        }
-    }
-
-    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private void enableSyntheticPasswordLocked() throws RemoteException {
-        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
-            credentialType, boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            userCredential = null;
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, userCredential, userId);
-
-        VerifyCredentialResponse response = authResult.gkResponse;
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            // credential has matched
-            // perform verifyChallenge with synthetic password which generates the real auth
-            // token for the current user
-            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                    challenge, userId);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                return VerifyCredentialResponse.ERROR;
-            }
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(userCredential, userId);
-            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
-
-            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
-            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
-            unlockUser(userId, null, secret);
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            activateEscrowTokens(authResult.authToken, userId);
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    /**
-     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
-     * on an existing authentication token. Even though a new SP blob is created, the underlying
-     * synthetic password is never changed.
-     *
-     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
-     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
-     * added back when new password is set in future.
-     */
-    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
-            AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
-        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        final Map<Integer, String> profilePasswords;
-        if (credential != null) {
-            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = null;
-
-            if (mSpManager.hasSidForUser(userId)) {
-                // We are changing password of a secured device, nothing more needed as
-                // createPasswordBasedSyntheticPassword has already taken care of maintaining
-                // the password handle and SID unchanged.
-
-                //refresh auth token
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            } else {
-                // A new password is set on a previously-unsecured device, we need to generate
-                // a new SID, and re-add keys to vold and keystore.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-                fixateNewestUserKeyAuth(userId);
-                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-            }
-        } else {
-            // Cache all profile password if they use unified work challenge. This will later be
-            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
-
-            // we are clearing password of a secured device, so need to nuke SID as well.
-            mSpManager.clearSidForUser(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            // Clear key from vold so ActivityManager can just unlock the user with empty secret
-            // during boot.
-            clearUserKeyProtection(userId);
-            fixateNewestUserKeyAuth(userId);
-            setKeystorePassword(null, userId);
-        }
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
-        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
-        return newHandle;
-    }
-
-    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            try {
-                savedCredential = getDecryptedPasswordForTiedProfile(userId);
-            } catch (FileNotFoundException e) {
-                Slog.i(TAG, "Child profile key not found");
-            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                    | NoSuchAlgorithmException | NoSuchPaddingException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, savedCredential, userId);
-        VerifyCredentialResponse response = authResult.gkResponse;
-        AuthenticationToken auth = authResult.authToken;
-        if (auth != null) {
-            // We are performing a trusted credential change i.e. a correct existing credential
-            // is provided
-            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else if (response != null
-                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
-            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
-            // So provision a new SP and SID. This would invalidate existing escrow tokens.
-            // Still support this for now but this flow will be removed in the next release.
-
-            Slog.w(TAG, "Untrusted credential change invoked");
-            initializeSyntheticPasswordLocked(null, credential, credentialType, userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
-            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
-                    (response != null ? "rate limit exceeded" : "failed"));
-            return;
-        }
-        notifyActivePasswordMetricsAvailable(credential, userId);
-
-    }
-
-    @Override
-    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
-        synchronized (mSpManager) {
-            enableSyntheticPasswordLocked();
-            // Migrate to synthetic password based credentials if the user has no password,
-            // the token can then be activated immediately.
-            AuthenticationToken auth = null;
-            if (!isUserSecure(userId)) {
-                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                    auth = initializeSyntheticPasswordLocked(null, null,
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE, userId);
-                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
-                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
-                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
-                            pwdHandle, null, userId).authToken;
-                }
-            }
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-                if (!mSpManager.hasEscrowData(userId)) {
-                    throw new SecurityException("Escrow token is disabled on the current user");
-                }
-            }
-            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
-            if (auth != null) {
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-            return handle;
-        }
-    }
-
-    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
-        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-        synchronized (mSpManager) {
-            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
-                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            return mSpManager.existsHandle(handle, userId);
-        }
-    }
-
-    @Override
-    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            if (handle == getSyntheticPasswordHandleLocked(userId)) {
-                Slog.w(TAG, "Cannot remove password handle");
-                return false;
-            }
-            if (mSpManager.removePendingToken(handle, userId)) {
-                return true;
-            }
-            if (mSpManager.existsHandle(handle, userId)) {
-                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
-            byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        boolean result;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
-                    userId);
-        }
-        if (result) {
-            synchronized (mSeparateChallengeLock) {
-                setSeparateProfileChallengeEnabled(userId, true, null);
-            }
-            notifyPasswordChanged(userId);
-        }
-        return result;
-    }
-
-    private boolean setLockCredentialWithTokenInternal(String credential, int type,
-            long tokenHandle, byte[] token, int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
-                    getGateKeeperService(), tokenHandle, token, userId);
-            if (result.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return false;
-            }
-            long oldHandle = getSyntheticPasswordHandleLocked(userId);
-            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
-            return true;
-        }
-    }
-
-    @Override
-    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
-            throws RemoteException {
-        ensureCallerSystemUid();
-        AuthenticationResult authResult;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
-                    tokenHandle, token, userId);
-            if (authResult.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return;
-            }
-        }
-        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-
-        pw.println("Current lock settings service state:");
-        pw.println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-
-        List<UserInfo> users = mUserManager.getUsers();
-        for (int user = 0; user < users.size(); user++) {
-            final int userId = users.get(user).id;
-            pw.println("    User " + userId);
-            synchronized (mSpManager) {
-                pw.println(String.format("        SP Handle = %x",
-                        getSyntheticPasswordHandleLocked(userId)));
-            }
-            try {
-                pw.println(String.format("        SID = %x",
-                        getGateKeeperService().getSecureUserId(userId)));
-            } catch (RemoteException e) {
-                // ignore.
-            }
-        }
-    }
-
-    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
-        long ident = Binder.clearCallingIdentity();
-        try {
-            // Managed profile should have escrow enabled
-            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                Slog.i(TAG, "Managed profile can have escrow token");
-                return;
-            }
-            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
-            // Devices with Device Owner should have escrow enabled on all users.
-            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
-                Slog.i(TAG, "Corp-owned device can have escrow token");
-                return;
-            }
-            // We could also have a profile owner on the given (non-managed) user for unicorn cases
-            if (dpm.getProfileOwnerAsUser(userId) != null) {
-                Slog.i(TAG, "User with profile owner can have escrow token");
-                return;
-            }
-            // If the device is yet to be provisioned (still in SUW), there is still
-            // a chance that Device Owner will be set on the device later, so postpone
-            // disabling escrow token for now.
-            if (!dpm.isDeviceProvisioned()) {
-                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
-                return;
-            }
-
-            // Escrow tokens are enabled on automotive builds.
-            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                return;
-            }
-
-            // Disable escrow token permanently on all other device/user types.
-            Slog.i(TAG, "Disabling escrow token on user " + userId);
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                mSpManager.destroyEscrowData(userId);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    private void ensureCallerSystemUid() throws SecurityException {
-        final int callingUid = mInjector.binderGetCallingUid();
-        if (callingUid != Process.SYSTEM_UID) {
-            throw new SecurityException("Only system can call this API.");
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java
deleted file mode 100644
index 9d671e39..0000000
--- a/services/core/java/com/android/server/LockSettingsShellCommand.java
+++ /dev/null
@@ -1,166 +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.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ShellCommand;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
-
-class LockSettingsShellCommand extends ShellCommand {
-
-    private static final String COMMAND_SET_PATTERN = "set-pattern";
-    private static final String COMMAND_SET_PIN = "set-pin";
-    private static final String COMMAND_SET_PASSWORD = "set-password";
-    private static final String COMMAND_CLEAR = "clear";
-    private static final String COMMAND_SP = "sp";
-    private static final String COMMAND_SET_DISABLED = "set-disabled";
-
-    private int mCurrentUserId;
-    private final LockPatternUtils mLockPatternUtils;
-    private final Context mContext;
-    private String mOld = "";
-    private String mNew = "";
-
-    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
-        mContext = context;
-        mLockPatternUtils = lockPatternUtils;
-    }
-
-    @Override
-    public int onCommand(String cmd) {
-        try {
-            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
-
-            parseArgs();
-            if (!checkCredential()) {
-                return -1;
-            }
-            switch (cmd) {
-                case COMMAND_SET_PATTERN:
-                    runSetPattern();
-                    break;
-                case COMMAND_SET_PASSWORD:
-                    runSetPassword();
-                    break;
-                case COMMAND_SET_PIN:
-                    runSetPin();
-                    break;
-                case COMMAND_CLEAR:
-                    runClear();
-                    break;
-                case COMMAND_SP:
-                    runEnableSp();
-                    break;
-                case COMMAND_SET_DISABLED:
-                    runSetDisabled();
-                    break;
-                default:
-                    getErrPrintWriter().println("Unknown command: " + cmd);
-                    break;
-            }
-            return 0;
-        } catch (Exception e) {
-            getErrPrintWriter().println("Error while executing command: " + cmd);
-            e.printStackTrace(getErrPrintWriter());
-            return -1;
-        }
-    }
-
-    @Override
-    public void onHelp() {
-    }
-
-    private void parseArgs() {
-        String opt;
-        while ((opt = getNextOption()) != null) {
-            if ("--old".equals(opt)) {
-                mOld = getNextArgRequired();
-            } else if ("--user".equals(opt)) {
-                mCurrentUserId = Integer.parseInt(getNextArgRequired());
-            } else {
-                getErrPrintWriter().println("Unknown option: " + opt);
-                throw new IllegalArgumentException();
-            }
-        }
-        mNew = getNextArg();
-    }
-
-    private void runEnableSp() {
-        if (mNew != null) {
-            mLockPatternUtils.enableSyntheticPassword();
-            getOutPrintWriter().println("Synthetic password enabled");
-        }
-        getOutPrintWriter().println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-    }
-
-    private void runSetPattern() throws RemoteException {
-        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
-        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
-    }
-
-    private void runSetPassword() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
-        getOutPrintWriter().println("Password set to '" + mNew + "'");
-    }
-
-    private void runSetPin() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
-        getOutPrintWriter().println("Pin set to '" + mNew + "'");
-    }
-
-    private void runClear() throws RemoteException {
-        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
-        getOutPrintWriter().println("Lock credential cleared");
-    }
-
-    private void runSetDisabled() throws RemoteException {
-        final boolean disabled = Boolean.parseBoolean(mNew);
-        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
-        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
-    }
-
-    private boolean checkCredential() throws RemoteException, RequestThrottledException {
-        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
-        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
-        if (havePassword || havePattern) {
-            boolean result;
-            if (havePassword) {
-                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
-            } else {
-                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
-                        mCurrentUserId);
-            }
-            if (result) {
-                return true;
-            } else {
-                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
deleted file mode 100644
index fe9bfd0..0000000
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ /dev/null
@@ -1,717 +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.android.server;
-
-import static android.content.Context.USER_SERVICE;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.os.Environment;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-/**
- * Storage for the lock settings service.
- */
-class LockSettingsStorage {
-
-    private static final String TAG = "LockSettingsStorage";
-    private static final String TABLE = "locksettings";
-    private static final boolean DEBUG = false;
-
-    private static final String COLUMN_KEY = "name";
-    private static final String COLUMN_USERID = "user";
-    private static final String COLUMN_VALUE = "value";
-
-    private static final String[] COLUMNS_FOR_QUERY = {
-            COLUMN_VALUE
-    };
-    private static final String[] COLUMNS_FOR_PREFETCH = {
-            COLUMN_KEY, COLUMN_VALUE
-    };
-
-    private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
-    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
-    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
-    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
-    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
-
-    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
-
-    private static final Object DEFAULT = new Object();
-
-    private final DatabaseHelper mOpenHelper;
-    private final Context mContext;
-    private final Cache mCache = new Cache();
-    private final Object mFileWriteLock = new Object();
-
-    @VisibleForTesting
-    public static class CredentialHash {
-        static final int VERSION_LEGACY = 0;
-        static final int VERSION_GATEKEEPER = 1;
-
-        private CredentialHash(byte[] hash, int type, int version) {
-            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                if (hash == null) {
-                    throw new RuntimeException("Empty hash for CredentialHash");
-                }
-            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
-                if (hash != null) {
-                    throw new RuntimeException("None type CredentialHash should not have hash");
-                }
-            }
-            this.hash = hash;
-            this.type = type;
-            this.version = version;
-            this.isBaseZeroPattern = false;
-        }
-
-        private CredentialHash(byte[] hash, boolean isBaseZeroPattern) {
-            this.hash = hash;
-            this.type = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            this.version = VERSION_GATEKEEPER;
-            this.isBaseZeroPattern = isBaseZeroPattern;
-        }
-
-        static CredentialHash create(byte[] hash, int type) {
-            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                throw new RuntimeException("Bad type for CredentialHash");
-            }
-            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
-        }
-
-        static CredentialHash createEmptyHash() {
-            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                    VERSION_GATEKEEPER);
-        }
-
-        byte[] hash;
-        int type;
-        int version;
-        boolean isBaseZeroPattern;
-    }
-
-    public LockSettingsStorage(Context context) {
-        mContext = context;
-        mOpenHelper = new DatabaseHelper(context);
-    }
-
-    public void setDatabaseOnCreateCallback(Callback callback) {
-        mOpenHelper.setCallback(callback);
-    }
-
-    public void writeKeyValue(String key, String value, int userId) {
-        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
-    }
-
-    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
-        ContentValues cv = new ContentValues();
-        cv.put(COLUMN_KEY, key);
-        cv.put(COLUMN_USERID, userId);
-        cv.put(COLUMN_VALUE, value);
-
-        db.beginTransaction();
-        try {
-            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
-                    new String[] {key, Integer.toString(userId)});
-            db.insert(TABLE, null, cv);
-            db.setTransactionSuccessful();
-            mCache.putKeyValue(key, value, userId);
-        } finally {
-            db.endTransaction();
-        }
-
-    }
-
-    public String readKeyValue(String key, String defaultValue, int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasKeyValue(key, userId)) {
-                return mCache.peekKeyValue(key, defaultValue, userId);
-            }
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        Object result = DEFAULT;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
-                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
-                new String[] { Integer.toString(userId), key },
-                null, null, null)) != null) {
-            if (cursor.moveToFirst()) {
-                result = cursor.getString(0);
-            }
-            cursor.close();
-        }
-        mCache.putKeyValueIfUnchanged(key, result, userId, version);
-        return result == DEFAULT ? defaultValue : (String) result;
-    }
-
-    public void prefetchUser(int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.isFetched(userId)) {
-                return;
-            }
-            mCache.setFetched(userId);
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
-                COLUMN_USERID + "=?",
-                new String[] { Integer.toString(userId) },
-                null, null, null)) != null) {
-            while (cursor.moveToNext()) {
-                String key = cursor.getString(0);
-                String value = cursor.getString(1);
-                mCache.putKeyValueIfUnchanged(key, value, userId, version);
-            }
-            cursor.close();
-        }
-
-        // Populate cache by reading the password and pattern files.
-        readCredentialHash(userId);
-    }
-
-    private CredentialHash readPasswordHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getLegacyLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    private CredentialHash readPatternHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getBaseZeroLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, true);
-        }
-
-        stored = readFile(getLegacyLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    public CredentialHash readCredentialHash(int userId) {
-        CredentialHash passwordHash = readPasswordHashIfExists(userId);
-        CredentialHash patternHash = readPatternHashIfExists(userId);
-        if (passwordHash != null && patternHash != null) {
-            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
-                return passwordHash;
-            } else {
-                return patternHash;
-            }
-        } else if (passwordHash != null) {
-            return passwordHash;
-        } else if (patternHash != null) {
-            return patternHash;
-        } else {
-            return CredentialHash.createEmptyHash();
-        }
-    }
-
-    public void removeChildProfileLock(int userId) {
-        if (DEBUG)
-            Slog.e(TAG, "Remove child profile lock for user: " + userId);
-        try {
-            deleteFile(getChildProfileLockFile(userId));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void writeChildProfileLock(int userId, byte[] lock) {
-        writeFile(getChildProfileLockFile(userId), lock);
-    }
-
-    public byte[] readChildProfileLock(int userId) {
-        return readFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasChildProfileLock(int userId) {
-        return hasFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasPassword(int userId) {
-        return hasFile(getLockPasswordFilename(userId)) ||
-            hasFile(getLegacyLockPasswordFilename(userId));
-    }
-
-    public boolean hasPattern(int userId) {
-        return hasFile(getLockPatternFilename(userId)) ||
-            hasFile(getBaseZeroLockPatternFilename(userId)) ||
-            hasFile(getLegacyLockPatternFilename(userId));
-    }
-
-    public boolean hasCredential(int userId) {
-        return hasPassword(userId) || hasPattern(userId);
-    }
-
-    private boolean hasFile(String name) {
-        byte[] contents = readFile(name);
-        return contents != null && contents.length > 0;
-    }
-
-    private byte[] readFile(String name) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasFile(name)) {
-                return mCache.peekFile(name);
-            }
-            version = mCache.getVersion();
-        }
-
-        RandomAccessFile raf = null;
-        byte[] stored = null;
-        try {
-            raf = new RandomAccessFile(name, "r");
-            stored = new byte[(int) raf.length()];
-            raf.readFully(stored, 0, stored.length);
-            raf.close();
-        } catch (IOException e) {
-            Slog.e(TAG, "Cannot read file " + e);
-        } finally {
-            if (raf != null) {
-                try {
-                    raf.close();
-                } catch (IOException e) {
-                    Slog.e(TAG, "Error closing file " + e);
-                }
-            }
-        }
-        mCache.putFileIfUnchanged(name, stored, version);
-        return stored;
-    }
-
-    private void writeFile(String name, byte[] hash) {
-        synchronized (mFileWriteLock) {
-            RandomAccessFile raf = null;
-            try {
-                // Write the hash to file, requiring each write to be synchronized to the
-                // underlying storage device immediately to avoid data loss in case of power loss.
-                // This also ensures future secdiscard operation on the file succeeds since the
-                // file would have been allocated on flash.
-                raf = new RandomAccessFile(name, "rws");
-                // Truncate the file if pattern is null, to clear the lock
-                if (hash == null || hash.length == 0) {
-                    raf.setLength(0);
-                } else {
-                    raf.write(hash, 0, hash.length);
-                }
-                raf.close();
-            } catch (IOException e) {
-                Slog.e(TAG, "Error writing to file " + e);
-            } finally {
-                if (raf != null) {
-                    try {
-                        raf.close();
-                    } catch (IOException e) {
-                        Slog.e(TAG, "Error closing file " + e);
-                    }
-                }
-            }
-            mCache.putFile(name, hash);
-        }
-    }
-
-    private void deleteFile(String name) {
-        if (DEBUG) Slog.e(TAG, "Delete file " + name);
-        synchronized (mFileWriteLock) {
-            File file = new File(name);
-            if (file.exists()) {
-                file.delete();
-                mCache.putFile(name, null);
-            }
-        }
-    }
-
-    public void writeCredentialHash(CredentialHash hash, int userId) {
-        byte[] patternHash = null;
-        byte[] passwordHash = null;
-
-        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            passwordHash = hash.hash;
-        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-            patternHash = hash.hash;
-        }
-        writeFile(getLockPasswordFilename(userId), passwordHash);
-        writeFile(getLockPatternFilename(userId), patternHash);
-    }
-
-    @VisibleForTesting
-    String getLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
-    }
-
-    private String getBaseZeroLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getChildProfileLockFile(int userId) {
-        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
-    }
-
-    private String getLockCredentialFilePathForUser(int userId, String basename) {
-        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
-                        SYSTEM_DIRECTORY;
-        if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + basename;
-        } else {
-            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
-        }
-    }
-
-    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
-        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
-    }
-
-    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
-        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
-    }
-
-    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
-        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
-        File file = new File(path);
-        if (file.exists()) {
-            try {
-                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to secdiscard " + path, e);
-            } finally {
-                file.delete();
-            }
-            mCache.putFile(path, null);
-        }
-    }
-
-    @VisibleForTesting
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
-    }
-
-    @VisibleForTesting
-    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
-            String name) {
-        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
-        String baseName = String.format("%016x.%s", handle, name);
-        if (!baseDir.exists()) {
-            baseDir.mkdir();
-        }
-        return new File(baseDir, baseName).getAbsolutePath();
-    }
-
-    public void removeUser(int userId) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
-        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-        final UserInfo parentInfo = um.getProfileParent(userId);
-
-        if (parentInfo == null) {
-            // This user owns its lock settings files - safe to delete them
-            synchronized (mFileWriteLock) {
-                String name = getLockPasswordFilename(userId);
-                File file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-                name = getLockPatternFilename(userId);
-                file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-            }
-        } else {
-            // Managed profile
-            removeChildProfileLock(userId);
-        }
-
-        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
-        try {
-            db.beginTransaction();
-            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
-            db.setTransactionSuccessful();
-            mCache.removeUser(userId);
-            // The directory itself will be deleted as part of user deletion operation by the
-            // framework, so only need to purge cache here.
-            //TODO: (b/34600579) invoke secdiscardable
-            mCache.purgePath(spStateDir.getAbsolutePath());
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    @VisibleForTesting
-    void closeDatabase() {
-        mOpenHelper.close();
-    }
-
-    @VisibleForTesting
-    void clearCache() {
-        mCache.clear();
-    }
-
-    public interface Callback {
-        void initialize(SQLiteDatabase db);
-    }
-
-    class DatabaseHelper extends SQLiteOpenHelper {
-        private static final String TAG = "LockSettingsDB";
-        private static final String DATABASE_NAME = "locksettings.db";
-
-        private static final int DATABASE_VERSION = 2;
-
-        private Callback mCallback;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            setWriteAheadLoggingEnabled(true);
-        }
-
-        public void setCallback(Callback callback) {
-            mCallback = callback;
-        }
-
-        private void createTable(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    COLUMN_KEY + " TEXT," +
-                    COLUMN_USERID + " INTEGER," +
-                    COLUMN_VALUE + " TEXT" +
-                    ");");
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            createTable(db);
-            if (mCallback != null) {
-                mCallback.initialize(db);
-            }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            int upgradeVersion = oldVersion;
-            if (upgradeVersion == 1) {
-                // Previously migrated lock screen widget settings. Now defunct.
-                upgradeVersion = 2;
-            }
-
-            if (upgradeVersion != DATABASE_VERSION) {
-                Log.w(TAG, "Failed to upgrade database!");
-            }
-        }
-    }
-
-    /**
-     * Cache consistency model:
-     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
-     *   section either provided by the database transaction or mWriteLock, such that writes to the
-     *   cache and writes to the backing storage are guaranteed to occur in the same order
-     *
-     * - Reads can populate the cache, but because they are no strong ordering guarantees with
-     *   respect to writes this precaution is taken:
-     *   - The cache is assigned a version number that increases every time the cache is modified.
-     *     Reads from backing storage can only populate the cache if the backing storage
-     *     has not changed since the load operation has begun.
-     *     This guarantees that no read operation can shadow a write to the cache that happens
-     *     after it had begun.
-     */
-    private static class Cache {
-        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
-        private final CacheKey mCacheKey = new CacheKey();
-        private int mVersion = 0;
-
-        String peekKeyValue(String key, String defaultValue, int userId) {
-            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
-            return cached == DEFAULT ? defaultValue : (String) cached;
-        }
-
-        boolean hasKeyValue(String key, int userId) {
-            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
-        }
-
-        void putKeyValue(String key, String value, int userId) {
-            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
-        }
-
-        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
-            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
-        }
-
-        byte[] peekFile(String fileName) {
-            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        boolean hasFile(String fileName) {
-            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        void putFile(String key, byte[] value) {
-            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
-        }
-
-        void putFileIfUnchanged(String key, byte[] value, int version) {
-            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
-        }
-
-        void setFetched(int userId) {
-            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
-        }
-
-        boolean isFetched(int userId) {
-            return contains(CacheKey.TYPE_FETCHED, "", userId);
-        }
-
-
-        private synchronized void put(int type, String key, Object value, int userId) {
-            // Create a new CachKey here because it may be saved in the map if the key is absent.
-            mCache.put(new CacheKey().set(type, key, userId), value);
-            mVersion++;
-        }
-
-        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
-                int version) {
-            if (!contains(type, key, userId) && mVersion == version) {
-                put(type, key, value, userId);
-            }
-        }
-
-        private synchronized boolean contains(int type, String key, int userId) {
-            return mCache.containsKey(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized Object peek(int type, String key, int userId) {
-            return mCache.get(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized int getVersion() {
-            return mVersion;
-        }
-
-        synchronized void removeUser(int userId) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                if (mCache.keyAt(i).userId == userId) {
-                    mCache.removeAt(i);
-                }
-            }
-
-            // Make sure in-flight loads can't write to cache.
-            mVersion++;
-        }
-
-        synchronized void purgePath(String path) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                CacheKey entry = mCache.keyAt(i);
-                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
-                    mCache.removeAt(i);
-                }
-            }
-            mVersion++;
-        }
-
-        synchronized void clear() {
-            mCache.clear();
-            mVersion++;
-        }
-
-        private static final class CacheKey {
-            static final int TYPE_KEY_VALUE = 0;
-            static final int TYPE_FILE = 1;
-            static final int TYPE_FETCHED = 2;
-
-            String key;
-            int userId;
-            int type;
-
-            public CacheKey set(int type, String key, int userId) {
-                this.type = type;
-                this.key = key;
-                this.userId = userId;
-                return this;
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                if (!(obj instanceof CacheKey))
-                    return false;
-                CacheKey o = (CacheKey) obj;
-                return userId == o.userId && type == o.type && key.equals(o.key);
-            }
-
-            @Override
-            public int hashCode() {
-                return key.hashCode() ^ userId ^ type;
-            }
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
deleted file mode 100644
index f5fe3db..0000000
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.admin.DevicePolicyManager;
-import android.app.trust.IStrongAuthTracker;
-import android.content.Context;
-import android.os.Binder;
-import android.os.DeadObjectException;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-import android.util.SparseIntArray;
-
-import java.util.ArrayList;
-
-/**
- * Keeps track of requests for strong authentication.
- */
-public class LockSettingsStrongAuth {
-
-    private static final String TAG = "LockSettings";
-
-    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
-    private static final int MSG_REGISTER_TRACKER = 2;
-    private static final int MSG_UNREGISTER_TRACKER = 3;
-    private static final int MSG_REMOVE_USER = 4;
-    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
-
-    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
-            "LockSettingsStrongAuth.timeoutForUser";
-
-    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
-    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
-    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
-            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
-    private final int mDefaultStrongAuthFlags;
-    private final Context mContext;
-
-    private AlarmManager mAlarmManager;
-
-    public LockSettingsStrongAuth(Context context) {
-        mContext = context;
-        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
-        mAlarmManager = context.getSystemService(AlarmManager.class);
-    }
-
-    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                return;
-            }
-        }
-        mStrongAuthTrackers.add(tracker);
-
-        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-            int key = mStrongAuthForUser.keyAt(i);
-            int value = mStrongAuthForUser.valueAt(i);
-            try {
-                tracker.onStrongAuthRequiredChanged(value, key);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                mStrongAuthTrackers.remove(i);
-                return;
-            }
-        }
-    }
-
-    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-                int key = mStrongAuthForUser.keyAt(i);
-                handleRequireStrongAuthOneUser(strongAuthReason, key);
-            }
-        } else {
-            handleRequireStrongAuthOneUser(strongAuthReason, userId);
-        }
-    }
-
-    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
-        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
-        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
-                ? STRONG_AUTH_NOT_REQUIRED
-                : (oldValue | strongAuthReason);
-        if (oldValue != newValue) {
-            mStrongAuthForUser.put(userId, newValue);
-            notifyStrongAuthTrackers(newValue, userId);
-        }
-    }
-
-    private void handleRemoveUser(int userId) {
-        int index = mStrongAuthForUser.indexOfKey(userId);
-        if (index >= 0) {
-            mStrongAuthForUser.removeAt(index);
-            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
-        }
-    }
-
-    private void handleScheduleStrongAuthTimeout(int userId) {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
-        // cancel current alarm listener for the user (if there was one)
-        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
-        if (alarm != null) {
-            mAlarmManager.cancel(alarm);
-        } else {
-            alarm = new StrongAuthTimeoutAlarmListener(userId);
-            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
-        }
-        // schedule a new alarm listener for the user
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
-                alarm, mHandler);
-    }
-
-    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            try {
-                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
-            } catch (DeadObjectException e) {
-                Slog.d(TAG, "Removing dead StrongAuthTracker.");
-                mStrongAuthTrackers.remove(i);
-                i--;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void removeUser(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
-    }
-
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
-            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
-                    userId).sendToTarget();
-        } else {
-            throw new IllegalArgumentException(
-                    "userId must be an explicit user id or USER_ALL");
-        }
-    }
-
-    public void reportUnlock(int userId) {
-        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
-    }
-
-    public void reportSuccessfulStrongAuthUnlock(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
-    }
-
-    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
-
-        private final int mUserId;
-
-        public StrongAuthTimeoutAlarmListener(int userId) {
-            mUserId = userId;
-        }
-
-        @Override
-        public void onAlarm() {
-            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_REGISTER_TRACKER:
-                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_UNREGISTER_TRACKER:
-                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_REQUIRE_STRONG_AUTH:
-                    handleRequireStrongAuth(msg.arg1, msg.arg2);
-                    break;
-                case MSG_REMOVE_USER:
-                    handleRemoveUser(msg.arg1);
-                    break;
-                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
-                    handleScheduleStrongAuthTimeout(msg.arg1);
-                    break;
-            }
-        }
-    };
-}
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 26e471e..06c46b9 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.PendingIntent;
 import android.app.ProgressDialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -23,6 +24,8 @@
 import android.os.AsyncTask;
 import android.os.RecoverySystem;
 import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 import android.util.Slog;
 import android.view.WindowManager;
@@ -30,9 +33,13 @@
 import com.android.internal.R;
 
 import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class MasterClearReceiver extends BroadcastReceiver {
     private static final String TAG = "MasterClear";
+    private boolean mWipeExternalStorage;
+    private boolean mWipeEsims;
 
     @Override
     public void onReceive(final Context context, final Intent intent) {
@@ -53,8 +60,8 @@
 
         final boolean shutdown = intent.getBooleanExtra("shutdown", false);
         final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
-        final boolean wipeExternalStorage = intent.getBooleanExtra(
-                Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
+        mWipeExternalStorage = intent.getBooleanExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
+        mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false);
         final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false)
                 || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false);
 
@@ -64,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);
@@ -74,20 +82,20 @@
             }
         };
 
-        if (wipeExternalStorage) {
+        if (mWipeExternalStorage || mWipeEsims) {
             // thr will be started at the end of this task.
-            new WipeAdoptableDisksTask(context, thr).execute();
+            new WipeDataTask(context, thr).execute();
         } else {
             thr.start();
         }
     }
 
-    private class WipeAdoptableDisksTask extends AsyncTask<Void, Void, Void> {
+    private class WipeDataTask extends AsyncTask<Void, Void, Void> {
         private final Thread mChainedTask;
         private final Context mContext;
         private final ProgressDialog mProgressDialog;
 
-        public WipeAdoptableDisksTask(Context context, Thread chainedTask) {
+        public WipeDataTask(Context context, Thread chainedTask) {
             mContext = context;
             mChainedTask = chainedTask;
             mProgressDialog = new ProgressDialog(context);
@@ -104,9 +112,11 @@
         @Override
         protected Void doInBackground(Void... params) {
             Slog.w(TAG, "Wiping adoptable disks");
-            StorageManager sm = (StorageManager) mContext.getSystemService(
-                    Context.STORAGE_SERVICE);
-            sm.wipeAdoptableDisks();
+            if (mWipeExternalStorage) {
+                StorageManager sm = (StorageManager) mContext.getSystemService(
+                        Context.STORAGE_SERVICE);
+                sm.wipeAdoptableDisks();
+            }
             return null;
         }
 
diff --git a/services/core/java/com/android/server/OemLockService.java b/services/core/java/com/android/server/OemLockService.java
deleted file mode 100644
index 03f82a8..0000000
--- a/services/core/java/com/android/server/OemLockService.java
+++ /dev/null
@@ -1,147 +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.
- */
-
-package com.android.server;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.service.oemlock.IOemLockService;
-import android.service.persistentdata.PersistentDataBlockManager;
-
-/**
- * Service for managing the OEM lock state of the device.
- *
- * The current implementation is a wrapper around the previous implementation of OEM lock.
- *  - the DISALLOW_OEM_UNLOCK user restriction was set if the carrier disallowed unlock
- *  - the user allows unlock in settings which calls PDBM.setOemUnlockEnabled()
- */
-public class OemLockService extends SystemService {
-    private Context mContext;
-
-    public OemLockService(Context context) {
-        super(context);
-        mContext = context;
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.OEM_LOCK_SERVICE, mService);
-    }
-
-    private boolean doIsOemUnlockAllowedByCarrier() {
-        return !UserManager.get(mContext).hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK);
-    }
-
-    private boolean doIsOemUnlockAllowedByUser() {
-        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
-            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return pdbm.getOemUnlockEnabled();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Implements the binder interface for the service.
-     */
-    private final IBinder mService = new IOemLockService.Stub() {
-        @Override
-        public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
-            enforceManageCarrierOemUnlockPermission();
-            enforceUserIsAdmin();
-
-            // Note: this implementation does not require a signature
-
-            // Continue using user restriction for backwards compatibility
-            final UserHandle userHandle = UserHandle.of(UserHandle.getCallingUserId());
-            final long token = Binder.clearCallingIdentity();
-            try {
-                UserManager.get(mContext)
-                        .setUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, !allowed, userHandle);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public boolean isOemUnlockAllowedByCarrier() {
-            enforceManageCarrierOemUnlockPermission();
-            return doIsOemUnlockAllowedByCarrier();
-        }
-
-        @Override
-        public void setOemUnlockAllowedByUser(boolean allowedByUser) {
-            if (ActivityManager.isUserAMonkey()) {
-                // Prevent a monkey from changing this
-                return;
-            }
-
-            enforceManageUserOemUnlockPermission();
-            enforceUserIsAdmin();
-
-            final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
-                    mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-
-            final long token = Binder.clearCallingIdentity();
-            try {
-                // The method name is misleading as it really just means whether or not the device
-                // can be unlocked but doesn't actually do any unlocking.
-                pdbm.setOemUnlockEnabled(allowedByUser);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public boolean isOemUnlockAllowedByUser() {
-            enforceManageUserOemUnlockPermission();
-            return doIsOemUnlockAllowedByUser();
-        }
-    };
-
-    private void enforceManageCarrierOemUnlockPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE,
-                "Can't manage OEM unlock allowed by carrier");
-    }
-
-    private void enforceManageUserOemUnlockPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE,
-                "Can't manage OEM unlock allowed by user");
-    }
-
-    private void enforceUserIsAdmin() {
-        final int userId = UserHandle.getCallingUserId();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            if (!UserManager.get(mContext).isUserAdmin(userId)) {
-                throw new SecurityException("Must be an admin user");
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java
new file mode 100644
index 0000000..80f8e51
--- /dev/null
+++ b/services/core/java/com/android/server/PersistentDataBlockManagerInternal.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Internal interface for storing and retrieving persistent data.
+ */
+public interface PersistentDataBlockManagerInternal {
+
+    /** Stores the handle to a lockscreen credential to be used for Factory Reset Protection. */
+    void setFrpCredentialHandle(byte[] handle);
+
+    /** Retrieves handle to a lockscreen credential to be used for Factory Reset Protection. */
+    byte[] getFrpCredentialHandle();
+}
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index e3cd87c..1d4c3db 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 
 import libcore.io.IoUtils;
 
@@ -71,8 +72,13 @@
     private static final int HEADER_SIZE = 8;
     // Magic number to mark block device as adhering to the format consumed by this service
     private static final int PARTITION_TYPE_MARKER = 0x19901873;
+    /** Size of the block reserved for FPR credential, including 4 bytes for the size header. */
+    private static final int FRP_CREDENTIAL_RESERVED_SIZE = 1000;
+    /** Maximum size of the FRP credential handle that can be stored. */
+    private static final int MAX_FRP_CREDENTIAL_HANDLE_SIZE = FRP_CREDENTIAL_RESERVED_SIZE - 4;
     // Limit to 100k as blocks larger than this might cause strain on Binder.
     private static final int MAX_DATA_BLOCK_SIZE = 1024 * 100;
+
     public static final int DIGEST_SIZE_BYTES = 32;
     private static final String OEM_UNLOCK_PROP = "sys.oem_unlock_allowed";
     private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked";
@@ -136,6 +142,7 @@
                 Thread.currentThread().interrupt();
                 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
             }
+            LocalServices.addService(PersistentDataBlockManagerInternal.class, mInternalService);
         }
         super.onBootPhase(phase);
     }
@@ -382,7 +389,7 @@
             enforceUid(Binder.getCallingUid());
 
             // Need to ensure we don't write over the last byte
-            long maxBlockSize = getBlockDeviceSize() - HEADER_SIZE - 1;
+            long maxBlockSize = getMaximumDataBlockSize();
             if (data.length > maxBlockSize) {
                 // partition is ~500k so shouldn't be a problem to downcast
                 return (int) -maxBlockSize;
@@ -562,8 +569,99 @@
 
         @Override
         public long getMaximumDataBlockSize() {
-            long actualSize = getBlockDeviceSize() - HEADER_SIZE - 1;
+            long actualSize = getBlockDeviceSize() - HEADER_SIZE - DIGEST_SIZE_BYTES
+                    - FRP_CREDENTIAL_RESERVED_SIZE - 1;
             return actualSize <= MAX_DATA_BLOCK_SIZE ? actualSize : MAX_DATA_BLOCK_SIZE;
         }
+
+        @Override
+        public boolean hasFrpCredentialHandle() {
+            enforcePersistentDataBlockAccess();
+            return mInternalService.getFrpCredentialHandle() != null;
+        }
+    };
+
+    private PersistentDataBlockManagerInternal mInternalService =
+            new PersistentDataBlockManagerInternal() {
+
+        @Override
+        public void setFrpCredentialHandle(byte[] handle) {
+            Preconditions.checkArgument(handle == null || handle.length > 0,
+                    "handle must be null or non-empty");
+            Preconditions.checkArgument(handle == null
+                            || handle.length <= MAX_FRP_CREDENTIAL_HANDLE_SIZE,
+                    "handle must not be longer than " + MAX_FRP_CREDENTIAL_HANDLE_SIZE);
+
+            FileOutputStream outputStream;
+            try {
+                outputStream = new FileOutputStream(new File(mDataBlockFile));
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "partition not available", e);
+                return;
+            }
+
+            ByteBuffer data = ByteBuffer.allocate(FRP_CREDENTIAL_RESERVED_SIZE);
+            data.putInt(handle == null ? 0 : handle.length);
+            if (handle != null) {
+                data.put(handle);
+            }
+            data.flip();
+
+            synchronized (mLock) {
+                if (!mIsWritable) {
+                    IoUtils.closeQuietly(outputStream);
+                    return;
+                }
+
+                try {
+                    FileChannel channel = outputStream.getChannel();
+
+                    channel.position(getBlockDeviceSize() - 1 - FRP_CREDENTIAL_RESERVED_SIZE);
+                    channel.write(data);
+                    outputStream.flush();
+                } catch (IOException e) {
+                    Slog.e(TAG, "unable to access persistent partition", e);
+                    return;
+                } finally {
+                    IoUtils.closeQuietly(outputStream);
+                }
+
+                computeAndWriteDigestLocked();
+            }
+        }
+
+        @Override
+        public byte[] getFrpCredentialHandle() {
+            if (!enforceChecksumValidity()) {
+                return null;
+            }
+
+            DataInputStream inputStream;
+            try {
+                inputStream = new DataInputStream(
+                        new FileInputStream(new File(mDataBlockFile)));
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "partition not available");
+                return null;
+            }
+
+            try {
+                synchronized (mLock) {
+                    inputStream.skip(getBlockDeviceSize() - 1 - FRP_CREDENTIAL_RESERVED_SIZE);
+                    int length = inputStream.readInt();
+                    if (length <= 0 || length > MAX_FRP_CREDENTIAL_HANDLE_SIZE) {
+                        return null;
+                    }
+                    byte[] bytes = new byte[length];
+                    inputStream.readFully(bytes);
+                    return bytes;
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "unable to access persistent partition", e);
+                return null;
+            } finally {
+                IoUtils.closeQuietly(inputStream);
+            }
+        }
     };
 }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 45f9025..3d7408e 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -267,9 +267,10 @@
 
         // determine the ABI from either ApplicationInfo or Build
         String arch = "arm";
-        if (cameraInfo.primaryCpuAbi != null
-            && VMRuntime.is64BitAbi(cameraInfo.primaryCpuAbi)) {
-            arch = arch + "64";
+        if (cameraInfo.primaryCpuAbi != null) {
+            if (VMRuntime.is64BitAbi(cameraInfo.primaryCpuAbi)) {
+                arch = arch + "64";
+            }
         } else {
             if (VMRuntime.is64BitAbi(Build.SUPPORTED_ABIS[0])) {
                 arch = arch + "64";
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 35b452a..383cc8b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -90,14 +90,12 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.os.AppFuseMount;
-import com.android.internal.os.FuseAppLoop;
 import com.android.internal.os.FuseUnavailableMountException;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.Zygote;
@@ -143,7 +141,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
-import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -2958,6 +2955,11 @@
         synchronized (mLock) {
             mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
         }
+        if (userId == UserHandle.USER_SYSTEM) {
+            String propertyName = "sys.user." + userId + ".ce_available";
+            Slog.d(TAG, "Setting property: " + propertyName + "=true");
+            SystemProperties.set(propertyName, "true");
+        }
     }
 
     @Override
@@ -3291,20 +3293,41 @@
         }
     }
 
-    @Override
-    public long getAllocatableBytes(String volumeUuid, int flags) {
-        final StorageManager storage = mContext.getSystemService(StorageManager.class);
-        final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
-
-        // Apps can't defy reserved space
-        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
-
-        final boolean aggressive = (flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
-        if (aggressive) {
+    private int adjustAllocateFlags(int flags, int callingUid, String callingPackage) {
+        // Require permission to allocate aggressively
+        if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.ALLOCATE_AGGRESSIVE, TAG);
         }
 
+        // Apps normally can't directly defy reserved space
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED;
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED;
+
+        // However, if app is actively using the camera, then we're willing to
+        // clear up to half of the reserved cache space, since the user might be
+        // trying to capture an important memory.
+        final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (appOps.isOperationActive(AppOpsManager.OP_CAMERA, callingUid, callingPackage)) {
+                Slog.d(TAG, "UID " + callingUid + " is actively using camera;"
+                        + " letting them defy reserved cached data");
+                flags |= StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        return flags;
+    }
+
+    @Override
+    public long getAllocatableBytes(String volumeUuid, int flags, String callingPackage) {
+        flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
+
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
         final long token = Binder.clearCallingIdentity();
         try {
             // In general, apps can allocate as much space as they want, except
@@ -3319,18 +3342,18 @@
 
             if (stats.isQuotaSupported(volumeUuid)) {
                 final long cacheTotal = stats.getCacheBytes(volumeUuid);
-                final long cacheReserved = storage.getStorageCacheBytes(path);
+                final long cacheReserved = storage.getStorageCacheBytes(path, flags);
                 final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
 
-                if (aggressive) {
-                    return Math.max(0, (usable + cacheTotal) - fullReserved);
+                if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+                    return Math.max(0, (usable + cacheClearable) - fullReserved);
                 } else {
                     return Math.max(0, (usable + cacheClearable) - lowReserved);
                 }
             } else {
                 // When we don't have fast quota information, we ignore cached
                 // data and only consider unused bytes.
-                if (aggressive) {
+                if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
                     return Math.max(0, usable - fullReserved);
                 } else {
                     return Math.max(0, usable - lowReserved);
@@ -3344,20 +3367,16 @@
     }
 
     @Override
-    public void allocateBytes(String volumeUuid, long bytes, int flags) {
-        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+    public void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) {
+        flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
 
-        // Apps can't defy reserved space
-        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
-
-        // This method call will enforce FLAG_ALLOCATE_AGGRESSIVE permissions so
-        // we don't have to enforce them locally
-        final long allocatableBytes = getAllocatableBytes(volumeUuid, flags);
+        final long allocatableBytes = getAllocatableBytes(volumeUuid, flags, callingPackage);
         if (bytes > allocatableBytes) {
             throw new ParcelableException(new IOException("Failed to allocate " + bytes
                     + " because only " + allocatableBytes + " allocatable"));
         }
 
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final long token = Binder.clearCallingIdentity();
         try {
             // Free up enough disk space to satisfy both the requested allocation
diff --git a/services/core/java/com/android/server/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/SyntheticPasswordCrypto.java
deleted file mode 100644
index 71ab2a5..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordCrypto.java
+++ /dev/null
@@ -1,196 +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.
- */
-
-package com.android.server;
-
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Arrays;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-public class SyntheticPasswordCrypto {
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
-    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
-    // Time between the user credential is verified with GK and the decryption of synthetic password
-    // under the auth-bound key. This should always happen one after the other, but give it 15
-    // seconds just to be sure.
-    private static final int USER_AUTHENTICATION_VALIDITY = 15;
-
-    private static byte[] decrypt(SecretKey key, byte[] blob)
-            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
-        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
-        return cipher.doFinal(ciphertext);
-    }
-
-    private static byte[] encrypt(SecretKey key, byte[] blob)
-            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
-            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        Cipher cipher = Cipher.getInstance(
-                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                        + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.ENCRYPT_MODE, key);
-        byte[] ciphertext = cipher.doFinal(blob);
-        byte[] iv = cipher.getIV();
-        if (iv.length != PROFILE_KEY_IV_SIZE) {
-            throw new RuntimeException("Invalid iv length: " + iv.length);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        outputStream.write(iv);
-        outputStream.write(ciphertext);
-        return outputStream.toByteArray();
-    }
-
-    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return encrypt(key, message);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException | IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return decrypt(key, ciphertext);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
-        try {
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-
-            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
-            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
-            return decrypt(decryptionKey, intermediate);
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException | UnrecoverableKeyException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to decrypt blob", e);
-        }
-    }
-
-    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                    .setCriticalToDeviceEncryption(true);
-            if (sid != 0) {
-                builder.setUserAuthenticationRequired(true)
-                        .setBoundToSpecificSecureUserId(sid)
-                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
-            }
-
-            keyStore.setEntry(keyAlias,
-                    new KeyStore.SecretKeyEntry(secretKey),
-                    builder.build());
-            byte[] intermediate = encrypt(secretKey, data);
-            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
-
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to encrypt blob", e);
-        }
-    }
-
-    public static void destroyBlobKey(String keyAlias) {
-        KeyStore keyStore;
-        try {
-            keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(keyAlias);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
-        try {
-            final int PADDING_LENGTH = 128;
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            if (personalisation.length > PADDING_LENGTH) {
-                throw new RuntimeException("Personalisation too long");
-            }
-            // Personalize the hash
-            // Pad it to the block size of the hash function
-            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
-            digest.update(personalisation);
-            for (byte[] data : message) {
-                digest.update(data);
-            }
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/SyntheticPasswordManager.java b/services/core/java/com/android/server/SyntheticPasswordManager.java
deleted file mode 100644
index 1d17ff7..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordManager.java
+++ /dev/null
@@ -1,707 +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.
- */
-package com.android.server;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-
-import libcore.util.HexEncoding;
-
-import java.nio.ByteBuffer;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-
-
-/**
- * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
- * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
- * synthetic password blobs which are wrapped by user credentials or escrow tokens.
- *
- * Here is the assumptions it makes:
- *   Each user has one single synthetic password at any time.
- *   The SP has an associated password handle, which binds to the SID for that user. The password
- *   handle is persisted by SyntheticPasswordManager internally.
- *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
- *
- * Information persisted on disk:
- *   for each user (stored under DEFAULT_HANDLE):
- *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
- *                     credential exists, cleared when user clears their credential.
- *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
- *                     tokens. Destroyed when escrow support is turned off for the given user.
- *
- *     for each SP blob under the user (stored under the corresponding handle):
- *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
- *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
- *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
- *                            purpose of secure deletion.
- *
- */
-public class SyntheticPasswordManager {
-    private static final String SP_BLOB_NAME = "spblob";
-    private static final String SP_E0_NAME = "e0";
-    private static final String SP_P1_NAME = "p1";
-    private static final String SP_HANDLE_NAME = "handle";
-    private static final String SECDISCARDABLE_NAME = "secdis";
-    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
-    private static final String PASSWORD_DATA_NAME = "pwd";
-
-    public static final long DEFAULT_HANDLE = 0;
-    private static final String DEFAULT_PASSWORD = "default-password";
-
-    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
-    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
-    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
-
-    // 256-bit synthetic password
-    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
-
-    private static final int PASSWORD_SCRYPT_N = 11;
-    private static final int PASSWORD_SCRYPT_R = 3;
-    private static final int PASSWORD_SCRYPT_P = 1;
-    private static final int PASSWORD_SALT_LENGTH = 16;
-    private static final int PASSWORD_TOKEN_LENGTH = 32;
-    private static final String TAG = "SyntheticPasswordManager";
-
-    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
-    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
-    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
-    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
-    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
-
-    static class AuthenticationResult {
-        public AuthenticationToken authToken;
-        public VerifyCredentialResponse gkResponse;
-    }
-
-    static class AuthenticationToken {
-        /*
-         * Here is the relationship between all three fields:
-         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
-         * syntheticPassword = hash(P0 || P1)
-         * E0 = P0 encrypted under syntheticPassword, stored on disk.
-         */
-        private @Nullable byte[] E0;
-        private @Nullable byte[] P1;
-        private @NonNull String syntheticPassword;
-
-        public String deriveKeyStorePassword() {
-            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
-                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
-        }
-
-        public byte[] deriveGkPassword() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
-                    syntheticPassword.getBytes());
-        }
-
-        public byte[] deriveDiskEncryptionKey() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
-                    syntheticPassword.getBytes());
-        }
-
-        private void initialize(byte[] P0, byte[] P1) {
-            this.P1 = P1;
-            this.syntheticPassword = String.valueOf(HexEncoding.encode(
-                    SyntheticPasswordCrypto.personalisedHash(
-                            PERSONALIZATION_SP_SPLIT, P0, P1)));
-            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
-                    PERSONALIZATION_E0, P0);
-        }
-
-        public void recreate(byte[] secret) {
-            initialize(secret, this.P1);
-        }
-
-        protected static AuthenticationToken create() {
-            AuthenticationToken result = new AuthenticationToken();
-            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
-                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
-            return result;
-        }
-
-        public byte[] computeP0() {
-            if (E0 == null) {
-                return null;
-            }
-            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
-                    E0);
-        }
-    }
-
-    static class PasswordData {
-        byte scryptN;
-        byte scryptR;
-        byte scryptP;
-        public int passwordType;
-        byte[] salt;
-        public byte[] passwordHandle;
-
-        public static PasswordData create(int passwordType) {
-            PasswordData result = new PasswordData();
-            result.scryptN = PASSWORD_SCRYPT_N;
-            result.scryptR = PASSWORD_SCRYPT_R;
-            result.scryptP = PASSWORD_SCRYPT_P;
-            result.passwordType = passwordType;
-            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
-            return result;
-        }
-
-        public static PasswordData fromBytes(byte[] data) {
-            PasswordData result = new PasswordData();
-            ByteBuffer buffer = ByteBuffer.allocate(data.length);
-            buffer.put(data, 0, data.length);
-            buffer.flip();
-            result.passwordType = buffer.getInt();
-            result.scryptN = buffer.get();
-            result.scryptR = buffer.get();
-            result.scryptP = buffer.get();
-            int saltLen = buffer.getInt();
-            result.salt = new byte[saltLen];
-            buffer.get(result.salt);
-            int handleLen = buffer.getInt();
-            result.passwordHandle = new byte[handleLen];
-            buffer.get(result.passwordHandle);
-            return result;
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
-                    + Integer.BYTES + salt.length + Integer.BYTES + passwordHandle.length);
-            buffer.putInt(passwordType);
-            buffer.put(scryptN);
-            buffer.put(scryptR);
-            buffer.put(scryptP);
-            buffer.putInt(salt.length);
-            buffer.put(salt);
-            buffer.putInt(passwordHandle.length);
-            buffer.put(passwordHandle);
-            return buffer.array();
-        }
-    }
-
-    private LockSettingsStorage mStorage;
-
-    public SyntheticPasswordManager(LockSettingsStorage storage) {
-        mStorage = storage;
-    }
-
-
-    public int getCredentialType(long handle, int userId) {
-        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
-        if (passwordData == null) {
-            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
-            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
-        }
-        return PasswordData.fromBytes(passwordData).passwordType;
-    }
-
-    /**
-     * Initializing a new Authentication token, possibly from an existing credential and hash.
-     *
-     * The authentication token would bear a randomly-generated synthetic password.
-     *
-     * This method has the side effect of rebinding the SID of the given user to the
-     * newly-generated SP.
-     *
-     * If the existing credential hash is non-null, the existing SID mill be migrated so
-     * the synthetic password in the authentication token will produce the same SID
-     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
-     * in a per-user data storage.)
-     *
-     * If the existing credential hash is null, it means the given user should have no SID so
-     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
-     * the supplied credential parameter is also ignored.
-     *
-     * Also saves the escrow information necessary to re-generate the synthetic password under
-     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
-     * password escrow should be disabled completely on the given user.
-     *
-     */
-    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
-            byte[] hash, String credential, int userId) throws RemoteException {
-        AuthenticationToken result = AuthenticationToken.create();
-        GateKeeperResponse response;
-        if (hash != null) {
-            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
-                    result.deriveGkPassword());
-            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
-                clearSidForUser(userId);
-            } else {
-                saveSyntheticPasswordHandle(response.getPayload(), userId);
-            }
-        } else {
-            clearSidForUser(userId);
-        }
-        saveEscrowData(result, userId);
-        return result;
-    }
-
-    /**
-     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
-     * Used when adding password to previously-unsecured devices.
-     */
-    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
-            int userId) throws RemoteException {
-        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
-                authToken.deriveGkPassword());
-        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-            Log.e(TAG, "Fail to create new SID for user " + userId);
-            return;
-        }
-        saveSyntheticPasswordHandle(response.getPayload(), userId);
-    }
-
-    // Nuke the SP handle (and as a result, its SID) for the given user.
-    public void clearSidForUser(int userId) {
-        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasSidForUser(int userId) {
-        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    // if null, it means there is no SID associated with the user
-    // This can happen if the user is migrated to SP but currently
-    // do not have a lockscreen password.
-    private byte[] loadSyntheticPasswordHandle(int userId) {
-        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
-        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
-    }
-
-    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
-        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-        return authToken.E0 != null && authToken.P1 != null;
-    }
-
-    private void saveEscrowData(AuthenticationToken authToken, int userId) {
-        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
-        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasEscrowData(int userId) {
-        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
-                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    public void destroyEscrowData(int userId) {
-        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    /**
-     * Create a new password based SP blob based on the supplied authentication token, such that
-     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
-     * in the same authentication token.
-     *
-     * This method only creates SP blob wrapping around the given synthetic password and does not
-     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
-     * is consistent with the device state by calling other APIs in this class.
-     *
-     * @see #newSidForUser
-     * @see #clearSidForUser
-     */
-    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            String credential, int credentialType, AuthenticationToken authToken, int userId)
-                    throws RemoteException {
-        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
-            credential = DEFAULT_PASSWORD;
-        }
-
-        long handle = generateHandle();
-        PasswordData pwd = PasswordData.create(credentialType);
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-
-        // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
-        // to prevent them from accumulating and causing problems.
-        gatekeeper.clearSecureUserId(fakeUid(userId));
-        GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
-                passwordTokenToGkInput(pwdToken));
-        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-            Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
-            return DEFAULT_HANDLE;
-        }
-        pwd.passwordHandle = response.getPayload();
-        long sid = sidFromPasswordHandle(pwd.passwordHandle);
-        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-
-        byte[] applicationId = transformUnderSecdiscardable(pwdToken,
-                createSecdiscardable(handle, userId));
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
-                applicationId, sid, userId);
-        return handle;
-    }
-
-    private ArrayMap<Integer, ArrayMap<Long, byte[]>> tokenMap = new ArrayMap<>();
-
-    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
-        long handle = generateHandle();
-        byte[] applicationId = transformUnderSecdiscardable(token,
-                createSecdiscardable(handle, userId));
-        if (!tokenMap.containsKey(userId)) {
-            tokenMap.put(userId, new ArrayMap<>());
-        }
-        tokenMap.get(userId).put(handle, applicationId);
-        return handle;
-    }
-
-    public Set<Long> getPendingTokensForUser(int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return Collections.emptySet();
-        }
-        return tokenMap.get(userId).keySet();
-    }
-
-    public boolean removePendingToken(long handle, int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        return tokenMap.get(userId).remove(handle) != null;
-    }
-
-    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
-            int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        byte[] applicationId = tokenMap.get(userId).get(handle);
-        if (applicationId == null) {
-            return false;
-        }
-        if (!loadEscrowData(authToken, userId)) {
-            Log.w(TAG, "User is not escrowable");
-            return false;
-        }
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
-                applicationId, 0L, userId);
-        tokenMap.get(userId).remove(handle);
-        return true;
-    }
-
-    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
-            byte[] applicationId, long sid, int userId) {
-        final byte[] secret;
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            secret = authToken.computeP0();
-        } else {
-            secret = authToken.syntheticPassword.getBytes();
-        }
-        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
-        byte[] blob = new byte[content.length + 1 + 1];
-        blob[0] = SYNTHETIC_PASSWORD_VERSION;
-        blob[1] = type;
-        System.arraycopy(content, 0, blob, 2, content.length);
-        saveState(SP_BLOB_NAME, blob, handle, userId);
-    }
-
-    /**
-     * 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.
-     */
-    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            long handle, String credential, int userId) throws RemoteException {
-        if (credential == null) {
-            credential = DEFAULT_PASSWORD;
-        }
-        AuthenticationResult result = new AuthenticationResult();
-        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-        byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
-
-        GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
-                pwd.passwordHandle, gkPwdToken);
-        int responseCode = response.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            result.gkResponse = VerifyCredentialResponse.OK;
-            if (response.getShouldReEnroll()) {
-                GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
-                        pwd.passwordHandle, gkPwdToken, gkPwdToken);
-                if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    pwd.passwordHandle = reenrollResponse.getPayload();
-                    saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-                } else {
-                    Log.w(TAG, "Fail to re-enroll user password for user " + userId);
-                    // continue the flow anyway
-                }
-            }
-        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
-            return result;
-        } else  {
-            result.gkResponse = VerifyCredentialResponse.ERROR;
-            return result;
-        }
-
-
-        byte[] applicationId = transformUnderSecdiscardable(pwdToken,
-                loadSecdiscardable(handle, userId));
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
-                applicationId, userId);
-
-        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
-        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-        return result;
-    }
-
-    /**
-     * Decrypt a synthetic password by supplying an escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
-     */
-    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
-                    throws RemoteException {
-        AuthenticationResult result = new AuthenticationResult();
-        byte[] applicationId = transformUnderSecdiscardable(token,
-                loadSecdiscardable(handle, userId));
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
-                applicationId, userId);
-        if (result.authToken != null) {
-            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-            if (result.gkResponse == null) {
-                // The user currently has no password. return OK with null payload so null
-                // is propagated to unlockUser()
-                result.gkResponse = VerifyCredentialResponse.OK;
-            }
-        } else {
-            result.gkResponse = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
-            byte[] applicationId, int userId) {
-        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
-        if (blob == null) {
-            return null;
-        }
-        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
-            throw new RuntimeException("Unknown blob version");
-        }
-        if (blob[1] != type) {
-            throw new RuntimeException("Invalid blob type");
-        }
-        byte[] secret = decryptSPBlob(getHandleName(handle),
-                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
-        if (secret == null) {
-            Log.e(TAG, "Fail to decrypt SP for user " + userId);
-            return null;
-        }
-        AuthenticationToken result = new AuthenticationToken();
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            if (!loadEscrowData(result, userId)) {
-                Log.e(TAG, "User is not escrowable: " + userId);
-                return null;
-            }
-            result.recreate(secret);
-        } else {
-            result.syntheticPassword = new String(secret);
-        }
-        return result;
-    }
-
-    /**
-     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
-     * if required.
-     *
-     * Normally performing verifyChallenge with an AuthenticationToken should always return
-     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
-     * decrypt SP.
-     */
-    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
-            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
-        byte[] spHandle = loadSyntheticPasswordHandle(userId);
-        if (spHandle == null) {
-            // There is no password handle associated with the given user, i.e. the user is not
-            // secured by lockscreen and has no SID, so just return here;
-            return null;
-        }
-        VerifyCredentialResponse result;
-        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
-                spHandle, auth.deriveGkPassword());
-        int responseCode = response.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            result = new VerifyCredentialResponse(response.getPayload());
-            if (response.getShouldReEnroll()) {
-                response = gatekeeper.enroll(userId, spHandle,
-                        spHandle, auth.deriveGkPassword());
-                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    spHandle = response.getPayload();
-                    saveSyntheticPasswordHandle(spHandle, userId);
-                    // Call self again to re-verify with updated handle
-                    return verifyChallenge(gatekeeper, auth, challenge, userId);
-                } else {
-                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
-                    // Fall through, return existing handle
-                }
-            }
-        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            result = new VerifyCredentialResponse(response.getTimeout());
-        } else {
-            result = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    public boolean existsHandle(long handle, int userId) {
-        return hasState(SP_BLOB_NAME, handle, userId);
-    }
-
-    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-    }
-
-    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, handle, userId);
-        destroyState(PASSWORD_DATA_NAME, handle, userId);
-    }
-
-    private void destroySyntheticPassword(long handle, int userId) {
-        destroyState(SP_BLOB_NAME, handle, userId);
-        destroySPBlobKey(getHandleName(handle));
-    }
-
-    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
-        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
-                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
-        byte[] result = new byte[data.length + secdiscardable.length];
-        System.arraycopy(data, 0, result, 0, data.length);
-        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
-        return result;
-    }
-
-    private byte[] createSecdiscardable(long handle, int userId) {
-        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
-        saveState(SECDISCARDABLE_NAME, data, handle, userId);
-        return data;
-    }
-
-    private byte[] loadSecdiscardable(long handle, int userId) {
-        return loadState(SECDISCARDABLE_NAME, handle, userId);
-    }
-
-    private boolean hasState(String stateName, long handle, int userId) {
-        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
-    }
-
-    private byte[] loadState(String stateName, long handle, int userId) {
-        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
-    }
-
-    private void saveState(String stateName, byte[] data, long handle, int userId) {
-        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
-    }
-
-    private void destroyState(String stateName, long handle, int userId) {
-        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
-    }
-
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
-    }
-
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
-    }
-
-    protected void destroySPBlobKey(String keyAlias) {
-        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
-    }
-
-    public static long generateHandle() {
-        SecureRandom rng = new SecureRandom();
-        long result;
-        do {
-            result = rng.nextLong();
-        } while (result == DEFAULT_HANDLE);
-        return result;
-    }
-
-    private int fakeUid(int uid) {
-        return 100000 + uid;
-    }
-
-    protected static byte[] secureRandom(int length) {
-        try {
-            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private String getHandleName(long handle) {
-        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
-    }
-
-    private byte[] computePasswordToken(String password, PasswordData data) {
-        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
-                PASSWORD_TOKEN_LENGTH);
-    }
-
-    private byte[] passwordTokenToGkInput(byte[] token) {
-        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
-    }
-
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return nativeSidFromPasswordHandle(handle);
-    }
-
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
-    }
-
-    native long nativeSidFromPasswordHandle(byte[] handle);
-    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
-
-    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
-    public static String bytesToHex(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        char[] hexChars = new char[bytes.length * 2];
-        for ( int j = 0; j < bytes.length; j++ ) {
-            int v = bytes[j] & 0xFF;
-            hexChars[j * 2] = hexArray[v >>> 4];
-            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
-        }
-        return new String(hexChars);
-    }
-}
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 72ff606..581914d 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Slog;
 
@@ -118,14 +119,14 @@
         // Register it.
         mServices.add(service);
         // Start it.
-        long time = System.currentTimeMillis();
+        long time = SystemClock.elapsedRealtime();
         try {
             service.onStart();
         } catch (RuntimeException ex) {
             throw new RuntimeException("Failed to start service " + service.getClass().getName()
                     + ": onStart threw an exception", ex);
         }
-        warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
+        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
     }
 
     /**
@@ -146,7 +147,7 @@
             final int serviceLen = mServices.size();
             for (int i = 0; i < serviceLen; i++) {
                 final SystemService service = mServices.get(i);
-                long time = System.currentTimeMillis();
+                long time = SystemClock.elapsedRealtime();
                 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());
                 try {
                     service.onBootPhase(mCurrentPhase);
@@ -156,7 +157,7 @@
                             + ": onBootPhase threw an exception during phase "
                             + mCurrentPhase, ex);
                 }
-                warnIfTooLong(System.currentTimeMillis() - time, service, "onBootPhase");
+                warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
         } finally {
@@ -178,14 +179,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onStartUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting start of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onStartUser ");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStartUser ");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -197,14 +198,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onUnlockUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onUnlockUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting unlock of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onUnlockUser ");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onUnlockUser ");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -216,14 +217,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onSwitchUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onSwitchUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting switch of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onSwitchUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onSwitchUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -235,14 +236,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStopUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onStopUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting stop of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onStopUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStopUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
@@ -254,14 +255,14 @@
             final SystemService service = mServices.get(i);
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onCleanupUser "
                     + service.getClass().getName());
-            long time = System.currentTimeMillis();
+            long time = SystemClock.elapsedRealtime();
             try {
                 service.onCleanupUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting cleanup of user " + userHandle
                         + " to service " + service.getClass().getName(), ex);
             }
-            warnIfTooLong(System.currentTimeMillis() - time, service, "onCleanupUser");
+            warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onCleanupUser");
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 16e63b3..4733840 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -48,6 +48,7 @@
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.util.DebugUtils;
 import android.util.Slog;
 import android.view.InputDevice;
 import android.media.AudioAttributes;
@@ -60,10 +61,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.ListIterator;
 
 public class VibratorService extends IVibratorService.Stub
         implements InputManager.InputDeviceListener {
@@ -225,19 +223,24 @@
 
         long[] clickEffectTimings = getLongIntArray(context.getResources(),
                 com.android.internal.R.array.config_virtualKeyVibePattern);
-        VibrationEffect clickEffect;
-        if (clickEffectTimings.length == 0) {
-            clickEffect = null;
-        } else if (clickEffectTimings.length == 1) {
-            clickEffect = VibrationEffect.createOneShot(
-                    clickEffectTimings[0], VibrationEffect.DEFAULT_AMPLITUDE);
-        } else {
-            clickEffect = VibrationEffect.createWaveform(clickEffectTimings, -1);
-        }
+        VibrationEffect clickEffect = createEffect(clickEffectTimings);
         VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
                 new long[] {0, 30, 100, 30} /*timings*/, -1);
+        long[] tickEffectTimings = getLongIntArray(context.getResources(),
+                com.android.internal.R.array.config_clockTickVibePattern);
+        VibrationEffect tickEffect = createEffect(tickEffectTimings);
 
-        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect };
+        mFallbackEffects = new VibrationEffect[] { clickEffect, doubleClickEffect, tickEffect };
+    }
+
+    private static VibrationEffect createEffect(long[] timings) {
+        if (timings == null || timings.length == 0) {
+            return null;
+        } else if (timings.length == 1) {
+            return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(timings, -1);
+        }
     }
 
     public void systemReady() {
@@ -943,6 +946,21 @@
         }
 
         private int runVibrate() {
+            try {
+                final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.ZEN_MODE);
+                if (zenMode != Settings.Global.ZEN_MODE_OFF) {
+                    try (PrintWriter pw = getOutPrintWriter();) {
+                        pw.print("Ignoring because device is on DND mode ");
+                        pw.println(DebugUtils.flagsToString(Settings.Global.class, "ZEN_MODE_",
+                                zenMode));
+                        return 0;
+                    }
+                }
+            } catch (SettingNotFoundException e) {
+                // ignore
+            }
+
             final long duration = Long.parseLong(getNextArgRequired());
             if (duration > MAX_VIBRATION_MS) {
                 throw new IllegalArgumentException("maximum duration is " + MAX_VIBRATION_MS);
@@ -967,7 +985,8 @@
                 pw.println("    Prints this help text.");
                 pw.println("");
                 pw.println("  vibrate duration [description]");
-                pw.println("    Vibrates for duration milliseconds.");
+                pw.println("    Vibrates for duration milliseconds; ignored when device is on DND ");
+                pw.println("    (Do Not Disturb) mode.");
                 pw.println("");
             }
         }
diff --git a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
index 7552368..b9453db 100644
--- a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
+++ b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
@@ -53,6 +53,7 @@
                 AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
     }
 
+    @Override
     public AuthenticatorDescription parseServiceAttributes(Resources res,
             String packageName, AttributeSet attrs) {
         TypedArray sa = res.obtainAttributes(attrs,
@@ -81,11 +82,13 @@
     }
 
     private static class MySerializer implements XmlSerializerAndParser<AuthenticatorDescription> {
+        @Override
         public void writeAsXml(AuthenticatorDescription item, XmlSerializer out)
                 throws IOException {
             out.attribute(null, "type", item.type);
         }
 
+        @Override
         public AuthenticatorDescription createFromXml(XmlPullParser parser)
                 throws IOException, XmlPullParserException {
             return AuthenticatorDescription.newKey(parser.getAttributeValue(null, "type"));
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d6a010f..c0bbe35 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1372,6 +1372,7 @@
         if (accounts != null) {
             synchronized (accounts.dbLock) {
                 synchronized (accounts.cacheLock) {
+                    accounts.statementForLogging.close();
                     accounts.accountsDb.close();
                 }
             }
@@ -2954,13 +2955,9 @@
                              * have users launching arbitrary activities by tricking users to
                              * interact with malicious notifications.
                              */
-                            if (!checkKeyIntent(
+                            checkKeyIntent(
                                     Binder.getCallingUid(),
-                                    intent)) {
-                                onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
-                                        "invalid intent in bundle returned");
-                                return;
-                            }
+                                    intent);
                             doNotification(
                                     mAccounts,
                                     account,
@@ -3355,13 +3352,9 @@
             Intent intent = null;
             if (result != null
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
-                if (!checkKeyIntent(
+                checkKeyIntent(
                         Binder.getCallingUid(),
-                        intent)) {
-                    onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
-                            "invalid intent in bundle returned");
-                    return;
-                }
+                        intent);
             }
             IAccountManagerResponse response;
             if (mExpectActivityLaunch && result != null
@@ -4708,14 +4701,13 @@
          * into launching arbitrary intents on the device via by tricking to click authenticator
          * supplied entries in the system Settings app.
          */
-        protected boolean checkKeyIntent(int authUid, Intent intent) {
+        protected void checkKeyIntent(
+                int authUid,
+                Intent intent) throws SecurityException {
             long bid = Binder.clearCallingIdentity();
             try {
                 PackageManager pm = mContext.getPackageManager();
                 ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId);
-                if (resolveInfo == null) {
-                    return false;
-                }
                 ActivityInfo targetActivityInfo = resolveInfo.activityInfo;
                 int targetUid = targetActivityInfo.applicationInfo.uid;
                 if (!isExportedSystemActivity(targetActivityInfo)
@@ -4725,10 +4717,9 @@
                     String activityName = targetActivityInfo.name;
                     String tmpl = "KEY_INTENT resolved to an Activity (%s) in a package (%s) that "
                             + "does not share a signature with the supplying authenticator (%s).";
-                    Log.e(TAG, String.format(tmpl, activityName, pkgName, mAccountType));
-                    return false;
+                    throw new SecurityException(
+                            String.format(tmpl, activityName, pkgName, mAccountType));
                 }
-                return true;
             } finally {
                 Binder.restoreCallingIdentity(bid);
             }
@@ -4878,13 +4869,9 @@
             }
             if (result != null
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
-                if (!checkKeyIntent(
+                checkKeyIntent(
                         Binder.getCallingUid(),
-                        intent)) {
-                    onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
-                            "invalid intent in bundle returned");
-                    return;
-                }
+                        intent);
             }
             if (result != null
                     && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) {
@@ -5074,6 +5061,7 @@
                 this.userDebugDbInsertionPoint = userDebugDbInsertionPoint;
             }
 
+            @Override
             public void run() {
                 SQLiteStatement logStatement = userAccount.statementForLogging;
                 logStatement.bindLong(1, accountId);
@@ -5301,25 +5289,25 @@
         long identityToken = Binder.clearCallingIdentity();
         try {
             packages = mPackageManager.getPackagesForUid(callingUid);
-        } finally {
-            Binder.restoreCallingIdentity(identityToken);
-        }
-        if (packages == null) {
-            Log.d(TAG, "No packages for callingUid " + callingUid);
-            return false;
-        }
-        for (String name : packages) {
-            try {
-                PackageInfo packageInfo = mPackageManager.getPackageInfo(name, 0 /* flags */);
-                if (packageInfo != null
-                        && (packageInfo.applicationInfo.privateFlags
-                                & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
-                    return true;
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.d(TAG, "Package not found " + e.getMessage());
+            if (packages == null) {
+                Log.d(TAG, "No packages for callingUid " + callingUid);
                 return false;
             }
+            for (String name : packages) {
+                try {
+                    PackageInfo packageInfo =
+                        mPackageManager.getPackageInfo(name, 0 /* flags */);
+                    if (packageInfo != null
+                        && (packageInfo.applicationInfo.privateFlags
+                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+                        return true;
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    Log.d(TAG, "Package not found " + e.getMessage());
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
         }
         return false;
     }
@@ -6190,7 +6178,7 @@
         }
     }
 
-    private class NotificationId {
+    private static class NotificationId {
         final String mTag;
         private final int mId;
 
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 8ca7ea1..0c3d268 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -1321,6 +1321,7 @@
         }
     }
 
+    @Override
     public void close() {
         mDeDatabase.close();
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b7144d4..d9944a7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -606,6 +607,8 @@
     // the notification will not be legible to the user.
     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
 
+    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
+
     /** All system services */
     SystemServiceManager mSystemServiceManager;
     AssistUtils mAssistUtils;
@@ -716,7 +719,9 @@
 
     public boolean canShowErrorDialogs() {
         return mShowDialogs && !mSleeping && !mShuttingDown
-                && !mKeyguardController.isKeyguardShowing();
+                && !mKeyguardController.isKeyguardShowing()
+                && !(UserManager.isDeviceInDemoMode(mContext)
+                        && mUserController.getCurrentUser().isDemo());
     }
 
     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
@@ -1462,12 +1467,6 @@
             = new ProcessMap<ArrayList<ProcessRecord>>();
 
     /**
-     * This is set if we had to do a delayed dexopt of an app before launching
-     * it, to increase the ANR timeouts in that case.
-     */
-    boolean mDidDexOpt;
-
-    /**
      * Set if the systemServer made a call to enterSafeMode.
      */
     boolean mSafeMode;
@@ -1963,13 +1962,6 @@
                 }
             } break;
             case SERVICE_TIMEOUT_MSG: {
-                if (mDidDexOpt) {
-                    mDidDexOpt = false;
-                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
-                    nmsg.obj = msg.obj;
-                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
-                    return;
-                }
                 mServices.serviceTimeout((ProcessRecord)msg.obj);
             } break;
             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
@@ -2045,13 +2037,6 @@
                 }
             } break;
             case PROC_START_TIMEOUT_MSG: {
-                if (mDidDexOpt) {
-                    mDidDexOpt = false;
-                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
-                    nmsg.obj = msg.obj;
-                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
-                    return;
-                }
                 ProcessRecord app = (ProcessRecord)msg.obj;
                 synchronized (ActivityManagerService.this) {
                     processStartTimedOutLocked(app);
@@ -5460,34 +5445,103 @@
      * @param firstPids of dalvik VM processes to dump stack traces for first
      * @param lastPids of dalvik VM processes to dump stack traces for last
      * @param nativePids optional list of native pids to dump stack crawls
-     * @return file containing stack traces, or null if no dump file is configured
      */
     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
             ArrayList<Integer> nativePids) {
-        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
-        if (tracesPath == null || tracesPath.length() == 0) {
-            return null;
+        ArrayList<Integer> extraPids = null;
+
+        // Measure CPU usage as soon as we're called in order to get a realistic sampling
+        // of the top users at the time of the request.
+        if (processCpuTracker != null) {
+            processCpuTracker.init();
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException ignored) {
+            }
+
+            processCpuTracker.update();
+
+            // We'll take the stack crawls of just the top apps using CPU.
+            final int N = processCpuTracker.countWorkingStats();
+            extraPids = new ArrayList<>();
+            for (int i = 0; i < N && extraPids.size() < 5; i++) {
+                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
+                if (lastPids.indexOfKey(stats.pid) >= 0) {
+                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
+
+                    extraPids.add(stats.pid);
+                } else if (DEBUG_ANR) {
+                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+                            + stats.pid);
+                }
+            }
         }
 
-        File tracesFile = new File(tracesPath);
-        try {
-            if (clearTraces && tracesFile.exists()) tracesFile.delete();
-            tracesFile.createNewFile();
-            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
-        } catch (IOException e) {
-            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
-            return null;
+        boolean useTombstonedForJavaTraces = false;
+        File tracesFile;
+
+        final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
+        if (tracesDir.isEmpty()) {
+            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
+            // dumping scheme. All traces are written to a global trace file (usually
+            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
+            // the file if requested.
+            //
+            // This mode of operation will be removed in the near future.
+
+
+            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
+            if (globalTracesPath.isEmpty()) {
+                Slog.w(TAG, "dumpStackTraces: no trace path configured");
+                return null;
+            }
+
+            tracesFile = new File(globalTracesPath);
+            try {
+                if (clearTraces && tracesFile.exists()) {
+                    tracesFile.delete();
+                }
+
+                tracesFile.createNewFile();
+                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
+                return null;
+            }
+        } else {
+            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
+            // Each set of ANR traces is written to a separate file and dumpstate will process
+            // all such files and add them to a captured bug report if they're recent enough.
+            //
+            // 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_", "", new File(tracesDir));
+                FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
+            } catch (IOException ioe) {
+                Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
+                return null;
+            }
+
+            useTombstonedForJavaTraces = true;
         }
 
-        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
+        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
+                useTombstonedForJavaTraces);
         return tracesFile;
     }
 
+    /**
+     * Legacy code, do not use. Existing users will be deleted.
+     *
+     * @deprecated
+     */
+    @Deprecated
     public static class DumpStackFileObserver extends FileObserver {
         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
-        static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
 
         private final String mTracesPath;
         private boolean mClosed;
@@ -5541,17 +5595,45 @@
         }
     }
 
-    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
-            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
-            ArrayList<Integer> nativePids) {
-        // Use a FileObserver to detect when traces finish writing.
-        // The order of traces is considered important to maintain for legibility.
-        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
+    /**
+     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
+     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
+     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
+     * attempting to obtain native traces in the case of a failure. Returns the total time spent
+     * capturing traces.
+     */
+    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
+        final long timeStart = SystemClock.elapsedRealtime();
+        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
+            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
+        }
+
+        return SystemClock.elapsedRealtime() - timeStart;
+    }
+
+    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
+            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
+            boolean useTombstonedForJavaTraces) {
+
+        // We don't need any sort of inotify based monitoring when we're dumping traces via
+        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
+        // control of all writes to the file in question.
+        final DumpStackFileObserver observer;
+        if (useTombstonedForJavaTraces) {
+            observer = null;
+        } else {
+            // Use a FileObserver to detect when traces finish writing.
+            // The order of traces is considered important to maintain for legibility.
+            observer = new DumpStackFileObserver(tracesFile);
+        }
 
         // We must complete all stack dumps within 20 seconds.
         long remainingTime = 20 * 1000;
         try {
-            observer.startWatching();
+            if (observer != null) {
+                observer.startWatching();
+            }
 
             // First collect all of the stacks of the most important pids.
             if (firstPids != null) {
@@ -5559,7 +5641,12 @@
                 for (int i = 0; i < num; i++) {
                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
                             + firstPids.get(i));
-                    final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
+                    final long timeTaken;
+                    if (useTombstonedForJavaTraces) {
+                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
+                    } else {
+                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
+                    }
 
                     remainingTime -= timeTaken;
                     if (remainingTime <= 0) {
@@ -5578,12 +5665,11 @@
             if (nativePids != null) {
                 for (int pid : nativePids) {
                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
-                    final long nativeDumpTimeoutMs = Math.min(
-                            DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
+                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
 
                     final long start = SystemClock.elapsedRealtime();
                     Debug.dumpNativeBacktraceToFileTimeout(
-                            pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
+                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
                     final long timeTaken = SystemClock.elapsedRealtime() - start;
 
                     remainingTime -= timeTaken;
@@ -5599,48 +5685,34 @@
                 }
             }
 
-            // Lastly, measure CPU usage.
-            if (processCpuTracker != null) {
-                processCpuTracker.init();
-                System.gc();
-                processCpuTracker.update();
-                try {
-                    synchronized (processCpuTracker) {
-                        processCpuTracker.wait(500); // measure over 1/2 second.
+            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
+            if (extraPids != null) {
+                for (int pid : extraPids) {
+                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
+
+                    final long timeTaken;
+                    if (useTombstonedForJavaTraces) {
+                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
+                    } else {
+                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
                     }
-                } catch (InterruptedException e) {
-                }
-                processCpuTracker.update();
 
-                // We'll take the stack crawls of just the top apps using CPU.
-                final int N = processCpuTracker.countWorkingStats();
-                int numProcs = 0;
-                for (int i=0; i<N && numProcs<5; i++) {
-                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
-                    if (lastPids.indexOfKey(stats.pid) >= 0) {
-                        numProcs++;
-
-                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
-
-                        final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
-                        remainingTime -= timeTaken;
-                        if (remainingTime <= 0) {
-                            Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
+                    remainingTime -= timeTaken;
+                    if (remainingTime <= 0) {
+                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
                                 "); deadline exceeded.");
-                            return;
-                        }
+                        return;
+                    }
 
-                        if (DEBUG_ANR) {
-                            Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
-                        }
-                    } else if (DEBUG_ANR) {
-                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
-                                + stats.pid);
+                    if (DEBUG_ANR) {
+                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
                     }
                 }
             }
         } finally {
-            observer.stopWatching();
+            if (observer != null) {
+                observer.stopWatching();
+            }
         }
     }
 
@@ -5687,7 +5759,7 @@
             if (app != null) {
                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
                 firstPids.add(app.pid);
-                dumpStackTraces(tracesPath, firstPids, null, null, null);
+                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
             }
 
             File lastTracesFile = null;
@@ -10234,7 +10306,7 @@
 
     @Override
     public void moveStackToDisplay(int stackId, int displayId) {
-        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
+        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
 
         synchronized (this) {
             final long ident = Binder.clearCallingIdentity();
@@ -12396,10 +12468,10 @@
         switch (mWakefulness) {
             case PowerManagerInternal.WAKEFULNESS_AWAKE:
             case PowerManagerInternal.WAKEFULNESS_DREAMING:
-            case PowerManagerInternal.WAKEFULNESS_DOZING:
                 // Pause applications whenever the lock screen is shown or any sleep
                 // tokens have been acquired.
                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
+            case PowerManagerInternal.WAKEFULNESS_DOZING:
             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
             default:
                 // If we're asleep then pause applications unconditionally.
@@ -12858,7 +12930,7 @@
             timeout = getInputDispatchingTimeoutLocked(proc);
         }
 
-        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
+        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
             return -1;
         }
 
@@ -12891,12 +12963,6 @@
                     return false;
                 }
 
-                if (mDidDexOpt) {
-                    // Give more time since we were dexopting.
-                    mDidDexOpt = false;
-                    return false;
-                }
-
                 if (proc.instr != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
@@ -13307,7 +13373,6 @@
                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
                 if (r != null) {
                     final ActivityOptions activityOptions = r.pendingOptions;
-                    r.pendingOptions = null;
                     return activityOptions == null ? null : activityOptions.toBundle();
                 }
                 return null;
@@ -23879,7 +23944,9 @@
                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
                 return;
             }
-            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+            synchronized (ActivityManagerService.this) {
+                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+            }
         }
 
         @Override
@@ -23945,9 +24012,19 @@
 
                 // We might change the visibilities here, so prepare an empty app transition which
                 // might be overridden later if we actually change visibilities.
-                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
+                final boolean wasTransitionSet =
+                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
+                if (!wasTransitionSet) {
+                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
+                            false /* alwaysKeepCurrent */);
+                }
                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                mWindowManager.executeAppTransition();
+
+                // If there was a transition set already we don't want to interfere with it as we
+                // might be starting it too early.
+                if (!wasTransitionSet) {
+                    mWindowManager.executeAppTransition();
+                }
             }
             if (callback != null) {
                 callback.run();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 68f4d0d..fe006fc 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -74,6 +74,7 @@
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -154,6 +155,7 @@
 import android.view.IApplicationToken;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.content.ReferrerIntent;
 import com.android.internal.util.XmlUtils;
@@ -2319,10 +2321,12 @@
         outBounds.setEmpty();
         final float maxAspectRatio = info.maxAspectRatio;
         final ActivityStack stack = getStack();
-        if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) {
+        if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0
+                || isInVrUiMode(getConfiguration())) {
             // We don't set override configuration if that activity task isn't fullscreen. I.e. the
             // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
-            // the activity. This is indicated by an empty {@link outBounds}.
+            // the activity. This is indicated by an empty {@link outBounds}. We also don't set it
+            // if we are in VR mode.
             return;
         }
 
@@ -2358,6 +2362,17 @@
 
         // Compute configuration based on max supported width and height.
         outBounds.set(0, 0, maxActivityWidth, maxActivityHeight);
+        // Position the activity frame on the opposite side of the nav bar.
+        final int navBarPosition = service.mWindowManager.getNavBarPosition();
+        final int left = navBarPosition == NAV_BAR_LEFT
+                ? configuration.appBounds.right - outBounds.width() : 0;
+        outBounds.offsetTo(left, 0 /* top */);
+    }
+
+    /** Get bounds of the activity. */
+    @VisibleForTesting
+    Rect getBounds() {
+        return new Rect(mBounds);
     }
 
     /**
@@ -2581,6 +2596,7 @@
                 changes &= ~CONFIG_SMALLEST_SCREEN_SIZE;
             }
         }
+
         return changes;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bde317a..3620ddb 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -659,6 +659,13 @@
         return topRunningActivityLocked(false /* focusableOnly */);
     }
 
+    void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+        outActivities.clear();
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            mTaskHistory.get(taskNdx).getAllRunningVisibleActivitiesLocked(outActivities);
+        }
+    }
+
     private ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
@@ -745,6 +752,13 @@
         return null;
     }
 
+    final TaskRecord bottomTask() {
+        if (mTaskHistory.isEmpty()) {
+            return null;
+        }
+        return mTaskHistory.get(0);
+    }
+
     TaskRecord taskForIdLocked(int id) {
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -1690,14 +1704,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)
@@ -1896,7 +1916,16 @@
                         // the recents activity from an app.
                         behindFullscreenActivity = true;
                     }
-
+                } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
+                            + " returning to non-application type=" + task.getTaskToReturnTo());
+                    // Once we reach a fullscreen stack task that has a running activity and should
+                    // return to another stack task, then no other activities behind that one should
+                    // be visible.
+                    if (task.topRunningActivityLocked() != null &&
+                            task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
+                        behindFullscreenActivity = true;
+                    }
                 }
             }
 
@@ -2881,9 +2910,13 @@
                         transit = TRANSIT_TASK_OPEN_BEHIND;
                     } else {
                         // If a new task is being launched, then mark the existing top activity as
-                        // supporting picture-in-picture while pausing
-                        if (focusedTopActivity != null &&
-                                focusedTopActivity.getStack().getStackId() != PINNED_STACK_ID) {
+                        // supporting picture-in-picture while pausing only if the starting activity
+                        // would not be considered an overlay on top of the current activity
+                        // (eg. not fullscreen, or the assistant)
+                        if (focusedTopActivity != null
+                                && focusedTopActivity.getStackId() != PINNED_STACK_ID
+                                && r.getStackId() != ASSISTANT_STACK_ID
+                                && r.fullscreen) {
                             focusedTopActivity.supportsPictureInPictureWhilePausing = true;
                         }
                         transit = TRANSIT_TASK_OPEN;
@@ -3365,6 +3398,16 @@
      * @param allowFocusSelf Is the focus allowed to remain on the same stack.
      */
     private boolean adjustFocusToNextFocusableStackLocked(String reason, boolean allowFocusSelf) {
+        if (isAssistantStack() && bottomTask() != null &&
+                bottomTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+            // If the current stack is the assistant stack, then use the return-to type to determine
+            // whether to return to the home screen. This is needed to workaround an issue where
+            // launching a fullscreen task (and subequently returning from that task) will cause
+            // the fullscreen stack to be found as the next focusable stack below, even if the
+            // assistant was launched over home.
+            return mStackSupervisor.moveHomeStackTaskToTop(reason);
+        }
+
         final ActivityStack stack = mStackSupervisor.getNextFocusableStackLocked(
                 allowFocusSelf ? null : this);
         final String myReason = reason + " adjustFocusToNextFocusableStack";
@@ -3381,6 +3424,15 @@
             return mStackSupervisor.moveHomeStackTaskToTop(reason);
         }
 
+        if (stack.isAssistantStack() && top != null
+                && top.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+            // It is possible for the home stack to not be directly underneath the assistant stack.
+            // For example, the assistant may start an activity in the fullscreen stack. Upon
+            // returning to the assistant stack, we must ensure that the home stack is underneath
+            // when appropriate.
+            mStackSupervisor.moveHomeStackTaskToTop("adjustAssistantReturnToHome");
+        }
+
         stack.moveToFront(myReason);
         return true;
     }
@@ -3650,7 +3702,7 @@
 
             finishActivityResultsLocked(r, resultCode, resultData);
 
-            final boolean endTask = index <= 0;
+            final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
             final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
             if (mResumedActivity == r) {
                 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
@@ -4548,8 +4600,10 @@
             updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
         }
         // If a new task is moved to the front, then mark the existing top activity as supporting
-        // picture-in-picture while paused
-        if (topActivity != null && topActivity.getStack().getStackId() != PINNED_STACK_ID) {
+        // picture-in-picture while paused only if the task would not be considered an oerlay on top
+        // of the current activity (eg. not fullscreen, or the assistant)
+        if (topActivity != null && topActivity.getStackId() != PINNED_STACK_ID
+                && tr.getStackId() != ASSISTANT_STACK_ID && tr.containsOnlyFullscreenActivities()) {
             topActivity.supportsPictureInPictureWhilePausing = true;
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fe0e07e..ce86624 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -38,11 +39,13 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -454,6 +457,8 @@
 
     final ActivityMetricsLogger mActivityMetricsLogger;
 
+    private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
+
     @Override
     protected int getChildCount() {
         return mActivityDisplays.size();
@@ -961,17 +966,21 @@
                 if (!isFocusedStack(stack)) {
                     continue;
                 }
-                ActivityRecord hr = stack.topRunningActivityLocked();
-                if (hr != null) {
-                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
-                            && processName.equals(hr.processName)) {
+                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
+                final ActivityRecord top = stack.topRunningActivityLocked();
+                final int size = mTmpActivityList.size();
+                for (int i = 0; i < size; i++) {
+                    final ActivityRecord activity = mTmpActivityList.get(i);
+                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
+                            && processName.equals(activity.processName)) {
                         try {
-                            if (realStartActivityLocked(hr, app, true, true)) {
+                            if (realStartActivityLocked(activity, app,
+                                    top == activity /* andResume */, true /* checkConfig */)) {
                                 didSomething = true;
                             }
                         } catch (RemoteException e) {
                             Slog.w(TAG, "Exception in new application when starting activity "
-                                  + hr.intent.getComponent().flattenToShortString(), e);
+                                    + top.intent.getComponent().flattenToShortString(), e);
                             throw e;
                         }
                     }
@@ -1461,6 +1470,7 @@
                     mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
             r.setLastReportedConfiguration(mergedConfiguration);
 
+            logIfTransactionTooLarge(r.intent, r.icicle);
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                     System.identityHashCode(r), r.info,
                     // TODO: Have this take the merged configuration instead of separate global and
@@ -1546,6 +1556,21 @@
         return true;
     }
 
+    private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
+        int extrasSize = 0;
+        if (intent != null) {
+            final Bundle extras = intent.getExtras();
+            if (extras != null) {
+                extrasSize = extras.getSize();
+            }
+        }
+        int icicleSize = (icicle == null ? 0 : icicle.getSize());
+        if (extrasSize + icicleSize > 200000) {
+            Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize
+                    + ", icicle size: " + icicleSize);
+        }
+    }
+
     void startSpecificActivityLocked(ActivityRecord r,
             boolean andResume, boolean checkConfig) {
         // Is this activity's application already running?
@@ -1678,6 +1703,24 @@
             return false;
         }
 
+        // Check if the caller can manage activity stacks.
+        final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+                callingUid);
+        if (startAnyPerm == PERMISSION_GRANTED) {
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " allow launch any on display");
+            return true;
+        }
+
+        if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+                && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) {
+            // Limit launching on virtual displays, because their contents can be read from Surface
+            // by apps that created them.
+            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+                    + " disallow launch on virtual display for not-embedded activity");
+            return false;
+        }
+
         if (!activityDisplay.isPrivate()) {
             // Anyone can launch on a public display.
             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1699,15 +1742,6 @@
             return true;
         }
 
-        // Check if the caller can manage activity stacks.
-        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
-                callingUid);
-        if (startAnyPerm == PERMISSION_GRANTED) {
-            if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
-                    + " allow launch any on display");
-            return true;
-        }
-
         Slog.w(TAG, "Launch on display check: denied");
         return false;
     }
@@ -4440,13 +4474,6 @@
                 case IDLE_TIMEOUT_MSG: {
                     if (DEBUG_IDLE) Slog.d(TAG_IDLE,
                             "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
-                        nmsg.obj = msg.obj;
-                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
-                        return;
-                    }
                     // We don't at this point know if the activity is fullscreen,
                     // so we need to be conservative and assume it isn't.
                     activityIdleInternal((ActivityRecord) msg.obj,
@@ -4472,11 +4499,6 @@
                     }
                 } break;
                 case LAUNCH_TIMEOUT_MSG: {
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
-                        return;
-                    }
                     synchronized (mService) {
                         if (mLaunchingActivity.isHeld()) {
                             Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
@@ -5154,11 +5176,14 @@
             // Work Challenge is present) let startActivityInPackage handle the intercepting.
             if (!mService.mUserController.shouldConfirmCredentials(task.userId)
                     && task.getRootActivity() != null) {
-                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
+                final ActivityRecord targetActivity = task.getTopActivity();
+
+                mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */,
+                        targetActivity);
                 mActivityMetricsLogger.notifyActivityLaunching();
                 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */);
                 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
-                        task.getTopActivity());
+                        targetActivity);
 
                 // If we are launching the task in the docked stack, put it into resizing mode so
                 // the window renders full-screen with the background filling the void. Also only
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a145435..76f65e2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
+import static android.app.ActivityManager.START_ABORTED;
 import static android.app.ActivityManager.START_CANCELED;
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
@@ -279,7 +280,9 @@
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
             outActivity[0] = mLastStartActivityRecord[0];
         }
-        return mLastStartActivityResult;
+
+        // Aborted results are treated as successes externally, but we must track them internally.
+        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
     }
 
     /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
@@ -465,7 +468,7 @@
             // We pretend to the caller that it was really started, but
             // they will just get a cancel result.
             ActivityOptions.abort(options);
-            return START_SUCCESS;
+            return START_ABORTED;
         }
 
         // If permissions need a review before any of the app components can run, we
@@ -966,7 +969,7 @@
         return START_SUCCESS;
     }
 
-    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend) {
+    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
         boolean sendHint = forceSend;
 
         if (!sendHint) {
@@ -975,7 +978,7 @@
             final ActivityRecord resumedActivity = mSupervisor.getResumedActivityLocked();
             sendHint = resumedActivity == null
                 || resumedActivity.app == null
-                || !resumedActivity.app.equals(mStartActivity.app);
+                || !resumedActivity.app.equals(targetActivity.app);
         }
 
         if (sendHint && mService.mLocalPowerManager != null) {
@@ -1095,7 +1098,7 @@
                 }
             }
 
-            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
+            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
 
             reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
 
@@ -1124,6 +1127,7 @@
                 if (outActivity != null && outActivity.length > 0) {
                     outActivity[0] = reusedActivity;
                 }
+
                 return START_TASK_TO_FRONT;
             }
         }
@@ -1215,7 +1219,7 @@
                 EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
         mTargetStack.mLastPausedActivity = null;
 
-        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
+        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
 
         mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                 mOptions);
@@ -1517,7 +1521,8 @@
             if (mLaunchSingleInstance) {
                 // There can be one and only one instance of single instance activity in the
                 // history, and it is always in its own unique task, so we do a special search.
-               intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, false);
+               intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
+                       mStartActivity.isHomeActivity());
             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                 // For the launch adjacent case we only want to put the activity in an existing
                 // task if the activity already exists in the history.
@@ -1637,6 +1642,16 @@
                                 REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
                                 "reparentToDisplay");
                         mMovedToFront = true;
+                    } else if (launchStack.getStackId() == StackId.HOME_STACK_ID
+                        && mTargetStack.getStackId() != StackId.HOME_STACK_ID) {
+                        // It is possible for the home activity to be in another stack initially.
+                        // For example, the activity may have been initially started with an intent
+                        // which placed it in the fullscreen stack. To ensure the proper handling of
+                        // the activity based on home stack assumptions, we must move it over.
+                        intentActivity.getTask().reparent(launchStack.mStackId, ON_TOP,
+                                REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME,
+                                "reparentingHome");
+                        mMovedToFront = true;
                     }
                     mOptions = null;
 
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 8991537..0d1c579 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Set;
 
 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
@@ -908,10 +909,11 @@
 
         // For background ANRs, don't pass the ProcessCpuTracker to
         // avoid spending 1/2 second collecting stats to rank lastPids.
-        File tracesFile = mService.dumpStackTraces(true, firstPids,
-                                                   (isSilentANR) ? null : processCpuTracker,
-                                                   (isSilentANR) ? null : lastPids,
-                                                   nativePids);
+        File tracesFile = ActivityManagerService.dumpStackTraces(
+                true, firstPids,
+                (isSilentANR) ? null : processCpuTracker,
+                (isSilentANR) ? null : lastPids,
+                nativePids);
 
         String cpuInfo = null;
         if (ActivityManagerService.MONITOR_CPU_USAGE) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c20221b..65697e9 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -188,6 +188,7 @@
     }
 
     private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
+    private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
     private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
                     .newDecoder()
                     .onMalformedInput(CodingErrorAction.REPLACE)
@@ -219,6 +220,28 @@
         }
     }
 
+    @Override
+    public String getSubsystemLowPowerStats() {
+        Slog.d(TAG, "begin getSubsystemLowPowerStats");
+        try {
+            mUtf8BufferStat.clear();
+            mUtf16BufferStat.clear();
+            mDecoderStat.reset();
+            int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat);
+            if (bytesWritten < 0) {
+                return null;
+            } else if (bytesWritten == 0) {
+                return "Empty";
+            }
+            mUtf8BufferStat.limit(bytesWritten);
+            mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
+            mUtf16BufferStat.flip();
+            return mUtf16BufferStat.toString();
+        } finally {
+            Slog.d(TAG, "end getSubsystemLowPowerStats");
+        }
+    }
+
     BatteryStatsService(File systemDir, Handler handler) {
         // Our handler here will be accessing the disk, use a different thread than
         // what the ActivityManagerService gave us (no I/O on that one!).
@@ -962,10 +985,10 @@
     }
 
     @Override
-    public void noteBleScanStopped(WorkSource ws) {
+    public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteBluetoothScanStoppedFromSourceLocked(ws);
+            mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b3a2c29..da196e2 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -802,7 +802,7 @@
         IPackageManager pm = AppGlobals.getPackageManager();
         for (int i = perms.length-1; i >= 0; i--) {
             try {
-                PermissionInfo pi = pm.getPermissionInfo(perms[i], 0);
+                PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
                 if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
                         | PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
                         != PermissionInfo.PROTECTION_SIGNATURE) {
@@ -1404,13 +1404,6 @@
         long now = SystemClock.uptimeMillis();
         BroadcastRecord r = mOrderedBroadcasts.get(0);
         if (fromMsg) {
-            if (mService.mDidDexOpt) {
-                // Delay timeouts until dexopt finishes.
-                mService.mDidDexOpt = false;
-                long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
-                setBroadcastTimeoutLocked(timeoutTime);
-                return;
-            }
             if (!mService.mProcessesReady) {
                 // Only process broadcast timeouts if the system is ready. That way
                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index a46c851..d10f9fb 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -144,6 +144,7 @@
             failCallback(callback);
             return;
         }
+        Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord);
         mWindowManager.dismissKeyguard(callback);
     }
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 40a62bd..c009dde 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1112,6 +1112,19 @@
         return intent != null ? intent : affinityIntent;
     }
 
+    /**
+     * @return Whether there are only fullscreen activities in this task.
+     */
+    boolean containsOnlyFullscreenActivities() {
+        for (int i = 0; i < mActivities.size(); i++) {
+            final ActivityRecord r = mActivities.get(i);
+            if (!r.finishing && !r.fullscreen) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /** Returns the first non-finishing activity from the root. */
     ActivityRecord getRootActivity() {
         for (int i = 0; i < mActivities.size(); i++) {
@@ -1147,6 +1160,17 @@
         return null;
     }
 
+    void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) {
+        if (mStack != null) {
+            for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = mActivities.get(activityNdx);
+                if (!r.finishing && r.okToShowLocked() && r.visibleIgnoringKeyguard) {
+                    outActivities.add(r);
+                }
+            }
+        }
+    }
+
     ActivityRecord topRunningActivityWithStartingWindowLocked() {
         if (mStack != null) {
             for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
@@ -1592,6 +1616,13 @@
     }
 
     /**
+     * @return {@code true} if the task is being cleared for the purposes of being reused.
+     */
+    boolean isClearingToReuseTask() {
+        return mReuseTask;
+    }
+
+    /**
      * Find the activity in the history stack within the given task.  Returns
      * the index within the history at which it's found, or < 0 if not found.
      */
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index eeab605..f720cd5 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -123,12 +123,13 @@
     private final Injector mInjector;
     private final Handler mHandler;
 
-    // Holds the current foreground user's id
+    // Holds the current foreground user's id. Use mLock when updating
     @GuardedBy("mLock")
-    private int mCurrentUserId = UserHandle.USER_SYSTEM;
-    // Holds the target user's id during a user switch
+    private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
+    // Holds the target user's id during a user switch. The value of mCurrentUserId will be updated
+    // once target user goes into the foreground. Use mLock when updating
     @GuardedBy("mLock")
-    private int mTargetUserId = UserHandle.USER_NULL;
+    private volatile int mTargetUserId = UserHandle.USER_NULL;
 
     /**
      * Which users have been started, so are allowed to run code.
@@ -1506,6 +1507,11 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
+
+        // Optimization - if there is no pending user switch, return current id
+        if (mTargetUserId == UserHandle.USER_NULL) {
+            return getUserInfo(mCurrentUserId);
+        }
         synchronized (mLock) {
             return getCurrentUserLocked();
         }
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index 048bef7..feddfe3 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -163,6 +163,7 @@
         ComponentName requestedPackage;
         ComponentName callingPackage;
         int userId;
+        int processId = -1;
         boolean changed = false;
         synchronized (mGlobalAmLock) {
             vrMode = record.requestedVrComponent != null;
@@ -172,11 +173,15 @@
 
             // Tell the VrController that a VR mode change is requested.
             changed = changeVrModeLocked(vrMode, record.app);
+
+            if (record.app != null) {
+                processId = record.app.pid;
+            }
         }
 
         // Tell VrManager that a VR mode changed is requested, VrManager will handle
         // notifying all non-AM dependencies if needed.
-        vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
+        vrService.setVrMode(vrMode, requestedPackage, userId, processId, callingPackage);
         return changed;
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5c3106..0326299 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -166,7 +166,6 @@
 
     /** debug calls to devices APIs */
     protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG);
-
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 500;
 
@@ -240,6 +239,7 @@
     private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
     private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
     private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
+    private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
     // end of messages handled under wakelock
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -352,7 +352,7 @@
         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
         AudioSystem.STREAM_MUSIC            // STREAM_ACCESSIBILITY
     };
-    private int[] mStreamVolumeAlias;
+    protected static int[] mStreamVolumeAlias;
 
     /**
      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
@@ -648,20 +648,29 @@
         mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
 
         // Initialize volume
-        int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps",
-                MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
-        if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
-            MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume;
-            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4;
+        int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
+        if (maxCallVolume != -1) {
+            MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
+            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
+                    (maxCallVolume * 3) / 4;
         }
-        maxVolume = SystemProperties.getInt("ro.config.media_vol_steps",
-                MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
-        if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
-            MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume;
+
+        int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
+        if (maxMusicVolume != -1) {
+            MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
+        }
+
+        int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
+        if (defaultMusicVolume != -1 &&
+                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
+            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
+        } else {
             if (isPlatformTelevision()) {
-                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume / 4;
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
+                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
             } else {
-                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4;
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
+                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
             }
         }
 
@@ -704,6 +713,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);
 
         readAndSetLowRamDevice();
@@ -978,6 +991,19 @@
         checkAllFixedVolumeDevices();
         checkAllAliasStreamVolumes();
         checkMuteAffectedStreams();
+        updateDefaultVolumes();
+    }
+
+    // Update default indexes from aliased streams. Must be called after mStreamStates is created
+    private void updateDefaultVolumes() {
+        for (int stream = 0; stream < mStreamStates.length; stream++) {
+            if (stream != mStreamVolumeAlias[stream]) {
+                AudioSystem.DEFAULT_STREAM_VOLUME[stream] = rescaleIndex(
+                        AudioSystem.DEFAULT_STREAM_VOLUME[mStreamVolumeAlias[stream]],
+                        mStreamVolumeAlias[stream],
+                        stream);
+            }
+        }
     }
 
     private void dumpStreamStates(PrintWriter pw) {
@@ -1026,7 +1052,9 @@
         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
 
-        if (updateVolumes) {
+        if (updateVolumes && mStreamStates != null) {
+            updateDefaultVolumes();
+
             mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
                     caller);
 
@@ -1347,7 +1375,7 @@
             // This is simulated by stepping by the full allowed volume range
             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
                     (device & mSafeMediaVolumeDevices) != 0) {
-                step = mSafeMediaVolumeIndex;
+                step = safeMediaVolumeIndex(device);
             } else {
                 step = streamState.getMaxIndex();
             }
@@ -1693,7 +1721,7 @@
                 if (index != 0) {
                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
                             (device & mSafeMediaVolumeDevices) != 0) {
-                        index = mSafeMediaVolumeIndex;
+                        index = safeMediaVolumeIndex(device);
                     } else {
                         index = streamState.getMaxIndex();
                     }
@@ -1817,7 +1845,7 @@
     }
 
     // UI update and Broadcast Intent
-    private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
+    protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
         streamType = mStreamVolumeAlias[streamType];
 
         if (streamType == AudioSystem.STREAM_MUSIC) {
@@ -3436,7 +3464,7 @@
                             MUSIC_ACTIVE_POLL_PERIOD_MS);
                     int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
                     if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) &&
-                            (index > mSafeMediaVolumeIndex)) {
+                            (index > safeMediaVolumeIndex(device))) {
                         // Approximate cumulative active music time
                         mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;
                         if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
@@ -3454,12 +3482,40 @@
         mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget();
     }
 
+    private int getSafeUsbMediaVolumeIndex()
+    {
+        // determine UI volume index corresponding to the wanted safe gain in dBFS
+        int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+        int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+
+        while (Math.abs(max-min) > 1) {
+            int index = (max + min) / 2;
+            float gainDB = AudioSystem.getStreamVolumeDB(
+                    AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
+            if (Float.isNaN(gainDB)) {
+                //keep last min in case of read error
+                break;
+            } else if (gainDB == SAFE_VOLUME_GAIN_DBFS) {
+                min = index;
+                break;
+            } else if (gainDB < SAFE_VOLUME_GAIN_DBFS) {
+                min = index;
+            } else {
+                max = index;
+            }
+        }
+        return min * 10;
+    }
+
     private void onConfigureSafeVolume(boolean force, String caller) {
         synchronized (mSafeMediaVolumeState) {
             int mcc = mContext.getResources().getConfiguration().mcc;
             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
+
+                mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
+
                 boolean safeMediaVolumeEnabled =
                         SystemProperties.getBoolean("audio.safemedia.force", false)
                         || mContext.getResources().getBoolean(
@@ -4843,6 +4899,12 @@
                     mAudioEventWakeLock.release();
                     break;
 
+                case MSG_DISABLE_AUDIO_FOR_UID:
+                    mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
+                            msg.arg2 /* uid */);
+                    mAudioEventWakeLock.release();
+                    break;
+
                 case MSG_REPORT_NEW_ROUTES: {
                     int N = mRoutesObservers.beginBroadcast();
                     if (N > 0) {
@@ -5302,38 +5364,20 @@
         return delay;
     }
 
-    private void sendDeviceConnectionIntent(int device, int state, String address,
-            String deviceName) {
-        if (DEBUG_DEVICES) {
-            Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) +
-                    " state:0x" + Integer.toHexString(state) + " address:" + address +
-                    " name:" + deviceName + ");");
-        }
-        Intent intent = new Intent();
-
-        intent.putExtra(CONNECT_INTENT_KEY_STATE, state);
-        intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address);
-        intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName);
-
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-
+    private void updateAudioRoutes(int device, int state)
+    {
         int connType = 0;
 
         if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
             connType = AudioRoutesInfo.MAIN_HEADSET;
-            intent.setAction(Intent.ACTION_HEADSET_PLUG);
-            intent.putExtra("microphone", 1);
         } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
                    device == AudioSystem.DEVICE_OUT_LINE) {
-            /*do apps care about line-out vs headphones?*/
             connType = AudioRoutesInfo.MAIN_HEADPHONES;
-            intent.setAction(Intent.ACTION_HEADSET_PLUG);
-            intent.putExtra("microphone", 0);
         } else if (device == AudioSystem.DEVICE_OUT_HDMI ||
                 device == AudioSystem.DEVICE_OUT_HDMI_ARC) {
             connType = AudioRoutesInfo.MAIN_HDMI;
-            configureHdmiPlugIntent(intent, state);
-        } else if (device == AudioSystem.DEVICE_OUT_USB_DEVICE) {
+        } else if (device == AudioSystem.DEVICE_OUT_USB_DEVICE||
+                device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
             connType = AudioRoutesInfo.MAIN_USB;
         }
 
@@ -5352,6 +5396,52 @@
                 }
             }
         }
+    }
+
+    private void sendDeviceConnectionIntent(int device, int state, String address,
+            String deviceName) {
+        if (DEBUG_DEVICES) {
+            Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) +
+                    " state:0x" + Integer.toHexString(state) + " address:" + address +
+                    " name:" + deviceName + ");");
+        }
+        Intent intent = new Intent();
+
+        if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone", 1);
+        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
+                   device == AudioSystem.DEVICE_OUT_LINE) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone",  0);
+        } else if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
+            intent.setAction(Intent.ACTION_HEADSET_PLUG);
+            intent.putExtra("microphone",
+                    AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_IN_USB_HEADSET, "")
+                        == AudioSystem.DEVICE_STATE_AVAILABLE ? 1 : 0);
+        } else if (device == AudioSystem.DEVICE_IN_USB_HEADSET) {
+            if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_USB_HEADSET, "")
+                    == AudioSystem.DEVICE_STATE_AVAILABLE) {
+                intent.setAction(Intent.ACTION_HEADSET_PLUG);
+                intent.putExtra("microphone", 1);
+            } else {
+                // do not send ACTION_HEADSET_PLUG when only the input side is seen as changing
+                return;
+            }
+        } else if (device == AudioSystem.DEVICE_OUT_HDMI ||
+                device == AudioSystem.DEVICE_OUT_HDMI_ARC) {
+            configureHdmiPlugIntent(intent, state);
+        }
+
+        if (intent.getAction() == null) {
+            return;
+        }
+
+        intent.putExtra(CONNECT_INTENT_KEY_STATE, state);
+        intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address);
+        intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName);
+
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -5380,9 +5470,7 @@
             if ((state == 0) && ((device & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0)) {
                 setBluetoothA2dpOnInt(true);
             }
-            boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
-                            (((device & AudioSystem.DEVICE_BIT_IN) != 0) &&
-                             ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));
+
             if (!handleDeviceConnection(state == 1, device, address, deviceName)) {
                 // change of connection state failed, bailout
                 return;
@@ -5422,9 +5510,8 @@
                     }
                 }
             }
-            if (!isUsb && device != AudioSystem.DEVICE_IN_WIRED_HEADSET) {
-                sendDeviceConnectionIntent(device, state, address, deviceName);
-            }
+            sendDeviceConnectionIntent(device, state, address, deviceName);
+            updateAudioRoutes(device, state);
         }
     }
 
@@ -5950,9 +6037,18 @@
     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 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 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;
+                                                AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
+                                                AudioSystem.DEVICE_OUT_USB_HEADSET;
     // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
     // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
     // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
@@ -5961,6 +6057,17 @@
     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
 
+    private int safeMediaVolumeIndex(int device) {
+        if ((device & mSafeMediaVolumeDevices) == 0) {
+            return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
+        }
+        if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
+            return mSafeUsbMediaVolumeIndex;
+        } else {
+            return mSafeMediaVolumeIndex;
+        }
+    }
+
     private void setSafeMediaVolumeEnabled(boolean on, String caller) {
         synchronized (mSafeMediaVolumeState) {
             if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
@@ -5995,8 +6102,8 @@
                 continue;
             }
             int index = streamState.getIndex(device);
-            if (index > mSafeMediaVolumeIndex) {
-                streamState.setIndex(mSafeMediaVolumeIndex, device, caller);
+            if (index > safeMediaVolumeIndex(device)) {
+                streamState.setIndex(safeMediaVolumeIndex(device), device, caller);
                 sendMsg(mAudioHandler,
                         MSG_SET_DEVICE_VOLUME,
                         SENDMSG_QUEUE,
@@ -6014,7 +6121,7 @@
             if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
                     (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
                     ((device & mSafeMediaVolumeDevices) != 0) &&
-                    (index > mSafeMediaVolumeIndex)) {
+                    (index > safeMediaVolumeIndex(device))) {
                 return false;
             }
             return true;
@@ -6240,6 +6347,7 @@
         pw.print("  mSafeMediaVolumeState=");
         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
+        pw.print("  mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex);
         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
@@ -6534,6 +6642,13 @@
                 }
             }
         }
+
+        @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/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 702cbbe..663559f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -29,6 +29,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.text.DateFormat;
 import java.util.ArrayList;
@@ -67,6 +69,12 @@
                     .createIfNeeded()
                     .build();
 
+    // TODO support VolumeShaper on those players
+    private static final int[] UNDUCKABLE_PLAYER_TYPES = {
+            AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO,
+            AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL,
+    };
+
     // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
     private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
             new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
@@ -87,6 +95,43 @@
     }
 
     //=================================================================
+    private final ArrayList<Integer> mBannedUids = new ArrayList<Integer>();
+
+    // see AudioManagerInternal.disableAudioForUid(boolean disable, int uid)
+    public void disableAudioForUid(boolean disable, int uid) {
+        synchronized(mPlayerLock) {
+            final int index = mBannedUids.indexOf(new Integer(uid));
+            if (index >= 0) {
+                if (!disable) {
+                    mBannedUids.remove(index);
+                    // nothing else to do, future playback requests from this uid are ok
+                } // no else to handle, uid already present, so disabling again is no-op
+            } else {
+                if (disable) {
+                    for (AudioPlaybackConfiguration apc : mPlayers.values()) {
+                        checkBanPlayer(apc, uid);
+                    }
+                    mBannedUids.add(new Integer(uid));
+                } // no else to handle, uid already not in list, so enabling again is no-op
+            }
+        }
+    }
+
+    private boolean checkBanPlayer(@NonNull AudioPlaybackConfiguration apc, int uid) {
+        final boolean toBan = (apc.getClientUid() == uid);
+        if (toBan) {
+            final int piid = apc.getPlayerInterfaceId();
+            try {
+                Log.v(TAG, "banning player " + piid + " uid:" + uid);
+                apc.getPlayerProxy().pause();
+            } catch (Exception e) {
+                Log.e(TAG, "error banning player " + piid + " uid:" + uid, e);
+            }
+        }
+        return toBan;
+    }
+
+    //=================================================================
     // Track players and their states
     // methods playerAttributes, playerEvent, releasePlayer are all oneway calls
     //  into AudioService. They trigger synchronous dispatchPlaybackChange() which updates
@@ -129,6 +174,14 @@
             if (apc == null) {
                 return;
             }
+            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                for (Integer uidInteger: mBannedUids) {
+                    if (checkBanPlayer(apc, uidInteger.intValue())) {
+                        // player was banned, do not update its state
+                        return;
+                    }
+                }
+            }
             if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                 // FIXME SoundPool not ready for state reporting
                 return;
@@ -178,10 +231,17 @@
             pw.println("\n  ducked players:");
             mDuckingManager.dump(pw);
             // players muted due to the device ringing or being in a call
-            pw.println("\n  muted player piids:");
+            pw.print("\n  muted player piids:");
             for (int piid : mMutedPlayers) {
-                pw.println(" " + piid);
+                pw.print(" " + piid);
             }
+            pw.println();
+            // banned players:
+            pw.print("\n  banned uids:");
+            for (int uid : mBannedUids) {
+                pw.print(" " + uid);
+            }
+            pw.println();
         }
     }
 
@@ -298,12 +358,12 @@
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
                                 + " - SPEECH");
                         return false;
-                    } else if (apc.getPlayerType()
-                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
-                        // TODO support ducking of SoundPool players
+                    } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) {
                         Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
                                 + " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
-                                + " - SoundPool");
+                                + " due to type:"
+                                + AudioPlaybackConfiguration.toLogFriendlyPlayerType(
+                                        apc.getPlayerType()));
                         return false;
                     }
                     apcsToDuck.add(apc);
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index 359cc36..ad20ed8 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -17,15 +17,13 @@
 package com.android.server.audio;
 
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.media.AudioSystem;
 import android.os.Handler;
 import android.util.Log;
-import android.view.OrientationEventListener;
 import android.view.Surface;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowOrientationListener;
-
 /**
  * Class to handle device rotation events for AudioService, and forward device rotation
  * to the audio HALs through AudioSystem.
@@ -42,18 +40,17 @@
 
     private static final String TAG = "AudioService.RotationHelper";
 
-    private static AudioOrientationListener sOrientationListener;
-    private static AudioWindowOrientationListener sWindowOrientationListener;
+    private static AudioDisplayListener sDisplayListener;
 
     private static final Object sRotationLock = new Object();
     private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
 
     private static Context sContext;
+    private static Handler sHandler;
 
     /**
      * post conditions:
-     * - (sWindowOrientationListener != null) xor (sOrientationListener != null)
-     * - sWindowOrientationListener xor sOrientationListener is enabled
+     * - sDisplayListener != null
      * - sContext != null
      */
     static void init(Context context, Handler handler) {
@@ -61,34 +58,20 @@
             throw new IllegalArgumentException("Invalid null context");
         }
         sContext = context;
-        sWindowOrientationListener = new AudioWindowOrientationListener(context, handler);
-        sWindowOrientationListener.enable();
-        if (!sWindowOrientationListener.canDetectOrientation()) {
-            // cannot use com.android.server.policy.WindowOrientationListener, revert to public
-            // orientation API
-            Log.i(TAG, "Not using WindowOrientationListener, reverting to OrientationListener");
-            sWindowOrientationListener.disable();
-            sWindowOrientationListener = null;
-            sOrientationListener = new AudioOrientationListener(context);
-            sOrientationListener.enable();
-        }
+        sHandler = handler;
+        sDisplayListener = new AudioDisplayListener();
+        enable();
     }
 
     static void enable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.enable();
-        } else {
-            sOrientationListener.enable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .registerDisplayListener(sDisplayListener, sHandler);
         updateOrientation();
     }
 
     static void disable() {
-        if (sWindowOrientationListener != null) {
-            sWindowOrientationListener.disable();
-        } else {
-            sOrientationListener.disable();
-        }
+        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
+                .unregisterDisplayListener(sDisplayListener);
     }
 
     /**
@@ -128,84 +111,21 @@
     }
 
     /**
-     * Uses android.view.OrientationEventListener
+     * Uses android.hardware.display.DisplayManager.DisplayListener
      */
-    final static class AudioOrientationListener extends OrientationEventListener {
-        AudioOrientationListener(Context context) {
-            super(context);
+    final static class AudioDisplayListener implements DisplayManager.DisplayListener {
+
+        @Override
+        public void onDisplayAdded(int displayId) {
         }
 
         @Override
-        public void onOrientationChanged(int orientation) {
+        public void onDisplayRemoved(int displayId) {
+        }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
             updateOrientation();
         }
     }
-
-    /**
-     * Uses com.android.server.policy.WindowOrientationListener
-     */
-    final static class AudioWindowOrientationListener extends WindowOrientationListener {
-        private static RotationCheckThread sRotationCheckThread;
-
-        AudioWindowOrientationListener(Context context, Handler handler) {
-            super(context, handler);
-        }
-
-        public void onProposedRotationChanged(int rotation) {
-            updateOrientation();
-            if (sRotationCheckThread != null) {
-                sRotationCheckThread.endCheck();
-            }
-            sRotationCheckThread = new RotationCheckThread();
-            sRotationCheckThread.beginCheck();
-        }
-    }
-
-    /**
-     * When com.android.server.policy.WindowOrientationListener report an orientation change,
-     * the UI may not have rotated yet. This thread polls with gradually increasing delays
-     * the new orientation.
-     */
-    final static class RotationCheckThread extends Thread {
-        // how long to wait between each rotation check
-        private final int[] WAIT_TIMES_MS = { 10, 20, 50, 100, 100, 200, 200, 500 };
-        private int mWaitCounter;
-        private final Object mCounterLock = new Object();
-
-        RotationCheckThread() {
-            super("RotationCheck");
-        }
-
-        void beginCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = 0;
-            }
-            try {
-                start();
-            } catch (IllegalStateException e) { }
-        }
-
-        void endCheck() {
-            synchronized(mCounterLock) {
-                mWaitCounter = WAIT_TIMES_MS.length;
-            }
-        }
-
-        public void run() {
-            while (mWaitCounter < WAIT_TIMES_MS.length) {
-                int waitTimeMs;
-                synchronized(mCounterLock) {
-                    waitTimeMs = mWaitCounter < WAIT_TIMES_MS.length ?
-                            WAIT_TIMES_MS[mWaitCounter] : 0;
-                    mWaitCounter++;
-                }
-                try {
-                    if (waitTimeMs > 0) {
-                        sleep(waitTimeMs);
-                        updateOrientation();
-                    }
-                } catch (InterruptedException e) { }
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index d155825..3133a51 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -21,6 +21,7 @@
 import android.content.IntentFilter;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceProxy;
+import android.metrics.LogMaker;
 import android.nfc.INfcAdapter;
 import android.os.Binder;
 import android.os.Handler;
@@ -28,15 +29,23 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserManager;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -56,12 +65,6 @@
 
     public static final String CAMERA_SERVICE_PROXY_BINDER_NAME = "media.camera.proxy";
 
-    // State arguments to use with the notifyCameraState call from camera service:
-    public static final int CAMERA_STATE_OPEN = 0;
-    public static final int CAMERA_STATE_ACTIVE = 1;
-    public static final int CAMERA_STATE_IDLE = 2;
-    public static final int CAMERA_STATE_CLOSED = 3;
-
     // Flags arguments to NFC adapter to enable/disable NFC
     public static final int DISABLE_POLLING_FLAGS = 0x1000;
     public static final int ENABLE_POLLING_FLAGS = 0x0000;
@@ -71,6 +74,9 @@
 
     private static final int RETRY_DELAY_TIME = 20; //ms
 
+    // Maximum entries to keep in usage history before dumping out
+    private static final int MAX_USAGE_HISTORY = 100;
+
     private final Context mContext;
     private final ServiceThread mHandlerThread;
     private final Handler mHandler;
@@ -82,14 +88,52 @@
 
     private ICameraService mCameraServiceRaw;
 
-    private final ArraySet<String> mActiveCameraIds = new ArraySet<>();
-
+    private final ArrayMap<String, CameraUsageEvent> mActiveCameraUsage = new ArrayMap<>();
+    private final List<CameraUsageEvent> mCameraUsageHistory = new ArrayList<>();
+    private final MetricsLogger mLogger = new MetricsLogger();
     private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
     private static final String NFC_SERVICE_BINDER_NAME = "nfc";
     private static final IBinder nfcInterfaceToken = new Binder();
 
     private final boolean mNotifyNfc;
-    private int mActiveCameraCount = 0;
+
+    /**
+     * Structure to track camera usage
+     */
+    private static class CameraUsageEvent {
+        public final int mCameraFacing;
+        public final String mClientName;
+
+        private boolean mCompleted;
+        private long mDurationOrStartTimeMs;  // Either start time, or duration once completed
+
+        public CameraUsageEvent(int facing, String clientName) {
+            mCameraFacing = facing;
+            mClientName = clientName;
+            mDurationOrStartTimeMs = SystemClock.elapsedRealtime();
+            mCompleted = false;
+        }
+
+        public void markCompleted() {
+            if (mCompleted) {
+                return;
+            }
+            mCompleted = true;
+            mDurationOrStartTimeMs = SystemClock.elapsedRealtime() - mDurationOrStartTimeMs;
+            if (CameraServiceProxy.DEBUG) {
+                Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
+                        " was in use by " + mClientName + " for " +
+                        mDurationOrStartTimeMs + " ms");
+            }
+        }
+
+        /**
+         * Return duration of camera usage event, or 0 if the event is not done
+         */
+        public long getDuration() {
+            return mCompleted ? mDurationOrStartTimeMs : 0;
+        }
+    }
 
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
@@ -123,11 +167,14 @@
         }
 
         @Override
-        public void notifyCameraState(String cameraId, int newCameraState) {
+        public void notifyCameraState(String cameraId, int newCameraState, int facing,
+                String clientName) {
             String state = cameraStateToString(newCameraState);
-            if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state);
+            String facingStr = cameraFacingToString(facing);
+            if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
+                    state + " for client " + clientName);
 
-            updateActivityCount(cameraId, newCameraState);
+            updateActivityCount(cameraId, newCameraState, facing, clientName);
         }
     };
 
@@ -173,6 +220,9 @@
         mContext.registerReceiver(mIntentReceiver, filter);
 
         publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy);
+        publishLocalService(CameraServiceProxy.class, this);
+
+        CameraStatsJobService.schedule(mContext);
     }
 
     @Override
@@ -202,8 +252,8 @@
             mCameraServiceRaw = null;
 
             // All cameras reset to idle on camera service death
-            boolean wasEmpty = mActiveCameraIds.isEmpty();
-            mActiveCameraIds.clear();
+            boolean wasEmpty = mActiveCameraUsage.isEmpty();
+            mActiveCameraUsage.clear();
 
             if ( mNotifyNfc && !wasEmpty ) {
                 notifyNfcService(/*enablePolling*/ true);
@@ -211,6 +261,46 @@
         }
     }
 
+    /**
+     * Dump camera usage events to log.
+     * Package-private
+     */
+    void dumpUsageEvents() {
+        synchronized(mLock) {
+            // Randomize order of events so that it's not meaningful
+            Collections.shuffle(mCameraUsageHistory);
+            for (CameraUsageEvent e : mCameraUsageHistory) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Camera: " + e.mClientName + " used a camera facing " +
+                            cameraFacingToString(e.mCameraFacing) + " for " +
+                            e.getDuration() + " ms");
+                }
+                int subtype = 0;
+                switch(e.mCameraFacing) {
+                    case ICameraServiceProxy.CAMERA_FACING_BACK:
+                        subtype = MetricsEvent.CAMERA_BACK_USED;
+                        break;
+                    case ICameraServiceProxy.CAMERA_FACING_FRONT:
+                        subtype = MetricsEvent.CAMERA_FRONT_USED;
+                        break;
+                    case ICameraServiceProxy.CAMERA_FACING_EXTERNAL:
+                        subtype = MetricsEvent.CAMERA_EXTERNAL_USED;
+                        break;
+                    default:
+                        continue;
+                }
+                LogMaker l = new LogMaker(MetricsEvent.ACTION_CAMERA_EVENT)
+                        .setType(MetricsEvent.TYPE_ACTION)
+                        .setSubtype(subtype)
+                        .setLatency(e.getDuration())
+                        .setPackageName(e.mClientName);
+                mLogger.write(l);
+            }
+            mCameraUsageHistory.clear();
+        }
+        CameraStatsJobService.schedule(mContext);
+    }
+
     private void switchUserLocked(int userHandle) {
         Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
         mLastUser = userHandle;
@@ -278,21 +368,35 @@
         return true;
     }
 
-    private void updateActivityCount(String cameraId, int newCameraState) {
+    private void updateActivityCount(String cameraId, int newCameraState, int facing, String clientName) {
         synchronized(mLock) {
-            boolean wasEmpty = mActiveCameraIds.isEmpty();
+            // Update active camera list and notify NFC if necessary
+            boolean wasEmpty = mActiveCameraUsage.isEmpty();
             switch (newCameraState) {
-                case CAMERA_STATE_OPEN:
+                case ICameraServiceProxy.CAMERA_STATE_OPEN:
                     break;
-                case CAMERA_STATE_ACTIVE:
-                    mActiveCameraIds.add(cameraId);
+                case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
+                    CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName);
+                    CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
+                    if (oldEvent != null) {
+                        Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
+                        oldEvent.markCompleted();
+                        mCameraUsageHistory.add(oldEvent);
+                    }
                     break;
-                case CAMERA_STATE_IDLE:
-                case CAMERA_STATE_CLOSED:
-                    mActiveCameraIds.remove(cameraId);
+                case ICameraServiceProxy.CAMERA_STATE_IDLE:
+                case ICameraServiceProxy.CAMERA_STATE_CLOSED:
+                    CameraUsageEvent doneEvent = mActiveCameraUsage.remove(cameraId);
+                    if (doneEvent != null) {
+                        doneEvent.markCompleted();
+                        mCameraUsageHistory.add(doneEvent);
+                        if (mCameraUsageHistory.size() > MAX_USAGE_HISTORY) {
+                            dumpUsageEvents();
+                        }
+                    }
                     break;
             }
-            boolean isEmpty = mActiveCameraIds.isEmpty();
+            boolean isEmpty = mActiveCameraUsage.isEmpty();
             if ( mNotifyNfc && (wasEmpty != isEmpty) ) {
                 notifyNfcService(isEmpty);
             }
@@ -328,12 +432,23 @@
 
     private static String cameraStateToString(int newCameraState) {
         switch (newCameraState) {
-            case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
-            case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
-            case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
-            case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
+            case ICameraServiceProxy.CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
+            case ICameraServiceProxy.CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
+            case ICameraServiceProxy.CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
+            case ICameraServiceProxy.CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
             default: break;
         }
         return "CAMERA_STATE_UNKNOWN";
     }
+
+    private static String cameraFacingToString(int cameraFacing) {
+        switch (cameraFacing) {
+            case ICameraServiceProxy.CAMERA_FACING_BACK: return "CAMERA_FACING_BACK";
+            case ICameraServiceProxy.CAMERA_FACING_FRONT: return "CAMERA_FACING_FRONT";
+            case ICameraServiceProxy.CAMERA_FACING_EXTERNAL: return "CAMERA_FACING_EXTERNAL";
+            default: break;
+        }
+        return "CAMERA_FACING_UNKNOWN";
+    }
+
 }
diff --git a/services/core/java/com/android/server/camera/CameraStatsJobService.java b/services/core/java/com/android/server/camera/CameraStatsJobService.java
new file mode 100644
index 0000000..b8a6846
--- /dev/null
+++ b/services/core/java/com/android/server/camera/CameraStatsJobService.java
@@ -0,0 +1,77 @@
+/*
+ * 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/LICENSE2.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.camera;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.util.Slog;
+
+import java.util.concurrent.TimeUnit;
+
+import com.android.server.LocalServices;
+
+/**
+ * A JobService to periodically collect camera usage stats.
+ */
+public class CameraStatsJobService extends JobService {
+    private static final String TAG = "CameraStatsJobService";
+
+    // Must be unique within UID (system service)
+    private static final int CAMERA_REPORTING_JOB_ID = 0xCA3E7A;
+
+    private static ComponentName sCameraStatsJobServiceName = new ComponentName(
+            "android",
+            CameraStatsJobService.class.getName());
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        CameraServiceProxy serviceProxy = LocalServices.getService(CameraServiceProxy.class);
+        if (serviceProxy == null) {
+            Slog.w(TAG, "Can't collect camera usage stats - no camera service proxy found");
+            return false;
+        }
+
+        serviceProxy.dumpUsageEvents();
+        return false;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        // All work is done in onStartJob, so nothing to stop here
+        return false;
+    }
+
+    public static void schedule(Context context) {
+
+        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        if (js == null) {
+            Slog.e(TAG, "Can't collect camera usage stats - no Job Scheduler");
+            return;
+        }
+        js.schedule(new JobInfo.Builder(CAMERA_REPORTING_JOB_ID, sCameraStatsJobServiceName)
+                .setMinimumLatency(TimeUnit.DAYS.toMillis(1))
+                .setRequiresDeviceIdle(true)
+                .build());
+
+    }
+
+}
diff --git a/services/core/java/com/android/server/car/CarServiceHelperService.java b/services/core/java/com/android/server/car/CarServiceHelperService.java
new file mode 100644
index 0000000..9392a6a
--- /dev/null
+++ b/services/core/java/com/android/server/car/CarServiceHelperService.java
@@ -0,0 +1,91 @@
+/*
+ * 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.car;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.car.ICarServiceHelper;
+import com.android.server.SystemService;
+
+/**
+ * System service side companion service for CarService.
+ * Starts car service and provide necessary API for CarService. Only for car product.
+ */
+public class CarServiceHelperService extends SystemService {
+    private static final String TAG = "CarServiceHelper";
+    private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
+    private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
+    private IBinder mCarService;
+    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
+
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+            Slog.i(TAG, "**CarService connected**");
+            mCarService = iBinder;
+            // Cannot depend on ICar which is defined in CarService, so handle binder call directly
+            // instead.
+            // void setCarServiceHelper(in IBinder helper)
+            Parcel data = Parcel.obtain();
+            data.writeInterfaceToken(CAR_SERVICE_INTERFACE);
+            data.writeStrongBinder(mHelper.asBinder());
+            try {
+                mCarService.transact(IBinder.FIRST_CALL_TRANSACTION, // setCarServiceHelper
+                        data, null, Binder.FLAG_ONEWAY);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "RemoteException from car service", e);
+                handleCarServiceCrash();
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            handleCarServiceCrash();
+        }
+    };
+
+    public CarServiceHelperService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        Intent intent = new Intent();
+        intent.setPackage("com.android.car");
+        intent.setAction(CAR_SERVICE_INTERFACE);
+        if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
+                UserHandle.SYSTEM)) {
+            Slog.wtf(TAG, "cannot start car service");
+        }
+    }
+
+    private void handleCarServiceCrash() {
+        //TODO define recovery bahavior
+    }
+
+    private class ICarServiceHelperImpl extends ICarServiceHelper.Stub {
+        //TODO
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index d7cd81f..0993f42 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -71,9 +71,6 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.UserManagerInternal;
-import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
@@ -93,7 +90,6 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.server.LocalServices;
 import com.android.server.connectivity.tethering.IControlsTethering;
 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
 import com.android.server.connectivity.tethering.OffloadController;
@@ -241,13 +237,6 @@
         filter.addDataScheme("file");
         mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
 
-        UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
-
-        // this check is useful only for some unit tests; example: ConnectivityServiceTest
-        if (userManager != null) {
-            userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
-        }
-
         // load device config info
         updateConfiguration();
     }
@@ -722,11 +711,6 @@
     }
 
     private void showTetheredNotification(int id) {
-        showTetheredNotification(id, true);
-    }
-
-    @VisibleForTesting
-    protected void showTetheredNotification(int id, boolean tetheringOn) {
         NotificationManager notificationManager =
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         if (notificationManager == null) {
@@ -763,16 +747,9 @@
                 null, UserHandle.CURRENT);
 
         Resources r = Resources.getSystem();
-        final CharSequence title;
-        final CharSequence message;
-
-        if (tetheringOn) {
-            title = r.getText(com.android.internal.R.string.tethered_notification_title);
-            message = r.getText(com.android.internal.R.string.tethered_notification_message);
-        } else {
-            title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
-            message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
-        }
+        CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title);
+        CharSequence message = r.getText(com.android.internal.R.string.
+                tethered_notification_message);
 
         if (mTetheredNotificationBuilder == null) {
             mTetheredNotificationBuilder =
@@ -794,8 +771,7 @@
                 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
     }
 
-    @VisibleForTesting
-    protected void clearTetheredNotification() {
+    private void clearTetheredNotification() {
         NotificationManager notificationManager =
             (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         if (notificationManager != null && mLastNotificationId != 0) {
@@ -912,38 +888,6 @@
         }
     }
 
-    @VisibleForTesting
-    protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
-        private final Tethering mWrapper;
-
-        public TetheringUserRestrictionListener(Tethering wrapper) {
-            mWrapper = wrapper;
-        }
-
-        public void onUserRestrictionsChanged(int userId,
-                                              Bundle newRestrictions,
-                                              Bundle prevRestrictions) {
-            final boolean newlyDisallowed =
-                    newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
-            final boolean previouslyDisallowed =
-                    prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
-            final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);
-
-            if (!tetheringDisallowedChanged) {
-                return;
-            }
-
-            mWrapper.clearTetheredNotification();
-            final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
-
-            if (newlyDisallowed && isTetheringActiveOnDevice) {
-                mWrapper.showTetheredNotification(
-                        com.android.internal.R.drawable.stat_sys_tether_general, false);
-                mWrapper.untetherAll();
-            }
-        }
-    }
-
     private void disableWifiIpServingLocked(String ifname, int apState) {
         mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
 
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 76195c4..f8c6582 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -42,7 +42,7 @@
     // 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 int DEFAULT_TETHER_OFFLOAD_DISABLED = 1;
     private static final String NO_INTERFACE_NAME = "";
     private static final String NO_IPV4_ADDRESS = "";
     private static final String NO_IPV4_GATEWAY = "";
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 13054a6..ad74ff8 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
@@ -101,6 +102,22 @@
             }
         }
 
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onStopUser(int userHandle) {
+            mService.onStopUser(userHandle);
+        }
+
         @Override
         public void onCleanupUser(int userHandle) {
             synchronized (mService.mCache) {
@@ -161,11 +178,25 @@
         }
     }
 
+    void onStartUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStartUser(userHandle);
+    }
+
+    void onUnlockUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onUnlockUser(userHandle);
+    }
+
+    void onStopUser(int userHandle) {
+        if (mSyncManager != null) mSyncManager.onStopUser(userHandle);
+    }
+
     @Override
     protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
         final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, "  ");
 
+        final boolean dumpAll = ArrayUtils.contains(args, "-a");
+
         // This makes it so that future permission checks will be in the context of this
         // process rather than the caller's process. We will restore this before returning.
         final long identityToken = clearCallingIdentity();
@@ -173,7 +204,7 @@
             if (mSyncManager == null) {
                 pw.println("No SyncManager created!  (Disk full?)");
             } else {
-                mSyncManager.dump(fd, pw);
+                mSyncManager.dump(fd, pw, dumpAll);
             }
             pw.println();
             pw.println("Observer tree:");
@@ -603,7 +634,7 @@
                 SyncStorageEngine.EndPoint info;
                 info = new SyncStorageEngine.EndPoint(account, authority, userId);
                 syncManager.clearScheduledSyncOperations(info);
-                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */, "API");
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -631,7 +662,7 @@
             }
             // Cancel active syncs and clear pending syncs from the queue.
             syncManager.cancelScheduledSyncOperation(info, extras);
-            syncManager.cancelActiveSync(info, extras);
+            syncManager.cancelActiveSync(info, extras, "API");
         } finally {
             restoreCallingIdentity(identityToken);
         }
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index a621d73..07f04b1 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -34,6 +34,8 @@
     private Messenger mMessenger;
     private SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>();
 
+    private final SyncLogger mLogger = SyncLogger.getInstance();
+
     /**
      * This service is started by the SyncManager which passes a messenger object to
      * communicate back with it. It never stops while the device is running.
@@ -63,6 +65,9 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
+
+        mLogger.purgeOldLogs();
+
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         synchronized (jobParamsMap) {
             jobParamsMap.put(params.getJobId(), params);
@@ -70,6 +75,9 @@
         Message m = Message.obtain();
         m.what = SyncManager.SyncHandler.MESSAGE_START_SYNC;
         SyncOperation op = SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+
+        mLogger.log("onStartJob() jobid=", params.getJobId(), " op=", op);
+
         if (op == null) {
             Slog.e(TAG, "Got invalid job " + params.getJobId());
             return false;
@@ -88,7 +96,7 @@
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
                     + params.getStopReason());
         }
-
+        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params));
         synchronized (jobParamsMap) {
             jobParamsMap.remove(params.getJobId());
         }
@@ -108,9 +116,13 @@
         return false;
     }
 
-    public void callJobFinished(int jobId, boolean needsReschedule) {
+    public void callJobFinished(int jobId, boolean needsReschedule, String why) {
         synchronized (jobParamsMap) {
             JobParameters params = jobParamsMap.get(jobId);
+            mLogger.log("callJobFinished()",
+                    " needsReschedule=", needsReschedule,
+                    " ", mLogger.jobParametersToString(params),
+                    " why=", why);
             if (params != null) {
                 jobFinished(params, needsReschedule);
                 jobParamsMap.remove(jobId);
@@ -119,4 +131,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java
new file mode 100644
index 0000000..8503768
--- /dev/null
+++ b/services/core/java/com/android/server/content/SyncLogger.java
@@ -0,0 +1,274 @@
+/*
+ * 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.content;
+
+import android.app.job.JobParameters;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a rotating file logger for the sync manager, which is enabled only on userdebug/eng
+ * builds (unless debug.synclog is set to 1).
+ *
+ * Note this class could be used for other purposes too, but in general we don't want various
+ * system components to log to files, so it's put in a local package here.
+ */
+public class SyncLogger {
+    private static final String TAG = "SyncLogger";
+
+    private static SyncLogger sInstance;
+
+    SyncLogger() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static synchronized SyncLogger getInstance() {
+        if (sInstance == null) {
+            final boolean enable = "1".equals(SystemProperties.get("debug.synclog",
+                    Build.IS_DEBUGGABLE ? "1" : "0"));
+            if (enable) {
+                sInstance = new RotatingFileLogger();
+            } else {
+                sInstance = new SyncLogger();
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Write strings to the log file.
+     */
+    public void log(Object... message) {
+    }
+
+    /**
+     * Remove old log files.
+     */
+    public void purgeOldLogs() {
+        // The default implementation is no-op.
+    }
+
+    public String jobParametersToString(JobParameters params) {
+        // The default implementation is no-op.
+        return "";
+    }
+
+    /**
+     * Dump all existing log files into a given writer.
+     */
+    public void dumpAll(PrintWriter pw) {
+    }
+
+    /**
+     * @return whether log is enabled or not.
+     */
+    public boolean enabled() {
+        return false;
+    }
+
+    /**
+     * Actual implementation which is only used on userdebug/eng builds (by default).
+     */
+    private static class RotatingFileLogger extends SyncLogger {
+        private final Object mLock = new Object();
+
+        private final long mKeepAgeMs = TimeUnit.DAYS.toMillis(7);
+
+        private static final SimpleDateFormat sTimestampFormat
+                = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+        private static final SimpleDateFormat sFilenameDateFormat
+                = new SimpleDateFormat("yyyy-MM-dd");
+
+        @GuardedBy("mLock")
+        private final Date mCachedDate = new Date();
+
+        @GuardedBy("mLock")
+        private final StringBuilder mStringBuilder = new StringBuilder();
+
+        private final File mLogPath;
+
+        @GuardedBy("mLock")
+        private long mCurrentLogFileDayTimestamp;
+
+        @GuardedBy("mLock")
+        private Writer mLogWriter;
+
+        @GuardedBy("mLock")
+        private boolean mErrorShown;
+
+        private static final boolean DO_LOGCAT = Log.isLoggable(TAG, Log.DEBUG);
+
+        RotatingFileLogger() {
+            mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log");
+        }
+
+        @Override
+        public boolean enabled() {
+            return true;
+        }
+
+        private void handleException(String message, Exception e) {
+            if (!mErrorShown) {
+                Slog.e(TAG, message, e);
+                mErrorShown = true;
+            }
+        }
+
+        @Override
+        public void log(Object... message) {
+            if (message == null) {
+                return;
+            }
+            synchronized (mLock) {
+                final long now = System.currentTimeMillis();
+                openLogLocked(now);
+                if (mLogWriter == null) {
+                    return; // Couldn't open log file?
+                }
+
+                mStringBuilder.setLength(0);
+                mCachedDate.setTime(now);
+                mStringBuilder.append(sTimestampFormat.format(mCachedDate));
+                mStringBuilder.append(' ');
+
+                mStringBuilder.append(android.os.Process.myTid());
+                mStringBuilder.append(' ');
+
+                final int messageStart = mStringBuilder.length();
+
+                for (Object o : message) {
+                    mStringBuilder.append(o);
+                }
+                mStringBuilder.append('\n');
+
+                try {
+                    mLogWriter.append(mStringBuilder);
+                    mLogWriter.flush();
+
+                    // Also write on logcat.
+                    if (DO_LOGCAT) {
+                        Log.d(TAG, mStringBuilder.substring(messageStart));
+                    }
+                } catch (IOException e) {
+                    handleException("Failed to write log", e);
+                }
+            }
+        }
+
+        private void openLogLocked(long now) {
+            // If we already have a log file opened and the date has't changed, just use it.
+            final long day = now % DateUtils.DAY_IN_MILLIS;
+            if ((mLogWriter != null) && (day == mCurrentLogFileDayTimestamp)) {
+                return;
+            }
+
+            // Otherwise create a new log file.
+            closeCurrentLogLocked();
+
+            mCurrentLogFileDayTimestamp = day;
+
+            mCachedDate.setTime(now);
+            final String filename = "synclog-" + sFilenameDateFormat.format(mCachedDate) + ".log";
+            final File file = new File(mLogPath, filename);
+
+            file.getParentFile().mkdirs();
+
+            try {
+                mLogWriter = new FileWriter(file, /* append= */ true);
+            } catch (IOException e) {
+                handleException("Failed to open log file: " + file, e);
+            }
+        }
+
+        private void closeCurrentLogLocked() {
+            IoUtils.closeQuietly(mLogWriter);
+            mLogWriter = null;
+        }
+
+        @Override
+        public void purgeOldLogs() {
+            synchronized (mLock) {
+                FileUtils.deleteOlderFiles(mLogPath, /* keepCount= */ 1, mKeepAgeMs);
+            }
+        }
+
+        @Override
+        public String jobParametersToString(JobParameters params) {
+            if (params == null) {
+                return "job:null";
+            } else {
+                return "job:#" + params.getJobId() + ":"
+                        + SyncOperation.maybeCreateFromJobExtras(params.getExtras());
+            }
+        }
+
+        @Override
+        public void dumpAll(PrintWriter pw) {
+            synchronized (mLock) {
+                final String[] files = mLogPath.list();
+                if (files == null || (files.length == 0)) {
+                    return;
+                }
+                Arrays.sort(files);
+
+                for (String file : files) {
+                    dumpFile(pw, new File(mLogPath, file));
+                }
+            }
+        }
+
+        private void dumpFile(PrintWriter pw, File file) {
+            Slog.w(TAG, "Dumping " + file);
+            final char[] buffer = new char[32 * 1024];
+
+            try (Reader in = new BufferedReader(new FileReader(file))) {
+                int read;
+                while ((read = in.read(buffer)) >= 0) {
+                    if (read > 0) {
+                        pw.write(buffer, 0, read);
+                    }
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 3ca65cd..a9c0cb0 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -58,6 +58,7 @@
 import android.net.NetworkInfo;
 import android.net.TrafficStats;
 import android.os.BatteryStats;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -74,7 +75,6 @@
 import android.os.UserManager;
 import android.os.WorkSource;
 import android.provider.Settings;
-import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.EventLog;
 import android.util.Log;
@@ -113,6 +113,7 @@
 import java.util.Objects;
 import java.util.Random;
 import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * Implementation details:
@@ -241,6 +242,8 @@
 
     private final Random mRand;
 
+    private final SyncLogger mLogger;
+
     private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) {
         for (JobInfo job: pendingJobs) {
             if (job.getId() == jobId) {
@@ -289,13 +292,15 @@
                         mStorageIsLow = true;
                         cancelActiveSync(
                                 SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
-                                null /* any sync */);
+                                null /* any sync */,
+                                "storage low");
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Slog.v(TAG, "Internal storage is ok.");
                         }
                         mStorageIsLow = false;
-                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+                        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                "storage ok");
                     }
                 }
             };
@@ -378,15 +383,16 @@
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Slog.v(TAG, "Reconnection detected: clearing all backoffs");
                             }
+                            // Note the location of this code was wrong from nyc to oc; fixed in DR.
+                            clearAllBackoffs("network reconnect");
                         }
-                        clearAllBackoffs();
                     }
                 }
             };
 
-    private void clearAllBackoffs() {
+    private void clearAllBackoffs(String why) {
         mSyncStorageEngine.clearAllBackoffsLocked();
-        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL);
+        rescheduleSyncs(EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL, why);
     }
 
     private boolean readDataConnectionState() {
@@ -400,6 +406,7 @@
                 public void onReceive(Context context, Intent intent) {
                     Log.w(TAG, "Writing sync state before shutdown...");
                     getSyncStorageEngine().writeAllState();
+                    mLogger.log("Shutting down.");
                 }
             };
 
@@ -455,6 +462,7 @@
                             continue;
                         }
                         if (opx.key.equals(opy.key)) {
+                            mLogger.log("Removing duplicate sync: ", opy);
                             mJobScheduler.cancel(opy.jobId);
                         }
                     }
@@ -467,25 +475,57 @@
         if (mJobScheduler != null) {
             return;
         }
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.d(TAG, "initializing JobScheduler object.");
-        }
-        mJobScheduler = (JobScheduler) mContext.getSystemService(
-                Context.JOB_SCHEDULER_SERVICE);
-        mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
-        // Get all persisted syncs from JobScheduler
-        List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
-        for (JobInfo job : pendingJobs) {
-            SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
-            if (op != null) {
-                if (!op.isPeriodic) {
-                    // Set the pending status of this EndPoint to true. Pending icon is
-                    // shown on the settings activity.
-                    mSyncStorageEngine.markPending(op.target, true);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.d(TAG, "initializing JobScheduler object.");
+            }
+            mJobScheduler = (JobScheduler) mContext.getSystemService(
+                    Context.JOB_SCHEDULER_SERVICE);
+            mJobSchedulerInternal = LocalServices.getService(JobSchedulerInternal.class);
+            // Get all persisted syncs from JobScheduler
+            List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
+
+            int numPersistedPeriodicSyncs = 0;
+            int numPersistedOneshotSyncs = 0;
+            for (JobInfo job : pendingJobs) {
+                SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+                if (op != null) {
+                    if (op.isPeriodic) {
+                        numPersistedPeriodicSyncs++;
+                    } else {
+                        numPersistedOneshotSyncs++;
+                        // Set the pending status of this EndPoint to true. Pending icon is
+                        // shown on the settings activity.
+                        mSyncStorageEngine.markPending(op.target, true);
+                    }
                 }
             }
+            if (mLogger.enabled()) {
+                mLogger.log("Connected to JobScheduler: "
+                        + numPersistedPeriodicSyncs + " periodic syncs "
+                        + numPersistedOneshotSyncs + " oneshot syncs.");
+            }
+            cleanupJobs();
+
+            if ((numPersistedPeriodicSyncs == 0) && likelyHasPeriodicSyncs()) {
+                Slog.wtf(TAG, "Device booted with no persisted periodic syncs.");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-        cleanupJobs();
+    }
+
+    /**
+     * @return whether the device most likely has some periodic syncs.
+     */
+    private boolean likelyHasPeriodicSyncs() {
+        try {
+            return AccountManager.get(mContext).getAccountsByType("com.google").length > 0;
+        } catch (Throwable th) {
+            // Just in case.
+        }
+        return false;
     }
 
     private JobScheduler getJobScheduler() {
@@ -502,6 +542,8 @@
         // and creating threads and so on; it may fail if the disk is full.
         mContext = context;
 
+        mLogger = SyncLogger.getInstance();
+
         SyncStorageEngine.init(context);
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
@@ -667,8 +709,23 @@
         // before we started checking for account access because they already know
         // the account (they run before) which is the genie is out of the bottle.
         whiteListExistingSyncAdaptersIfNeeded();
+
+        mLogger.log("Sync manager initialized.");
     }
 
+    public void onStartUser(int userHandle) {
+        mLogger.log("onStartUser: user=", userHandle);
+    }
+
+    public void onUnlockUser(int userHandle) {
+        mLogger.log("onUnlockUser: user=", userHandle);
+    }
+
+    public void onStopUser(int userHandle) {
+        mLogger.log("onStopUser: user=", userHandle);
+    }
+
+
     private void whiteListExistingSyncAdaptersIfNeeded() {
         if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
             return;
@@ -1062,11 +1119,13 @@
     }
 
     private void removeSyncsForAuthority(EndPoint info) {
+        mLogger.log("removeSyncsForAuthority: ", info);
         verifyJobScheduler();
         List<SyncOperation> ops = getAllPendingSyncs();
         for (SyncOperation op: ops) {
             if (op.target.matchesSpec(info)) {
-                 getJobScheduler().cancel(op.jobId);
+                mLogger.log("canceling: ", op);
+                getJobScheduler().cancel(op.jobId);
             }
         }
     }
@@ -1145,8 +1204,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras,
+            String why) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_CANCEL");
+
+        mLogger.log("sendCancelSyncsMessage() ep=", info, " why=", why);
+
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
         msg.setData(extras);
@@ -1227,7 +1290,7 @@
         }
     }
 
-    private void clearBackoffSetting(EndPoint target) {
+    private void clearBackoffSetting(EndPoint target, String why) {
         Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(target);
         if (backoff != null && backoff.first == SyncStorageEngine.NOT_IN_BACKOFF_MODE &&
                 backoff.second == SyncStorageEngine.NOT_IN_BACKOFF_MODE) {
@@ -1240,7 +1303,7 @@
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE);
 
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, why);
     }
 
     private void increaseBackoffSetting(EndPoint target) {
@@ -1281,14 +1344,16 @@
             Slog.v(TAG, "Backoff until: " + backoff + ", delayTime: " + newDelayInMs);
         }
         mSyncStorageEngine.setBackoff(target, backoff, newDelayInMs);
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "increaseBackoffSetting");
     }
 
     /**
      * Reschedule all scheduled syncs for this EndPoint. The syncs will be scheduled according
      * to current backoff and delayUntil values of this EndPoint.
      */
-    private void rescheduleSyncs(EndPoint target) {
+    private void rescheduleSyncs(EndPoint target, String why) {
+        mLogger.log("rescheduleSyncs() ep=", target, " why=", why);
+
         List<SyncOperation> ops = getAllPendingSyncs();
         int count = 0;
         for (SyncOperation op: ops) {
@@ -1316,7 +1381,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Slog.v(TAG, "Delay Until time set to " + newDelayUntilTime + " for " + target);
         }
-        rescheduleSyncs(target);
+        rescheduleSyncs(target, "delayUntil newDelayUntilTime: " + newDelayUntilTime);
     }
 
     private boolean isAdapterDelayed(EndPoint target) {
@@ -1338,8 +1403,8 @@
      * have null account/provider info to specify all accounts/providers.
      * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
-        sendCancelSyncsMessage(info, extras);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras, String why) {
+        sendCancelSyncsMessage(info, extras, why);
     }
 
     /**
@@ -1599,11 +1664,13 @@
                         null /* any account */,
                         null /* any authority */,
                         userId),
-                null /* any sync. */
+                null /* any sync. */,
+                "onUserStopped"
         );
     }
 
     private void onUserRemoved(int userId) {
+        mLogger.log("onUserRemoved: u", userId);
         updateRunningAccounts(null /* Don't sync any target */);
 
         // Clean up the storage engine database
@@ -1674,6 +1741,8 @@
             // Include "this" in the message so that the handler can ignore it if this
             // ActiveSyncContext is no longer the mActiveSyncContext at message handling
             // time.
+            mLogger.log("onFinished result=", result, " endpoint=",
+                    (mSyncOperation == null ? "null" : mSyncOperation.target));
             sendSyncFinishedOrCanceledMessage(this, result);
         }
 
@@ -1715,6 +1784,7 @@
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                             | Context.BIND_ALLOW_OOM_MANAGEMENT,
                     new UserHandle(mSyncOperation.target.userId));
+            mLogger.log("bindService() returned=", mBound, " for ", this);
             if (!bindResult) {
                 mBound = false;
             } else {
@@ -1737,6 +1807,7 @@
             }
             if (mBound) {
                 mBound = false;
+                mLogger.log("unbindService for ", this);
                 mContext.unbindService(this);
                 try {
                     mBatteryStats.noteSyncFinish(mEventName, mSyncAdapterUid);
@@ -1759,13 +1830,15 @@
         }
     }
 
-    protected void dump(FileDescriptor fd, PrintWriter pw) {
+    protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        dumpPendingSyncs(pw);
-        dumpPeriodicSyncs(pw);
         dumpSyncState(ipw);
-        dumpSyncHistory(ipw);
         dumpSyncAdapters(ipw);
+
+        if (dumpAll) {
+            ipw.println("Detailed Sync History");
+            mLogger.dumpAll(pw);
+        }
     }
 
     static String formatTime(long time) {
@@ -1774,9 +1847,58 @@
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
 
+    private final static Comparator<SyncOperation> sOpDumpComparator = (op1, op2) -> {
+        int res = Integer.compare(op1.target.userId, op2.target.userId);
+        if (res != 0) return res;
+
+        final Comparator<String> stringComparator = String.CASE_INSENSITIVE_ORDER;
+
+        res = stringComparator.compare(op1.target.account.type, op2.target.account.type);
+        if (res != 0) return res;
+
+        res = stringComparator.compare(op1.target.account.name, op2.target.account.name);
+        if (res != 0) return res;
+
+        res = stringComparator.compare(op1.target.provider, op2.target.provider);
+        if (res != 0) return res;
+
+        res = Integer.compare(op1.reason, op2.reason);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.periodMillis, op2.periodMillis);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.expectedRuntime, op2.expectedRuntime);
+        if (res != 0) return res;
+
+        res = Long.compare(op1.jobId, op2.jobId);
+        if (res != 0) return res;
+
+        return 0;
+    };
+
+    private final static Comparator<SyncOperation> sOpRuntimeComparator = (op1, op2) -> {
+        int res = Long.compare(op1.expectedRuntime, op2.expectedRuntime);
+        if (res != 0) return res;
+
+        return sOpDumpComparator.compare(op1, op2);
+    };
+
+    private static <T> int countIf(Collection<T> col, Predicate<T> p) {
+        int ret = 0;
+        for (T item : col) {
+            if (p.test(item)) ret++;
+        }
+        return ret;
+    }
+
     protected void dumpPendingSyncs(PrintWriter pw) {
-        pw.println("Pending Syncs:");
         List<SyncOperation> pendingSyncs = getAllPendingSyncs();
+
+        pw.print("Pending Syncs: ");
+        pw.println(countIf(pendingSyncs, op -> !op.isPeriodic));
+
+        Collections.sort(pendingSyncs, sOpRuntimeComparator);
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (!op.isPeriodic) {
@@ -1784,13 +1906,16 @@
                 count++;
             }
         }
-        pw.println("Total: " + count);
         pw.println();
     }
 
     protected void dumpPeriodicSyncs(PrintWriter pw) {
-        pw.println("Periodic Syncs:");
         List<SyncOperation> pendingSyncs = getAllPendingSyncs();
+
+        pw.print("Periodic Syncs: ");
+        pw.println(countIf(pendingSyncs, op -> op.isPeriodic));
+
+        Collections.sort(pendingSyncs, sOpDumpComparator);
         int count = 0;
         for (SyncOperation op: pendingSyncs) {
             if (op.isPeriodic) {
@@ -1798,11 +1923,62 @@
                 count++;
             }
         }
-        pw.println("Total: " + count);
         pw.println();
     }
 
+    /**
+     * Similar to {@link android.util.TimeUtils#formatDuration}, but it's more suitable and concise
+     * for the sync manager dumpsys.  (Don't add the leading + sign, don't show milliseconds.)
+     */
+    public static StringBuilder formatDurationHMS(StringBuilder sb, long duration) {
+        duration /= 1000;
+        if (duration < 0) {
+            sb.append('-');
+            duration = -duration;
+        }
+        final long seconds = duration % 60;
+        duration /= 60;
+
+        final long minutes = duration % 60;
+        duration /= 60;
+
+        final long hours = duration % 24;
+        duration /= 24;
+
+        final long days = duration;
+
+        boolean print = false;
+        if (days > 0) {
+            sb.append(days);
+            sb.append('d');
+            print = true;
+        }
+        print = printTwoDigitNumber(sb, hours, 'h', print);
+        print = printTwoDigitNumber(sb, minutes, 'm', print);
+        print = printTwoDigitNumber(sb, seconds, 's', print);
+        if (!print) {
+            sb.append("0s");
+        }
+
+        return sb;
+    }
+
+    private static boolean printTwoDigitNumber(StringBuilder sb, long value, char unit,
+            boolean always) {
+        if (!always && (value == 0)) {
+            return false;
+        }
+        if (always && (value < 10)) {
+            sb.append('0');
+        }
+        sb.append(value);
+        sb.append(unit);
+        return true;
+    }
+
     protected void dumpSyncState(PrintWriter pw) {
+        final StringBuilder sb = new StringBuilder();
+
         pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
         pw.print("auto sync: ");
         List<UserInfo> users = getAllUsers();
@@ -1828,13 +2004,16 @@
         final long now = SystemClock.elapsedRealtime();
         pw.print("now: "); pw.print(now);
         pw.println(" (" + formatTime(System.currentTimeMillis()) + ")");
-        pw.println(" (HH:MM:SS)");
-        pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now / 1000));
-        pw.println(" (HH:MM:SS)");
+
+        sb.setLength(0);
+        pw.print("uptime: "); pw.print(formatDurationHMS(sb, now));
+        pw.println();
         pw.print("time spent syncing: ");
-        pw.print(DateUtils.formatElapsedTime(
-                mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000));
-        pw.print(" (HH:MM:SS), sync ");
+
+        sb.setLength(0);
+        pw.print(formatDurationHMS(sb,
+                mSyncHandler.mSyncTimeTracker.timeSpentSyncing()));
+        pw.print(", sync ");
         pw.print(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not ");
         pw.println("in progress");
 
@@ -1842,17 +2021,24 @@
         pw.println("Active Syncs: " + mActiveSyncContexts.size());
         final PackageManager pm = mContext.getPackageManager();
         for (SyncManager.ActiveSyncContext activeSyncContext : mActiveSyncContexts) {
-            final long durationInSeconds = (now - activeSyncContext.mStartTime) / 1000;
+            final long durationInSeconds = (now - activeSyncContext.mStartTime);
             pw.print("  ");
-            pw.print(DateUtils.formatElapsedTime(durationInSeconds));
+            sb.setLength(0);
+            pw.print(formatDurationHMS(sb, durationInSeconds));
             pw.print(" - ");
             pw.print(activeSyncContext.mSyncOperation.dump(pm, false));
             pw.println();
         }
+        pw.println();
+
+        dumpPendingSyncs(pw);
+        dumpPeriodicSyncs(pw);
 
         // Join the installed sync adapter with the accounts list and emit for everything.
-        pw.println();
         pw.println("Sync Status");
+
+        final ArrayList<Pair<EndPoint, SyncStatusInfo>> statuses = new ArrayList<>();
+
         for (AccountAndUser account : accounts) {
             pw.printf("Account %s u%d %s\n",
                     account.account.name, account.userId, account.account.type);
@@ -1872,7 +2058,7 @@
                     "Tot",       // 9
                     "Time",      // 10
                     "Last Sync", // 11
-                    "Etc"        // 12
+                    "Backoff"    // 12
             );
 
             final List<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> sorted =
@@ -1899,11 +2085,14 @@
                                         account.userId));
                 SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
                 SyncStatusInfo status = syncAuthoritySyncStatus.second;
+                statuses.add(Pair.create(settings.target, status));
                 String authority = settings.target.provider;
                 if (authority.length() > 50) {
                     authority = authority.substring(authority.length() - 50);
                 }
                 table.set(row, 0, authority, settings.syncable, settings.enabled);
+
+                sb.setLength(0);
                 table.set(row, 4,
                         status.numSourceLocal,
                         status.numSourcePoll,
@@ -1911,7 +2100,7 @@
                         status.numSourceServer,
                         status.numSourceUser,
                         status.numSyncs,
-                        DateUtils.formatElapsedTime(status.totalElapsedTime / 1000));
+                        formatDurationHMS(sb, status.totalElapsedTime));
 
                 int row1 = row;
                 if (settings.delayUntil > now) {
@@ -1938,6 +2127,34 @@
             }
             table.writeTo(pw);
         }
+
+        dumpSyncHistory(pw);
+
+        pw.println();
+        pw.println("Per Adapter History");
+
+        for (int i = 0; i < statuses.size(); i++) {
+            final Pair<EndPoint, SyncStatusInfo> event = statuses.get(i);
+
+            pw.print("  ");
+            pw.print(event.first.account.name);
+            pw.print('/');
+            pw.print(event.first.account.type);
+            pw.print(" u");
+            pw.print(event.first.userId);
+            pw.print(" [");
+            pw.print(event.first.provider);
+            pw.print("]");
+            pw.println();
+
+            for (int j = 0; j < event.second.getEventCount(); j++) {
+                pw.print("    ");
+                pw.print(formatTime(event.second.getEventTime(j)));
+                pw.print(' ');
+                pw.print(event.second.getEvent(j));
+                pw.println();
+            }
+        }
     }
 
     private void dumpTimeSec(PrintWriter pw, long time) {
@@ -2503,7 +2720,7 @@
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: "
                                     + endpoint + " bundle: " + extras);
                         }
-                        cancelActiveSyncH(endpoint, extras);
+                        cancelActiveSyncH(endpoint, extras, "MESSAGE_CANCEL");
                         break;
 
                     case SyncHandler.MESSAGE_SYNC_FINISHED:
@@ -2519,7 +2736,8 @@
                             Slog.v(TAG, "syncFinished" + payload.activeSyncContext.mSyncOperation);
                         }
                         mSyncJobService.callJobFinished(
-                                payload.activeSyncContext.mSyncOperation.jobId, false);
+                                payload.activeSyncContext.mSyncOperation.jobId, false,
+                                "sync finished");
                         runSyncFinishedOrCanceledH(payload.syncResult,
                                 payload.activeSyncContext);
                         break;
@@ -2552,9 +2770,14 @@
                             // outstanding
                             try {
                                 if (currentSyncContext.mSyncAdapter != null) {
+                                    mLogger.log("Calling cancelSync for SERVICE_DISCONNECTED ",
+                                            currentSyncContext,
+                                            " adapter=", currentSyncContext.mSyncAdapter);
                                     currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext);
+                                    mLogger.log("Canceled");
                                 }
                             } catch (RemoteException e) {
+                                mLogger.log("RemoteException ", Log.getStackTraceString(e));
                                 // We don't need to retry this in this case.
                             }
 
@@ -2563,7 +2786,8 @@
                             SyncResult syncResult = new SyncResult();
                             syncResult.stats.numIoExceptions++;
                             mSyncJobService.callJobFinished(
-                                    currentSyncContext.mSyncOperation.jobId, false);
+                                    currentSyncContext.mSyncOperation.jobId, false,
+                                    "service disconnected");
                             runSyncFinishedOrCanceledH(syncResult, currentSyncContext);
                         }
                         break;
@@ -2581,7 +2805,8 @@
                                     "Detected sync making no progress for %s. cancelling.",
                                     monitoredSyncContext));
                             mSyncJobService.callJobFinished(
-                                    monitoredSyncContext.mSyncOperation.jobId, false);
+                                    monitoredSyncContext.mSyncOperation.jobId, false,
+                                    "no network activity");
                             runSyncFinishedOrCanceledH(
                                     null /* cancel => no result */, monitoredSyncContext);
                         } else {
@@ -2613,8 +2838,10 @@
          * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off
          * sync will be scheduled.
          */
-        private void deferSyncH(SyncOperation op, long delay) {
-            mSyncJobService.callJobFinished(op.jobId, false);
+        private void deferSyncH(SyncOperation op, long delay, String why) {
+            mLogger.log("deferSyncH() ", (op.isPeriodic ? "periodic " : ""),
+                    "sync.  op=", op, " delay=", delay, " why=", why);
+            mSyncJobService.callJobFinished(op.jobId, false, why);
             if (op.isPeriodic) {
                 scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
             } else {
@@ -2638,10 +2865,10 @@
         /**
          * Cancel an active sync and reschedule it on the JobScheduler with some delay.
          */
-        private void deferActiveSyncH(ActiveSyncContext asc) {
+        private void deferActiveSyncH(ActiveSyncContext asc, String why) {
             SyncOperation op = asc.mSyncOperation;
             runSyncFinishedOrCanceledH(null, asc);
-            deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+            deferSyncH(op, SYNC_DELAY_ON_CONFLICT, why);
         }
 
         private void startSyncH(SyncOperation op) {
@@ -2649,7 +2876,7 @@
             if (isLoggable) Slog.v(TAG, op.toString());
 
             if (mStorageIsLow) {
-                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE);
+                deferSyncH(op, SYNC_DELAY_ON_LOW_STORAGE, "storage low");
                 return;
             }
 
@@ -2659,7 +2886,8 @@
                 List<SyncOperation> ops = getAllPendingSyncs();
                 for (SyncOperation syncOperation: ops) {
                     if (syncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, pending");
                         return;
                     }
                 }
@@ -2667,13 +2895,14 @@
                 // executing according to some backoff criteria.
                 for (ActiveSyncContext asc: mActiveSyncContexts) {
                     if (asc.mSyncOperation.sourcePeriodicId == op.jobId) {
-                        mSyncJobService.callJobFinished(op.jobId, false);
+                        mSyncJobService.callJobFinished(op.jobId, false,
+                                "periodic sync, already running");
                         return;
                     }
                 }
                 // Check for adapter delays.
                 if (isAdapterDelayed(op.target)) {
-                    deferSyncH(op, 0 /* No minimum delay */);
+                    deferSyncH(op, 0 /* No minimum delay */, "backing off");
                     return;
                 }
             }
@@ -2687,13 +2916,13 @@
                         if (isLoggable) {
                             Slog.v(TAG, "Rescheduling sync due to conflict " + op.toString());
                         }
-                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
+                        deferSyncH(op, SYNC_DELAY_ON_CONFLICT, "delay on conflict");
                         return;
                     } else {
                         if (isLoggable) {
                             Slog.v(TAG, "Pushing back running sync due to a higher priority sync");
                         }
-                        deferActiveSyncH(asc);
+                        deferActiveSyncH(asc, "preempted");
                         break;
                     }
                 }
@@ -2703,12 +2932,13 @@
             switch (syncOpState) {
                 case SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS:
                 case SYNC_OP_STATE_INVALID: {
-                    mSyncJobService.callJobFinished(op.jobId, false);
+                    mSyncJobService.callJobFinished(op.jobId, false,
+                            "invalid op state: " + syncOpState);
                 } return;
             }
 
             if (!dispatchSyncOperation(op)) {
-                mSyncJobService.callJobFinished(op.jobId, false);
+                mSyncJobService.callJobFinished(op.jobId, false, "dispatchSyncOperation() failed");
             }
 
             setAuthorityPendingState(op.target);
@@ -2733,6 +2963,9 @@
                     Slog.v(TAG, acc.toString());
                 }
             }
+            if (mLogger.enabled()) {
+                mLogger.log("updateRunningAccountsH: ", Arrays.toString(mRunningAccounts));
+            }
             if (mBootCompleted) {
                 doDatabaseCleanup();
             }
@@ -2764,6 +2997,7 @@
             List<SyncOperation> ops = getAllPendingSyncs();
             for (SyncOperation op: ops) {
                 if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) {
+                    mLogger.log("canceling: ", op);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2878,9 +3112,11 @@
                 if (op.sourcePeriodicId == syncOperation.jobId || op.jobId == syncOperation.jobId) {
                     ActiveSyncContext asc = findActiveSyncContextH(syncOperation.jobId);
                     if (asc != null) {
-                        mSyncJobService.callJobFinished(syncOperation.jobId, false);
+                        mSyncJobService.callJobFinished(syncOperation.jobId, false,
+                                "removePeriodicSyncInternalH");
                         runSyncFinishedOrCanceledH(null, asc);
                     }
+                    mLogger.log("removePeriodicSyncInternalH-canceling: ", op);
                     getJobScheduler().cancel(op.jobId);
                 }
             }
@@ -2990,6 +3226,8 @@
             final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
             syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
             if (syncAdapterInfo == null) {
+                mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ",
+                        syncAdapterType);
                 Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                         + ", removing settings for it");
                 mSyncStorageEngine.removeAuthority(info);
@@ -3010,6 +3248,8 @@
             postMonitorSyncProgressMessage(activeSyncContext);
 
             if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                mLogger.log("dispatchSyncOperation() failed: bind failed. target: ",
+                        targetComponent);
                 Slog.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
@@ -3025,16 +3265,26 @@
                 activeSyncContext.mIsLinkedToDeath = true;
                 syncAdapter.linkToDeath(activeSyncContext, 0);
 
+                mLogger.log("Sync start: account=" + syncOperation.target.account,
+                        " authority=", syncOperation.target.provider,
+                        " reason=", SyncOperation.reasonToString(null, syncOperation.reason),
+                        " extras=", SyncOperation.extrasToString(syncOperation.extras),
+                        " adapter=", activeSyncContext.mSyncAdapter);
+
                 activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
                 activeSyncContext.mSyncAdapter
                         .startSync(activeSyncContext, syncOperation.target.provider,
                                 syncOperation.target.account, syncOperation.extras);
+
+                mLogger.log("Sync is running now...");
             } catch (RemoteException remoteExc) {
+                mLogger.log("Sync failed with RemoteException: ", remoteExc.toString());
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation.target);
                 scheduleSyncOperationH(syncOperation);
             } catch (RuntimeException exc) {
+                mLogger.log("Sync failed with RuntimeException: ", exc.toString());
                 closeActiveSyncContext(activeSyncContext);
                 Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
@@ -3045,7 +3295,8 @@
          * @param info Can have null fields to indicate all the active syncs for that field.
          * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint.
          */
-        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) {
+        private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras,
+                String why) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
@@ -3061,7 +3312,8 @@
                                     false /* no config settings */)) {
                         continue;
                     }
-                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false);
+                    mSyncJobService.callJobFinished(activeSyncContext.mSyncOperation.jobId, false,
+                            why);
                     runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext);
                 }
             }
@@ -3097,18 +3349,12 @@
                 activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
                 activeSyncContext.mIsLinkedToDeath = false;
             }
-            closeActiveSyncContext(activeSyncContext);
             final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
             String historyMessage;
             int downstreamActivity;
             int upstreamActivity;
 
-            if (!syncOperation.isPeriodic) {
-                // mSyncJobService.jobFinidhed is async, we need to ensure that this job is
-                // removed from JobScheduler's pending jobs list before moving forward and
-                // potentially rescheduling all pending jobs to respect new backoff values.
-                getJobScheduler().cancel(syncOperation.jobId);
-            }
+            mLogger.log("runSyncFinishedOrCanceledH() op=", syncOperation, " result=", syncResult);
 
             if (syncResult != null) {
                 if (isLoggable) {
@@ -3116,12 +3362,22 @@
                             + syncOperation + ", result " + syncResult);
                 }
 
+                // In the non-canceled case, close the active sync context before doing the rest
+                // of the stuff.
+                closeActiveSyncContext(activeSyncContext);
+
+                // Note this part is probably okay to do before closeActiveSyncContext()...
+                // But moved here to restore OC-dev's behavior.  See b/64597061.
+                if (!syncOperation.isPeriodic) {
+                    getJobScheduler().cancel(syncOperation.jobId);
+                }
+
                 if (!syncResult.hasError()) {
                     historyMessage = SyncStorageEngine.MESG_SUCCESS;
                     // TODO: set these correctly when the SyncResult is extended to include it
                     downstreamActivity = 0;
                     upstreamActivity = 0;
-                    clearBackoffSetting(syncOperation.target);
+                    clearBackoffSetting(syncOperation.target, "sync success");
 
                     // If the operation completes successfully and it was scheduled due to
                     // a periodic operation failing, we reschedule the periodic operation to
@@ -3152,16 +3408,28 @@
                 if (isLoggable) {
                     Slog.v(TAG, "runSyncFinishedOrCanceled [canceled]: " + syncOperation);
                 }
+
+                if (!syncOperation.isPeriodic) {
+                    getJobScheduler().cancel(syncOperation.jobId);
+                }
+
                 if (activeSyncContext.mSyncAdapter != null) {
                     try {
+                        mLogger.log("Calling cancelSync for runSyncFinishedOrCanceled ",
+                                activeSyncContext, "  adapter=", activeSyncContext.mSyncAdapter);
                         activeSyncContext.mSyncAdapter.cancelSync(activeSyncContext);
+                        mLogger.log("Canceled");
                     } catch (RemoteException e) {
+                        mLogger.log("RemoteException ", Log.getStackTraceString(e));
                         // we don't need to retry this in this case
                     }
                 }
                 historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
                 upstreamActivity = 0;
+
+                // In the cancel sync case, close it after calling cancelSync().
+                closeActiveSyncContext(activeSyncContext);
             }
 
             stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
@@ -3198,6 +3466,8 @@
                         + activeSyncContext.toString());
             }
             mSyncHandler.removeMessages(SyncHandler.MESSAGE_MONITOR_SYNC, activeSyncContext);
+
+            mLogger.log("closeActiveSyncContext: ", activeSyncContext);
         }
 
         /**
@@ -3403,7 +3673,7 @@
     }
 
     static class PrintTable {
-        private ArrayList<Object[]> mTable = Lists.newArrayList();
+        private ArrayList<String[]> mTable = Lists.newArrayList();
         private final int mCols;
 
         PrintTable(int cols) {
@@ -3416,13 +3686,17 @@
                         " columns. can't set " + values.length + " at column " + col);
             }
             for (int i = mTable.size(); i <= row; i++) {
-                final Object[] list = new Object[mCols];
+                final String[] list = new String[mCols];
                 mTable.add(list);
                 for (int j = 0; j < mCols; j++) {
                     list[j] = "";
                 }
             }
-            System.arraycopy(values, 0, mTable.get(row), col, values.length);
+            final String[] rowArray = mTable.get(row);
+            for (int i = 0; i < values.length; i++) {
+                final Object value = values[i];
+                rowArray[col + i] = (value == null) ? "" : value.toString();
+            }
         }
 
         void writeTo(PrintWriter out) {
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index c371f97..7d2cc00 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -18,10 +18,11 @@
 
 import android.accounts.Account;
 import android.app.job.JobInfo;
-import android.content.pm.PackageManager;
 import android.content.ContentResolver;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Slog;
 
@@ -236,6 +237,9 @@
      * contain a valid sync operation.
      */
     static SyncOperation maybeCreateFromJobExtras(PersistableBundle jobExtras) {
+        if (jobExtras == null) {
+            return null;
+        }
         String accountName, accountType;
         String provider;
         int userId, owningUid;
@@ -350,37 +354,46 @@
         return dump(null, true);
     }
 
-    String dump(PackageManager pm, boolean useOneLine) {
+    String dump(PackageManager pm, boolean shorter) {
         StringBuilder sb = new StringBuilder();
-        sb.append("JobId: ").append(jobId)
-                .append(", ")
+        sb.append("JobId=").append(jobId)
+                .append(" ")
                 .append(target.account.name)
-                .append(" u")
-                .append(target.userId).append(" (")
+                .append("/")
                 .append(target.account.type)
-                .append(")")
-                .append(", ")
+                .append(" u")
+                .append(target.userId)
+                .append(" [")
                 .append(target.provider)
-                .append(", ");
+                .append("] ");
         sb.append(SyncStorageEngine.SOURCES[syncSource]);
-        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
-            sb.append(", EXPEDITED");
+        if (expectedRuntime != 0) {
+            sb.append(" ExpectedIn=");
+            SyncManager.formatDurationHMS(sb,
+                    (expectedRuntime - SystemClock.elapsedRealtime()));
         }
-        sb.append(", reason: ");
+        if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+            sb.append(" EXPEDITED");
+        }
+        sb.append(" Reason=");
         sb.append(reasonToString(pm, reason));
         if (isPeriodic) {
-            sb.append(", period: " + periodMillis).append(", flexMillis: " + flexMillis);
+            sb.append(" (period=");
+            SyncManager.formatDurationHMS(sb, periodMillis);
+            sb.append(" flex=");
+            SyncManager.formatDurationHMS(sb, flexMillis);
+            sb.append(")");
         }
-        if (!useOneLine) {
-            sb.append("\n    ");
-            sb.append("owningUid=");
+        if (!shorter) {
+            sb.append(" Owner={");
             UserHandle.formatUid(sb, owningUid);
-            sb.append(" owningPackage=");
+            sb.append(" ");
             sb.append(owningPackage);
-        }
-        if (!useOneLine && !extras.keySet().isEmpty()) {
-            sb.append("\n    ");
-            extrasToStringBuilder(extras, sb);
+            sb.append("}");
+            if (!extras.keySet().isEmpty()) {
+                sb.append(" ");
+                extrasToStringBuilder(extras, sb);
+            }
         }
         return sb.toString();
     }
@@ -434,7 +447,11 @@
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
     }
 
-    private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+    static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+        if (bundle == null) {
+            sb.append("null");
+            return;
+        }
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -442,6 +459,12 @@
         sb.append("]");
     }
 
+    static String extrasToString(Bundle bundle) {
+        final StringBuilder sb = new StringBuilder();
+        extrasToStringBuilder(bundle, sb);
+        return sb.toString();
+    }
+
     String wakeLockName() {
         if (wakeLockName != null) {
             return wakeLockName;
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f804fa1..7b277c0 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1183,6 +1183,16 @@
                 ds.failureCount++;
                 ds.failureTime += elapsedTime;
             }
+            final StringBuilder event = new StringBuilder();
+            event.append("" + resultMessage + " Source=" + SyncStorageEngine.SOURCES[item.source]
+                    + " Elapsed=");
+            SyncManager.formatDurationHMS(event, elapsedTime);
+            event.append(" Reason=");
+            event.append(SyncOperation.reasonToString(null, item.reason));
+            event.append(" Extras=");
+            SyncOperation.extrasToStringBuilder(item.extras, event);
+
+            status.addEvent(event.toString());
 
             if (writeStatusNow) {
                 writeStatusLocked();
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 168744b..9aabdab 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -32,8 +32,8 @@
 import android.text.format.DateUtils;
 import android.util.EventLog;
 import android.util.MathUtils;
-import android.util.Spline;
 import android.util.Slog;
+import android.util.Spline;
 import android.util.TimeUtils;
 
 import java.io.PrintWriter;
@@ -59,6 +59,13 @@
     private static final int MSG_UPDATE_AMBIENT_LUX = 1;
     private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;
 
+    // Length of the ambient light horizon used to calculate the long term estimate of ambient
+    // light.
+    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
+
+    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
+    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
+
     // Callbacks for requesting updates to the display's power state
     private final Callbacks mCallbacks;
 
@@ -229,13 +236,13 @@
         // debugging purposes.
         mDozing = dozing;
         boolean changed = setLightSensorEnabled(enable && !dozing);
+        if (enable && !dozing && userInitiatedChange) {
+            prepareBrightnessAdjustmentSample();
+        }
         changed |= setScreenAutoBrightnessAdjustment(adjustment);
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
         }
-        if (enable && !dozing && userInitiatedChange) {
-            prepareBrightnessAdjustmentSample();
-        }
     }
 
     public void dump(PrintWriter pw) {
@@ -345,22 +352,51 @@
     }
 
     private void setAmbientLux(float lux) {
+        if (DEBUG) {
+            Slog.d(TAG, "setAmbientLux(" + lux + ")");
+        }
         mAmbientLux = lux;
         mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux);
         mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux);
     }
 
-    private float calculateAmbientLux(long now) {
+    private float calculateAmbientLux(long now, long horizon) {
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux(" + now + ", " + horizon + ")");
+        }
         final int N = mAmbientLightRingBuffer.size();
         if (N == 0) {
             Slog.e(TAG, "calculateAmbientLux: No ambient light readings available");
             return -1;
         }
+
+        // Find the first measurement that is just outside of the horizon.
+        int endIndex = 0;
+        final long horizonStartTime = now - horizon;
+        for (int i = 0; i < N-1; i++) {
+            if (mAmbientLightRingBuffer.getTime(i + 1) <= horizonStartTime) {
+                endIndex++;
+            } else {
+                break;
+            }
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=("
+                    + mAmbientLightRingBuffer.getTime(endIndex) + ", "
+                    + mAmbientLightRingBuffer.getLux(endIndex)
+                    + ")");
+        }
         float sum = 0;
         float totalWeight = 0;
         long endTime = AMBIENT_LIGHT_PREDICTION_TIME_MILLIS;
-        for (int i = N - 1; i >= 0; i--) {
-            long startTime = (mAmbientLightRingBuffer.getTime(i) - now);
+        for (int i = N - 1; i >= endIndex; i--) {
+            long eventTime = mAmbientLightRingBuffer.getTime(i);
+            if (i == endIndex && eventTime < horizonStartTime) {
+                // If we're at the final value, make sure we only consider the part of the sample
+                // within our desired horizon.
+                eventTime = horizonStartTime;
+            }
+            final long startTime = eventTime - now;
             float weight = calculateWeight(startTime, endTime);
             float lux = mAmbientLightRingBuffer.getLux(i);
             if (DEBUG) {
@@ -435,7 +471,7 @@
                         timeWhenSensorWarmedUp);
                 return;
             }
-            setAmbientLux(calculateAmbientLux(time));
+            setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
             mAmbientLuxValid = true;
             if (DEBUG) {
                 Slog.d(TAG, "updateAmbientLux: Initializing: "
@@ -447,14 +483,25 @@
 
         long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
         long nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
-        float ambientLux = calculateAmbientLux(time);
+        // Essentially, we calculate both a slow ambient lux, to ensure there's a true long-term
+        // change in lighting conditions, and a fast ambient lux to determine what the new
+        // brightness situation is since the slow lux can be quite slow to converge.
+        //
+        // Note that both values need to be checked for sufficient change before updating the
+        // proposed ambient light value since the slow value might be sufficiently far enough away
+        // from the fast value to cause a recalculation while its actually just converging on
+        // the fast value still.
+        float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
+        float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
 
-        if (ambientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
-                || ambientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
-            setAmbientLux(ambientLux);
+        if (slowAmbientLux >= mBrighteningLuxThreshold &&
+                fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
+                || slowAmbientLux <= mDarkeningLuxThreshold
+                && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
+            setAmbientLux(fastAmbientLux);
             if (DEBUG) {
                 Slog.d(TAG, "updateAmbientLux: "
-                        + ((ambientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
+                        + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
                         + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
                         + ", mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
                         + ", mAmbientLux=" + mAmbientLux);
@@ -616,6 +663,12 @@
         void updateBrightness();
     }
 
+    /**
+     * A ring buffer of ambient light measurements sorted by time.
+     *
+     * Each entry consists of a timestamp and a lux measurement, and the overall buffer is sorted
+     * from oldest to newest.
+     */
     private static final class AmbientLightRingBuffer {
         // Proportional extra capacity of the buffer beyond the expected number of light samples
         // in the horizon
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8129f45..8269042 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -132,7 +132,7 @@
 
     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
 
-    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
     private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
     private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
     private static final int MSG_REQUEST_TRAVERSAL = 4;
@@ -266,7 +266,6 @@
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
-
     }
 
     public void setupSchedulerPolicies() {
@@ -284,9 +283,9 @@
         // We need to pre-load the persistent data store so it's ready before the default display
         // adapter is up so that we have it's configuration. We could load it lazily, but since
         // we're going to have to read it in eventually we may as well do it here rather than after
-        // we've waited for the diplay to register itself with us.
+        // we've waited for the display to register itself with us.
         mPersistentDataStore.loadIfNeeded();
-        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
+        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
 
         publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                 true /*allowIsolated*/);
@@ -298,12 +297,16 @@
     public void onBootPhase(int phase) {
         if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
             synchronized (mSyncRoot) {
-                long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
-                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
+                long timeout = SystemClock.uptimeMillis()
+                        + mInjector.getDefaultDisplayDelayTimeout();
+                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
+                        mVirtualDisplayAdapter == null) {
                     long delay = timeout - SystemClock.uptimeMillis();
                     if (delay <= 0) {
                         throw new RuntimeException("Timeout waiting for default display "
-                                + "to be initialized.");
+                                + "to be initialized. DefaultDisplay="
+                                + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
+                                + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
                     }
                     if (DEBUG) {
                         Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
@@ -685,11 +688,23 @@
         }
     }
 
-    private void registerDefaultDisplayAdapter() {
-        // Register default display adapter.
+    private void registerDefaultDisplayAdapters() {
+        // Register default display adapters.
         synchronized (mSyncRoot) {
+            // main display adapter
             registerDisplayAdapterLocked(new LocalDisplayAdapter(
                     mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
+
+            // Standalone VR devices rely on a virtual display as their primary display for
+            // 2D UI. We register virtual display adapter along side the main display adapter
+            // here so that it is ready by the time the system sends the home Intent for
+            // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
+            // the virtual display inside VR before any VR-specific apps even run.
+            mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
+                    mHandler, mDisplayAdapterListener);
+            if (mVirtualDisplayAdapter != null) {
+                registerDisplayAdapterLocked(mVirtualDisplayAdapter);
+            }
         }
     }
 
@@ -698,7 +713,6 @@
             if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
                 registerOverlayDisplayAdapterLocked();
                 registerWifiDisplayAdapterLocked();
-                registerVirtualDisplayAdapterLocked();
             }
         }
     }
@@ -719,12 +733,6 @@
         }
     }
 
-    private void registerVirtualDisplayAdapterLocked() {
-        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler,
-                mDisplayAdapterListener);
-        registerDisplayAdapterLocked(mVirtualDisplayAdapter);
-    }
-
     private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
         // In safe mode, we disable non-essential display adapters to give the user
         // an opportunity to fix broken settings or other problems that might affect
@@ -1219,6 +1227,22 @@
                 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
         }
+
+        long getDefaultDisplayDelayTimeout() {
+            return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
+        }
+    }
+
+    @VisibleForTesting
+    DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
+        synchronized (mSyncRoot) {
+            LogicalDisplay display = mLogicalDisplays.get(displayId);
+            if (display != null) {
+                DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+                return displayDevice.getDisplayDeviceInfoLocked();
+            }
+            return null;
+        }
     }
 
     private final class DisplayManagerHandler extends Handler {
@@ -1229,8 +1253,8 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
-                    registerDefaultDisplayAdapter();
+                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
+                    registerDefaultDisplayAdapters();
                     break;
 
                 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e82724d..6e6e7d1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -165,6 +165,18 @@
     // a stylish color fade animation instead.
     private boolean mColorFadeFadesConfig;
 
+    // True if we need to fake a transition to off when coming out of a doze state.
+    // Some display hardware will blank itself when coming out of doze in order to hide
+    // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
+    // blank itself and begin an appropriate power on animation.
+    private boolean mDisplayBlanksAfterDozeConfig;
+
+    // True if there are only buckets of brightness values when the display is in the doze state,
+    // rather than a full range of values. If this is true, then we'll avoid animating the screen
+    // brightness since it'd likely be multiple jarring brightness transitions instead of just one
+    // to reach the final state.
+    private boolean mBrightnessBucketsInDozeConfig;
+
     // The pending power request.
     // Initially null until the first call to requestPowerState.
     // Guarded by mLock.
@@ -410,6 +422,12 @@
         mColorFadeFadesConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_animateScreenLights);
 
+        mDisplayBlanksAfterDozeConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_displayBlanksAfterDoze);
+
+        mBrightnessBucketsInDozeConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
+
         if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
             mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
             if (mProximitySensor != null) {
@@ -771,7 +789,7 @@
             boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
             if ((state == Display.STATE_ON
                     && mSkipRampState == RAMP_STATE_SKIP_NONE
-                    || state == Display.STATE_DOZE)
+                    || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
                     && !wasOrWillBeInVr) {
                 animateScreenBrightness(brightness,
                         slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
@@ -794,7 +812,7 @@
         // Notify policy about screen turned on.
         if (ready && state != Display.STATE_OFF
                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
             mWindowManagerPolicy.screenTurnedOn();
         }
 
@@ -877,6 +895,10 @@
     }
 
     private boolean setScreenState(int state) {
+        return setScreenState(state, false /*reportOnly*/);
+    }
+
+    private boolean setScreenState(int state, boolean reportOnly) {
         final boolean isOff = (state == Display.STATE_OFF);
         if (mPowerState.getScreenState() != state) {
 
@@ -884,24 +906,24 @@
             // actually turn the screen off.
             if (isOff && !mScreenOffBecauseOfProximity) {
                 if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
-                    mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
+                    setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
                     blockScreenOff();
                     mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
-                    return false;
+                    unblockScreenOff();
                 } else if (mPendingScreenOffUnblocker != null) {
-
                     // Abort doing the state change until screen off is unblocked.
                     return false;
                 }
             }
 
-            mPowerState.setScreenState(state);
-
-            // Tell battery stats about the transition.
-            try {
-                mBatteryStats.noteScreenState(state);
-            } catch (RemoteException ex) {
-                // same process
+            if (!reportOnly) {
+                mPowerState.setScreenState(state);
+                // Tell battery stats about the transition.
+                try {
+                    mBatteryStats.noteScreenState(state);
+                } catch (RemoteException ex) {
+                    // same process
+                }
             }
         }
 
@@ -913,7 +935,7 @@
         // finished drawing underneath.
         if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                 && !mScreenOffBecauseOfProximity) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
             unblockScreenOn();
             mWindowManagerPolicy.screenTurnedOff();
         } else if (!isOff
@@ -923,10 +945,10 @@
             // Complete the full state transition on -> turningOff -> off.
             unblockScreenOff();
             mWindowManagerPolicy.screenTurnedOff();
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
         }
         if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
-            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
+            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
             if (mPowerState.getColorFadeLevel() == 0.0f) {
                 blockScreenOn();
             } else {
@@ -939,6 +961,11 @@
         return mPendingScreenOnUnblocker == null;
     }
 
+    private void setReportedScreenState(int state) {
+        Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
+        mReportedScreenStateToPolicy = state;
+    }
+
     private int clampScreenBrightness(int value) {
         return MathUtils.constrain(
                 value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
@@ -968,6 +995,22 @@
             mPendingScreenOff = false;
         }
 
+        if (mDisplayBlanksAfterDozeConfig
+                && Display.isDozeState(mPowerState.getScreenState())
+                && !Display.isDozeState(target)) {
+            // Skip the screen off animation and add a black surface to hide the
+            // contents of the screen.
+            mPowerState.prepareColorFade(mContext,
+                    mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
+            mColorFadeOffAnimator.end();
+            // Some display hardware will blank itself on the transition between doze and non-doze
+            // but still on display states. In this case we want to report to policy that the
+            // display has turned off so it can prepare the appropriate power on animation, but we
+            // don't want to actually transition to the fully off state since that takes
+            // significantly longer to transition from.
+            setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
+        }
+
         // If we were in the process of turning off the screen but didn't quite
         // finish.  Then finish up now to prevent a jarring transition back
         // to screen on if we skipped blocking screen on as usual.
@@ -1263,7 +1306,8 @@
         pw.println("  mAppliedLowPower=" + mAppliedLowPower);
         pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
         pw.println("  mPendingScreenOff=" + mPendingScreenOff);
-        pw.println("  mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy));
+        pw.println("  mReportedToPolicy=" +
+                reportedToPolicyToString(mReportedScreenStateToPolicy));
 
         pw.println("  mScreenBrightnessRampAnimator.isAnimating()=" +
                 mScreenBrightnessRampAnimator.isAnimating());
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index e2fd0ac..efa4a1d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -20,6 +20,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
+import android.os.Trace;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Slog;
@@ -49,6 +50,7 @@
     private static final String TAG = "DisplayPowerState";
 
     private static boolean DEBUG = false;
+    private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
 
     private final Handler mHandler;
     private final Choreographer mChoreographer;
@@ -190,6 +192,7 @@
      * Dismisses the color fade surface.
      */
     public void dismissColorFade() {
+        Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
         mColorFade.dismiss();
         mColorFadePrepared = false;
         mColorFadeReady = true;
@@ -328,6 +331,8 @@
 
             if (mColorFadePrepared) {
                 mColorFade.draw(mColorFadeLevel);
+                Trace.traceCounter(Trace.TRACE_TAG_POWER,
+                        COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100));
             }
 
             mColorFadeReady = true;
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index 6902b1a..dbbb318 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -23,7 +23,6 @@
 import android.os.ServiceManager;
 import android.util.Slog;
 import android.util.SparseArray;
-
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.Arrays;
@@ -48,6 +47,9 @@
      */
     public static final int LEVEL_COLOR_MATRIX_INVERT_COLOR = 300;
 
+    private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
+    private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
+
     /**
      * Map of level -> color transformation matrix.
      */
@@ -172,7 +174,7 @@
                 data.writeInt(0);
             }
             try {
-                flinger.transact(1015, data, null, 0);
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX, data, null, 0);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to set color transform", ex);
             } finally {
@@ -191,7 +193,7 @@
             data.writeInterfaceToken("android.ui.ISurfaceComposer");
             data.writeInt(mode);
             try {
-                flinger.transact(1014, data, null, 0);
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_DALTONIZER, data, null, 0);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to set Daltonizer mode", ex);
             } finally {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index cdc973b..ce5f430 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -515,6 +515,7 @@
                         try {
                             final int mode = getPowerModeForState(state);
                             SurfaceControl.setDisplayPowerMode(token, mode);
+                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
@@ -530,6 +531,8 @@
                                 + "id=" + displayId + ", brightness=" + brightness + ")");
                         try {
                             mBacklight.setBrightness(brightness);
+                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
+                                    "DisplayBrightness", brightness);
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index b3cf57b..026921d 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -111,11 +111,7 @@
     private float[] mMatrixNight = new float[16];
 
     /**
-     *  These coefficients were generated by an LLS quadratic regression fitted to the
-     *  overdetermined system based on experimental readings (and subsequent conversion from xy
-     *  chromaticity coordinates to gamma-corrected RGB values): { (temperature, R, G, B) } ->
-     *  { (7304, 1.0, 1.0, 1.0), (4082, 1.0, 0.857, 0.719), (2850, 1.0, .754, .516),
-     *  (2596, 1.0, 0.722, 0.454) }. The 3x3 matrix is formatted like so:
+     *  The 3x3 color transformation matrix is formatted like so:
      *  <table>
      *      <tr><td>R: a coefficient</td><td>G: a coefficient</td><td>B: a coefficient</td></tr>
      *      <tr><td>R: b coefficient</td><td>G: b coefficient</td><td>B: b coefficient</td></tr>
@@ -123,9 +119,9 @@
      *  </table>
      */
     private static final float[] mColorTempCoefficients = new float[] {
-            0.0f, -0.00000000962353339f, -0.0000000189359041f,
-            0.0f, 0.000153045476f, 0.000302412211f,
-            1.0f, 0.390782778f, -0.198650895f
+            0.0f, -0.000000014365268757f, -0.000000000910931179f,
+            0.0f, 0.000255092801250106f, 0.000207598323269139f,
+            1.0f, -0.064156942434907716f, -0.349361641294833436f
     };
 
     private int mCurrentUser = UserHandle.USER_NULL;
@@ -410,7 +406,7 @@
             return;
         }
 
-        Matrix.setIdentityM(mMatrixNight, 0);
+        Matrix.setIdentityM(outTemp, 0);
 
         final float squareTemperature = colorTemperature * colorTemperature;
         final float red = squareTemperature * mColorTempCoefficients[0]
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 9d3021a..d6ab888 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -23,6 +23,7 @@
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
 
 import android.content.Context;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -359,6 +360,10 @@
                 if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
                 }
+                if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                }
+
                 mInfo.type = Display.TYPE_VIRTUAL;
                 mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
                         DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index 5339bac..370e569 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -79,7 +79,7 @@
         }
         if (!authenticated) {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintError(getContext());
+                vibrateError();
             }
             // allow system-defined limit of number of attempts before giving up
             int lockoutMode =  handleFailedAttempt();
@@ -99,7 +99,7 @@
             result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
         } else {
             if (receiver != null) {
-                FingerprintUtils.vibrateFingerprintSuccess(getContext());
+                vibrateSuccess();
             }
             result |= true; // we have a valid fingerprint, done
             resetFailedAttempts();
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 1a2e144..3eae157 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -23,6 +23,8 @@
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.util.Slog;
 
 import java.util.NoSuchElementException;
@@ -36,14 +38,18 @@
     protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
     protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h.
     protected static final boolean DEBUG = FingerprintService.DEBUG;
+    private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30};
+    private final Context mContext;
+    private final long mHalDeviceId;
+    private final int mTargetUserId;
+    private final int mGroupId;
+    // True if client does not have MANAGE_FINGERPRINT permission
+    private final boolean mIsRestricted;
+    private final String mOwner;
+    private final VibrationEffect mSuccessVibrationEffect;
+    private final VibrationEffect mErrorVibrationEffect;
     private IBinder mToken;
     private IFingerprintServiceReceiver mReceiver;
-    private int mTargetUserId;
-    private int mGroupId;
-    private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
-    private String mOwner;
-    private Context mContext;
-    private long mHalDeviceId;
     protected boolean mAlreadyCancelled;
 
     /**
@@ -68,6 +74,8 @@
         mGroupId = groupId;
         mIsRestricted = restricted;
         mOwner = owner;
+        mSuccessVibrationEffect = getSuccessVibrationEffect(context);
+        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
         try {
             if (token != null) {
                 token.linkToDeath(this, 0);
@@ -79,7 +87,7 @@
 
     /**
      * Contacts fingerprint HAL to start the client.
-     * @return 0 on succes, errno from driver on failure
+     * @return 0 on success, errno from driver on failure
      */
     public abstract int start();
 
@@ -211,4 +219,39 @@
     public final IBinder getToken() {
         return mToken;
     }
+
+    public final void vibrateSuccess() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mSuccessVibrationEffect);
+        }
+    }
+
+    public final void vibrateError() {
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        if (vibrator != null) {
+            vibrator.vibrate(mErrorVibrationEffect);
+        }
+    }
+
+    private static VibrationEffect getSuccessVibrationEffect(Context ctx) {
+        int[] arr = ctx.getResources().getIntArray(
+                com.android.internal.R.array.config_longPressVibePattern);
+        final long[] vibePattern;
+        if (arr == null || arr.length == 0) {
+            vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN;
+        } else {
+            vibePattern = new long[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                vibePattern[i] = arr[i];
+            }
+        }
+        if (vibePattern.length == 1) {
+            return VibrationEffect.createOneShot(
+                    vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
+        } else {
+            return VibrationEffect.createWaveform(vibePattern, -1);
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java
index 6170894..c9efcf2 100644
--- a/services/core/java/com/android/server/fingerprint/EnrollClient.java
+++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java
@@ -65,7 +65,7 @@
         if (receiver == null)
             return true; // client not listening
 
-        FingerprintUtils.vibrateFingerprintSuccess(getContext());
+        vibrateSuccess();
         MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL);
         try {
             receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
index 49dc8e4..5fbd735 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.fingerprint.Fingerprint;
-import android.os.Vibrator;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
@@ -31,9 +30,6 @@
  */
 public class FingerprintUtils {
 
-    private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
-    private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
-
     private static final Object sInstanceLock = new Object();
     private static FingerprintUtils sInstance;
 
@@ -72,20 +68,6 @@
         getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
     }
 
-    public static void vibrateFingerprintError(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
-        }
-    }
-
-    public static void vibrateFingerprintSuccess(Context context) {
-        Vibrator vibrator = context.getSystemService(Vibrator.class);
-        if (vibrator != null) {
-            vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
-        }
-    }
-
     private FingerprintsUserState getStateForUser(Context ctx, int userId) {
         synchronized (this) {
             FingerprintsUserState state = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 907b5c1..717efbf 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -232,6 +232,9 @@
     private static native void nativeReloadDeviceAliases(long ptr);
     private static native String nativeDump(long ptr);
     private static native void nativeMonitor(long ptr);
+    private static native boolean nativeIsInputDeviceEnabled(long ptr, int deviceId);
+    private static native void nativeEnableInputDevice(long ptr, int deviceId);
+    private static native void nativeDisableInputDevice(long ptr, int deviceId);
     private static native void nativeSetPointerIconType(long ptr, int iconId);
     private static native void nativeReloadPointerIcons(long ptr);
     private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon);
@@ -650,6 +653,32 @@
         return null;
     }
 
+    // Binder call
+    @Override
+    public boolean isInputDeviceEnabled(int deviceId) {
+        return nativeIsInputDeviceEnabled(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public void enableInputDevice(int deviceId) {
+        if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE,
+                "enableInputDevice()")) {
+            throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
+        }
+        nativeEnableInputDevice(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public void disableInputDevice(int deviceId) {
+        if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE,
+                "disableInputDevice()")) {
+            throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
+        }
+        nativeDisableInputDevice(mPtr, deviceId);
+    }
+
     /**
      * Gets the ids of all input devices in the system.
      * @return The input device ids.
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index 8ad1bea..ba92295 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -39,19 +39,23 @@
     public static final int EVENT_NULL = 0;
     public static final int EVENT_START_JOB = 1;
     public static final int EVENT_STOP_JOB = 2;
+    public static final int EVENT_START_PERIODIC_JOB = 3;
+    public static final int EVENT_STOP_PERIODIC_JOB = 4;
 
     private final RingBufferIndices mEventIndices = new RingBufferIndices(EVENT_BUFFER_SIZE);
     private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
     private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
     private final int[] mEventUids = new int[EVENT_BUFFER_SIZE];
     private final String[] mEventTags = new String[EVENT_BUFFER_SIZE];
+    private final int[] mEventJobIds = new int[EVENT_BUFFER_SIZE];
 
-    public void addEvent(int cmd, int uid, String tag) {
+    public void addEvent(int cmd, int uid, String tag, int jobId) {
         int index = mEventIndices.add();
         mEventCmds[index] = cmd;
         mEventTimes[index] = SystemClock.elapsedRealtime();
         mEventUids[index] = uid;
         mEventTags[index] = tag;
+        mEventJobIds[index] = jobId;
     }
 
     DataSet mCurDataSet = new DataSet();
@@ -365,7 +369,8 @@
         } else {
             mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
-        addEvent(EVENT_START_JOB, job.getSourceUid(), job.getBatteryName());
+        addEvent(job.getJob().isPeriodic() ? EVENT_START_PERIODIC_JOB :  EVENT_START_JOB,
+                job.getSourceUid(), job.getBatteryName(), job.getJobId());
     }
 
     public void noteInactive(JobStatus job) {
@@ -376,7 +381,8 @@
             mCurDataSet.decActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
         rebatchIfNeeded(now);
-        addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName());
+        addEvent(job.getJob().isPeriodic() ? EVENT_STOP_JOB :  EVENT_STOP_PERIODIC_JOB,
+                job.getSourceUid(), job.getBatteryName(), job.getJobId());
     }
 
     public void noteConcurrency(int totalActive, int fgActive) {
@@ -448,16 +454,20 @@
             }
             final String label;
             switch (mEventCmds[index]) {
-                case EVENT_START_JOB:           label = "START"; break;
-                case EVENT_STOP_JOB:            label = " STOP"; break;
-                default:                        label = "   ??"; break;
+                case EVENT_START_JOB:           label = "  START"; break;
+                case EVENT_STOP_JOB:            label = "   STOP"; break;
+                case EVENT_START_PERIODIC_JOB:  label = "START-P"; break;
+                case EVENT_STOP_PERIODIC_JOB:   label = " STOP-P"; break;
+                default:                        label = "     ??"; break;
             }
             pw.print(prefix);
             TimeUtils.formatDuration(mEventTimes[index]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
             pw.print(" ");
             pw.print(label);
-            pw.print(": ");
+            pw.print(": #");
             UserHandle.formatUid(pw, uid);
+            pw.print("/");
+            pw.print(mEventJobIds[index]);
             pw.print(" ");
             pw.println(mEventTags[index]);
         }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 108cd325..af51525 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -355,11 +355,11 @@
             synchronized (mLock) {
                 try {
                     mParser.setString(Settings.Global.getString(mResolver,
-                            Settings.Global.ALARM_MANAGER_CONSTANTS));
+                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
                 } catch (IllegalArgumentException e) {
                     // Failed to parse the settings string, log this and move on
                     // with defaults.
-                    Slog.e(TAG, "Bad device idle settings", e);
+                    Slog.e(TAG, "Bad jobscheduler settings", e);
                 }
 
                 MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
@@ -1128,7 +1128,8 @@
         delayMillis =
                 Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
         JobStatus newJob = new JobStatus(failureToReschedule, elapsedNowMillis + delayMillis,
-                JobStatus.NO_LATEST_RUNTIME, backoffAttempts);
+                JobStatus.NO_LATEST_RUNTIME, backoffAttempts,
+                failureToReschedule.getLastSuccessfulRunTime(), System.currentTimeMillis());
         for (int ic=0; ic<mControllers.size(); ic++) {
             StateController controller = mControllers.get(ic);
             controller.rescheduleForFailureLocked(newJob, failureToReschedule);
@@ -1166,7 +1167,9 @@
                     newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
         }
         return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed,
-                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
+                newLatestRuntimeElapsed, 0 /* backoffAttempt */,
+                System.currentTimeMillis() /* lastSuccessfulRunTime */,
+                periodicToReschedule.getLastFailedRunTime());
     }
 
     // JobCompletedListener implementations.
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index f0cd8a8..84810be 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -345,6 +345,11 @@
             out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
             out.attribute(null, "priority", String.valueOf(jobStatus.getPriority()));
             out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
+
+            out.attribute(null, "lastSuccessfulRunTime",
+                    String.valueOf(jobStatus.getLastSuccessfulRunTime()));
+            out.attribute(null, "lastFailedRunTime",
+                    String.valueOf(jobStatus.getLastFailedRunTime()));
         }
 
         private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
@@ -555,6 +560,8 @@
                 IOException {
             JobInfo.Builder jobBuilder;
             int uid, sourceUserId;
+            long lastSuccessfulRunTime;
+            long lastFailedRunTime;
 
             // Read out job identifier attributes and priority.
             try {
@@ -572,6 +579,12 @@
                 }
                 val = parser.getAttributeValue(null, "sourceUserId");
                 sourceUserId = val == null ? -1 : Integer.parseInt(val);
+
+                val = parser.getAttributeValue(null, "lastSuccessfulRunTime");
+                lastSuccessfulRunTime = val == null ? 0 : Long.parseLong(val);
+
+                val = parser.getAttributeValue(null, "lastFailedRunTime");
+                lastFailedRunTime = val == null ? 0 : Long.parseLong(val);
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Error parsing job's required fields, skipping");
                 return null;
@@ -708,7 +721,8 @@
             // And now we're done
             JobStatus js = new JobStatus(
                     jobBuilder.build(), uid, sourcePackageName, sourceUserId, sourceTag,
-                    elapsedRuntimes.first, elapsedRuntimes.second);
+                    elapsedRuntimes.first, elapsedRuntimes.second,
+                    lastSuccessfulRunTime, lastFailedRunTime);
             return js;
         }
 
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 446b0d6..9658da7 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -26,6 +26,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.text.format.Time;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -184,6 +185,17 @@
     public long madeActive;
 
     /**
+     * Last time a job finished successfully for a periodic job, in the currentTimeMillis time,
+     * for dumpsys.
+     */
+    private long mLastSuccessfulRunTime;
+
+    /**
+     * Last time a job finished unsuccessfully, in the currentTimeMillis time, for dumpsys.
+     */
+    private long mLastFailedRunTime;
+
+    /**
      * For use only by ContentObserverController: state it is maintaining about content URIs
      * being observed.
      */
@@ -196,7 +208,7 @@
 
     private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
             int sourceUserId, String tag, int numFailures, long earliestRunTimeElapsedMillis,
-            long latestRunTimeElapsedMillis) {
+            long latestRunTimeElapsedMillis, long lastSuccessfulRunTime, long lastFailedRunTime) {
         this.job = job;
         this.callingUid = callingUid;
 
@@ -263,6 +275,9 @@
             requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER;
         }
         this.requiredConstraints = requiredConstraints;
+
+        mLastSuccessfulRunTime = lastSuccessfulRunTime;
+        mLastFailedRunTime = lastFailedRunTime;
     }
 
     /** Copy constructor. */
@@ -270,7 +285,8 @@
         this(jobStatus.getJob(), jobStatus.getUid(),
                 jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
                 jobStatus.getSourceTag(), jobStatus.getNumFailures(),
-                jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed());
+                jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed(),
+                jobStatus.getLastSuccessfulRunTime(), jobStatus.getLastFailedRunTime());
     }
 
     /**
@@ -281,18 +297,22 @@
      * We consider a freshly loaded job to no longer be in back-off.
      */
     public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
-            String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) {
+            String sourceTag, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
+            long lastSuccessfulRunTime, long lastFailedRunTime) {
         this(job, callingUid, sourcePackageName, sourceUserId, sourceTag, 0,
-                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
+                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
+                lastSuccessfulRunTime, lastFailedRunTime);
     }
 
     /** Create a new job to be rescheduled with the provided parameters. */
     public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
-                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
+            long newLatestRuntimeElapsedMillis, int backoffAttempt,
+            long lastSuccessfulRunTime, long lastFailedRunTime) {
         this(rescheduling.job, rescheduling.getUid(),
                 rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(),
                 rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis,
-                newLatestRuntimeElapsedMillis);
+                newLatestRuntimeElapsedMillis,
+                lastSuccessfulRunTime, lastFailedRunTime);
     }
 
     /**
@@ -316,7 +336,8 @@
                     elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
         }
         return new JobStatus(job, callingUid, sourcePackageName, sourceUserId, tag, 0,
-                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
+                earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
+                0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */);
     }
 
     public void enqueueWorkLocked(IActivityManager am, JobWorkItem work) {
@@ -669,6 +690,14 @@
         trackingControllers |= which;
     }
 
+    public long getLastSuccessfulRunTime() {
+        return mLastSuccessfulRunTime;
+    }
+
+    public long getLastFailedRunTime() {
+        return mLastFailedRunTime;
+    }
+
     public boolean shouldDump(int filterUid) {
         return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
                 || UserHandle.getAppId(getSourceUid()) == filterUid;
@@ -1041,5 +1070,17 @@
         if (numFailures != 0) {
             pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
         }
+        final Time t = new Time();
+        final String format = "%Y-%m-%d %H:%M:%S";
+        if (mLastSuccessfulRunTime != 0) {
+            pw.print(prefix); pw.print("Last successful run: ");
+            t.set(mLastSuccessfulRunTime);
+            pw.println(t.format(format));
+        }
+        if (mLastFailedRunTime != 0) {
+            pw.print(prefix); pw.print("Last failed run: ");
+            t.set(mLastFailedRunTime);
+            pw.println(t.format(format));
+        }
     }
 }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 20711c0..11a4eb4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -77,10 +77,12 @@
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.location.gnssmetrics.GnssMetrics;
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
+
 import com.android.server.power.BatterySaverPolicy;
 import com.android.server.power.BatterySaverPolicy.ServiceType;
 
@@ -417,6 +419,9 @@
     private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
     private boolean mItarSpeedLimitExceeded = false;
 
+    // GNSS Metrics
+    private GnssMetrics mGnssMetrics;
+
     private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
         @Override
         public void registerGnssStatusCallback(IGnssStatusListener callback) {
@@ -461,6 +466,11 @@
             // Always on, notify HAL so it can get data it needs
             sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
         }
+
+        @Override
+        public void onLost(Network network) {
+            sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+        }
     };
 
     /**
@@ -533,7 +543,9 @@
                     loadPropertiesFromResource(context, mProperties);
                     String lpp_profile = mProperties.getProperty("LPP_PROFILE");
                     // set the persist property LPP_PROFILE for the value
-                    SystemProperties.set(LPP_PROFILE, lpp_profile);
+                    if (lpp_profile != null) {
+                        SystemProperties.set(LPP_PROFILE, lpp_profile);
+                    }
                 } else {
                     // reset the persist property
                     SystemProperties.set(LPP_PROFILE, "");
@@ -778,6 +790,7 @@
                 return isEnabled();
             }
         };
+        mGnssMetrics = new GnssMetrics();
 
         /*
         * A cycle of native_init() and native_cleanup() is needed so that callbacks are registered
@@ -808,11 +821,21 @@
     private void handleUpdateNetworkState(Network network) {
         // retrieve NetworkInfo for this UID
         NetworkInfo info = mConnMgr.getNetworkInfo(network);
-        if (info == null) {
-            return;
+
+        boolean networkAvailable = false;
+        boolean isConnected = false;
+        int type = ConnectivityManager.TYPE_NONE;
+        boolean isRoaming = false;
+        String apnName = null;
+
+        if (info != null) {
+            networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
+            isConnected = info.isConnected();
+            type = info.getType();
+            isRoaming = info.isRoaming();
+            apnName = info.getExtraInfo();
         }
 
-        boolean isConnected = info.isConnected();
         if (DEBUG) {
             String message = String.format(
                     "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
@@ -824,8 +847,6 @@
         }
 
         if (native_is_agps_ril_supported()) {
-            boolean dataEnabled = TelephonyManager.getDefault().getDataEnabled();
-            boolean networkAvailable = info.isAvailable() && dataEnabled;
             String defaultApn = getSelectedApn();
             if (defaultApn == null) {
                 defaultApn = "dummy-apn";
@@ -833,10 +854,10 @@
 
             native_update_network_state(
                     isConnected,
-                    info.getType(),
-                    info.isRoaming(),
+                    type,
+                    isRoaming,
                     networkAvailable,
-                    info.getExtraInfo(),
+                    apnName,
                     defaultApn);
         } else if (DEBUG) {
             Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not  supported");
@@ -844,7 +865,6 @@
 
         if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
             if (isConnected) {
-                String apnName = info.getExtraInfo();
                 if (apnName == null) {
                     // assign a dummy value in the case of C2K as otherwise we will have a runtime
                     // exception in the following call to native_agps_data_conn_open
@@ -1190,21 +1210,29 @@
 
     @Override
     public int getStatus(Bundle extras) {
-        if (extras != null) {
-            extras.putInt("satellites", mSvCount);
-        }
+        setLocationExtras(extras);
         return mStatus;
     }
 
-    private void updateStatus(int status, int svCount) {
-        if (status != mStatus || svCount != mSvCount) {
+    private void updateStatus(int status, int svCount, int meanCn0, int maxCn0) {
+        if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0 ) {
             mStatus = status;
             mSvCount = svCount;
-            mLocationExtras.putInt("satellites", svCount);
+            mMeanCn0 = meanCn0;
+            mMaxCn0 = maxCn0;
+            setLocationExtras(mLocationExtras);
             mStatusUpdateTime = SystemClock.elapsedRealtime();
         }
     }
 
+    private void setLocationExtras(Bundle extras) {
+        if (extras != null) {
+            extras.putInt("satellites", mSvCount);
+            extras.putInt("meanCn0", mMeanCn0);
+            extras.putInt("maxCn0", mMaxCn0);
+        }
+    }
+
     @Override
     public long getStatusUpdateTime() {
         return mStatusUpdateTime;
@@ -1455,9 +1483,8 @@
             }
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
             mFixRequestTime = SystemClock.elapsedRealtime();
-
             if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
                 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
                 // and our fix interval is not short
@@ -1479,7 +1506,7 @@
             mLastFixTime = 0;
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
         }
     }
 
@@ -1508,6 +1535,7 @@
         if (mItarSpeedLimitExceeded) {
             Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
                     "  GPS/GNSS Navigation output blocked.");
+            mGnssMetrics.logReceivedLocationStatus(false);
             return;  // No output of location allowed
         }
 
@@ -1527,11 +1555,23 @@
             }
         }
 
+        mGnssMetrics.logReceivedLocationStatus(hasLatLong);
+        if (hasLatLong) {
+            if (location.hasAccuracy()) {
+                mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
+            }
+            if (mTimeToFirstFix > 0) {
+                int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
+                mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
+            }
+        }
+
         mLastFixTime = SystemClock.elapsedRealtime();
         // report time to first fix
         if (mTimeToFirstFix == 0 && hasLatLong) {
             mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);
             if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
+            mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
 
             // notify status listeners
             mListenerHelper.onFirstFix(mTimeToFirstFix);
@@ -1552,7 +1592,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.AVAILABLE, mSvCount);
+            updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
 
        if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
@@ -1613,18 +1653,27 @@
                 mSvAzimuths,
                 mSvCarrierFreqs);
 
+        // Log CN0 as part of GNSS metrics
+        mGnssMetrics.logCn0(mCn0s, svCount);
+
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + svCount);
         }
-        // Calculate number of sets used in fix.
+        // Calculate number of satellites used in fix.
         int usedInFixCount = 0;
+        int maxCn0 = 0;
+        int meanCn0 = 0;
         for (int i = 0; i < svCount; i++) {
             if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
                 ++usedInFixCount;
+                if (mCn0s[i] > maxCn0) {
+                    maxCn0 = (int)mCn0s[i];
+                }
+                meanCn0 += mCn0s[i];
             }
             if (VERBOSE) {
                 Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
-                        " cn0: " + mCn0s[i]/10 +
+                        " cn0: " + mCn0s[i] +
                         " elev: " + mSvElevations[i] +
                         " azimuth: " + mSvAzimuths[i] +
                         " carrier frequency: " + mSvCarrierFreqs[i] +
@@ -1638,8 +1687,11 @@
                         ? "" : "F"));
             }
         }
-        // return number of sets used in fix instead of total
-        updateStatus(mStatus, usedInFixCount);
+        if (usedInFixCount > 0) {
+            meanCn0 /= usedInFixCount;
+        }
+        // return number of sats used in fix instead of total reported
+        updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
 
         if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
             SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
@@ -1647,7 +1699,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
     }
 
@@ -1704,20 +1756,32 @@
     }
 
     /**
-     * called from native code - Gps measurements callback
+     * called from native code - GNSS measurements callback
      */
     private void reportMeasurementData(GnssMeasurementsEvent event) {
         if (!mItarSpeedLimitExceeded) {
-            mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+            // send to handler to allow native to return quickly
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+                }
+            });
         }
     }
 
     /**
-     * called from native code - GPS navigation message callback
+     * called from native code - GNSS navigation message callback
      */
     private void reportNavigationMessage(GnssNavigationMessage event) {
         if (!mItarSpeedLimitExceeded) {
-            mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+            // send to handler to allow native to return quickly
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+                }
+            });
         }
     }
 
@@ -1813,6 +1877,25 @@
         };
     }
 
+    public interface GnssMetricsProvider {
+        /**
+         * Returns GNSS metrics as proto string
+         */
+        String getGnssMetricsAsProtoString();
+    }
+
+    /**
+     * @hide
+     */
+    public GnssMetricsProvider getGnssMetricsProvider() {
+        return new GnssMetricsProvider() {
+            @Override
+            public String getGnssMetricsAsProtoString() {
+                return mGnssMetrics.dumpGnssMetricsAsProtoString();
+            }
+        };
+    }
+
     /**
      * Initialize Batching if enabled
      */
@@ -2442,9 +2525,12 @@
         }
     }
 
+
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         StringBuilder s = new StringBuilder();
+        s.append("  mStarted=").append(mStarted).append('\n');
         s.append("  mFixInterval=").append(mFixInterval).append('\n');
         s.append("  mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
         s.append("  mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
@@ -2458,10 +2544,9 @@
         if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
         if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
         s.append(")\n");
-
-        s.append("  internal state: ").append(native_get_internal_state());
+        s.append(mGnssMetrics.dumpGnssMetricsAsText());
+        s.append("  native internal state: ").append(native_get_internal_state());
         s.append("\n");
-
         pw.append(s);
     }
 
@@ -2505,6 +2590,8 @@
     private float mSvAzimuths[] = new float[MAX_SVS];
     private float mSvCarrierFreqs[] = new float[MAX_SVS];
     private int mSvCount;
+    private int mMeanCn0;
+    private int mMaxCn0;
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
 
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index caf1d6c..924520b 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -54,9 +54,8 @@
     }
 
     public void onGpsEnabledChanged() {
-        if (tryUpdateRegistrationWithService()) {
-            updateResult();
-        }
+        tryUpdateRegistrationWithService();
+        updateResult();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 8d21928..df3c49b 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -55,9 +55,8 @@
     }
 
     public void onGpsEnabledChanged() {
-        if (tryUpdateRegistrationWithService()) {
-            updateResult();
-        }
+        tryUpdateRegistrationWithService();
+        updateResult();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 62332c9..c012ee4 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -41,6 +41,7 @@
     private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000;  // 1MB.
     private static final String DEFAULT_USER_AGENT = "Android";
     private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
+    private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(60);
 
     private final String[] mXtraServers;
     // to load balance our server requests
@@ -123,6 +124,7 @@
                     "x-wap-profile",
                     "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
             connection.setConnectTimeout(CONNECTION_TIMEOUT_MS);
+            connection.setReadTimeout(READ_TIMEOUT_MS);
 
             connection.connect();
             int statusCode = connection.getResponseCode();
diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java
index ec2828b..f51bc87 100644
--- a/services/core/java/com/android/server/location/RemoteListenerHelper.java
+++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java
@@ -25,6 +25,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.lang.Runnable;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -45,7 +46,7 @@
 
     private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>();
 
-    private boolean mIsRegistered;
+    private boolean mIsRegistered;  // must access only on handler thread
     private boolean mHasIsSupported;
     private boolean mIsSupported;
 
@@ -83,12 +84,12 @@
             } else if (mHasIsSupported && !mIsSupported) {
                 result = RESULT_NOT_SUPPORTED;
             } else if (!isGpsEnabled()) {
-                result = RESULT_GPS_LOCATION_DISABLED;
-            } else if (!tryRegister()) {
                 // only attempt to register if GPS is enabled, otherwise we will register once GPS
                 // becomes available
-                result = RESULT_INTERNAL_ERROR;
+                result = RESULT_GPS_LOCATION_DISABLED;
             } else if (mHasIsSupported && mIsSupported) {
+                tryRegister();
+                // initially presume success, possible internal error could follow asynchornously
                 result = RESULT_SUCCESS;
             } else {
                 // at this point if the supported flag is not set, the notification will be sent
@@ -117,8 +118,8 @@
 
     protected abstract boolean isAvailableInPlatform();
     protected abstract boolean isGpsEnabled();
-    protected abstract boolean registerWithService();
-    protected abstract void unregisterFromService();
+    protected abstract boolean registerWithService(); // must access only on handler thread
+    protected abstract void unregisterFromService(); // must access only on handler thread
     protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
 
     protected interface ListenerOperation<TListener extends IInterface> {
@@ -138,22 +139,16 @@
         }
     }
 
-    protected boolean tryUpdateRegistrationWithService() {
+    protected void tryUpdateRegistrationWithService() {
         synchronized (mListenerMap) {
             if (!isGpsEnabled()) {
                 tryUnregister();
-                return true;
+                return;
             }
             if (mListenerMap.isEmpty()) {
-                return true;
+                return;
             }
-            if (tryRegister()) {
-                // registration was successful, there is no need to update the state
-                return true;
-            }
-            ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
-            foreachUnsafe(operation);
-            return false;
+            tryRegister();
         }
     }
 
@@ -180,19 +175,40 @@
         }
     }
 
-    private boolean tryRegister() {
-        if (!mIsRegistered) {
-            mIsRegistered = registerWithService();
-        }
-        return mIsRegistered;
+    private void tryRegister() {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (!mIsRegistered) {
+                    mIsRegistered = registerWithService();
+                }
+                if (!mIsRegistered) {
+                    // post back a failure
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            synchronized (mListenerMap) {
+                                ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
+                                foreachUnsafe(operation);
+                            }
+                        }
+                    });
+                }
+            }
+        });
     }
 
     private void tryUnregister() {
-        if (!mIsRegistered) {
-            return;
-        }
-        unregisterFromService();
-        mIsRegistered = false;
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (!mIsRegistered) {
+                    return;
+                }
+                unregisterFromService();
+                mIsRegistered = false;
+            }
+        });
     }
 
     private int calculateCurrentResultUnsafe() {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
new file mode 100644
index 0000000..f8f8ffb
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -0,0 +1,2436 @@
+/*
+ * Copyright (C) 2012 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.locksettings;
+
+import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
+import static android.Manifest.permission.READ_CONTACTS;
+import static android.content.Context.KEYGUARD_SERVICE;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+import static com.android.internal.widget.LockPatternUtils.USER_FRP;
+import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
+
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
+import android.app.backup.BackupManager;
+import android.app.trust.IStrongAuthTracker;
+import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.StrictMode;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.provider.Settings.SettingNotFoundException;
+import android.security.KeyStore;
+import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.Preconditions;
+import com.android.internal.widget.ICheckCredentialProgressCallback;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.SystemService;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import libcore.util.HexEncoding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+/**
+ * Keeps the lock pattern/password data and related settings for each user. Used by
+ * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
+ * lockscreen information for secondary users.
+ *
+ * @hide
+ */
+public class LockSettingsService extends ILockSettings.Stub {
+    private static final String TAG = "LockSettingsService";
+    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
+    private static final boolean DEBUG = false;
+
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+    private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
+
+    // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
+    // Do not call into ActivityManager while holding mSpManager lock.
+    private final Object mSeparateChallengeLock = new Object();
+
+    private final DeviceProvisionedObserver mDeviceProvisionedObserver =
+            new DeviceProvisionedObserver();
+
+    private final Injector mInjector;
+    private final Context mContext;
+    private final Handler mHandler;
+    @VisibleForTesting
+    protected final LockSettingsStorage mStorage;
+    private final LockSettingsStrongAuth mStrongAuth;
+    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
+
+    private final LockPatternUtils mLockPatternUtils;
+    private final NotificationManager mNotificationManager;
+    private final UserManager mUserManager;
+    private final IActivityManager mActivityManager;
+    private final SyntheticPasswordManager mSpManager;
+
+    private final KeyStore mKeyStore;
+
+    private boolean mFirstCallToVold;
+    protected IGateKeeperService mGateKeeperService;
+
+    /**
+     * The UIDs that are used for system credential storage in keystore.
+     */
+    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
+            Process.WIFI_UID, Process.VPN_UID,
+            Process.ROOT_UID, Process.SYSTEM_UID };
+
+    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
+    // devices. The most basic of these is to show/hide notifications about missing features until
+    // the user unlocks the account and credential-encrypted storage is available.
+    public static final class Lifecycle extends SystemService {
+        private LockSettingsService mLockSettingsService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            AndroidKeyStoreProvider.install();
+            mLockSettingsService = new LockSettingsService(getContext());
+            publishBinderService("lock_settings", mLockSettingsService);
+        }
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mLockSettingsService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mLockSettingsService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onCleanupUser(int userHandle) {
+            mLockSettingsService.onCleanupUser(userHandle);
+        }
+    }
+
+    @VisibleForTesting
+    protected static class SynchronizedStrongAuthTracker
+            extends LockPatternUtils.StrongAuthTracker {
+        public SynchronizedStrongAuthTracker(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
+            synchronized (this) {
+                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
+            }
+        }
+
+        @Override
+        public int getStrongAuthForUser(int userId) {
+            synchronized (this) {
+                return super.getStrongAuthForUser(userId);
+            }
+        }
+
+        void register(LockSettingsStrongAuth strongAuth) {
+            strongAuth.registerStrongAuthTracker(this.mStub);
+        }
+    }
+
+    /**
+     * Tie managed profile to primary profile if it is in unified mode and not tied before.
+     *
+     * @param managedUserId Managed profile user Id
+     * @param managedUserPassword Managed profile original password (when it has separated lock).
+     *            NULL when it does not have a separated lock before.
+     */
+    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
+        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
+        // Only for managed profile
+        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
+            return;
+        }
+        // Do not tie managed profile when work challenge is enabled
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+            return;
+        }
+        // Do not tie managed profile to parent when it's done already
+        if (mStorage.hasChildProfileLock(managedUserId)) {
+            return;
+        }
+        // Do not tie it to parent when parent does not have a screen lock
+        final int parentId = mUserManager.getProfileParent(managedUserId).id;
+        if (!isUserSecure(parentId)) {
+            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
+            return;
+        }
+        // Do not tie when the parent has no SID (but does have a screen lock).
+        // This can only happen during an upgrade path where SID is yet to be
+        // generated when the user unlocks for the first time.
+        try {
+            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
+            return;
+        }
+        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
+        byte[] randomLockSeed = new byte[] {};
+        try {
+            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
+            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
+            final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    managedUserPassword, quality, managedUserId);
+            // We store a private credential for the managed user that's unlocked by the primary
+            // account holder's credential. As such, the user will never be prompted to enter this
+            // password directly, so we always store a password.
+            setLong(LockPatternUtils.PASSWORD_TYPE_KEY, quality, managedUserId);
+            tieProfileLockToParent(managedUserId, newPassword);
+        } catch (NoSuchAlgorithmException | RemoteException e) {
+            Slog.e(TAG, "Fail to tie managed profile", e);
+            // Nothing client can do to fix this issue, so we do not throw exception out
+        }
+    }
+
+    static class Injector {
+
+        protected Context mContext;
+
+        public Injector(Context context) {
+            mContext = context;
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public Handler getHandler() {
+            return new Handler();
+        }
+
+        public LockSettingsStorage getStorage() {
+            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
+            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                @Override
+                public void initialize(SQLiteDatabase db) {
+                    // Get the lockscreen default from a system property, if available
+                    boolean lockScreenDisable = SystemProperties.getBoolean(
+                            "ro.lockscreen.disable.default", false);
+                    if (lockScreenDisable) {
+                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+                    }
+                }
+            });
+            return storage;
+        }
+
+        public LockSettingsStrongAuth getStrongAuth() {
+            return new LockSettingsStrongAuth(mContext);
+        }
+
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return new SynchronizedStrongAuthTracker(mContext);
+        }
+
+        public IActivityManager getActivityManager() {
+            return ActivityManager.getService();
+        }
+
+        public LockPatternUtils getLockPatternUtils() {
+            return new LockPatternUtils(mContext);
+        }
+
+        public NotificationManager getNotificationManager() {
+            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+
+        public UserManager getUserManager() {
+            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        }
+
+        public DevicePolicyManager getDevicePolicyManager() {
+            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        }
+
+        public KeyStore getKeyStore() {
+            return KeyStore.getInstance();
+        }
+
+        public IStorageManager getStorageManager() {
+            final IBinder service = ServiceManager.getService("mount");
+            if (service != null) {
+                return IStorageManager.Stub.asInterface(service);
+            }
+            return null;
+        }
+
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return new SyntheticPasswordManager(storage, getUserManager());
+        }
+
+        public int binderGetCallingUid() {
+            return Binder.getCallingUid();
+        }
+    }
+
+    public LockSettingsService(Context context) {
+        this(new Injector(context));
+    }
+
+    @VisibleForTesting
+    protected LockSettingsService(Injector injector) {
+        mInjector = injector;
+        mContext = injector.getContext();
+        mKeyStore = injector.getKeyStore();
+        mHandler = injector.getHandler();
+        mStrongAuth = injector.getStrongAuth();
+        mActivityManager = injector.getActivityManager();
+
+        mLockPatternUtils = injector.getLockPatternUtils();
+        mFirstCallToVold = true;
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_ADDED);
+        filter.addAction(Intent.ACTION_USER_STARTING);
+        filter.addAction(Intent.ACTION_USER_REMOVED);
+        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
+                null, null);
+
+        mStorage = injector.getStorage();
+        mNotificationManager = injector.getNotificationManager();
+        mUserManager = injector.getUserManager();
+        mStrongAuthTracker = injector.getStrongAuthTracker();
+        mStrongAuthTracker.register(mStrongAuth);
+
+        mSpManager = injector.getSyntheticPasswordManager(mStorage);
+    }
+
+    /**
+     * If the account is credential-encrypted, show notification requesting the user to unlock the
+     * device.
+     */
+    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
+        final UserInfo user = mUserManager.getUserInfo(userId);
+        if (!user.isManagedProfile()) {
+            // When the user is locked, we communicate it loud-and-clear
+            // on the lockscreen; we only show a notification below for
+            // locked managed profiles.
+            return;
+        }
+
+        final UserHandle userHandle = user.getUserHandle();
+        final boolean isSecure = isUserSecure(userId);
+        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
+            UserInfo parent = mUserManager.getProfileParent(userId);
+            if (parent != null &&
+                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
+                    !mUserManager.isQuietModeEnabled(userHandle)) {
+                // Only show notifications for managed profiles once their parent
+                // user is unlocked.
+                showEncryptionNotificationForProfile(userHandle);
+            }
+        }
+    }
+
+    private void showEncryptionNotificationForProfile(UserHandle user) {
+        Resources r = mContext.getResources();
+        CharSequence title = r.getText(
+                com.android.internal.R.string.user_encrypted_title);
+        CharSequence message = r.getText(
+                com.android.internal.R.string.profile_encrypted_message);
+        CharSequence detail = r.getText(
+                com.android.internal.R.string.profile_encrypted_detail);
+
+        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
+        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
+                user.getIdentifier());
+        if (unlockIntent == null) {
+            return;
+        }
+        unlockIntent.setFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        showEncryptionNotification(user, title, message, detail, intent);
+    }
+
+    private void showEncryptionNotification(UserHandle user, CharSequence title,
+            CharSequence message, CharSequence detail, PendingIntent intent) {
+        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
+
+        // Suppress all notifications on non-FBE devices for now
+        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
+
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setSubText(detail)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setContentIntent(intent)
+                        .build();
+        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            notification, user);
+    }
+
+    private void hideEncryptionNotification(UserHandle userHandle) {
+        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
+        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            userHandle);
+    }
+
+    public void onCleanupUser(int userId) {
+        hideEncryptionNotification(new UserHandle(userId));
+    }
+
+    public void onStartUser(final int userId) {
+        maybeShowEncryptionNotificationForUser(userId);
+    }
+
+    public void onUnlockUser(final int userId) {
+        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
+        // ActivityManager.unlockUser()
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Hide notification first, as tie managed profile lock takes time
+                hideEncryptionNotification(new UserHandle(userId));
+
+                // Now we have unlocked the parent user we should show notifications
+                // about any profiles that exist.
+                List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (int i = 0; i < profiles.size(); i++) {
+                    UserInfo profile = profiles.get(i);
+                    final boolean isSecure = isUserSecure(profile.id);
+                    if (isSecure && profile.isManagedProfile()) {
+                        UserHandle userHandle = profile.getUserHandle();
+                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
+                                !mUserManager.isQuietModeEnabled(userHandle)) {
+                            showEncryptionNotificationForProfile(userHandle);
+                        }
+                    }
+                }
+
+                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                    tieManagedProfileLockIfNecessary(userId, null);
+                }
+            }
+        });
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
+                // Notify keystore that a new user was added.
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > UserHandle.USER_SYSTEM) {
+                    removeUser(userHandle, /* unknownUser= */ true);
+                }
+                final KeyStore ks = KeyStore.getInstance();
+                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
+                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
+                ks.onUserAdded(userHandle, parentHandle);
+            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                mStorage.prefetchUser(userHandle);
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > 0) {
+                    removeUser(userHandle, /* unknownUser= */ false);
+                }
+            }
+        }
+    };
+
+    @Override // binder interface
+    public void systemReady() {
+        migrateOldData();
+        try {
+            getGateKeeperService();
+            mSpManager.initWeaverService();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
+        }
+        mDeviceProvisionedObserver.onSystemReady();
+        // TODO: maybe skip this for split system user mode.
+        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
+    }
+
+    private void migrateOldData() {
+        try {
+            // These Settings moved before multi-user was enabled, so we only have to do it for the
+            // root user.
+            if (getString("migrated", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                for (String validSetting : VALID_SETTINGS) {
+                    String value = Settings.Secure.getString(cr, validSetting);
+                    if (value != null) {
+                        setString(validSetting, value, 0);
+                    }
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated", "true", 0);
+                Slog.i(TAG, "Migrated lock settings to new location");
+            }
+
+            // These Settings changed after multi-user was enabled, hence need to be moved per user.
+            if (getString("migrated_user_specific", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int user = 0; user < users.size(); user++) {
+                    // Migrate owner info
+                    final int userId = users.get(user).id;
+                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
+                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
+                    if (!TextUtils.isEmpty(ownerInfo)) {
+                        setString(OWNER_INFO, ownerInfo, userId);
+                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
+                    }
+
+                    // Migrate owner info enabled. Note there was a bug where older platforms only
+                    // stored this value if the checkbox was toggled at least once. The code detects
+                    // this case by handling the exception.
+                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
+                    boolean enabled;
+                    try {
+                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
+                        enabled = ivalue != 0;
+                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
+                    } catch (SettingNotFoundException e) {
+                        // Setting was never stored. Store it if the string is not empty.
+                        if (!TextUtils.isEmpty(ownerInfo)) {
+                            setLong(OWNER_INFO_ENABLED, 1, userId);
+                        }
+                    }
+                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated_user_specific", "true", 0);
+                Slog.i(TAG, "Migrated per-user lock settings to new location");
+            }
+
+            // Migrates biometric weak such that the fallback mechanism becomes the primary.
+            if (getString("migrated_biometric_weak", null, 0) == null) {
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int i = 0; i < users.size(); i++) {
+                    int userId = users.get(i).id;
+                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                alternateType,
+                                userId);
+                    }
+                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                }
+                setString("migrated_biometric_weak", "true", 0);
+                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
+            }
+
+            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
+            // user was present on the system, so if we're upgrading to M and there is more than one
+            // user we disable the flag to remain consistent.
+            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
+                final List<UserInfo> users = mUserManager.getUsers();
+                final int userCount = users.size();
+                int switchableUsers = 0;
+                for (int i = 0; i < userCount; i++) {
+                    if (users.get(i).supportsSwitchTo()) {
+                        switchableUsers++;
+                    }
+                }
+
+                if (switchableUsers > 1) {
+                    for (int i = 0; i < userCount; i++) {
+                        int id = users.get(i).id;
+
+                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
+                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                        }
+                    }
+                }
+
+                setString("migrated_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen disabled flag");
+            }
+
+            final List<UserInfo> users = mUserManager.getUsers();
+            for (int i = 0; i < users.size(); i++) {
+                final UserInfo userInfo = users.get(i);
+                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
+                    // When managed profile has a unified lock, the password quality stored has 2
+                    // possibilities only.
+                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
+                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
+                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
+                    // unified lock.
+                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
+                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                        // Only possible when it's upgraded from nyc dp3
+                        Slog.i(TAG, "Migrated tied profile lock type");
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
+                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
+                        // It should not happen
+                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
+                    }
+                }
+                try {
+                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
+                    java.security.KeyStore keyStore =
+                            java.security.KeyStore.getInstance("AndroidKeyStore");
+                    keyStore.load(null);
+                    if (keyStore.containsAlias(alias)) {
+                        keyStore.deleteEntry(alias);
+                    }
+                } catch (KeyStoreException | NoSuchAlgorithmException |
+                        CertificateException | IOException e) {
+                    Slog.e(TAG, "Unable to remove tied profile key", e);
+                }
+            }
+
+            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_WATCH);
+            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
+            // and device management the lockscreen must be re-enabled now for users that upgrade.
+            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
+                final int userCount = users.size();
+                for (int i = 0; i < userCount; i++) {
+                    int id = users.get(i).id;
+                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                }
+                setString("migrated_wear_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
+            }
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Unable to migrate old data", re);
+        }
+    }
+
+    private final void checkWritePermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
+    }
+
+    private final void checkPasswordReadPermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
+    }
+
+    private final void checkReadPermission(String requestedKey, int userId) {
+        final int callingUid = Binder.getCallingUid();
+
+        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + READ_CONTACTS + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+
+        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + PERMISSION + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
+        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
+        synchronized (mSeparateChallengeLock) {
+            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
+        }
+    }
+
+    @Override
+    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
+            String managedUserPassword) throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
+            if (enabled) {
+                mStorage.removeChildProfileLock(userId);
+                removeKeystoreProfileKey(userId);
+            } else {
+                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
+            }
+        }
+    }
+
+    @Override
+    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value ? "1" : "0");
+    }
+
+    @Override
+    public void setLong(String key, long value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, Long.toString(value));
+    }
+
+    @Override
+    public void setString(String key, String value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value);
+    }
+
+    private void setStringUnchecked(String key, int userId, String value) {
+        Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");
+
+        mStorage.writeKeyValue(key, value, userId);
+        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
+            BackupManager.dataChanged("com.android.providers.settings");
+        }
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ?
+                defaultValue : (value.equals("1") || value.equals("true"));
+    }
+
+    @Override
+    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
+    }
+
+    @Override
+    public String getString(String key, String defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        return getStringUnchecked(key, defaultValue, userId);
+    }
+
+    public String getStringUnchecked(String key, String defaultValue, int userId) {
+        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        if (userId == USER_FRP) {
+            return getFrpStringUnchecked(key);
+        }
+
+        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
+            key = Settings.Secure.LOCK_PATTERN_ENABLED;
+        }
+
+        return mStorage.readKeyValue(key, defaultValue, userId);
+    }
+
+    private String getFrpStringUnchecked(String key) {
+        if (LockPatternUtils.PASSWORD_TYPE_KEY.equals(key)) {
+            return String.valueOf(readFrpPasswordQuality());
+        }
+        return null;
+    }
+
+    private int readFrpPasswordQuality() {
+        return mStorage.readPersistentDataBlock().qualityForUi;
+    }
+
+    @Override
+    public boolean havePassword(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPassword(userId);
+    }
+
+    @Override
+    public boolean havePattern(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPattern(userId);
+    }
+
+    private boolean isUserSecure(int userId) {
+        synchronized (mSpManager) {
+            try {
+                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                    long handle = getSyntheticPasswordHandleLocked(userId);
+                    return mSpManager.getCredentialType(handle, userId) !=
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
+                }
+            } catch (RemoteException e) {
+                // fall through
+            }
+        }
+        return mStorage.hasCredential(userId);
+    }
+
+    private void setKeystorePassword(String password, int userHandle) {
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserPasswordChanged(userHandle, password);
+    }
+
+    private void unlockKeystore(String password, int userHandle) {
+        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
+        final KeyStore ks = KeyStore.getInstance();
+        ks.unlock(userHandle, password);
+    }
+
+    @VisibleForTesting
+    protected String getDecryptedPasswordForTiedProfile(int userId)
+            throws KeyStoreException, UnrecoverableKeyException,
+            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
+            CertificateException, IOException {
+        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
+        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
+                storedData.length);
+        byte[] decryptionResult;
+        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
+                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
+
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+
+        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
+        decryptionResult = cipher.doFinal(encryptedPassword);
+        return new String(decryptionResult, StandardCharsets.UTF_8);
+    }
+
+    private void unlockChildProfile(int profileHandle) throws RemoteException {
+        try {
+            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            if (e instanceof FileNotFoundException) {
+                Slog.i(TAG, "Child profile key not found");
+            } else {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+    }
+
+    private void unlockUser(int userId, byte[] token, byte[] secret) {
+        // TODO: make this method fully async so we can update UI with progress strings
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IProgressListener listener = new IProgressListener.Stub() {
+            @Override
+            public void onStarted(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser started");
+            }
+
+            @Override
+            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser progress " + progress);
+            }
+
+            @Override
+            public void onFinished(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser finished");
+                latch.countDown();
+            }
+        };
+
+        try {
+            mActivityManager.unlockUser(userId, token, secret, listener);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        try {
+            latch.await(15, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+        try {
+            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
+                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (UserInfo pi : profiles) {
+                    // Unlock managed profile with unified lock
+                    if (pi.isManagedProfile()
+                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                            && mStorage.hasChildProfileLock(pi.id)
+                            && mUserManager.isUserRunning(pi.id)) {
+                        unlockChildProfile(pi.id);
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Failed to unlock child profile", e);
+        }
+    }
+
+    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return null;
+        }
+        Map<Integer, String> result = new ArrayMap<Integer, String>();
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (!profile.isManagedProfile()) {
+                continue;
+            }
+            final int managedUserId = profile.id;
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                continue;
+            }
+            try {
+                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
+            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
+                    | NoSuchPaddingException | InvalidKeyException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                // ignore
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
+     * depending on the parent user's secure state.
+     *
+     * When clearing tied work challenges, a pre-computed password table for profiles are required,
+     * since changing password for profiles requires existing password, and existing passwords can
+     * only be computed before the parent user's password is cleared.
+     *
+     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
+     * method again on profiles. However the recursion is guaranteed to terminate as this method
+     * terminates when the user is a managed profile.
+     */
+    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
+            Map<Integer, String> profilePasswordMap) throws RemoteException {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return;
+        }
+        final boolean isSecure = isUserSecure(userId);
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (profile.isManagedProfile()) {
+                final int managedUserId = profile.id;
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                    continue;
+                }
+                if (isSecure) {
+                    tieManagedProfileLockIfNecessary(managedUserId, null);
+                } else {
+                    // We use cached work profile password computed before clearing the parent's
+                    // credential, otherwise they get lost
+                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                                profilePasswordMap.get(managedUserId),
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                    } else {
+                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
+                        // Supplying null here would lead to untrusted credential change
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                    }
+                    mStorage.removeChildProfileLock(managedUserId);
+                    removeKeystoreProfileKey(managedUserId);
+                }
+            }
+        }
+    }
+
+    private boolean isManagedProfileWithUnifiedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    private boolean isManagedProfileWithSeparatedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    // This method should be called by LockPatternUtil only, all internal methods in this class
+    // should call setLockCredentialInternal.
+    @Override
+    public void setLockCredential(String credential, int type, String savedCredential,
+            int requestedQuality, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId);
+            setSeparateProfileChallengeEnabled(userId, true, null);
+            notifyPasswordChanged(userId);
+        }
+    }
+
+    private void setLockCredentialInternal(String credential, int credentialType,
+            String savedCredential, int requestedQuality, int userId) throws RemoteException {
+        // Normalize savedCredential and credential such that empty string is always represented
+        // as null.
+        if (TextUtils.isEmpty(savedCredential)) {
+            savedCredential = null;
+        }
+        if (TextUtils.isEmpty(credential)) {
+            credential = null;
+        }
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        requestedQuality, userId);
+                return;
+            }
+        }
+
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            if (credential != null) {
+                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
+            }
+            clearUserKeyProtection(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
+            setKeystorePassword(null, userId);
+            fixateNewestUserKeyAuth(userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            notifyActivePasswordMetricsAvailable(null, userId);
+
+            if (mStorage.getPersistentDataBlock() != null
+                    && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+                // If owner, write to persistent storage for FRP
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, userId, 0, null);
+            }
+            return;
+        }
+        if (credential == null) {
+            throw new RemoteException("Null credential with mismatched credential type");
+        }
+
+        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            if (savedCredential == null) {
+                try {
+                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
+                } catch (FileNotFoundException e) {
+                    Slog.i(TAG, "Child profile key not found");
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        } else {
+            if (currentHandle.hash == null) {
+                if (savedCredential != null) {
+                    Slog.w(TAG, "Saved credential provided, but none stored");
+                }
+                savedCredential = null;
+            }
+        }
+        synchronized (mSpManager) {
+            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
+                        currentHandle.type, requestedQuality, userId);
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        requestedQuality, userId);
+                return;
+            }
+        }
+        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
+        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
+                userId);
+        if (enrolledHandle != null) {
+            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
+            mStorage.writeCredentialHash(willStore, userId);
+            // push new secret and auth token to vold
+            GateKeeperResponse gkResponse = getGateKeeperService()
+                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
+            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
+            fixateNewestUserKeyAuth(userId);
+            // Refresh the auth token
+            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            if (mStorage.getPersistentDataBlock() != null
+                    && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+                // If owner, write to persistent storage for FRP
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_GATEKEEPER, userId,
+                        requestedQuality, willStore.toBytes());
+            }
+        } else {
+            throw new RemoteException("Failed to enroll " +
+                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
+                            : "pattern"));
+        }
+    }
+
+    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
+        return VerifyCredentialResponse.fromGateKeeperResponse(gateKeeperResponse);
+    }
+
+    @VisibleForTesting
+    protected void tieProfileLockToParent(int userId, String password) {
+        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
+        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
+        byte[] encryptionResult;
+        byte[] iv;
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            try {
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .build());
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .setUserAuthenticationRequired(true)
+                                .setUserAuthenticationValidityDurationSeconds(30)
+                                .setCriticalToDeviceEncryption(true)
+                                .build());
+                // Key imported, obtain a reference to it.
+                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
+                Cipher cipher = Cipher.getInstance(
+                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                                + KeyProperties.ENCRYPTION_PADDING_NONE);
+                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
+                encryptionResult = cipher.doFinal(randomLockSeed);
+                iv = cipher.getIV();
+            } finally {
+                // The original key can now be discarded.
+                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
+            }
+        } catch (CertificateException | UnrecoverableKeyException
+                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException("Failed to encrypt key", e);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            if (iv.length != PROFILE_KEY_IV_SIZE) {
+                throw new RuntimeException("Invalid iv length: " + iv.length);
+            }
+            outputStream.write(iv);
+            outputStream.write(encryptionResult);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to concatenate byte arrays", e);
+        }
+        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
+    }
+
+    private byte[] enrollCredential(byte[] enrolledHandle,
+            String enrolledCredential, String toEnroll, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        byte[] enrolledCredentialBytes = enrolledCredential == null
+                ? null
+                : enrolledCredential.getBytes();
+        byte[] toEnrollBytes = toEnroll == null
+                ? null
+                : toEnroll.getBytes();
+        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
+                enrolledCredentialBytes, toEnrollBytes);
+
+        if (response == null) {
+            return null;
+        }
+
+        byte[] hash = response.getPayload();
+        if (hash != null) {
+            setKeystorePassword(toEnroll, userId);
+        } else {
+            // Should not happen
+            Slog.e(TAG, "Throttled while enrolling a password");
+        }
+        return hash;
+    }
+
+    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
+        addUserKeyAuth(userId, null, key);
+    }
+
+    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
+        if (vcr == null) {
+            throw new RemoteException("Null response verifying a credential we just set");
+        }
+        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            throw new RemoteException("Non-OK response verifying a credential we just set: "
+                    + vcr.getResponseCode());
+        }
+        byte[] token = vcr.getPayload();
+        if (token == null) {
+            throw new RemoteException("Empty payload verifying a credential we just set");
+        }
+        addUserKeyAuth(userId, token, secretFromCredential(credential));
+    }
+
+    private void clearUserKeyProtection(int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
+        addUserKeyAuth(userId, null, null);
+    }
+
+    private static byte[] secretFromCredential(String credential) throws RemoteException {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            // Personalize the hash
+            byte[] personalization = "Android FBE credential hash"
+                    .getBytes(StandardCharsets.UTF_8);
+            // Pad it to the block size of the hash function
+            personalization = Arrays.copyOf(personalization, 128);
+            digest.update(personalization);
+            digest.update(credential.getBytes(StandardCharsets.UTF_8));
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
+        }
+    }
+
+    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
+            throws RemoteException {
+        final UserInfo userInfo = mUserManager.getUserInfo(userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    private void fixateNewestUserKeyAuth(int userId)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.fixateNewestUserKeyAuth(userId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    @Override
+    public void resetKeyStore(int userId) throws RemoteException {
+        checkWritePermission(userId);
+        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+        int managedUserId = -1;
+        String managedUserDecryptedPassword = null;
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        for (UserInfo pi : profiles) {
+            // Unlock managed profile with unified lock
+            if (pi.isManagedProfile()
+                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                    && mStorage.hasChildProfileLock(pi.id)) {
+                try {
+                    if (managedUserId == -1) {
+                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
+                        managedUserId = pi.id;
+                    } else {
+                        // Should not happen
+                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
+                                + ", uid2:" + pi.id);
+                    }
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        }
+        try {
+            // Clear all the users credentials could have been installed in for this user.
+            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
+                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
+                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+                }
+            }
+        } finally {
+            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
+                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
+                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+            }
+        }
+    }
+
+    @Override
+    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
+            int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, true, challenge, userId,
+                null /* progressCallback */);
+    }
+
+    /**
+     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
+     * format.
+     */
+    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
+            boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (TextUtils.isEmpty(credential)) {
+            throw new IllegalArgumentException("Credential can't be null or empty");
+        }
+        if (userId == USER_FRP && Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
+            return VerifyCredentialResponse.ERROR;
+        }
+        VerifyCredentialResponse response = null;
+        response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
+                userId, progressCallback);
+        // The user employs synthetic password based credential.
+        if (response != null) {
+            return response;
+        }
+
+        final CredentialHash storedHash;
+        if (userId == USER_FRP) {
+            PersistentData data = mStorage.readPersistentDataBlock();
+            if (data.type != PersistentData.TYPE_GATEKEEPER) {
+                Slog.wtf(TAG, "Expected PersistentData.TYPE_GATEKEEPER, but was: " + data.type);
+                return VerifyCredentialResponse.ERROR;
+            }
+            return verifyFrpCredential(credential, credentialType, data, progressCallback);
+        } else {
+            storedHash = mStorage.readCredentialHash(userId);
+        }
+
+        if (storedHash.type != credentialType) {
+            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
+                    + " stored: " + storedHash.type + " passed in: " + credentialType);
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                && storedHash.isBaseZeroPattern;
+
+        String credentialToVerify;
+        if (shouldReEnrollBaseZero) {
+            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
+        } else {
+            credentialToVerify = credential;
+        }
+
+        response = verifyCredential(userId, storedHash, credentialToVerify,
+                hasChallenge, challenge, progressCallback);
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+            if (shouldReEnrollBaseZero) {
+                setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
+            }
+        }
+
+        return response;
+    }
+
+    private VerifyCredentialResponse verifyFrpCredential(String credential, int credentialType,
+            PersistentData data, ICheckCredentialProgressCallback progressCallback)
+            throws RemoteException {
+        CredentialHash storedHash = CredentialHash.fromBytes(data.payload);
+        if (storedHash.type != credentialType) {
+            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
+                    + " stored: " + storedHash.type + " passed in: " + credentialType);
+            return VerifyCredentialResponse.ERROR;
+        }
+        if (ArrayUtils.isEmpty(storedHash.hash) || TextUtils.isEmpty(credential)) {
+            Slog.e(TAG, "Stored hash or credential is empty");
+            return VerifyCredentialResponse.ERROR;
+        }
+        VerifyCredentialResponse response = VerifyCredentialResponse.fromGateKeeperResponse(
+                getGateKeeperService().verifyChallenge(data.userId, 0 /* challenge */,
+                        storedHash.hash, credential.getBytes()));
+        if (progressCallback != null
+                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            progressCallback.onCredentialVerified();
+        }
+        return response;
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
+            long challenge, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        if (!isManagedProfileWithUnifiedLock(userId)) {
+            throw new RemoteException("User id must be managed profile with unified lock");
+        }
+        final int parentProfileId = mUserManager.getProfileParent(userId).id;
+        // Unlock parent by using parent's challenge
+        final VerifyCredentialResponse parentResponse = doVerifyCredential(
+                credential,
+                type,
+                true /* hasChallenge */,
+                challenge,
+                parentProfileId,
+                null /* progressCallback */);
+        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            // Failed, just return parent's response
+            return parentResponse;
+        }
+
+        try {
+            // Unlock work profile, and work profile with unified lock must use password only
+            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    true,
+                    challenge,
+                    userId, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            Slog.e(TAG, "Failed to decrypt child profile key", e);
+            throw new RemoteException("Unable to get tied profile token");
+        }
+    }
+
+    /**
+     * Lowest-level credential verification routine that talks to GateKeeper. If verification
+     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
+     * hash to GK.
+     */
+    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
+            String credential, boolean hasChallenge, long challenge,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
+            // don't need to pass empty credentials to GateKeeper
+            return VerifyCredentialResponse.OK;
+        }
+
+        if (storedHash == null || TextUtils.isEmpty(credential)) {
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        // We're potentially going to be doing a bunch of disk I/O below as part
+        // of unlocking the user, so yell if calling from the main thread.
+        StrictMode.noteDiskRead();
+
+        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
+            final byte[] hash;
+            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
+            } else {
+                hash = mLockPatternUtils.passwordToHash(credential, userId);
+            }
+            if (Arrays.equals(hash, storedHash.hash)) {
+                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
+                } else {
+                    unlockKeystore(credential, userId);
+                }
+                // Users with legacy credentials don't have credential-backed
+                // FBE keys, so just pass through a fake token/secret
+                Slog.i(TAG, "Unlocking user with fake token: " + userId);
+                final byte[] fakeToken = String.valueOf(userId).getBytes();
+                unlockUser(userId, fakeToken, fakeToken);
+
+                // migrate credential to GateKeeper
+                setLockCredentialInternal(credential, storedHash.type, null,
+                        storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                                ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                                : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                                /* TODO(roosa): keep the same password quality */, userId);
+                if (!hasChallenge) {
+                    notifyActivePasswordMetricsAvailable(credential, userId);
+                    return VerifyCredentialResponse.OK;
+                }
+                // Fall through to get the auth token. Technically this should never happen,
+                // as a user that had a legacy credential would have to unlock their device
+                // before getting to a flow with a challenge, but supporting for consistency.
+            } else {
+                return VerifyCredentialResponse.ERROR;
+            }
+        }
+        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
+                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
+        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
+        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+
+            // credential has matched
+
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(credential, userId);
+            unlockKeystore(credential, userId);
+
+            Slog.i(TAG, "Unlocking user " + userId + " with token length "
+                    + response.getPayload().length);
+            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            int reEnrollQuality = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                    ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                    : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                    /* TODO(roosa): keep the same password quality */;
+            if (shouldReEnroll) {
+                setLockCredentialInternal(credential, storedHash.type, credential,
+                        reEnrollQuality, userId);
+            } else {
+                // Now that we've cleared of all required GK migration, let's do the final
+                // migration to synthetic password.
+                synchronized (mSpManager) {
+                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
+                                storedHash.hash, credential, storedHash.type, reEnrollQuality,
+                                userId);
+                        activateEscrowTokens(auth, userId);
+                    }
+                }
+            }
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
+        final PasswordMetrics metrics;
+        if (password == null) {
+            metrics = new PasswordMetrics();
+        } else {
+            metrics = PasswordMetrics.computeForPassword(password);
+            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
+        }
+
+        // Asynchronous to avoid dead lock
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.setActivePasswordState(metrics, userId);
+        });
+    }
+
+    /**
+     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
+     * reporting the password changed.
+     */
+    private void notifyPasswordChanged(@UserIdInt int userId) {
+        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.reportPasswordChanged(userId);
+        });
+    }
+
+    @Override
+    public boolean checkVoldPassword(int userId) throws RemoteException {
+        if (!mFirstCallToVold) {
+            return false;
+        }
+        mFirstCallToVold = false;
+
+        checkPasswordReadPermission(userId);
+
+        // There's no guarantee that this will safely connect, but if it fails
+        // we will simply show the lock screen when we shouldn't, so relatively
+        // benign. There is an outside chance something nasty would happen if
+        // this service restarted before vold stales out the password in this
+        // case. The nastiness is limited to not showing the lock screen when
+        // we should, within the first minute of decrypting the phone if this
+        // service can't connect to vold, it restarts, and then the new instance
+        // does successfully connect.
+        final IStorageManager service = mInjector.getStorageManager();
+        String password;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            password = service.getPassword();
+            service.clearPassword();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (password == null) {
+            return false;
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        return false;
+    }
+
+    private void removeUser(int userId, boolean unknownUser) {
+        mSpManager.removeUser(userId);
+        mStorage.removeUser(userId);
+        mStrongAuth.removeUser(userId);
+
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserRemoved(userId);
+
+        try {
+            final IGateKeeperService gk = getGateKeeperService();
+            if (gk != null) {
+                gk.clearSecureUserId(userId);
+            }
+        } catch (RemoteException ex) {
+            Slog.w(TAG, "unable to clear GK secure user id");
+        }
+        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
+            removeKeystoreProfileKey(userId);
+        }
+    }
+
+    private void removeKeystoreProfileKey(int targetUserId) {
+        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
+        try {
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            // We have tried our best to remove all keys
+            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
+        }
+    }
+
+    @Override
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.registerStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.unregisterStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
+    }
+
+    @Override
+    public void userPresent(int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.reportUnlock(userId);
+    }
+
+    @Override
+    public int getStrongAuthForUser(int userId) {
+        checkPasswordReadPermission(userId);
+        return mStrongAuthTracker.getStrongAuthForUser(userId);
+    }
+
+    private boolean isCallerShell() {
+        final int callingUid = Binder.getCallingUid();
+        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+    }
+
+    private void enforceShell() {
+        if (!isCallerShell()) {
+            throw new SecurityException("Caller must be shell");
+        }
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
+            throws RemoteException {
+        enforceShell();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    private static final String[] VALID_SETTINGS = new String[] {
+            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
+            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
+            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
+            LockPatternUtils.LOCKSCREEN_OPTIONS,
+            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
+            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            Secure.LOCK_PATTERN_ENABLED,
+            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
+            Secure.LOCK_PATTERN_VISIBLE,
+            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
+    };
+
+    // Reading these settings needs the contacts permission
+    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO
+    };
+
+    // Reading these settings needs the same permission as checking the password
+    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            SEPARATE_PROFILE_CHALLENGE_KEY
+    };
+
+    private static final String[] SETTINGS_TO_BACKUP = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO,
+            Secure.LOCK_PATTERN_VISIBLE,
+            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
+    };
+
+    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
+            mGateKeeperService = null;
+        }
+    }
+
+    protected synchronized IGateKeeperService getGateKeeperService()
+            throws RemoteException {
+        if (mGateKeeperService != null) {
+            return mGateKeeperService;
+        }
+
+        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
+        if (service != null) {
+            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
+            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
+            return mGateKeeperService;
+        }
+
+        Slog.e(TAG, "Unable to acquire GateKeeperService");
+        return null;
+    }
+
+    /**
+     * Precondition: vold and keystore unlocked.
+     *
+     * Create new synthetic password, set up synthetic password blob protected by the supplied
+     * user credential, and make the newly-created SP blob active.
+     *
+     * The invariant under a synthetic password is:
+     * 1. If user credential exists, then both vold and keystore and protected with keys derived
+     *     from the synthetic password.
+     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
+     *     make it consistent with current behaviour. It also allows ActivityManager to call
+     *     unlockUser() with empty secret.
+     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
+     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
+     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
+     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
+     *     credential change, in which case we have no way to derive the existing synthetic password
+     *     and has to create a new one.
+     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
+     *     clears/re-creates his lockscreen PIN.
+     *
+     *
+     * Different cases of calling this method:
+     * 1. credentialHash != null
+     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
+     *     migrated to associate with the new SP.
+     *     This happens during a normal migration case when the user currently has password.
+     *
+     * 2. credentialhash == null and credential == null
+     *     A new SP blob and a new SID will be created, while the user has no credentials.
+     *     This can happens when we are activating an escrow token on a unsecured device, during
+     *     which we want to create the SP structure with an empty user credential.
+     *
+     * 3. credentialhash == null and credential != null
+     *     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,
+            String credential, int credentialType, int requestedQuality,
+            int userId) throws RemoteException {
+        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
+                credentialHash, credential, userId);
+        if (auth == null) {
+            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
+            return null;
+        }
+        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, requestedQuality, userId);
+        if (credential != null) {
+            if (credentialHash == null) {
+                // Since when initializing SP, we didn't provide an existing password handle
+                // for it to migrate SID, we need to create a new SID for the user.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+            }
+            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+        } else {
+            clearUserKeyProtection(userId);
+            setKeystorePassword(null, userId);
+            getGateKeeperService().clearSecureUserId(userId);
+        }
+        fixateNewestUserKeyAuth(userId);
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
+        return auth;
+    }
+
+    private long getSyntheticPasswordHandleLocked(int userId) {
+        try {
+            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
+        } catch (RemoteException e) {
+            return SyntheticPasswordManager.DEFAULT_HANDLE;
+        }
+    }
+
+    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
+        if (userId == USER_FRP) {
+            final int type = mStorage.readPersistentDataBlock().type;
+            return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
+      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
+        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private void enableSyntheticPasswordLocked() throws RemoteException {
+        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int
+            credentialType, boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            userCredential = null;
+        }
+
+        final AuthenticationResult authResult;
+        VerifyCredentialResponse response;
+        synchronized (mSpManager) {
+            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+                return null;
+            }
+            if (userId == USER_FRP) {
+                return mSpManager.verifyFrpCredential(getGateKeeperService(),
+                        userCredential, credentialType, progressCallback);
+            }
+
+            long handle = getSyntheticPasswordHandleLocked(userId);
+            authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                    getGateKeeperService(), handle, userCredential, userId);
+
+            response = authResult.gkResponse;
+            // credential has matched
+            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+                // perform verifyChallenge with synthetic password which generates the real GK auth
+                // token and response for the current user
+                response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+                        challenge, userId);
+                if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                    // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
+                    // match the recorded GK password handle.
+                    Slog.wtf(TAG, "verifyChallenge with SP failed.");
+                    return VerifyCredentialResponse.ERROR;
+                }
+            }
+        }
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(userCredential, userId);
+            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
+
+            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
+            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
+            unlockUser(userId, null, secret);
+
+            activateEscrowTokens(authResult.authToken, userId);
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    /**
+     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
+     * on an existing authentication token. Even though a new SP blob is created, the underlying
+     * synthetic password is never changed.
+     *
+     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
+     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
+     * added back when new password is set in future.
+     */
+    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
+            AuthenticationToken auth, int requestedQuality, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
+        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, requestedQuality, userId);
+        final Map<Integer, String> profilePasswords;
+        if (credential != null) {
+            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = null;
+
+            if (mSpManager.hasSidForUser(userId)) {
+                // We are changing password of a secured device, nothing more needed as
+                // createPasswordBasedSyntheticPassword has already taken care of maintaining
+                // the password handle and SID unchanged.
+
+                //refresh auth token
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            } else {
+                // A new password is set on a previously-unsecured device, we need to generate
+                // a new SID, and re-add keys to vold and keystore.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+                fixateNewestUserKeyAuth(userId);
+                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+            }
+        } else {
+            // Cache all profile password if they use unified work challenge. This will later be
+            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
+
+            // we are clearing password of a secured device, so need to nuke SID as well.
+            mSpManager.clearSidForUser(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            // Clear key from vold so ActivityManager can just unlock the user with empty secret
+            // during boot.
+            clearUserKeyProtection(userId);
+            fixateNewestUserKeyAuth(userId);
+            setKeystorePassword(null, userId);
+        }
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
+        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
+        return newHandle;
+    }
+
+    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
+            String savedCredential, int requestedQuality, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            try {
+                savedCredential = getDecryptedPasswordForTiedProfile(userId);
+            } catch (FileNotFoundException e) {
+                Slog.i(TAG, "Child profile key not found");
+            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                    | NoSuchAlgorithmException | NoSuchPaddingException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                getGateKeeperService(), handle, savedCredential, userId);
+        VerifyCredentialResponse response = authResult.gkResponse;
+        AuthenticationToken auth = authResult.authToken;
+        if (auth != null) {
+            // We are performing a trusted credential change i.e. a correct existing credential
+            // is provided
+            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, requestedQuality,
+                    userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else if (response != null
+                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
+            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
+            // So provision a new SP and SID. This would invalidate existing escrow tokens.
+            // Still support this for now but this flow will be removed in the next release.
+
+            Slog.w(TAG, "Untrusted credential change invoked");
+            initializeSyntheticPasswordLocked(null, credential, credentialType, requestedQuality,
+                    userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
+            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
+                    (response != null ? "rate limit exceeded" : "failed"));
+            return;
+        }
+        notifyActivePasswordMetricsAvailable(credential, userId);
+
+    }
+
+    @Override
+    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
+        synchronized (mSpManager) {
+            enableSyntheticPasswordLocked();
+            // Migrate to synthetic password based credentials if the user has no password,
+            // the token can then be activated immediately.
+            AuthenticationToken auth = null;
+            if (!isUserSecure(userId)) {
+                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                    auth = initializeSyntheticPasswordLocked(null, null,
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
+                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
+                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
+                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
+                            pwdHandle, null, userId).authToken;
+                }
+            }
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+                if (!mSpManager.hasEscrowData(userId)) {
+                    throw new SecurityException("Escrow token is disabled on the current user");
+                }
+            }
+            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
+            if (auth != null) {
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+            return handle;
+        }
+    }
+
+    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
+        synchronized (mSpManager) {
+            disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
+                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            return mSpManager.existsHandle(handle, userId);
+        }
+    }
+
+    @Override
+    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            if (handle == getSyntheticPasswordHandleLocked(userId)) {
+                Slog.w(TAG, "Cannot remove password handle");
+                return false;
+            }
+            if (mSpManager.removePendingToken(handle, userId)) {
+                return true;
+            }
+            if (mSpManager.existsHandle(handle, userId)) {
+                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
+            byte[] token, int requestedQuality, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        boolean result;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
+                    requestedQuality, userId);
+        }
+        if (result) {
+            synchronized (mSeparateChallengeLock) {
+                setSeparateProfileChallengeEnabled(userId, true, null);
+            }
+            notifyPasswordChanged(userId);
+        }
+        return result;
+    }
+
+    private boolean setLockCredentialWithTokenInternal(String credential, int type,
+            long tokenHandle, byte[] token, int requestedQuality, int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
+                    getGateKeeperService(), tokenHandle, token, userId);
+            if (result.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return false;
+            }
+            long oldHandle = getSyntheticPasswordHandleLocked(userId);
+            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken,
+                    requestedQuality, userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
+            return true;
+        }
+    }
+
+    @Override
+    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
+            throws RemoteException {
+        ensureCallerSystemUid();
+        AuthenticationResult authResult;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
+                    tokenHandle, token, userId);
+            if (authResult.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return;
+            }
+        }
+        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
+        pw.println("Current lock settings service state:");
+        pw.println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+
+        List<UserInfo> users = mUserManager.getUsers();
+        for (int user = 0; user < users.size(); user++) {
+            final int userId = users.get(user).id;
+            pw.println("    User " + userId);
+            synchronized (mSpManager) {
+                pw.println(String.format("        SP Handle = %x",
+                        getSyntheticPasswordHandleLocked(userId)));
+            }
+            try {
+                pw.println(String.format("        SID = %x",
+                        getGateKeeperService().getSecureUserId(userId)));
+            } catch (RemoteException e) {
+                // ignore.
+            }
+        }
+    }
+
+    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            // Managed profile should have escrow enabled
+            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                Slog.i(TAG, "Managed profile can have escrow token");
+                return;
+            }
+            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
+            // Devices with Device Owner should have escrow enabled on all users.
+            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
+                Slog.i(TAG, "Corp-owned device can have escrow token");
+                return;
+            }
+            // We could also have a profile owner on the given (non-managed) user for unicorn cases
+            if (dpm.getProfileOwnerAsUser(userId) != null) {
+                Slog.i(TAG, "User with profile owner can have escrow token");
+                return;
+            }
+            // If the device is yet to be provisioned (still in SUW), there is still
+            // a chance that Device Owner will be set on the device later, so postpone
+            // disabling escrow token for now.
+            if (!dpm.isDeviceProvisioned()) {
+                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
+                return;
+            }
+
+            // Escrow tokens are enabled on automotive builds.
+            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                return;
+            }
+
+            // Disable escrow token permanently on all other device/user types.
+            Slog.i(TAG, "Disabling escrow token on user " + userId);
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                mSpManager.destroyEscrowData(userId);
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void ensureCallerSystemUid() throws SecurityException {
+        final int callingUid = mInjector.binderGetCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("Only system can call this API.");
+        }
+    }
+
+    private class DeviceProvisionedObserver extends ContentObserver {
+        private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor(
+                Settings.Global.DEVICE_PROVISIONED);
+
+        private boolean mRegistered;
+
+        public DeviceProvisionedObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mDeviceProvisionedUri.equals(uri)) {
+                updateRegistration();
+
+                if (isProvisioned()) {
+                    Slog.i(TAG, "Reporting device setup complete to IGateKeeperService");
+                    reportDeviceSetupComplete();
+                }
+            }
+        }
+
+        public void onSystemReady() {
+            if (frpCredentialEnabled()) {
+                updateRegistration();
+            } else {
+                // If we don't intend to use frpCredentials and we're not provisioned yet, send
+                // deviceSetupComplete immediately, so gatekeeper can discard any lingering
+                // credentials immediately.
+                if (!isProvisioned()) {
+                    Slog.i(TAG, "FRP credential disabled, reporting device setup complete "
+                            + "to Gatekeeper immediately");
+                    reportDeviceSetupComplete();
+                }
+            }
+        }
+
+        private void reportDeviceSetupComplete() {
+            try {
+                getGateKeeperService().reportDeviceSetupComplete();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failure reporting to IGateKeeperService", e);
+            }
+        }
+
+        private void updateRegistration() {
+            boolean register = !isProvisioned();
+            if (register == mRegistered) {
+                return;
+            }
+            if (register) {
+                mContext.getContentResolver().registerContentObserver(mDeviceProvisionedUri,
+                        false, this);
+            } else {
+                mContext.getContentResolver().unregisterContentObserver(this);
+            }
+            mRegistered = register;
+        }
+
+        private boolean isProvisioned() {
+            return Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
new file mode 100644
index 0000000..d730c56
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+
+class LockSettingsShellCommand extends ShellCommand {
+
+    private static final String COMMAND_SET_PATTERN = "set-pattern";
+    private static final String COMMAND_SET_PIN = "set-pin";
+    private static final String COMMAND_SET_PASSWORD = "set-password";
+    private static final String COMMAND_CLEAR = "clear";
+    private static final String COMMAND_SP = "sp";
+    private static final String COMMAND_SET_DISABLED = "set-disabled";
+
+    private int mCurrentUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final Context mContext;
+    private String mOld = "";
+    private String mNew = "";
+
+    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        try {
+            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
+
+            parseArgs();
+            if (!checkCredential()) {
+                return -1;
+            }
+            switch (cmd) {
+                case COMMAND_SET_PATTERN:
+                    runSetPattern();
+                    break;
+                case COMMAND_SET_PASSWORD:
+                    runSetPassword();
+                    break;
+                case COMMAND_SET_PIN:
+                    runSetPin();
+                    break;
+                case COMMAND_CLEAR:
+                    runClear();
+                    break;
+                case COMMAND_SP:
+                    runChangeSp();
+                    break;
+                case COMMAND_SET_DISABLED:
+                    runSetDisabled();
+                    break;
+                default:
+                    getErrPrintWriter().println("Unknown command: " + cmd);
+                    break;
+            }
+            return 0;
+        } catch (Exception e) {
+            getErrPrintWriter().println("Error while executing command: " + cmd);
+            e.printStackTrace(getErrPrintWriter());
+            return -1;
+        }
+    }
+
+    @Override
+    public void onHelp() {
+    }
+
+    private void parseArgs() {
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("--old".equals(opt)) {
+                mOld = getNextArgRequired();
+            } else if ("--user".equals(opt)) {
+                mCurrentUserId = Integer.parseInt(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Unknown option: " + opt);
+                throw new IllegalArgumentException();
+            }
+        }
+        mNew = getNextArg();
+    }
+
+    private void runChangeSp() {
+        if (mNew != null ) {
+            if ("1".equals(mNew)) {
+                mLockPatternUtils.enableSyntheticPassword();
+                getOutPrintWriter().println("Synthetic password enabled");
+            } else if ("0".equals(mNew)) {
+                mLockPatternUtils.disableSyntheticPassword();
+                getOutPrintWriter().println("Synthetic password disabled");
+            }
+        }
+        getOutPrintWriter().println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+    }
+
+    private void runSetPattern() throws RemoteException {
+        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
+        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
+    }
+
+    private void runSetPassword() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
+        getOutPrintWriter().println("Password set to '" + mNew + "'");
+    }
+
+    private void runSetPin() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
+        getOutPrintWriter().println("Pin set to '" + mNew + "'");
+    }
+
+    private void runClear() throws RemoteException {
+        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
+        getOutPrintWriter().println("Lock credential cleared");
+    }
+
+    private void runSetDisabled() throws RemoteException {
+        final boolean disabled = Boolean.parseBoolean(mNew);
+        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
+        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
+    }
+
+    private boolean checkCredential() throws RemoteException, RequestThrottledException {
+        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
+        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
+        if (havePassword || havePattern) {
+            boolean result;
+            if (havePassword) {
+                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
+            } else {
+                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
+                        mCurrentUserId);
+            }
+            if (result) {
+                return true;
+            } else {
+                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
new file mode 100644
index 0000000..79372e48
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -0,0 +1,903 @@
+/*
+ * 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.android.server.locksettings;
+
+import static android.content.Context.USER_SERVICE;
+
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.LocalServices;
+import com.android.server.PersistentDataBlockManagerInternal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Storage for the lock settings service.
+ */
+class LockSettingsStorage {
+
+    private static final String TAG = "LockSettingsStorage";
+    private static final String TABLE = "locksettings";
+    private static final boolean DEBUG = false;
+
+    private static final String COLUMN_KEY = "name";
+    private static final String COLUMN_USERID = "user";
+    private static final String COLUMN_VALUE = "value";
+
+    private static final String[] COLUMNS_FOR_QUERY = {
+            COLUMN_VALUE
+    };
+    private static final String[] COLUMNS_FOR_PREFETCH = {
+            COLUMN_KEY, COLUMN_VALUE
+    };
+
+    private static final String SYSTEM_DIRECTORY = "/system/";
+    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
+    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
+    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
+    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
+    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
+    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
+
+    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
+
+    private static final Object DEFAULT = new Object();
+
+    private final DatabaseHelper mOpenHelper;
+    private final Context mContext;
+    private final Cache mCache = new Cache();
+    private final Object mFileWriteLock = new Object();
+
+    private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
+
+    @VisibleForTesting
+    public static class CredentialHash {
+        static final int VERSION_LEGACY = 0;
+        static final int VERSION_GATEKEEPER = 1;
+
+        private CredentialHash(byte[] hash, int type, int version) {
+            this(hash, type, version, false /* isBaseZeroPattern */);
+        }
+
+        private CredentialHash(byte[] hash, int type, int version, boolean isBaseZeroPattern) {
+            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                if (hash == null) {
+                    throw new RuntimeException("Empty hash for CredentialHash");
+                }
+            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
+                if (hash != null) {
+                    throw new RuntimeException("None type CredentialHash should not have hash");
+                }
+            }
+            this.hash = hash;
+            this.type = type;
+            this.version = version;
+            this.isBaseZeroPattern = isBaseZeroPattern;
+        }
+
+        private static CredentialHash createBaseZeroPattern(byte[] hash) {
+            return new CredentialHash(hash, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    VERSION_GATEKEEPER, true /* isBaseZeroPattern */);
+        }
+
+        static CredentialHash create(byte[] hash, int type) {
+            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                throw new RuntimeException("Bad type for CredentialHash");
+            }
+            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
+        }
+
+        static CredentialHash createEmptyHash() {
+            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                    VERSION_GATEKEEPER);
+        }
+
+        byte[] hash;
+        int type;
+        int version;
+        boolean isBaseZeroPattern;
+
+        public byte[] toBytes() {
+            Preconditions.checkState(!isBaseZeroPattern, "base zero patterns are not serializable");
+
+            try {
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                DataOutputStream dos = new DataOutputStream(os);
+                dos.write(version);
+                dos.write(type);
+                if (hash != null && hash.length > 0) {
+                    dos.writeInt(hash.length);
+                    dos.write(hash);
+                } else {
+                    dos.writeInt(0);
+                }
+                dos.close();
+                return os.toByteArray();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static CredentialHash fromBytes(byte[] bytes) {
+            try {
+                DataInputStream is = new DataInputStream(new ByteArrayInputStream(bytes));
+                int version = is.read();
+                int type = is.read();
+                int hashSize = is.readInt();
+                byte[] hash = null;
+                if (hashSize > 0) {
+                    hash = new byte[hashSize];
+                    is.readFully(hash);
+                }
+                return new CredentialHash(hash, type, version);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public LockSettingsStorage(Context context) {
+        mContext = context;
+        mOpenHelper = new DatabaseHelper(context);
+    }
+
+    public void setDatabaseOnCreateCallback(Callback callback) {
+        mOpenHelper.setCallback(callback);
+    }
+
+    public void writeKeyValue(String key, String value, int userId) {
+        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
+    }
+
+    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
+        ContentValues cv = new ContentValues();
+        cv.put(COLUMN_KEY, key);
+        cv.put(COLUMN_USERID, userId);
+        cv.put(COLUMN_VALUE, value);
+
+        db.beginTransaction();
+        try {
+            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+                    new String[] {key, Integer.toString(userId)});
+            db.insert(TABLE, null, cv);
+            db.setTransactionSuccessful();
+            mCache.putKeyValue(key, value, userId);
+        } finally {
+            db.endTransaction();
+        }
+
+    }
+
+    public String readKeyValue(String key, String defaultValue, int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasKeyValue(key, userId)) {
+                return mCache.peekKeyValue(key, defaultValue, userId);
+            }
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        Object result = DEFAULT;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+                new String[] { Integer.toString(userId), key },
+                null, null, null)) != null) {
+            if (cursor.moveToFirst()) {
+                result = cursor.getString(0);
+            }
+            cursor.close();
+        }
+        mCache.putKeyValueIfUnchanged(key, result, userId, version);
+        return result == DEFAULT ? defaultValue : (String) result;
+    }
+
+    public void prefetchUser(int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.isFetched(userId)) {
+                return;
+            }
+            mCache.setFetched(userId);
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
+                COLUMN_USERID + "=?",
+                new String[] { Integer.toString(userId) },
+                null, null, null)) != null) {
+            while (cursor.moveToNext()) {
+                String key = cursor.getString(0);
+                String value = cursor.getString(1);
+                mCache.putKeyValueIfUnchanged(key, value, userId, version);
+            }
+            cursor.close();
+        }
+
+        // Populate cache by reading the password and pattern files.
+        readCredentialHash(userId);
+    }
+
+    private CredentialHash readPasswordHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getLegacyLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    private CredentialHash readPatternHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getBaseZeroLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return CredentialHash.createBaseZeroPattern(stored);
+        }
+
+        stored = readFile(getLegacyLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    public CredentialHash readCredentialHash(int userId) {
+        CredentialHash passwordHash = readPasswordHashIfExists(userId);
+        CredentialHash patternHash = readPatternHashIfExists(userId);
+        if (passwordHash != null && patternHash != null) {
+            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
+                return passwordHash;
+            } else {
+                return patternHash;
+            }
+        } else if (passwordHash != null) {
+            return passwordHash;
+        } else if (patternHash != null) {
+            return patternHash;
+        } else {
+            return CredentialHash.createEmptyHash();
+        }
+    }
+
+    public void removeChildProfileLock(int userId) {
+        if (DEBUG)
+            Slog.e(TAG, "Remove child profile lock for user: " + userId);
+        try {
+            deleteFile(getChildProfileLockFile(userId));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void writeChildProfileLock(int userId, byte[] lock) {
+        writeFile(getChildProfileLockFile(userId), lock);
+    }
+
+    public byte[] readChildProfileLock(int userId) {
+        return readFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasChildProfileLock(int userId) {
+        return hasFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasPassword(int userId) {
+        return hasFile(getLockPasswordFilename(userId)) ||
+            hasFile(getLegacyLockPasswordFilename(userId));
+    }
+
+    public boolean hasPattern(int userId) {
+        return hasFile(getLockPatternFilename(userId)) ||
+            hasFile(getBaseZeroLockPatternFilename(userId)) ||
+            hasFile(getLegacyLockPatternFilename(userId));
+    }
+
+    public boolean hasCredential(int userId) {
+        return hasPassword(userId) || hasPattern(userId);
+    }
+
+    private boolean hasFile(String name) {
+        byte[] contents = readFile(name);
+        return contents != null && contents.length > 0;
+    }
+
+    private byte[] readFile(String name) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasFile(name)) {
+                return mCache.peekFile(name);
+            }
+            version = mCache.getVersion();
+        }
+
+        RandomAccessFile raf = null;
+        byte[] stored = null;
+        try {
+            raf = new RandomAccessFile(name, "r");
+            stored = new byte[(int) raf.length()];
+            raf.readFully(stored, 0, stored.length);
+            raf.close();
+        } catch (IOException e) {
+            Slog.e(TAG, "Cannot read file " + e);
+        } finally {
+            if (raf != null) {
+                try {
+                    raf.close();
+                } catch (IOException e) {
+                    Slog.e(TAG, "Error closing file " + e);
+                }
+            }
+        }
+        mCache.putFileIfUnchanged(name, stored, version);
+        return stored;
+    }
+
+    private void writeFile(String name, byte[] hash) {
+        synchronized (mFileWriteLock) {
+            RandomAccessFile raf = null;
+            try {
+                // Write the hash to file, requiring each write to be synchronized to the
+                // underlying storage device immediately to avoid data loss in case of power loss.
+                // This also ensures future secdiscard operation on the file succeeds since the
+                // file would have been allocated on flash.
+                raf = new RandomAccessFile(name, "rws");
+                // Truncate the file if pattern is null, to clear the lock
+                if (hash == null || hash.length == 0) {
+                    raf.setLength(0);
+                } else {
+                    raf.write(hash, 0, hash.length);
+                }
+                raf.close();
+            } catch (IOException e) {
+                Slog.e(TAG, "Error writing to file " + e);
+            } finally {
+                if (raf != null) {
+                    try {
+                        raf.close();
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error closing file " + e);
+                    }
+                }
+            }
+            mCache.putFile(name, hash);
+        }
+    }
+
+    private void deleteFile(String name) {
+        if (DEBUG) Slog.e(TAG, "Delete file " + name);
+        synchronized (mFileWriteLock) {
+            File file = new File(name);
+            if (file.exists()) {
+                file.delete();
+                mCache.putFile(name, null);
+            }
+        }
+    }
+
+    public void writeCredentialHash(CredentialHash hash, int userId) {
+        byte[] patternHash = null;
+        byte[] passwordHash = null;
+
+        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            passwordHash = hash.hash;
+        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+            patternHash = hash.hash;
+        }
+        writeFile(getLockPasswordFilename(userId), passwordHash);
+        writeFile(getLockPatternFilename(userId), patternHash);
+    }
+
+    @VisibleForTesting
+    String getLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
+    }
+
+    private String getBaseZeroLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getChildProfileLockFile(int userId) {
+        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+    }
+
+    private String getLockCredentialFilePathForUser(int userId, String basename) {
+        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
+                        SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + basename;
+        } else {
+            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
+        }
+    }
+
+    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
+        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+    }
+
+    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
+        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+    }
+
+    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
+        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
+        File file = new File(path);
+        if (file.exists()) {
+            try {
+                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
+            } catch (Exception e) {
+                Slog.w(TAG, "Failed to secdiscard " + path, e);
+            } finally {
+                file.delete();
+            }
+            mCache.putFile(path, null);
+        }
+    }
+
+    public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
+        Map<Integer, List<Long>> result = new ArrayMap<>();
+        final UserManager um = UserManager.get(mContext);
+        for (UserInfo user : um.getUsers(false)) {
+            result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
+        }
+        return result;
+    }
+
+    public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        List<Long> result = new ArrayList<>();
+        File[] files = baseDir.listFiles();
+        if (files == null) {
+            return result;
+        }
+        for (File file : files) {
+            String[] parts = file.getName().split("\\.");
+            if (parts.length == 2 && parts[1].equals(stateName)) {
+                try {
+                    result.add(Long.parseUnsignedLong(parts[0], 16));
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Failed to parse handle " + parts[0]);
+                }
+            }
+        }
+        return result;
+    }
+
+    @VisibleForTesting
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
+    }
+
+    @VisibleForTesting
+    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
+            String name) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        String baseName = String.format("%016x.%s", handle, name);
+        if (!baseDir.exists()) {
+            baseDir.mkdir();
+        }
+        return new File(baseDir, baseName).getAbsolutePath();
+    }
+
+    public void removeUser(int userId) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final UserInfo parentInfo = um.getProfileParent(userId);
+
+        if (parentInfo == null) {
+            // This user owns its lock settings files - safe to delete them
+            synchronized (mFileWriteLock) {
+                String name = getLockPasswordFilename(userId);
+                File file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+                name = getLockPatternFilename(userId);
+                file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+            }
+        } else {
+            // Managed profile
+            removeChildProfileLock(userId);
+        }
+
+        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
+        try {
+            db.beginTransaction();
+            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+            db.setTransactionSuccessful();
+            mCache.removeUser(userId);
+            // The directory itself will be deleted as part of user deletion operation by the
+            // framework, so only need to purge cache here.
+            //TODO: (b/34600579) invoke secdiscardable
+            mCache.purgePath(spStateDir.getAbsolutePath());
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    @VisibleForTesting
+    void closeDatabase() {
+        mOpenHelper.close();
+    }
+
+    @VisibleForTesting
+    void clearCache() {
+        mCache.clear();
+    }
+
+    @Nullable
+    public PersistentDataBlockManagerInternal getPersistentDataBlock() {
+        if (mPersistentDataBlockManagerInternal == null) {
+            mPersistentDataBlockManagerInternal =
+                    LocalServices.getService(PersistentDataBlockManagerInternal.class);
+        }
+        return mPersistentDataBlockManagerInternal;
+    }
+
+    public void writePersistentDataBlock(int persistentType, int userId, int qualityForUi,
+            byte[] payload) {
+        PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlock();
+        if (persistentDataBlock == null) {
+            return;
+        }
+        persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes(
+                persistentType, userId, qualityForUi, payload));
+    }
+
+    public PersistentData readPersistentDataBlock() {
+        PersistentDataBlockManagerInternal persistentDataBlock = getPersistentDataBlock();
+        if (persistentDataBlock == null) {
+            return PersistentData.NONE;
+        }
+        return PersistentData.fromBytes(persistentDataBlock.getFrpCredentialHandle());
+    }
+
+    public static class PersistentData {
+        static final byte VERSION_1 = 1;
+        static final int VERSION_1_HEADER_SIZE = 1 + 1 + 4 + 4;
+
+        public static final int TYPE_NONE = 0;
+        public static final int TYPE_GATEKEEPER = 1;
+        public static final int TYPE_SP = 2;
+        public static final int TYPE_SP_WEAVER = 3;
+
+        public static final PersistentData NONE = new PersistentData(TYPE_NONE,
+                UserHandle.USER_NULL, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, null);
+
+        final int type;
+        final int userId;
+        final int qualityForUi;
+        final byte[] payload;
+
+        private PersistentData(int type, int userId, int qualityForUi, byte[] payload) {
+            this.type = type;
+            this.userId = userId;
+            this.qualityForUi = qualityForUi;
+            this.payload = payload;
+        }
+
+        public static PersistentData fromBytes(byte[] frpData) {
+            if (frpData == null || frpData.length == 0) {
+                return NONE;
+            }
+
+            DataInputStream is = new DataInputStream(new ByteArrayInputStream(frpData));
+            try {
+                byte version = is.readByte();
+                if (version == PersistentData.VERSION_1) {
+                    int type = is.readByte() & 0xFF;
+                    int userId = is.readInt();
+                    int qualityForUi = is.readInt();
+                    byte[] payload = new byte[frpData.length - VERSION_1_HEADER_SIZE];
+                    System.arraycopy(frpData, VERSION_1_HEADER_SIZE, payload, 0, payload.length);
+                    return new PersistentData(type, userId, qualityForUi, payload);
+                } else {
+                    Slog.wtf(TAG, "Unknown PersistentData version code: " + version);
+                    return null;
+                }
+            } catch (IOException e) {
+                Slog.wtf(TAG, "Could not parse PersistentData", e);
+                return null;
+            }
+        }
+
+        public static byte[] toBytes(int persistentType, int userId, int qualityForUi,
+                byte[] payload) {
+            if (persistentType == PersistentData.TYPE_NONE) {
+                Preconditions.checkArgument(payload == null,
+                        "TYPE_NONE must have empty payload");
+                return null;
+            }
+            Preconditions.checkArgument(payload != null && payload.length > 0,
+                    "empty payload must only be used with TYPE_NONE");
+
+            ByteArrayOutputStream os = new ByteArrayOutputStream(
+                    VERSION_1_HEADER_SIZE + payload.length);
+            DataOutputStream dos = new DataOutputStream(os);
+            try {
+                dos.writeByte(PersistentData.VERSION_1);
+                dos.writeByte(persistentType);
+                dos.writeInt(userId);
+                dos.writeInt(qualityForUi);
+                dos.write(payload);
+            } catch (IOException e) {
+                throw new RuntimeException("ByteArrayOutputStream cannot throw IOException");
+            }
+            return os.toByteArray();
+        }
+    }
+
+    public interface Callback {
+        void initialize(SQLiteDatabase db);
+    }
+
+    static class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String TAG = "LockSettingsDB";
+        private static final String DATABASE_NAME = "locksettings.db";
+
+        private static final int DATABASE_VERSION = 2;
+
+        private Callback mCallback;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            setWriteAheadLoggingEnabled(true);
+        }
+
+        public void setCallback(Callback callback) {
+            mCallback = callback;
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE + " (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    COLUMN_KEY + " TEXT," +
+                    COLUMN_USERID + " INTEGER," +
+                    COLUMN_VALUE + " TEXT" +
+                    ");");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createTable(db);
+            if (mCallback != null) {
+                mCallback.initialize(db);
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+            int upgradeVersion = oldVersion;
+            if (upgradeVersion == 1) {
+                // Previously migrated lock screen widget settings. Now defunct.
+                upgradeVersion = 2;
+            }
+
+            if (upgradeVersion != DATABASE_VERSION) {
+                Log.w(TAG, "Failed to upgrade database!");
+            }
+        }
+    }
+
+    /**
+     * Cache consistency model:
+     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
+     *   section either provided by the database transaction or mWriteLock, such that writes to the
+     *   cache and writes to the backing storage are guaranteed to occur in the same order
+     *
+     * - Reads can populate the cache, but because they are no strong ordering guarantees with
+     *   respect to writes this precaution is taken:
+     *   - The cache is assigned a version number that increases every time the cache is modified.
+     *     Reads from backing storage can only populate the cache if the backing storage
+     *     has not changed since the load operation has begun.
+     *     This guarantees that no read operation can shadow a write to the cache that happens
+     *     after it had begun.
+     */
+    private static class Cache {
+        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
+        private final CacheKey mCacheKey = new CacheKey();
+        private int mVersion = 0;
+
+        String peekKeyValue(String key, String defaultValue, int userId) {
+            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
+            return cached == DEFAULT ? defaultValue : (String) cached;
+        }
+
+        boolean hasKeyValue(String key, int userId) {
+            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
+        }
+
+        void putKeyValue(String key, String value, int userId) {
+            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
+        }
+
+        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
+            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
+        }
+
+        byte[] peekFile(String fileName) {
+            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        boolean hasFile(String fileName) {
+            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        void putFile(String key, byte[] value) {
+            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
+        }
+
+        void putFileIfUnchanged(String key, byte[] value, int version) {
+            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
+        }
+
+        void setFetched(int userId) {
+            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
+        }
+
+        boolean isFetched(int userId) {
+            return contains(CacheKey.TYPE_FETCHED, "", userId);
+        }
+
+
+        private synchronized void put(int type, String key, Object value, int userId) {
+            // Create a new CachKey here because it may be saved in the map if the key is absent.
+            mCache.put(new CacheKey().set(type, key, userId), value);
+            mVersion++;
+        }
+
+        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
+                int version) {
+            if (!contains(type, key, userId) && mVersion == version) {
+                put(type, key, value, userId);
+            }
+        }
+
+        private synchronized boolean contains(int type, String key, int userId) {
+            return mCache.containsKey(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized Object peek(int type, String key, int userId) {
+            return mCache.get(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized int getVersion() {
+            return mVersion;
+        }
+
+        synchronized void removeUser(int userId) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                if (mCache.keyAt(i).userId == userId) {
+                    mCache.removeAt(i);
+                }
+            }
+
+            // Make sure in-flight loads can't write to cache.
+            mVersion++;
+        }
+
+        synchronized void purgePath(String path) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                CacheKey entry = mCache.keyAt(i);
+                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
+                    mCache.removeAt(i);
+                }
+            }
+            mVersion++;
+        }
+
+        synchronized void clear() {
+            mCache.clear();
+            mVersion++;
+        }
+
+        private static final class CacheKey {
+            static final int TYPE_KEY_VALUE = 0;
+            static final int TYPE_FILE = 1;
+            static final int TYPE_FETCHED = 2;
+
+            String key;
+            int userId;
+            int type;
+
+            public CacheKey set(int type, String key, int userId) {
+                this.type = type;
+                this.key = key;
+                this.userId = userId;
+                return this;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (!(obj instanceof CacheKey))
+                    return false;
+                CacheKey o = (CacheKey) obj;
+                return userId == o.userId && type == o.type && key.equals(o.key);
+            }
+
+            @Override
+            public int hashCode() {
+                return key.hashCode() ^ userId ^ type;
+            }
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
new file mode 100644
index 0000000..0966153
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
+
+import android.app.AlarmManager;
+import android.app.AlarmManager.OnAlarmListener;
+import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
+import android.content.Context;
+import android.os.Binder;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+
+/**
+ * Keeps track of requests for strong authentication.
+ */
+public class LockSettingsStrongAuth {
+
+    private static final String TAG = "LockSettings";
+
+    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
+    private static final int MSG_REGISTER_TRACKER = 2;
+    private static final int MSG_UNREGISTER_TRACKER = 3;
+    private static final int MSG_REMOVE_USER = 4;
+    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
+
+    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
+            "LockSettingsStrongAuth.timeoutForUser";
+
+    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
+    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
+            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
+    private final int mDefaultStrongAuthFlags;
+    private final Context mContext;
+
+    private AlarmManager mAlarmManager;
+
+    public LockSettingsStrongAuth(Context context) {
+        mContext = context;
+        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
+        mAlarmManager = context.getSystemService(AlarmManager.class);
+    }
+
+    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                return;
+            }
+        }
+        mStrongAuthTrackers.add(tracker);
+
+        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+            int key = mStrongAuthForUser.keyAt(i);
+            int value = mStrongAuthForUser.valueAt(i);
+            try {
+                tracker.onStrongAuthRequiredChanged(value, key);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                mStrongAuthTrackers.remove(i);
+                return;
+            }
+        }
+    }
+
+    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+                int key = mStrongAuthForUser.keyAt(i);
+                handleRequireStrongAuthOneUser(strongAuthReason, key);
+            }
+        } else {
+            handleRequireStrongAuthOneUser(strongAuthReason, userId);
+        }
+    }
+
+    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
+        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
+        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
+                ? STRONG_AUTH_NOT_REQUIRED
+                : (oldValue | strongAuthReason);
+        if (oldValue != newValue) {
+            mStrongAuthForUser.put(userId, newValue);
+            notifyStrongAuthTrackers(newValue, userId);
+        }
+    }
+
+    private void handleRemoveUser(int userId) {
+        int index = mStrongAuthForUser.indexOfKey(userId);
+        if (index >= 0) {
+            mStrongAuthForUser.removeAt(index);
+            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
+        }
+    }
+
+    private void handleScheduleStrongAuthTimeout(int userId) {
+        final DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
+        // cancel current alarm listener for the user (if there was one)
+        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+        if (alarm != null) {
+            mAlarmManager.cancel(alarm);
+        } else {
+            alarm = new StrongAuthTimeoutAlarmListener(userId);
+            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
+        }
+        // schedule a new alarm listener for the user
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
+                alarm, mHandler);
+    }
+
+    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            try {
+                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
+            } catch (DeadObjectException e) {
+                Slog.d(TAG, "Removing dead StrongAuthTracker.");
+                mStrongAuthTrackers.remove(i);
+                i--;
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void removeUser(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
+    }
+
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
+            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
+                    userId).sendToTarget();
+        } else {
+            throw new IllegalArgumentException(
+                    "userId must be an explicit user id or USER_ALL");
+        }
+    }
+
+    public void reportUnlock(int userId) {
+        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
+    }
+
+    public void reportSuccessfulStrongAuthUnlock(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
+    }
+
+    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
+
+        private final int mUserId;
+
+        public StrongAuthTimeoutAlarmListener(int userId) {
+            mUserId = userId;
+        }
+
+        @Override
+        public void onAlarm() {
+            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
+        }
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REGISTER_TRACKER:
+                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_UNREGISTER_TRACKER:
+                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_REQUIRE_STRONG_AUTH:
+                    handleRequireStrongAuth(msg.arg1, msg.arg2);
+                    break;
+                case MSG_REMOVE_USER:
+                    handleRemoveUser(msg.arg1);
+                    break;
+                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
+                    handleScheduleStrongAuthTimeout(msg.arg1);
+                    break;
+            }
+        }
+    };
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
new file mode 100644
index 0000000..b7bca1fb
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -0,0 +1,196 @@
+/*
+ * 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.locksettings;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class SyntheticPasswordCrypto {
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
+    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
+    // Time between the user credential is verified with GK and the decryption of synthetic password
+    // under the auth-bound key. This should always happen one after the other, but give it 15
+    // seconds just to be sure.
+    private static final int USER_AUTHENTICATION_VALIDITY = 15;
+
+    private static byte[] decrypt(SecretKey key, byte[] blob)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
+        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
+        return cipher.doFinal(ciphertext);
+    }
+
+    private static byte[] encrypt(SecretKey key, byte[] blob)
+            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
+            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        Cipher cipher = Cipher.getInstance(
+                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                        + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.ENCRYPT_MODE, key);
+        byte[] ciphertext = cipher.doFinal(blob);
+        byte[] iv = cipher.getIV();
+        if (iv.length != PROFILE_KEY_IV_SIZE) {
+            throw new RuntimeException("Invalid iv length: " + iv.length);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        outputStream.write(iv);
+        outputStream.write(ciphertext);
+        return outputStream.toByteArray();
+    }
+
+    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return encrypt(key, message);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException | IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return decrypt(key, ciphertext);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+
+            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
+            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
+            return decrypt(decryptionKey, intermediate);
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException | UnrecoverableKeyException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to decrypt blob", e);
+        }
+    }
+
+    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .setCriticalToDeviceEncryption(true);
+            if (sid != 0) {
+                builder.setUserAuthenticationRequired(true)
+                        .setBoundToSpecificSecureUserId(sid)
+                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
+            }
+
+            keyStore.setEntry(keyAlias,
+                    new KeyStore.SecretKeyEntry(secretKey),
+                    builder.build());
+            byte[] intermediate = encrypt(secretKey, data);
+            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
+
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to encrypt blob", e);
+        }
+    }
+
+    public static void destroyBlobKey(String keyAlias) {
+        KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(keyAlias);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
+        try {
+            final int PADDING_LENGTH = 128;
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            if (personalisation.length > PADDING_LENGTH) {
+                throw new RuntimeException("Personalisation too long");
+            }
+            // Personalize the hash
+            // Pad it to the block size of the hash function
+            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
+            digest.update(personalisation);
+            for (byte[] data : message) {
+                digest.update(data);
+            }
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
new file mode 100644
index 0000000..f45c208
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -0,0 +1,1107 @@
+/*
+ * 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.locksettings;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverReadStatus;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.security.GateKeeper;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.widget.ICheckCredentialProgressCallback;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import libcore.util.HexEncoding;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+
+/**
+ * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
+ * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
+ * synthetic password blobs which are wrapped by user credentials or escrow tokens.
+ *
+ * Here is the assumptions it makes:
+ *   Each user has one single synthetic password at any time.
+ *   The SP has an associated password handle, which binds to the SID for that user. The password
+ *   handle is persisted by SyntheticPasswordManager internally.
+ *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
+ *
+ * Information persisted on disk:
+ *   for each user (stored under DEFAULT_HANDLE):
+ *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
+ *                     credential exists, cleared when user clears their credential.
+ *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
+ *                     tokens. Destroyed when escrow support is turned off for the given user.
+ *
+ *     for each SP blob under the user (stored under the corresponding handle):
+ *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
+ *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
+ *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
+ *                            purpose of secure deletion. Exists if this is a non-weaver SP
+ *                            (both password and token based), or it's a token-based SP under weaver.
+ *       WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
+ *
+ *
+ */
+public class SyntheticPasswordManager {
+    private static final String SP_BLOB_NAME = "spblob";
+    private static final String SP_E0_NAME = "e0";
+    private static final String SP_P1_NAME = "p1";
+    private static final String SP_HANDLE_NAME = "handle";
+    private static final String SECDISCARDABLE_NAME = "secdis";
+    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
+    private static final String PASSWORD_DATA_NAME = "pwd";
+    private static final String WEAVER_SLOT_NAME = "weaver";
+
+    public static final long DEFAULT_HANDLE = 0L;
+    private static final String DEFAULT_PASSWORD = "default-password";
+
+    private static final byte WEAVER_VERSION = 1;
+    private static final int INVALID_WEAVER_SLOT = -1;
+
+    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
+    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
+    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
+
+    // 256-bit synthetic password
+    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
+
+    private static final int PASSWORD_SCRYPT_N = 11;
+    private static final int PASSWORD_SCRYPT_R = 3;
+    private static final int PASSWORD_SCRYPT_P = 1;
+    private static final int PASSWORD_SALT_LENGTH = 16;
+    private static final int PASSWORD_TOKEN_LENGTH = 32;
+    private static final String TAG = "SyntheticPasswordManager";
+
+    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
+    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
+    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
+    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
+    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes();
+
+    static class AuthenticationResult {
+        public AuthenticationToken authToken;
+        public VerifyCredentialResponse gkResponse;
+    }
+
+    static class AuthenticationToken {
+        /*
+         * Here is the relationship between all three fields:
+         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
+         * syntheticPassword = hash(P0 || P1)
+         * E0 = P0 encrypted under syntheticPassword, stored on disk.
+         */
+        private @Nullable byte[] E0;
+        private @Nullable byte[] P1;
+        private @NonNull String syntheticPassword;
+
+        public String deriveKeyStorePassword() {
+            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
+                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
+        }
+
+        public byte[] deriveGkPassword() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
+                    syntheticPassword.getBytes());
+        }
+
+        public byte[] deriveDiskEncryptionKey() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
+                    syntheticPassword.getBytes());
+        }
+
+        private void initialize(byte[] P0, byte[] P1) {
+            this.P1 = P1;
+            this.syntheticPassword = String.valueOf(HexEncoding.encode(
+                    SyntheticPasswordCrypto.personalisedHash(
+                            PERSONALIZATION_SP_SPLIT, P0, P1)));
+            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
+                    PERSONALIZATION_E0, P0);
+        }
+
+        public void recreate(byte[] secret) {
+            initialize(secret, this.P1);
+        }
+
+        protected static AuthenticationToken create() {
+            AuthenticationToken result = new AuthenticationToken();
+            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
+                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
+            return result;
+        }
+
+        public byte[] computeP0() {
+            if (E0 == null) {
+                return null;
+            }
+            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
+                    E0);
+        }
+    }
+
+    static class PasswordData {
+        byte scryptN;
+        byte scryptR;
+        byte scryptP;
+        public int passwordType;
+        byte[] salt;
+        // For GateKeeper-based credential, this is the password handle returned by GK,
+        // for weaver-based credential, this is empty.
+        public byte[] passwordHandle;
+
+        public static PasswordData create(int passwordType) {
+            PasswordData result = new PasswordData();
+            result.scryptN = PASSWORD_SCRYPT_N;
+            result.scryptR = PASSWORD_SCRYPT_R;
+            result.scryptP = PASSWORD_SCRYPT_P;
+            result.passwordType = passwordType;
+            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
+            return result;
+        }
+
+        public static PasswordData fromBytes(byte[] data) {
+            PasswordData result = new PasswordData();
+            ByteBuffer buffer = ByteBuffer.allocate(data.length);
+            buffer.put(data, 0, data.length);
+            buffer.flip();
+            result.passwordType = buffer.getInt();
+            result.scryptN = buffer.get();
+            result.scryptR = buffer.get();
+            result.scryptP = buffer.get();
+            int saltLen = buffer.getInt();
+            result.salt = new byte[saltLen];
+            buffer.get(result.salt);
+            int handleLen = buffer.getInt();
+            if (handleLen > 0) {
+                result.passwordHandle = new byte[handleLen];
+                buffer.get(result.passwordHandle);
+            } else {
+                result.passwordHandle = null;
+            }
+            return result;
+        }
+
+        public byte[] toBytes() {
+
+            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
+                    + Integer.BYTES + salt.length + Integer.BYTES +
+                    (passwordHandle != null ? passwordHandle.length : 0));
+            buffer.putInt(passwordType);
+            buffer.put(scryptN);
+            buffer.put(scryptR);
+            buffer.put(scryptP);
+            buffer.putInt(salt.length);
+            buffer.put(salt);
+            if (passwordHandle != null && passwordHandle.length > 0) {
+                buffer.putInt(passwordHandle.length);
+                buffer.put(passwordHandle);
+            } else {
+                buffer.putInt(0);
+            }
+            return buffer.array();
+        }
+    }
+
+    static class TokenData {
+        byte[] secdiscardableOnDisk;
+        byte[] weaverSecret;
+        byte[] aggregatedSecret;
+    }
+
+    private LockSettingsStorage mStorage;
+    private IWeaver mWeaver;
+    private WeaverConfig mWeaverConfig;
+
+    private final UserManager mUserManager;
+
+    public SyntheticPasswordManager(LockSettingsStorage storage, UserManager userManager) {
+        mStorage = storage;
+        mUserManager = userManager;
+    }
+
+    @VisibleForTesting
+    protected IWeaver getWeaverService() throws RemoteException {
+        try {
+            return IWeaver.getService();
+        } catch (NoSuchElementException e) {
+            Slog.i(TAG, "Device does not support weaver");
+            return null;
+        }
+    }
+
+    public synchronized void initWeaverService() {
+        if (mWeaver != null) {
+            return;
+        }
+        try {
+            mWeaverConfig = null;
+            mWeaver = getWeaverService();
+            if (mWeaver != null) {
+                mWeaver.getConfig((int status, WeaverConfig config) -> {
+                    if (status == WeaverStatus.OK && config.slots > 0) {
+                        mWeaverConfig = config;
+                    } else {
+                        Slog.e(TAG, "Failed to get weaver config, status " + status
+                                + " slots: " + config.slots);
+                        mWeaver = null;
+                    }
+                });
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get weaver service", e);
+        }
+    }
+
+    private synchronized boolean isWeaverAvailable() {
+        if (mWeaver == null) {
+            //Re-initializing weaver in case there was a transient error preventing access to it.
+            initWeaverService();
+        }
+        return mWeaver != null && mWeaverConfig.slots > 0;
+    }
+
+    /**
+     * Enroll the given key value pair into the specified weaver slot. if the given key is null,
+     * a default all-zero key is used. If the value is not specified, a fresh random secret is
+     * generated as the value.
+     *
+     * @return the value stored in the weaver slot
+     * @throws RemoteException
+     */
+    private byte[] weaverEnroll(int slot, byte[] key, @Nullable byte[] value)
+            throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        if (value == null) {
+            value = secureRandom(mWeaverConfig.valueSize);
+        }
+        int writeStatus = mWeaver.write(slot, toByteArrayList(key), toByteArrayList(value));
+        if (writeStatus != WeaverStatus.OK) {
+            Log.e(TAG, "weaver write failed, slot: " + slot + " status: " + writeStatus);
+            return null;
+        }
+        return value;
+    }
+
+    /**
+     * Verify the supplied key against a weaver slot, returning a response indicating whether
+     * the verification is successful, throttled or failed. If successful, the bound secret
+     * is also returned.
+     * @throws RemoteException
+     */
+    private VerifyCredentialResponse weaverVerify(int slot, byte[] key) throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        final VerifyCredentialResponse[] response = new VerifyCredentialResponse[1];
+        mWeaver.read(slot, toByteArrayList(key), (int status, WeaverReadResponse readResponse) -> {
+            switch (status) {
+                case WeaverReadStatus.OK:
+                    response[0] = new VerifyCredentialResponse(
+                            fromByteArrayList(readResponse.value));
+                    break;
+                case WeaverReadStatus.THROTTLE:
+                    response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                    Log.e(TAG, "weaver read failed (THROTTLE), slot: " + slot);
+                    break;
+                case WeaverReadStatus.INCORRECT_KEY:
+                    if (readResponse.timeout == 0) {
+                        response[0] = VerifyCredentialResponse.ERROR;
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY), slot: " + slot);
+                    } else {
+                        response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY/THROTTLE), slot: " + slot);
+                    }
+                    break;
+                case WeaverReadStatus.FAILED:
+                    response[0] = VerifyCredentialResponse.ERROR;
+                    Log.e(TAG, "weaver read failed (FAILED), slot: " + slot);
+                    break;
+               default:
+                   response[0] = VerifyCredentialResponse.ERROR;
+                   Log.e(TAG, "weaver read unknown status " + status + ", slot: " + slot);
+                   break;
+            }
+        });
+        return response[0];
+    }
+
+    public void removeUser(int userId) {
+        if (isWeaverAvailable()) {
+            for (long handle : mStorage.listSyntheticPasswordHandlesForUser(WEAVER_SLOT_NAME,
+                    userId)) {
+                destroyWeaverSlot(handle, userId);
+            }
+        }
+    }
+
+    public int getCredentialType(long handle, int userId) {
+        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
+        if (passwordData == null) {
+            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
+            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
+        }
+        return PasswordData.fromBytes(passwordData).passwordType;
+    }
+
+    /**
+     * Initializing a new Authentication token, possibly from an existing credential and hash.
+     *
+     * The authentication token would bear a randomly-generated synthetic password.
+     *
+     * This method has the side effect of rebinding the SID of the given user to the
+     * newly-generated SP.
+     *
+     * If the existing credential hash is non-null, the existing SID mill be migrated so
+     * the synthetic password in the authentication token will produce the same SID
+     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
+     * in a per-user data storage.)
+     *
+     * If the existing credential hash is null, it means the given user should have no SID so
+     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
+     * the supplied credential parameter is also ignored.
+     *
+     * Also saves the escrow information necessary to re-generate the synthetic password under
+     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
+     * password escrow should be disabled completely on the given user.
+     *
+     */
+    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
+            byte[] hash, String credential, int userId) throws RemoteException {
+        AuthenticationToken result = AuthenticationToken.create();
+        GateKeeperResponse response;
+        if (hash != null) {
+            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
+                    result.deriveGkPassword());
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
+                clearSidForUser(userId);
+            } else {
+                saveSyntheticPasswordHandle(response.getPayload(), userId);
+            }
+        } else {
+            clearSidForUser(userId);
+        }
+        saveEscrowData(result, userId);
+        return result;
+    }
+
+    /**
+     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
+     * Used when adding password to previously-unsecured devices.
+     */
+    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
+            int userId) throws RemoteException {
+        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
+                authToken.deriveGkPassword());
+        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+            Log.e(TAG, "Fail to create new SID for user " + userId);
+            return;
+        }
+        saveSyntheticPasswordHandle(response.getPayload(), userId);
+    }
+
+    // Nuke the SP handle (and as a result, its SID) for the given user.
+    public void clearSidForUser(int userId) {
+        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasSidForUser(int userId) {
+        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    // if null, it means there is no SID associated with the user
+    // This can happen if the user is migrated to SP but currently
+    // do not have a lockscreen password.
+    private byte[] loadSyntheticPasswordHandle(int userId) {
+        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
+        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
+    }
+
+    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
+        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+        return authToken.E0 != null && authToken.P1 != null;
+    }
+
+    private void saveEscrowData(AuthenticationToken authToken, int userId) {
+        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
+        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasEscrowData(int userId) {
+        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
+                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    public void destroyEscrowData(int userId) {
+        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    private int loadWeaverSlot(long handle, int userId) {
+        final int LENGTH = Byte.BYTES + Integer.BYTES;
+        byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
+        if (data == null || data.length != LENGTH) {
+            return INVALID_WEAVER_SLOT;
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(LENGTH);
+        buffer.put(data, 0, data.length);
+        buffer.flip();
+        if (buffer.get() != WEAVER_VERSION) {
+            Log.e(TAG, "Invalid weaver slot version of handle " + handle);
+            return INVALID_WEAVER_SLOT;
+        }
+        return buffer.getInt();
+    }
+
+    private void saveWeaverSlot(int slot, long handle, int userId) {
+        ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
+        buffer.put(WEAVER_VERSION);
+        buffer.putInt(slot);
+        saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
+    }
+
+    private void destroyWeaverSlot(long handle, int userId) {
+        int slot = loadWeaverSlot(handle, userId);
+        if (slot != INVALID_WEAVER_SLOT) {
+            try {
+                weaverEnroll(slot, null, null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to destroy slot", e);
+            }
+        }
+        destroyState(WEAVER_SLOT_NAME, handle, userId);
+    }
+
+    private int getNextAvailableWeaverSlot() {
+        Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
+                WEAVER_SLOT_NAME);
+        HashSet<Integer> slots = new HashSet<>();
+        for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
+            for (Long handle : entry.getValue()) {
+                int slot = loadWeaverSlot(handle, entry.getKey());
+                slots.add(slot);
+            }
+        }
+        for (int i = 0; i < mWeaverConfig.slots; i++) {
+            if (!slots.contains(i)) {
+                return i;
+            }
+        }
+        throw new RuntimeException("Run out of weaver slots.");
+    }
+
+    /**
+     * Create a new password based SP blob based on the supplied authentication token, such that
+     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
+     * in the same authentication token.
+     *
+     * This method only creates SP blob wrapping around the given synthetic password and does not
+     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
+     * is consistent with the device state by calling other APIs in this class.
+     *
+     * @see #newSidForUser
+     * @see #clearSidForUser
+     */
+    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            String credential, int credentialType, AuthenticationToken authToken,
+            int requestedQuality, int userId)
+                    throws RemoteException {
+        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
+            credential = DEFAULT_PASSWORD;
+        }
+
+        long handle = generateHandle();
+        PasswordData pwd = PasswordData.create(credentialType);
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+        final long sid;
+        final byte[] applicationId;
+
+        if (isWeaverAvailable()) {
+            // Weaver based user password
+            int weaverSlot = getNextAvailableWeaverSlot();
+            byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
+            if (weaverSecret == null) {
+                Log.e(TAG, "Fail to enroll user password under weaver " + userId);
+                return DEFAULT_HANDLE;
+            }
+            saveWeaverSlot(weaverSlot, handle, userId);
+            synchronizeWeaverFrpPassword(pwd, requestedQuality, userId, weaverSlot);
+
+            pwd.passwordHandle = null;
+            sid = GateKeeper.INVALID_SECURE_USER_ID;
+            applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
+        } else {
+            // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
+            // to prevent them from accumulating and causing problems.
+            gatekeeper.clearSecureUserId(fakeUid(userId));
+            // GateKeeper based user password
+            GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
+                    passwordTokenToGkInput(pwdToken));
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
+                return DEFAULT_HANDLE;
+            }
+            pwd.passwordHandle = response.getPayload();
+            sid = sidFromPasswordHandle(pwd.passwordHandle);
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    createSecdiscardable(handle, userId));
+            synchronizeFrpPassword(pwd, requestedQuality, userId);
+        }
+        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
+                applicationId, sid, userId);
+        return handle;
+    }
+
+    public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
+            String userCredential, int credentialType,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        PersistentData persistentData = mStorage.readPersistentDataBlock();
+        if (persistentData.type == PersistentData.TYPE_SP) {
+            PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
+            byte[] pwdToken = computePasswordToken(userCredential, pwd);
+
+            GateKeeperResponse response = gatekeeper.verify(fakeUid(persistentData.userId),
+                    pwd.passwordHandle, passwordTokenToGkInput(pwdToken));
+            return VerifyCredentialResponse.fromGateKeeperResponse(response);
+        } else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) {
+            PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
+            byte[] pwdToken = computePasswordToken(userCredential, pwd);
+            int weaverSlot = persistentData.userId;
+
+            return weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken)).stripPayload();
+        } else {
+            Log.e(TAG, "persistentData.type must be TYPE_SP or TYPE_SP_WEAVER, but is "
+                    + persistentData.type);
+            return VerifyCredentialResponse.ERROR;
+        }
+    }
+
+
+    private void synchronizeFrpPassword(PasswordData pwd,
+            int requestedQuality, int userId) {
+        if (mStorage.getPersistentDataBlock() != null
+                && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+            if (pwd.passwordType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_SP, userId, requestedQuality,
+                        pwd.toBytes());
+            } else {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, userId, 0, null);
+            }
+        }
+    }
+
+    private void synchronizeWeaverFrpPassword(PasswordData pwd, int requestedQuality, int userId,
+            int weaverSlot) {
+        if (mStorage.getPersistentDataBlock() != null
+                && LockPatternUtils.userOwnsFrpCredential(mUserManager.getUserInfo(userId))) {
+            if (pwd.passwordType != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_WEAVER, weaverSlot,
+                        requestedQuality, pwd.toBytes());
+            } else {
+                mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, 0, 0, null);
+            }
+        }
+    }
+
+    private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
+
+    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
+        long handle = generateHandle();
+        if (!tokenMap.containsKey(userId)) {
+            tokenMap.put(userId, new ArrayMap<>());
+        }
+        TokenData tokenData = new TokenData();
+        final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH);
+        if (isWeaverAvailable()) {
+            tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize);
+            tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret,
+                            PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        } else {
+            tokenData.secdiscardableOnDisk = secdiscardable;
+            tokenData.weaverSecret = null;
+        }
+        tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
+
+        tokenMap.get(userId).put(handle, tokenData);
+        return handle;
+    }
+
+    public Set<Long> getPendingTokensForUser(int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return Collections.emptySet();
+        }
+        return tokenMap.get(userId).keySet();
+    }
+
+    public boolean removePendingToken(long handle, int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        return tokenMap.get(userId).remove(handle) != null;
+    }
+
+    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
+            int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        TokenData tokenData = tokenMap.get(userId).get(handle);
+        if (tokenData == null) {
+            return false;
+        }
+        if (!loadEscrowData(authToken, userId)) {
+            Log.w(TAG, "User is not escrowable");
+            return false;
+        }
+        if (isWeaverAvailable()) {
+            int slot = getNextAvailableWeaverSlot();
+            try {
+                weaverEnroll(slot, null, tokenData.weaverSecret);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to enroll weaver secret when activating token", e);
+                return false;
+            }
+            saveWeaverSlot(slot, handle, userId);
+        }
+        saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
+                tokenData.aggregatedSecret, 0L, userId);
+        tokenMap.get(userId).remove(handle);
+        return true;
+    }
+
+    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
+            byte[] applicationId, long sid, int userId) {
+        final byte[] secret;
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            secret = authToken.computeP0();
+        } else {
+            secret = authToken.syntheticPassword.getBytes();
+        }
+        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
+        byte[] blob = new byte[content.length + 1 + 1];
+        blob[0] = SYNTHETIC_PASSWORD_VERSION;
+        blob[1] = type;
+        System.arraycopy(content, 0, blob, 2, content.length);
+        saveState(SP_BLOB_NAME, blob, handle, userId);
+    }
+
+    /**
+     * 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.
+     */
+    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            long handle, String credential, int userId) throws RemoteException {
+        if (credential == null) {
+            credential = DEFAULT_PASSWORD;
+        }
+        AuthenticationResult result = new AuthenticationResult();
+        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+
+        final byte[] applicationId;
+        int weaverSlot = loadWeaverSlot(handle, userId);
+        if (weaverSlot != INVALID_WEAVER_SLOT) {
+            // Weaver based user password
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap password based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            result.gkResponse = weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken));
+            if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                return result;
+            }
+            applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload());
+        } else {
+            byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
+            GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
+                    pwd.passwordHandle, gkPwdToken);
+            int responseCode = response.getResponseCode();
+            if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+                result.gkResponse = VerifyCredentialResponse.OK;
+                if (response.getShouldReEnroll()) {
+                    GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
+                            pwd.passwordHandle, gkPwdToken, gkPwdToken);
+                    if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                        pwd.passwordHandle = reenrollResponse.getPayload();
+                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+                        synchronizeFrpPassword(pwd,
+                                pwd.passwordType == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                                ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                                : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                                /* TODO(roosa): keep the same password quality */,
+                                userId);
+                    } else {
+                        Log.w(TAG, "Fail to re-enroll user password for user " + userId);
+                        // continue the flow anyway
+                    }
+                }
+            } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+                result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
+                return result;
+            } else  {
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    loadSecdiscardable(handle, userId));
+        }
+
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
+                applicationId, userId);
+
+        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
+        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+        return result;
+    }
+
+    /**
+     * Decrypt a synthetic password by supplying an escrow token and corresponding token
+     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
+     * verification to referesh the SID & Auth token maintained by the system.
+     */
+    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
+            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
+                    throws RemoteException {
+        AuthenticationResult result = new AuthenticationResult();
+        byte[] secdiscardable = loadSecdiscardable(handle, userId);
+        int slotId = loadWeaverSlot(handle, userId);
+        if (slotId != INVALID_WEAVER_SLOT) {
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap token based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            VerifyCredentialResponse response = weaverVerify(slotId, null);
+            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
+                    response.getPayload() == null) {
+                Log.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            secdiscardable = SyntheticPasswordCrypto.decrypt(response.getPayload(),
+                    PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        }
+        byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
+                applicationId, userId);
+        if (result.authToken != null) {
+            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+            if (result.gkResponse == null) {
+                // The user currently has no password. return OK with null payload so null
+                // is propagated to unlockUser()
+                result.gkResponse = VerifyCredentialResponse.OK;
+            }
+        } else {
+            result.gkResponse = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
+            byte[] applicationId, int userId) {
+        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
+        if (blob == null) {
+            return null;
+        }
+        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
+            throw new RuntimeException("Unknown blob version");
+        }
+        if (blob[1] != type) {
+            throw new RuntimeException("Invalid blob type");
+        }
+        byte[] secret = decryptSPBlob(getHandleName(handle),
+                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
+        if (secret == null) {
+            Log.e(TAG, "Fail to decrypt SP for user " + userId);
+            return null;
+        }
+        AuthenticationToken result = new AuthenticationToken();
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            if (!loadEscrowData(result, userId)) {
+                Log.e(TAG, "User is not escrowable: " + userId);
+                return null;
+            }
+            result.recreate(secret);
+        } else {
+            result.syntheticPassword = new String(secret);
+        }
+        return result;
+    }
+
+    /**
+     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
+     * if required.
+     *
+     * Normally performing verifyChallenge with an AuthenticationToken should always return
+     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
+     * decrypt SP.
+     */
+    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
+            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
+        byte[] spHandle = loadSyntheticPasswordHandle(userId);
+        if (spHandle == null) {
+            // There is no password handle associated with the given user, i.e. the user is not
+            // secured by lockscreen and has no SID, so just return here;
+            return null;
+        }
+        VerifyCredentialResponse result;
+        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
+                spHandle, auth.deriveGkPassword());
+        int responseCode = response.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            result = new VerifyCredentialResponse(response.getPayload());
+            if (response.getShouldReEnroll()) {
+                response = gatekeeper.enroll(userId, spHandle,
+                        spHandle, auth.deriveGkPassword());
+                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    spHandle = response.getPayload();
+                    saveSyntheticPasswordHandle(spHandle, userId);
+                    // Call self again to re-verify with updated handle
+                    return verifyChallenge(gatekeeper, auth, challenge, userId);
+                } else {
+                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
+                    // Fall through, return existing handle
+                }
+            }
+        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            result = new VerifyCredentialResponse(response.getTimeout());
+        } else {
+            result = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    public boolean existsHandle(long handle, int userId) {
+        return hasState(SP_BLOB_NAME, handle, userId);
+    }
+
+    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
+    }
+
+    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
+        destroyState(PASSWORD_DATA_NAME, handle, userId);
+    }
+
+    private void destroySyntheticPassword(long handle, int userId) {
+        destroyState(SP_BLOB_NAME, handle, userId);
+        destroySPBlobKey(getHandleName(handle));
+        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
+            destroyWeaverSlot(handle, userId);
+        }
+    }
+
+    private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) {
+        byte[] weaverSecret = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_WEAVER_PASSWORD, secret);
+        byte[] result = new byte[data.length + weaverSecret.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length);
+        return result;
+    }
+
+    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
+        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
+        byte[] result = new byte[data.length + secdiscardable.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
+        return result;
+    }
+
+    private byte[] createSecdiscardable(long handle, int userId) {
+        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
+        saveSecdiscardable(handle, data, userId);
+        return data;
+    }
+
+    private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
+        saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
+    }
+
+    private byte[] loadSecdiscardable(long handle, int userId) {
+        return loadState(SECDISCARDABLE_NAME, handle, userId);
+    }
+
+    private boolean hasState(String stateName, long handle, int userId) {
+        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
+    }
+
+    private byte[] loadState(String stateName, long handle, int userId) {
+        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
+    }
+
+    private void saveState(String stateName, byte[] data, long handle, int userId) {
+        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
+    }
+
+    private void destroyState(String stateName, long handle, int userId) {
+        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
+    }
+
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
+    }
+
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
+    }
+
+    protected void destroySPBlobKey(String keyAlias) {
+        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
+    }
+
+    public static long generateHandle() {
+        SecureRandom rng = new SecureRandom();
+        long result;
+        do {
+            result = rng.nextLong();
+        } while (result == DEFAULT_HANDLE);
+        return result;
+    }
+
+    private int fakeUid(int uid) {
+        return 100000 + uid;
+    }
+
+    protected static byte[] secureRandom(int length) {
+        try {
+            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private String getHandleName(long handle) {
+        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
+    }
+
+    private byte[] computePasswordToken(String password, PasswordData data) {
+        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
+                PASSWORD_TOKEN_LENGTH);
+    }
+
+    private byte[] passwordTokenToGkInput(byte[] token) {
+        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
+    }
+
+    private byte[] passwordTokenToWeaverKey(byte[] token) {
+        byte[] key = SyntheticPasswordCrypto.personalisedHash(PERSONALISATION_WEAVER_KEY, token);
+        if (key.length < mWeaverConfig.keySize) {
+            throw new RuntimeException("weaver key length too small");
+        }
+        return Arrays.copyOf(key, mWeaverConfig.keySize);
+    }
+
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return nativeSidFromPasswordHandle(handle);
+    }
+
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
+    }
+
+    native long nativeSidFromPasswordHandle(byte[] handle);
+    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
+
+    protected static ArrayList<Byte> toByteArrayList(byte[] data) {
+        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
+        for (int i = 0; i < data.length; i++) {
+            result.add(data[i]);
+        }
+        return result;
+    }
+
+    protected static byte[] fromByteArrayList(ArrayList<Byte> data) {
+        byte[] result = new byte[data.size()];
+        for (int i = 0; i < data.size(); i++) {
+            result[i] = data.get(i);
+        }
+        return result;
+    }
+
+    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
+    public static String bytesToHex(byte[] bytes) {
+        if (bytes == null) {
+            return "null";
+        }
+        char[] hexChars = new char[bytes.length * 2];
+        for ( int j = 0; j < bytes.length; j++ ) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = hexArray[v >>> 4];
+            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+}
diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
index c6dc11c..f6f7676 100644
--- a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
@@ -31,17 +31,22 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
- * Monitors changes in audio playback and notify the newly started audio playback through the
- * {@link OnAudioPlaybackStartedListener}.
+ * Monitors changes in audio playback, and notify the newly started audio playback through the
+ * {@link OnAudioPlaybackStartedListener} and the activeness change through the
+ * {@link OnAudioPlaybackActiveStateListener}.
  */
 class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
     private static boolean DEBUG = MediaSessionService.DEBUG;
     private static String TAG = "AudioPlaybackMonitor";
 
+    private static AudioPlaybackMonitor sInstance;
+
     /**
      * Called when audio playback is started for a given UID.
      */
@@ -49,22 +54,36 @@
         void onAudioPlaybackStarted(int uid);
     }
 
+    /**
+     * Called when audio player state is changed.
+     */
+    interface OnAudioPlayerActiveStateChangedListener {
+        void onAudioPlayerActiveStateChanged(int uid, boolean active);
+    }
+
     private final Object mLock = new Object();
     private final Context mContext;
-    private final OnAudioPlaybackStartedListener mListener;
-
-    private Set<Integer> mActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
-    private Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
+    private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners
+            = new ArrayList<>();
+    private final List<OnAudioPlayerActiveStateChangedListener>
+            mAudioPlayerActiveStateChangedListeners = new ArrayList<>();
+    private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>();
+    private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
 
     // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
     // The UID whose audio playback becomes active at the last comes first.
     // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
     private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
 
-    AudioPlaybackMonitor(Context context, IAudioService audioService,
-            OnAudioPlaybackStartedListener listener) {
+    static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) {
+        if (sInstance == null) {
+            sInstance = new AudioPlaybackMonitor(context, audioService);
+        }
+        return sInstance;
+    }
+
+    private AudioPlaybackMonitor(Context context, IAudioService audioService) {
         mContext = context;
-        mListener = listener;
         try {
             audioService.registerPlaybackCallback(this);
         } catch (RemoteException e) {
@@ -84,9 +103,12 @@
     public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
         final long token = Binder.clearCallingIdentity();
         try {
-            Set<Integer> newActiveAudioPlaybackPlayerInterfaceIds = new HashSet<>();
             List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
+            List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners;
+            List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners;
             synchronized (mLock) {
+                // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids,
+                // and find newly activated audio playbacks.
                 mActiveAudioPlaybackClientUids.clear();
                 for (AudioPlaybackConfiguration config : configs) {
                     // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
@@ -94,16 +116,14 @@
                     // playback.
                     // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
                     // specific audio/video players.
-                    if (!config.isActive()
-                            || config.getPlayerType()
+                    if (!config.isActive() || config.getPlayerType()
                             == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                         continue;
                     }
-                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
 
-                    newActiveAudioPlaybackPlayerInterfaceIds.add(config.getPlayerInterfaceId());
-                    if (!mActiveAudioPlaybackPlayerInterfaceIds.contains(
-                            config.getPlayerInterfaceId())) {
+                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
+                    Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId());
+                    if (!isActiveState(oldState)) {
                         if (DEBUG) {
                             Log.d(TAG, "Found a new active media playback. " +
                                     AudioPlaybackConfiguration.toLogFriendlyString(config));
@@ -120,11 +140,32 @@
                         mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
                     }
                 }
-                mActiveAudioPlaybackPlayerInterfaceIds.clear();
-                mActiveAudioPlaybackPlayerInterfaceIds = newActiveAudioPlaybackPlayerInterfaceIds;
+                audioPlayerActiveStateChangedListeners = new ArrayList<>(
+                        mAudioPlayerActiveStateChangedListeners);
+                audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners);
             }
+            // Notify the change of audio playback states.
+            for (AudioPlaybackConfiguration config : configs) {
+                boolean wasActive = isActiveState(
+                        mAudioPlaybackStates.get(config.getPlayerInterfaceId()));
+                boolean isActive = config.isActive();
+                if (wasActive != isActive) {
+                    for (OnAudioPlayerActiveStateChangedListener listener
+                            : audioPlayerActiveStateChangedListeners) {
+                        listener.onAudioPlayerActiveStateChanged(config.getClientUid(),
+                                isActive);
+                    }
+                }
+            }
+            // Notify the start of audio playback
             for (int uid : newActiveAudioPlaybackClientUids) {
-                mListener.onAudioPlaybackStarted(uid);
+                for (OnAudioPlaybackStartedListener listener : audioPlaybackStartedListeners) {
+                    listener.onAudioPlaybackStarted(uid);
+                }
+            }
+            mAudioPlaybackStates.clear();
+            for (AudioPlaybackConfiguration config : configs) {
+                mAudioPlaybackStates.put(config.getPlayerInterfaceId(), config.getPlayerState());
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -132,6 +173,44 @@
     }
 
     /**
+     * Registers OnAudioPlaybackStartedListener.
+     */
+    public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlaybackStartedListener.
+     */
+    public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Registers OnAudioPlayerActiveStateChangedListener.
+     */
+    public void registerOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlayerActiveStateChangedListener.
+     */
+    public void unregisterOnAudioPlayerActiveStateChangedListener(
+            OnAudioPlayerActiveStateChangedListener listener) {
+        synchronized (mLock) {
+            mAudioPlayerActiveStateChangedListeners.remove(listener);
+        }
+    }
+
+    /**
      * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
      * audio/video) The UID whose audio playback becomes active at the last comes first.
      */
@@ -167,7 +246,8 @@
                 if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
                     break;
                 }
-                if (userId == UserHandle.getUserId(mSortedAudioPlaybackClientUids.get(i))) {
+                int uid = mSortedAudioPlaybackClientUids.get(i);
+                if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) {
                     // Clean up unnecessary UIDs.
                     // It doesn't need to be managed profile aware because it's just to prevent
                     // the list from increasing indefinitely. The media button session updating
@@ -198,4 +278,8 @@
             }
         }
     }
+
+    private boolean isActiveState(Integer state) {
+        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
+    }
 }
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 7b0e51e..922df1e 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.server.Watchdog;
+import com.android.server.media.AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener;
 
 import android.Manifest;
 import android.app.ActivityManager;
@@ -26,7 +27,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
+import android.media.IAudioRoutesObserver;
+import android.media.IAudioService;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -39,9 +43,12 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -89,10 +96,54 @@
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords =
             new ArrayMap<IBinder, ClientRecord>();
     private int mCurrentUserId = -1;
+    private boolean mHasBluetoothRoute = false;
+    private final IAudioService mAudioService;
+    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
 
     public MediaRouterService(Context context) {
         mContext = context;
         Watchdog.getInstance().addMonitor(this);
+
+        mAudioService = IAudioService.Stub.asInterface(
+                ServiceManager.getService(Context.AUDIO_SERVICE));
+
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener(
+                new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() {
+            @Override
+            public void onAudioPlayerActiveStateChanged(int uid, boolean active) {
+                if (active) {
+                    restoreRoute(uid);
+                } else {
+                    IntArray sortedAudioPlaybackClientUids =
+                            mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
+                    boolean restored = false;
+                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) {
+                        if (mAudioPlaybackMonitor.isPlaybackActive(
+                                sortedAudioPlaybackClientUids.get(i))) {
+                            restoreRoute(sortedAudioPlaybackClientUids.get(i));
+                            restored = true;
+                            break;
+                        }
+                    }
+                    if (!restored) {
+                        restoreBluetoothA2dp();
+                    }
+                }
+            }
+        });
+        AudioRoutesInfo audioRoutes = null;
+        try {
+            audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
+                @Override
+                public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+                    mHasBluetoothRoute = newRoutes.bluetoothName != null;
+                }
+            });
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException in the audio service.");
+        }
+        mHasBluetoothRoute = (audioRoutes != null && audioRoutes.bluetoothName != null);
     }
 
     public void systemRunning() {
@@ -135,7 +186,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                registerClientLocked(client, pid, packageName, resolvedUserId, trusted);
+                registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -178,6 +229,23 @@
 
     // Binder call
     @Override
+    public boolean isPlaybackActive(IMediaRouterClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                return isPlaybackActiveLocked(client);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -198,7 +266,7 @@
     // A null routeId means that the client wants to unselect its current route.
     // The explicit flag indicates whether the change was explicitly requested by the
     // user or the application which may cause changes to propagate out to the rest
-    // of the system.  Should be false when the change is in response to a new globally
+    // of the system.  Should be false when the change is in response to a new
     // selected route or a default selection.
     @Override
     public void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit) {
@@ -276,6 +344,36 @@
         }
     }
 
+    void restoreBluetoothA2dp() {
+        try {
+            mAudioService.setBluetoothA2dpOn(mHasBluetoothRoute);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException while calling setBluetoothA2dpOn.");
+        }
+    }
+
+    void restoreRoute(int uid) {
+        ClientRecord clientRecord = null;
+        UserRecord userRecord = mUserRecords.get(UserHandle.getUserId(uid));
+        if (userRecord != null && userRecord.mClientRecords != null) {
+            for (ClientRecord cr : userRecord.mClientRecords) {
+                if (validatePackageName(uid, cr.mPackageName)) {
+                    clientRecord = cr;
+                    break;
+                }
+            }
+        }
+        if (clientRecord != null) {
+            try {
+                clientRecord.mClient.onRestoreRoute();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to call onRestoreRoute. Client probably died.");
+            }
+        } else {
+            restoreBluetoothA2dp();
+        }
+    }
+
     void switchUser() {
         synchronized (mLock) {
             int userId = ActivityManager.getCurrentUser();
@@ -304,7 +402,7 @@
     }
 
     private void registerClientLocked(IMediaRouterClient client,
-            int pid, String packageName, int userId, boolean trusted) {
+            int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
         ClientRecord clientRecord = mAllClientRecords.get(binder);
         if (clientRecord == null) {
@@ -314,7 +412,7 @@
                 userRecord = new UserRecord(userId);
                 newUser = true;
             }
-            clientRecord = new ClientRecord(userRecord, client, pid, packageName, trusted);
+            clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted);
             try {
                 binder.linkToDeath(clientRecord, 0);
             } catch (RemoteException ex) {
@@ -350,6 +448,14 @@
         return null;
     }
 
+    private boolean isPlaybackActiveLocked(IMediaRouterClient client) {
+        ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+        if (clientRecord != null) {
+            return mAudioPlaybackMonitor.isPlaybackActive(clientRecord.mUid);
+        }
+        return false;
+    }
+
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -387,15 +493,14 @@
                 }
 
                 clientRecord.mSelectedRouteId = routeId;
-                if (explicit) {
-                    // Any app can disconnect from the globally selected route.
+                // Only let the system connect to new global routes for now.
+                // A similar check exists in the display manager for wifi display.
+                if (explicit && clientRecord.mTrusted) {
                     if (oldRouteId != null) {
                         clientRecord.mUserRecord.mHandler.obtainMessage(
                                 UserHandler.MSG_UNSELECT_ROUTE, oldRouteId).sendToTarget();
                     }
-                    // Only let the system connect to new global routes for now.
-                    // A similar check exists in the display manager for wifi display.
-                    if (routeId != null && clientRecord.mTrusted) {
+                    if (routeId != null) {
                         clientRecord.mUserRecord.mHandler.obtainMessage(
                                 UserHandler.MSG_SELECT_ROUTE, routeId).sendToTarget();
                     }
@@ -490,6 +595,7 @@
     final class ClientRecord implements DeathRecipient {
         public final UserRecord mUserRecord;
         public final IMediaRouterClient mClient;
+        public final int mUid;
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
@@ -499,9 +605,10 @@
         public String mSelectedRouteId;
 
         public ClientRecord(UserRecord userRecord, IMediaRouterClient client,
-                int pid, String packageName, boolean trusted) {
+                int uid, int pid, String packageName, boolean trusted) {
             mUserRecord = userRecord;
             mClient = client;
+            mUid = uid;
             mPid = pid;
             mPackageName = packageName;
             mTrusted = trusted;
@@ -517,7 +624,7 @@
         }
 
         MediaRouterClientState getState() {
-            return mTrusted ? mUserRecord.mTrustedState : mUserRecord.mUntrustedState;
+            return mTrusted ? mUserRecord.mRouterState : null;
         }
 
         public void dump(PrintWriter pw, String prefix) {
@@ -544,8 +651,7 @@
         public final int mUserId;
         public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
         public final UserHandler mHandler;
-        public MediaRouterClientState mTrustedState;
-        public MediaRouterClientState mUntrustedState;
+        public MediaRouterClientState mRouterState;
 
         public UserRecord(int userId) {
             mUserId = userId;
@@ -566,8 +672,7 @@
             }
 
             pw.println(indent + "State");
-            pw.println(indent + "mTrustedState=" + mTrustedState);
-            pw.println(indent + "mUntrustedState=" + mUntrustedState);
+            pw.println(indent + "mRouterState=" + mRouterState);
 
             if (!mHandler.runWithScissors(new Runnable() {
                 @Override
@@ -592,13 +697,6 @@
      * this class encapsulates all of the associated functionality and exports state
      * to the service as it evolves.
      * </p><p>
-     * One important task of this class is to keep track of the current globally selected
-     * route id for certain routes that have global effects, such as remote displays.
-     * Global route selections override local selections made within apps.  The change
-     * is propagated to all apps so that they are all in sync.  Synchronization works
-     * both ways.  Whenever the globally selected route is explicitly unselected by any
-     * app, then it becomes unselected globally and all apps are informed.
-     * </p><p>
      * This class is currently hardcoded to work with remote display providers but
      * it is intended to be eventually extended to support more general route providers
      * similar to the support library media router.
@@ -639,7 +737,7 @@
 
         private boolean mRunning;
         private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
-        private RouteRecord mGloballySelectedRouteRecord;
+        private RouteRecord mSelectedRouteRecord;
         private int mConnectionPhase = PHASE_NOT_AVAILABLE;
         private int mConnectionTimeoutReason;
         private long mConnectionTimeoutStartTime;
@@ -701,7 +799,7 @@
             final String indent = prefix + "  ";
             pw.println(indent + "mRunning=" + mRunning);
             pw.println(indent + "mDiscoveryMode=" + mDiscoveryMode);
-            pw.println(indent + "mGloballySelectedRouteRecord=" + mGloballySelectedRouteRecord);
+            pw.println(indent + "mSelectedRouteRecord=" + mSelectedRouteRecord);
             pw.println(indent + "mConnectionPhase=" + mConnectionPhase);
             pw.println(indent + "mConnectionTimeoutReason=" + mConnectionTimeoutReason);
             pw.println(indent + "mConnectionTimeoutStartTime=" + (mConnectionTimeoutReason != 0 ?
@@ -729,7 +827,7 @@
         private void stop() {
             if (mRunning) {
                 mRunning = false;
-                unselectGloballySelectedRoute();
+                unselectSelectedRoute();
                 mWatcher.stop(); // also stops all providers
             }
         }
@@ -768,15 +866,15 @@
 
         private void selectRoute(String routeId) {
             if (routeId != null
-                    && (mGloballySelectedRouteRecord == null
-                            || !routeId.equals(mGloballySelectedRouteRecord.getUniqueId()))) {
+                    && (mSelectedRouteRecord == null
+                            || !routeId.equals(mSelectedRouteRecord.getUniqueId()))) {
                 RouteRecord routeRecord = findRouteRecord(routeId);
                 if (routeRecord != null) {
-                    unselectGloballySelectedRoute();
+                    unselectSelectedRoute();
 
-                    Slog.i(TAG, "Selected global route:" + routeRecord);
-                    mGloballySelectedRouteRecord = routeRecord;
-                    checkGloballySelectedRouteState();
+                    Slog.i(TAG, "Selected route:" + routeRecord);
+                    mSelectedRouteRecord = routeRecord;
+                    checkSelectedRouteState();
                     routeRecord.getProvider().setSelectedDisplay(routeRecord.getDescriptorId());
 
                     scheduleUpdateClientState();
@@ -786,34 +884,34 @@
 
         private void unselectRoute(String routeId) {
             if (routeId != null
-                    && mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                unselectGloballySelectedRoute();
+                    && mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                unselectSelectedRoute();
             }
         }
 
-        private void unselectGloballySelectedRoute() {
-            if (mGloballySelectedRouteRecord != null) {
-                Slog.i(TAG, "Unselected global route:" + mGloballySelectedRouteRecord);
-                mGloballySelectedRouteRecord.getProvider().setSelectedDisplay(null);
-                mGloballySelectedRouteRecord = null;
-                checkGloballySelectedRouteState();
+        private void unselectSelectedRoute() {
+            if (mSelectedRouteRecord != null) {
+                Slog.i(TAG, "Unselected route:" + mSelectedRouteRecord);
+                mSelectedRouteRecord.getProvider().setSelectedDisplay(null);
+                mSelectedRouteRecord = null;
+                checkSelectedRouteState();
 
                 scheduleUpdateClientState();
             }
         }
 
         private void requestSetVolume(String routeId, int volume) {
-            if (mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                mGloballySelectedRouteRecord.getProvider().setDisplayVolume(volume);
+            if (mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                mSelectedRouteRecord.getProvider().setDisplayVolume(volume);
             }
         }
 
         private void requestUpdateVolume(String routeId, int direction) {
-            if (mGloballySelectedRouteRecord != null
-                    && routeId.equals(mGloballySelectedRouteRecord.getUniqueId())) {
-                mGloballySelectedRouteRecord.getProvider().adjustDisplayVolume(direction);
+            if (mSelectedRouteRecord != null
+                    && routeId.equals(mSelectedRouteRecord.getUniqueId())) {
+                mSelectedRouteRecord.getProvider().adjustDisplayVolume(direction);
             }
         }
 
@@ -839,7 +937,7 @@
                 provider.setCallback(null);
                 provider.setDiscoveryMode(RemoteDisplayState.DISCOVERY_MODE_NONE);
 
-                checkGloballySelectedRouteState();
+                checkSelectedRouteState();
                 scheduleUpdateClientState();
             }
         }
@@ -856,35 +954,34 @@
             if (index >= 0) {
                 ProviderRecord providerRecord = mProviderRecords.get(index);
                 if (providerRecord.updateDescriptor(state)) {
-                    checkGloballySelectedRouteState();
+                    checkSelectedRouteState();
                     scheduleUpdateClientState();
                 }
             }
         }
 
         /**
-         * This function is called whenever the state of the globally selected route
-         * may have changed.  It checks the state and updates timeouts or unselects
-         * the route as appropriate.
+         * This function is called whenever the state of the selected route may have changed.
+         * It checks the state and updates timeouts or unselects the route as appropriate.
          */
-        private void checkGloballySelectedRouteState() {
+        private void checkSelectedRouteState() {
             // Unschedule timeouts when the route is unselected.
-            if (mGloballySelectedRouteRecord == null) {
+            if (mSelectedRouteRecord == null) {
                 mConnectionPhase = PHASE_NOT_AVAILABLE;
                 updateConnectionTimeout(0);
                 return;
             }
 
             // Ensure that the route is still present and enabled.
-            if (!mGloballySelectedRouteRecord.isValid()
-                    || !mGloballySelectedRouteRecord.isEnabled()) {
+            if (!mSelectedRouteRecord.isValid()
+                    || !mSelectedRouteRecord.isEnabled()) {
                 updateConnectionTimeout(TIMEOUT_REASON_NOT_AVAILABLE);
                 return;
             }
 
             // Make sure we haven't lost our connection.
             final int oldPhase = mConnectionPhase;
-            mConnectionPhase = getConnectionPhase(mGloballySelectedRouteRecord.getStatus());
+            mConnectionPhase = getConnectionPhase(mSelectedRouteRecord.getStatus());
             if (oldPhase >= PHASE_CONNECTING && mConnectionPhase < PHASE_CONNECTING) {
                 updateConnectionTimeout(TIMEOUT_REASON_CONNECTION_LOST);
                 return;
@@ -894,15 +991,13 @@
             switch (mConnectionPhase) {
                 case PHASE_CONNECTED:
                     if (oldPhase != PHASE_CONNECTED) {
-                        Slog.i(TAG, "Connected to global route: "
-                                + mGloballySelectedRouteRecord);
+                        Slog.i(TAG, "Connected to route: " + mSelectedRouteRecord);
                     }
                     updateConnectionTimeout(0);
                     break;
                 case PHASE_CONNECTING:
                     if (oldPhase != PHASE_CONNECTING) {
-                        Slog.i(TAG, "Connecting to global route: "
-                                + mGloballySelectedRouteRecord);
+                        Slog.i(TAG, "Connecting to route: " + mSelectedRouteRecord);
                     }
                     updateConnectionTimeout(TIMEOUT_REASON_WAITING_FOR_CONNECTED);
                     break;
@@ -943,7 +1038,7 @@
         }
 
         private void connectionTimedOut() {
-            if (mConnectionTimeoutReason == 0 || mGloballySelectedRouteRecord == null) {
+            if (mConnectionTimeoutReason == 0 || mSelectedRouteRecord == null) {
                 // Shouldn't get here.  There must be a bug somewhere.
                 Log.wtf(TAG, "Handled connection timeout for no reason.");
                 return;
@@ -951,28 +1046,28 @@
 
             switch (mConnectionTimeoutReason) {
                 case TIMEOUT_REASON_NOT_AVAILABLE:
-                    Slog.i(TAG, "Global route no longer available: "
-                            + mGloballySelectedRouteRecord);
+                    Slog.i(TAG, "Selected route no longer available: "
+                            + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_CONNECTION_LOST:
-                    Slog.i(TAG, "Global route connection lost: "
-                            + mGloballySelectedRouteRecord);
+                    Slog.i(TAG, "Selected route connection lost: "
+                            + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_WAITING_FOR_CONNECTING:
-                    Slog.i(TAG, "Global route timed out while waiting for "
+                    Slog.i(TAG, "Selected route timed out while waiting for "
                             + "connection attempt to begin after "
                             + (SystemClock.uptimeMillis() - mConnectionTimeoutStartTime)
-                            + " ms: " + mGloballySelectedRouteRecord);
+                            + " ms: " + mSelectedRouteRecord);
                     break;
                 case TIMEOUT_REASON_WAITING_FOR_CONNECTED:
-                    Slog.i(TAG, "Global route timed out while connecting after "
+                    Slog.i(TAG, "Selected route timed out while connecting after "
                             + (SystemClock.uptimeMillis() - mConnectionTimeoutStartTime)
-                            + " ms: " + mGloballySelectedRouteRecord);
+                            + " ms: " + mSelectedRouteRecord);
                     break;
             }
             mConnectionTimeoutReason = 0;
 
-            unselectGloballySelectedRoute();
+            unselectSelectedRoute();
         }
 
         private void scheduleUpdateClientState() {
@@ -985,30 +1080,17 @@
         private void updateClientState() {
             mClientStateUpdateScheduled = false;
 
-            final String globallySelectedRouteId = mGloballySelectedRouteRecord != null ?
-                    mGloballySelectedRouteRecord.getUniqueId() : null;
-
             // Build a new client state for trusted clients.
-            MediaRouterClientState trustedState = new MediaRouterClientState();
-            trustedState.globallySelectedRouteId = globallySelectedRouteId;
+            MediaRouterClientState routerState = new MediaRouterClientState();
             final int providerCount = mProviderRecords.size();
             for (int i = 0; i < providerCount; i++) {
-                mProviderRecords.get(i).appendClientState(trustedState);
-            }
-
-            // Build a new client state for untrusted clients that can only see
-            // the currently selected route.
-            MediaRouterClientState untrustedState = new MediaRouterClientState();
-            untrustedState.globallySelectedRouteId = globallySelectedRouteId;
-            if (globallySelectedRouteId != null) {
-                untrustedState.routes.add(trustedState.getRoute(globallySelectedRouteId));
+                mProviderRecords.get(i).appendClientState(routerState);
             }
 
             try {
                 synchronized (mService.mLock) {
                     // Update the UserRecord.
-                    mUserRecord.mTrustedState = trustedState;
-                    mUserRecord.mUntrustedState = untrustedState;
+                    mUserRecord.mRouterState = routerState;
 
                     // Collect all clients.
                     final int count = mUserRecord.mClientRecords.size();
@@ -1023,7 +1105,7 @@
                     try {
                         mTempClients.get(i).onStateChanged();
                     } catch (RemoteException ex) {
-                        // ignore errors, client probably died
+                        Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
             } finally {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 38c6157..adb50f0 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -138,19 +138,20 @@
         mKeyguardManager =
                 (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
         mAudioService = getAudioService();
-        mAudioPlaybackMonitor = new AudioPlaybackMonitor(getContext(), mAudioService,
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(getContext(), mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlaybackStartedListener(
                 new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() {
-                    @Override
-                    public void onAudioPlaybackStarted(int uid) {
-                        synchronized (mLock) {
-                            FullUserRecord user =
-                                    getFullUserRecordLocked(UserHandle.getUserId(uid));
-                            if (user != null) {
-                                user.mPriorityStack.updateMediaButtonSessionIfNeeded();
-                            }
-                        }
+            @Override
+            public void onAudioPlaybackStarted(int uid) {
+                synchronized (mLock) {
+                    FullUserRecord user =
+                            getFullUserRecordLocked(UserHandle.getUserId(uid));
+                    if (user != null) {
+                        user.mPriorityStack.updateMediaButtonSessionIfNeeded();
                     }
-                });
+                }
+            }
+        });
         mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 9d92cbc..a6ea6b2 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -111,7 +111,7 @@
             mProjectionGrant.stop();
         }
         if (mMediaRouteInfo != null) {
-            mMediaRouter.getDefaultRoute().select();
+            mMediaRouter.getFallbackRoute().select();
         }
         mProjectionToken = projection.asBinder();
         mProjectionGrant = projection;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ea260a0..0f1cfa5 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3332,7 +3332,7 @@
 
         // Second step: apply bw changes based on change of state.
         if (newRule != oldRule) {
-            if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
+            if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
                 // Temporarily whitelist foreground app, removing from blacklist if necessary
                 // (since bw_penalty_box prevails over bw_happy_box).
 
@@ -3343,7 +3343,7 @@
                 if (isBlacklisted) {
                     setMeteredNetworkBlacklist(uid, false);
                 }
-            } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
+            } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
                 // Remove temporary whitelist from app that is not on foreground anymore.
 
                 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
@@ -3356,18 +3356,18 @@
                 if (isBlacklisted) {
                     setMeteredNetworkBlacklist(uid, true);
                 }
-            } else if ((newRule & RULE_REJECT_METERED) != 0
-                    || (oldRule & RULE_REJECT_METERED) != 0) {
+            } else if (hasRule(newRule, RULE_REJECT_METERED)
+                    || hasRule(oldRule, RULE_REJECT_METERED)) {
                 // Flip state because app was explicitly added or removed to blacklist.
                 setMeteredNetworkBlacklist(uid, isBlacklisted);
-                if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) {
+                if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) {
                     // Since blacklist prevails over whitelist, we need to handle the special case
                     // where app is whitelisted and blacklisted at the same time (although such
                     // scenario should be blocked by the UI), then blacklist is removed.
                     setMeteredNetworkWhitelist(uid, isWhitelisted);
                 }
-            } else if ((newRule & RULE_ALLOW_METERED) != 0
-                    || (oldRule & RULE_ALLOW_METERED) != 0) {
+            } else if (hasRule(newRule, RULE_ALLOW_METERED)
+                    || hasRule(oldRule, RULE_ALLOW_METERED)) {
                 // Flip state because app was explicitly added or removed to whitelist.
                 setMeteredNetworkWhitelist(uid, isWhitelisted);
             } else {
@@ -3480,9 +3480,9 @@
 
         // Second step: notify listeners if state changed.
         if (newRule != oldRule) {
-            if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) {
+            if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
                 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
-            } else if ((newRule & RULE_REJECT_ALL) != 0) {
+            } else if (hasRule(newRule, RULE_REJECT_ALL)) {
                 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
             } else {
                 // All scenarios should have been covered above
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 3ad2dca..421db40 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
-import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.content.Intent.ACTION_SHUTDOWN;
diff --git a/services/core/java/com/android/server/notification/AlertRateLimiter.java b/services/core/java/com/android/server/notification/AlertRateLimiter.java
new file mode 100644
index 0000000..4b168c5
--- /dev/null
+++ b/services/core/java/com/android/server/notification/AlertRateLimiter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.notification;
+
+
+/**
+ * {@hide}
+ */
+public class AlertRateLimiter {
+    static final long ALLOWED_ALERT_INTERVAL = 1000;
+    private long mLastNotificationMillis = 0;
+
+    boolean shouldRateLimitAlert(long now) {
+        final long millisSinceLast = now - mLastNotificationMillis;
+        if (millisSinceLast < 0 || millisSinceLast < ALLOWED_ALERT_INTERVAL) {
+            return true;
+        }
+        mLastNotificationMillis = now;
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 73a365b..5251c78 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -139,6 +139,19 @@
                         || Objects.equals(element, mConfig.secondarySettingName)) {
                     String prevValue = intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
                     String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
+                    int restoredFromSdkInt = intent.getIntExtra(
+                            Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, 0);
+                    if (restoredFromSdkInt < Build.VERSION_CODES.O) {
+                        // automatic system grants were added in O, so append the approved apps
+                        // rather than wiping out the setting
+                        if (!TextUtils.isEmpty(prevValue)) {
+                            if (!TextUtils.isEmpty(newValue)) {
+                                newValue = newValue + ENABLED_SERVICES_SEPARATOR + prevValue;
+                            } else {
+                                newValue = prevValue;
+                            }
+                        }
+                    }
                     settingRestored(element, prevValue, newValue, getSendingUserId());
                 }
             }
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 4981d5c..12b29cf 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -58,6 +58,10 @@
             }
         }
 
+        if (!record.isRecentlyIntrusive()) {
+            return null;
+        }
+
         return new RankingReconsideration(record.getKey(), HANG_TIME_MS) {
             @Override
             public void work() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5ee7ac4..90b3853 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
@@ -132,6 +133,7 @@
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeProto;
+import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -208,7 +210,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;
@@ -519,7 +521,8 @@
         }
     }
 
-    private final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
+    @VisibleForTesting
+    final NotificationDelegate mNotificationDelegate = new NotificationDelegate() {
 
         @Override
         public void onSetDisabled(int status) {
@@ -1011,6 +1014,25 @@
     }
 
     @VisibleForTesting
+    int getNotificationRecordCount() {
+        synchronized (mNotificationLock) {
+            int count = mNotificationList.size() + mNotificationsByKey.size()
+                    + mSummaryByGroupKey.size() + mEnqueuedNotifications.size();
+            // subtract duplicates
+            for (NotificationRecord posted : mNotificationList) {
+                if (mNotificationsByKey.containsKey(posted.getKey())) {
+                    count--;
+                }
+                if (posted.sbn.isGroup() && posted.getNotification().isGroupSummary()) {
+                    count --;
+                }
+            }
+
+            return count;
+        }
+    }
+
+    @VisibleForTesting
     void addNotification(NotificationRecord r) {
         mNotificationList.add(r);
         mNotificationsByKey.put(r.sbn.getKey(), r);
@@ -1054,7 +1076,12 @@
         mIsTelevision = isTelevision;
     }
 
-    // TODO: Tests should call onStart instead once the methods above are removed.
+    @VisibleForTesting
+    void setUsageStats(NotificationUsageStats us) {
+        mUsageStats = us;
+    }
+
+    // TODO: All tests should use this init instead of the one-off setters above.
     @VisibleForTesting
     void init(Looper looper, IPackageManager packageManager, PackageManager packageManagerClient,
             LightsManager lightsManager, NotificationListeners notificationListeners,
@@ -1185,6 +1212,37 @@
         mUserProfiles.updateCache(getContext());
         listenForCallState();
 
+        mSettingsObserver = new SettingsObserver(mHandler);
+
+        mArchive = new Archive(resources.getInteger(
+                R.integer.config_notificationServiceArchiveSize));
+
+        mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
+                || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
+    }
+
+    @Override
+    public void onStart() {
+        SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
+            @Override
+            public void repost(int userId, NotificationRecord r) {
+                try {
+                    if (DBG) {
+                        Slog.d(TAG, "Reposting " + r.getKey());
+                    }
+                    enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
+                            r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
+                            r.sbn.getNotification(), userId);
+                } catch (Exception e) {
+                    Slog.e(TAG, "Cannot un-snooze notification", e);
+                }
+            }
+        }, mUserProfiles);
+
+        init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(),
+                getLocalService(LightsManager.class), new NotificationListeners(),
+                null, snoozeHelper, new NotificationUsageStats(getContext()));
+
         // register for various Intents
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -1222,36 +1280,6 @@
         timeoutFilter.addDataScheme(SCHEME_TIMEOUT);
         getContext().registerReceiver(mNotificationTimeoutReceiver, timeoutFilter);
 
-        mSettingsObserver = new SettingsObserver(mHandler);
-
-        mArchive = new Archive(resources.getInteger(
-                R.integer.config_notificationServiceArchiveSize));
-
-        mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
-                || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
-    }
-
-    @Override
-    public void onStart() {
-        SnoozeHelper snoozeHelper = new SnoozeHelper(getContext(), new SnoozeHelper.Callback() {
-            @Override
-            public void repost(int userId, NotificationRecord r) {
-                try {
-                    if (DBG) {
-                        Slog.d(TAG, "Reposting " + r.getKey());
-                    }
-                    enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
-                            r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
-                            r.sbn.getNotification(), userId);
-                } catch (Exception e) {
-                    Slog.e(TAG, "Cannot un-snooze notification", e);
-                }
-            }
-        }, mUserProfiles);
-
-        init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(),
-                getLocalService(LightsManager.class), new NotificationListeners(),
-                null, snoozeHelper, new NotificationUsageStats(getContext()));
         publishBinderService(Context.NOTIFICATION_SERVICE, mService);
         publishLocalService(NotificationManagerInternal.class, mInternalService);
     }
@@ -3174,6 +3202,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;
@@ -3269,16 +3306,30 @@
     private boolean checkDisqualifyingFeatures(int userId, int callingUid, int id, String tag,
             NotificationRecord r) {
         final String pkg = r.sbn.getPackageName();
+        final String dialerPackage =
+                getContext().getSystemService(TelecomManager.class).getSystemDialerPackage();
         final boolean isSystemNotification =
-                isUidSystemOrPhone(callingUid) || ("android".equals(pkg));
+                isUidSystemOrPhone(callingUid) || ("android".equals(pkg))
+                || TextUtils.equals(pkg, dialerPackage);
         final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
 
         // Limit the number of notifications that any given package except the android
         // 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);
@@ -3290,33 +3341,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;
                 }
             }
         }
@@ -3343,6 +3376,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();
@@ -3678,18 +3737,6 @@
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold =
                 record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
-        final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
-        if (DBG)
-            Slog.v(TAG,
-                    "pkg=" + record.sbn.getPackageName() + " canInterrupt=" + canInterrupt +
-                            " intercept=" + record.isIntercepted()
-            );
-
-        // If we're not supposed to beep, vibrate, etc. then don't.
-        final String disableEffects = disableNotificationEffects(record);
-        if (disableEffects != null) {
-            ZenLog.traceDisableEffects(record, disableEffects);
-        }
 
         // Remember if this notification already owns the notification channels.
         boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
@@ -3699,19 +3746,18 @@
         boolean hasValidSound = false;
 
         if (isNotificationForCurrentUser(record)) {
-            // If the notification will appear in the status bar, it should send an accessibility
-            // event
-            if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
+            // If the notification icon will appear in the status bar, AND it hasn't been blocked
+            // by do-not-disturb, it should generate an accessibility event
+            if (!record.isUpdate
+                    && !record.isIntercepted()
+                    && record.getImportance() > IMPORTANCE_MIN) {
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
             }
-
-            if (disableEffects == null
-                    && canInterrupt
-                    && mSystemReady
-                    && mAudioManager != null) {
-                if (DBG) Slog.v(TAG, "Interrupting!");
+            if (aboveThreshold && mSystemReady && mAudioManager != null) {
+                // this notification wants to make noise & is allowed to make noise
                 Uri soundUri = record.getSound();
                 hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
+
                 long[] vibration = record.getVibration();
                 // Demote sound to vibration if vibration missing & phone in vibration mode.
                 if (vibration == null
@@ -3722,7 +3768,10 @@
                 }
                 hasValidVibrate = vibration != null;
 
-                if (!shouldMuteNotificationLocked(record)) {
+                boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
+
+                if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
+                    if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
                         mSoundNotificationKey = key;
                         if (mInCall) {
@@ -3779,14 +3828,37 @@
 
     @GuardedBy("mNotificationLock")
     boolean shouldMuteNotificationLocked(final NotificationRecord record) {
+        // Suppressed because it's a silent update
         final Notification notification = record.getNotification();
         if(record.isUpdate
                 && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
             return true;
         }
+
+        // muted by listener
+        final String disableEffects = disableNotificationEffects(record);
+        if (disableEffects != null) {
+            ZenLog.traceDisableEffects(record, disableEffects);
+            return true;
+        }
+
+        // suppressed due to DND
+        if (record.isIntercepted()) {
+            return true;
+        }
+
+        // Suppressed because another notification in its group handles alerting
         if (record.sbn.isGroup()) {
             return notification.suppressAlertingDueToGrouping();
         }
+
+        // Suppressed for being too recently noisy
+        final String pkg = record.sbn.getPackageName();
+        if (mUsageStats.isAlertRateLimited(pkg)) {
+            Slog.e(TAG, "Muting recently noisy " + record.getKey());
+            return true;
+        }
+
         return false;
     }
 
@@ -4004,16 +4076,19 @@
             }
             int indexBefore = findNotificationRecordIndexLocked(record);
             boolean interceptBefore = record.isIntercepted();
+            float contactAffinityBefore = record.getContactAffinity();
             int visibilityBefore = record.getPackageVisibilityOverride();
             recon.applyChangesLocked(record);
             applyZenModeLocked(record);
             mRankingHelper.sort(mNotificationList);
             int indexAfter = findNotificationRecordIndexLocked(record);
             boolean interceptAfter = record.isIntercepted();
+            float contactAffinityAfter = record.getContactAffinity();
             int visibilityAfter = record.getPackageVisibilityOverride();
             changed = indexBefore != indexAfter || interceptBefore != interceptAfter
                     || visibilityBefore != visibilityAfter;
-            if (interceptBefore && !interceptAfter) {
+            if (interceptBefore && !interceptAfter
+                    && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) {
                 buzzBeepBlinkLocked(record);
             }
         }
@@ -4193,9 +4268,11 @@
         return (x < low) ? low : ((x > high) ? high : x);
     }
 
+    @VisibleForTesting
     void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
-        AccessibilityManager manager = AccessibilityManager.getInstance(getContext());
-        if (!manager.isEnabled()) {
+        final AccessibilityManager accessibilityManager
+                = AccessibilityManager.getInstance(getContext());
+        if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
             return;
         }
 
@@ -4209,7 +4286,7 @@
             event.getText().add(tickerText);
         }
 
-        manager.sendAccessibilityEvent(event);
+        accessibilityManager.sendAccessibilityEvent(event);
     }
 
     /**
@@ -4506,6 +4583,7 @@
                 canceledNotifications = new ArrayList<>();
             }
             notificationList.remove(i);
+            mNotificationsByKey.remove(r.getKey());
             canceledNotifications.add(r);
             cancelNotificationLocked(r, sendDelete, reason, wasPosted);
         }
@@ -4615,6 +4693,7 @@
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, reason, listenerName);
                 notificationList.remove(i);
+                mNotificationsByKey.remove(childR.getKey());
                 cancelNotificationLocked(childR, sendDelete, reason, wasPosted);
             }
         }
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 365321c..c8f4d31 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -115,6 +115,18 @@
     }
 
     /**
+     * Called when a notification wants to alert.
+     */
+    public synchronized boolean isAlertRateLimited(String packageName) {
+        AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
+        if (stats != null) {
+            return stats.isAlertRateLimited();
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * Called when a notification is tentatively enqueued by an app, before rate checking.
      */
     public synchronized void registerEnqueuedByApp(String packageName) {
@@ -387,7 +399,9 @@
         public ImportanceHistogram quietImportance;
         public ImportanceHistogram finalImportance;
         public RateEstimator enqueueRate;
+        public AlertRateLimiter alertRate;
         public int numRateViolations;
+        public int numAlertViolations;
         public int numQuotaViolations;
         public long mLastAccessTime;
 
@@ -399,6 +413,7 @@
             quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
             finalImportance = new ImportanceHistogram(context, "note_importance_");
             enqueueRate = new RateEstimator();
+            alertRate = new AlertRateLimiter();
         }
 
         public AggregatedStats getPrevious() {
@@ -511,6 +526,7 @@
             maybeCount("note_sub_text", (numWithSubText - previous.numWithSubText));
             maybeCount("note_info_text", (numWithInfoText - previous.numWithInfoText));
             maybeCount("note_over_rate", (numRateViolations - previous.numRateViolations));
+            maybeCount("note_over_alert_rate", (numAlertViolations - previous.numAlertViolations));
             maybeCount("note_over_quota", (numQuotaViolations - previous.numQuotaViolations));
             noisyImportance.maybeCount(previous.noisyImportance);
             quietImportance.maybeCount(previous.quietImportance);
@@ -543,6 +559,7 @@
             previous.numWithSubText = numWithSubText;
             previous.numWithInfoText = numWithInfoText;
             previous.numRateViolations = numRateViolations;
+            previous.numAlertViolations = numAlertViolations;
             previous.numQuotaViolations = numQuotaViolations;
             noisyImportance.update(previous.noisyImportance);
             quietImportance.update(previous.quietImportance);
@@ -577,6 +594,14 @@
             enqueueRate.update(now);
         }
 
+        public boolean isAlertRateLimited() {
+            boolean limited = alertRate.shouldRateLimitAlert(SystemClock.elapsedRealtime());
+            if (limited) {
+                numAlertViolations++;
+            }
+            return limited;
+        }
+
         private String toStringWithIndent(String indent) {
             StringBuilder output = new StringBuilder();
             output.append(indent).append("AggregatedStats{\n");
@@ -635,7 +660,11 @@
             output.append("numWithSubText=").append(numWithSubText).append("\n");
             output.append(indentPlusTwo);
             output.append("numWithInfoText=").append(numWithInfoText).append("\n");
+            output.append(indentPlusTwo);
             output.append("numRateViolations=").append(numRateViolations).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numAlertViolations=").append(numAlertViolations).append("\n");
+            output.append(indentPlusTwo);
             output.append("numQuotaViolations=").append(numQuotaViolations).append("\n");
             output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
             output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
@@ -678,6 +707,7 @@
             maybePut(dump, "numRateViolations", numRateViolations);
             maybePut(dump, "numQuotaLViolations", numQuotaViolations);
             maybePut(dump, "notificationEnqueueRate", getEnqueueRate());
+            maybePut(dump, "numAlertViolations", numAlertViolations);
             noisyImportance.maybePut(dump, previous.noisyImportance);
             quietImportance.maybePut(dump, previous.quietImportance);
             finalImportance.maybePut(dump, previous.finalImportance);
diff --git a/services/core/java/com/android/server/oemlock/OemLock.java b/services/core/java/com/android/server/oemlock/OemLock.java
new file mode 100644
index 0000000..ee70c29
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/OemLock.java
@@ -0,0 +1,27 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+
+abstract class OemLock {
+    abstract void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature);
+    abstract boolean isOemUnlockAllowedByCarrier();
+
+    abstract void setOemUnlockAllowedByDevice(boolean allowedByDevice);
+    abstract boolean isOemUnlockAllowedByDevice();
+}
diff --git a/services/core/java/com/android/server/oemlock/OemLockService.java b/services/core/java/com/android/server/oemlock/OemLockService.java
new file mode 100644
index 0000000..5e19b13
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/OemLockService.java
@@ -0,0 +1,251 @@
+/*
+ * 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.oemlock;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.oemlock.V1_0.IOemLock;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.os.UserManagerInternal.UserRestrictionsListener;
+import android.service.oemlock.IOemLockService;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.pm.UserRestrictionsUtils;
+
+/**
+ * Service for managing the OEM lock state of the device.
+ *
+ * The OemLock HAL will be used if it is available, otherwise the persistent data block will be
+ * used.
+ */
+public class OemLockService extends SystemService {
+    private static final String TAG = "OemLock";
+
+    private static final String FLASH_LOCK_PROP = "ro.boot.flash.locked";
+    private static final String FLASH_LOCK_UNLOCKED = "0";
+
+    private Context mContext;
+    private OemLock mOemLock;
+
+    public static boolean isHalPresent() {
+        return VendorLock.getOemLockHalService() != null;
+    }
+
+    /** Select the OEM lock implementation */
+    private static OemLock getOemLock(Context context) {
+        final IOemLock oemLockHal = VendorLock.getOemLockHalService();
+        if (oemLockHal != null) {
+            Slog.i(TAG, "Using vendor lock via the HAL");
+            return new VendorLock(context, oemLockHal);
+        } else {
+            Slog.i(TAG, "Using persistent data block based lock");
+            return new PersistentDataBlockLock(context);
+        }
+    }
+
+    public OemLockService(Context context) {
+        this(context, getOemLock(context));
+    }
+
+    OemLockService(Context context, OemLock oemLock) {
+        super(context);
+        mContext = context;
+        mOemLock = oemLock;
+
+        LocalServices.getService(UserManagerInternal.class)
+                .addUserRestrictionsListener(mUserRestrictionsListener);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.OEM_LOCK_SERVICE, mService);
+    }
+
+    private final UserRestrictionsListener mUserRestrictionsListener =
+            new UserRestrictionsListener() {
+        @Override
+        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
+                Bundle prevRestrictions) {
+            // The admin can prevent OEM unlock with the DISALLOW_FACTORY_RESET user restriction
+            if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
+                     UserManager.DISALLOW_FACTORY_RESET)) {
+                final boolean unlockAllowedByAdmin =
+                        !newRestrictions.getBoolean(UserManager.DISALLOW_FACTORY_RESET);
+                if (!unlockAllowedByAdmin) {
+                    mOemLock.setOemUnlockAllowedByDevice(false);
+                }
+            }
+        }
+    };
+
+    /**
+     * Implements the binder interface for the service.
+     *
+     * This checks for the relevant permissions before forwarding the call to the OEM lock
+     * implementation being used on this device.
+     */
+    private final IBinder mService = new IOemLockService.Stub() {
+        @Override
+        public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+            enforceManageCarrierOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mOemLock.setOemUnlockAllowedByCarrier(allowed, signature);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByCarrier() {
+            enforceManageCarrierOemUnlockPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+              return mOemLock.isOemUnlockAllowedByCarrier();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        // The user has the final say so if they allow unlock, then the device allows the bootloader
+        // to OEM unlock it.
+        @Override
+        public void setOemUnlockAllowedByUser(boolean allowedByUser) {
+            if (ActivityManager.isUserAMonkey()) {
+                // Prevent a monkey from changing this
+                return;
+            }
+
+            enforceManageUserOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!canUserAllowOemUnlock()) {
+                    throw new SecurityException("User cannot allow OEM unlock");
+                }
+
+                mOemLock.setOemUnlockAllowedByDevice(allowedByUser);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByUser() {
+            enforceManageUserOemUnlockPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mOemLock.isOemUnlockAllowedByDevice();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean canUserAllowOemUnlock() {
+            enforceOemUnlockReadPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return isOemUnlockAllowedByAdmin() && mOemLock.isOemUnlockAllowedByCarrier();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowed() {
+            enforceOemUnlockReadPermission();
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mOemLock.isOemUnlockAllowedByCarrier() &&
+                        mOemLock.isOemUnlockAllowedByDevice();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isDeviceOemUnlocked() {
+            enforceOemUnlockReadPermission();
+
+            String locked = SystemProperties.get(FLASH_LOCK_PROP);
+            switch (locked) {
+                case FLASH_LOCK_UNLOCKED:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    };
+
+    private boolean isOemUnlockAllowedByAdmin() {
+        return !UserManager.get(mContext)
+                .hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET, UserHandle.SYSTEM);
+    }
+
+    private void enforceManageCarrierOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by carrier");
+    }
+
+    private void enforceManageUserOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by user");
+    }
+
+    private void enforceOemUnlockReadPermission() {
+        if (mContext.checkCallingOrSelfPermission(Manifest.permission.READ_OEM_UNLOCK_STATE)
+                == PackageManager.PERMISSION_DENIED
+                && mContext.checkCallingOrSelfPermission(Manifest.permission.OEM_UNLOCK_STATE)
+                == PackageManager.PERMISSION_DENIED) {
+            throw new SecurityException("Can't access OEM unlock state. Requires "
+                    + "READ_OEM_UNLOCK_STATE or OEM_UNLOCK_STATE permission.");
+        }
+    }
+
+    private void enforceUserIsAdmin() {
+        final int userId = UserHandle.getCallingUserId();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (!UserManager.get(mContext).isUserAdmin(userId)) {
+                throw new SecurityException("Must be an admin user");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
new file mode 100644
index 0000000..d9362d4
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
@@ -0,0 +1,92 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.service.persistentdata.PersistentDataBlockManager;
+import android.util.Slog;
+
+/**
+ * Implementation of the OEM lock using the persistent data block to communicate with the
+ * bootloader.
+ *
+ * The carrier flag is stored as a user restriction on the system user. The user flag is set in the
+ * presistent data block but depends on the carrier flag.
+ */
+class PersistentDataBlockLock extends OemLock {
+    private static final String TAG = "OemLock";
+
+    private Context mContext;
+
+    PersistentDataBlockLock(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+        // Note: this implementation does not require a signature
+        if (signature != null) {
+            Slog.w(TAG, "Signature provided but is not being used");
+        }
+
+        // Continue using user restriction for backwards compatibility
+        UserManager.get(mContext).setUserRestriction(
+                UserManager.DISALLOW_OEM_UNLOCK, !allowed, UserHandle.SYSTEM);
+
+        if (!allowed) {
+            disallowUnlockIfNotUnlocked();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByCarrier() {
+        return !UserManager.get(mContext)
+                .hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, UserHandle.SYSTEM);
+    }
+
+    @Override
+    void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
+        // The method name is misleading as it really just means whether or not the device can be
+        // unlocked but doesn't actually do any unlocking.
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+                mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        pdbm.setOemUnlockEnabled(allowedByDevice);
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByDevice() {
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        return pdbm.getOemUnlockEnabled();
+    }
+
+    /**
+     * Update state to prevent the bootloader from being able to unlock the device unless the device
+     * has already been unlocked by the bootloader in which case it is too late as it would remain
+     * unlocked.
+     */
+    private void disallowUnlockIfNotUnlocked() {
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm.getFlashLockState() != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
+            pdbm.setOemUnlockEnabled(false);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/oemlock/VendorLock.java b/services/core/java/com/android/server/oemlock/VendorLock.java
new file mode 100644
index 0000000..1b9de36
--- /dev/null
+++ b/services/core/java/com/android/server/oemlock/VendorLock.java
@@ -0,0 +1,167 @@
+/*
+ * 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.oemlock;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.oemlock.V1_0.IOemLock;
+import android.hardware.oemlock.V1_0.OemLockSecureStatus;
+import android.hardware.oemlock.V1_0.OemLockStatus;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+/**
+ * Uses the OEM lock HAL.
+ */
+class VendorLock extends OemLock {
+    private static final String TAG = "OemLock";
+
+    private Context mContext;
+    private IOemLock mOemLock;
+
+    static IOemLock getOemLockHalService() {
+        try {
+            return IOemLock.getService();
+        } catch (NoSuchElementException e) {
+            Slog.i(TAG, "OemLock HAL not present on device");
+            return null;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    VendorLock(Context context, IOemLock oemLock) {
+        mContext = context;
+        mOemLock = oemLock;
+    }
+
+    @Override
+    void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+        try {
+            switch (mOemLock.setOemUnlockAllowedByCarrier(allowed, toByteArrayList(signature))) {
+                case OemLockSecureStatus.OK:
+                    Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed);
+                    return;
+
+                case OemLockSecureStatus.INVALID_SIGNATURE:
+                    throw new SecurityException(
+                            "Invalid signature used in attempt to carrier unlock");
+
+                default:
+                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                    // Fallthrough
+                case OemLockSecureStatus.FAILED:
+                    throw new RuntimeException("Failed to set carrier OEM unlock state");
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set carrier state with HAL", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByCarrier() {
+        final Integer[] requestStatus = new Integer[1];
+        final Boolean[] allowedByCarrier = new Boolean[1];
+
+        try {
+            mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> {
+                requestStatus[0] = status;
+                allowedByCarrier[0] = allowed;
+            });
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get carrier state from HAL");
+            throw e.rethrowFromSystemServer();
+        }
+
+        switch (requestStatus[0]) {
+            case OemLockStatus.OK:
+                // Success
+                return allowedByCarrier[0];
+
+            default:
+                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                // Fallthrough
+            case OemLockStatus.FAILED:
+                throw new RuntimeException("Failed to get carrier OEM unlock state");
+        }
+    }
+
+    @Override
+    void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
+        try {
+            switch (mOemLock.setOemUnlockAllowedByDevice(allowedByDevice)) {
+                case OemLockSecureStatus.OK:
+                    Slog.i(TAG, "Updated device allows OEM lock state to: " + allowedByDevice);
+                    return;
+
+                default:
+                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                    // Fallthrough
+                case OemLockSecureStatus.FAILED:
+                    throw new RuntimeException("Failed to set device OEM unlock state");
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set device state with HAL", e);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    boolean isOemUnlockAllowedByDevice() {
+        final Integer[] requestStatus = new Integer[1];
+        final Boolean[] allowedByDevice = new Boolean[1];
+
+        try {
+            mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> {
+                requestStatus[0] = status;
+                allowedByDevice[0] = allowed;
+            });
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get devie state from HAL");
+            throw e.rethrowFromSystemServer();
+        }
+
+        switch (requestStatus[0]) {
+            case OemLockStatus.OK:
+                // Success
+                return allowedByDevice[0];
+
+            default:
+                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
+                // Fallthrough
+            case OemLockStatus.FAILED:
+                throw new RuntimeException("Failed to get device OEM unlock state");
+        }
+    }
+
+    private ArrayList toByteArrayList(byte[] data) {
+        if (data == null) {
+            return null;
+        }
+        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
+        for (final byte b : data) {
+            result.add(b);
+        }
+        return result;
+    }
+}
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index 46be232..e0b8426 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -57,7 +57,7 @@
             try {
                 // make good use of our CAP_SYS_NICE capability
                 Process.setThreadGroup(tid, !isForApp ?
-                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
+                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_RT_APP);
             } catch (RuntimeException e) {
                 Log.e(TAG, "Failed setThreadGroup: " + e);
                 return PackageManager.PERMISSION_DENIED;
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index d1aecb1..b217677 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageParser;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
+import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Environment;
@@ -701,6 +702,16 @@
                         LOCATION_PERMISSIONS, true, userId);
             }
 
+            // Ringtone Picker
+            Intent ringtonePickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+            PackageParser.Package ringtonePickerPackage =
+                    getDefaultSystemHandlerActivityPackageLPr(ringtonePickerIntent, userId);
+            if (ringtonePickerPackage != null
+                    && doesPackageSupportRuntimePermissions(ringtonePickerPackage)) {
+                grantRuntimePermissionsLPw(ringtonePickerPackage,
+                        STORAGE_PERMISSIONS, true, userId);
+            }
+
             mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
         }
     }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c95b5c5..5c4c040 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -310,6 +310,16 @@
         }
     }
 
+    public boolean copySystemProfile(String systemProfile, int uid, String packageName)
+            throws InstallerException {
+        if (!checkBeforeRemote()) return false;
+        try {
+            return mInstalld.copySystemProfile(systemProfile, uid, packageName);
+        } catch (Exception e) {
+            throw InstallerException.from(e);
+        }
+    }
+
     public void idmap(String targetApkPath, String overlayApkPath, int uid)
             throws InstallerException {
         if (!checkBeforeRemote()) return;
diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java
index 5092ebf..f326f1d 100644
--- a/services/core/java/com/android/server/pm/InstructionSets.java
+++ b/services/core/java/com/android/server/pm/InstructionSets.java
@@ -34,7 +34,7 @@
  */
 public class InstructionSets {
     private static final String PREFERRED_INSTRUCTION_SET =
-            VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);;
+            VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
     public static String[] getAppDexInstructionSets(ApplicationInfo info) {
         if (info.primaryCpuAbi != null) {
             if (info.secondaryCpuAbi != null) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 62b563a..bf64f64 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -865,7 +865,7 @@
             for (int i = 0; i < mSessions.size(); i++) {
                 final PackageInstallerSession session = mSessions.valueAt(i);
                 if (session.userId == userId) {
-                    result.add(session.generateInfo());
+                    result.add(session.generateInfo(false));
                 }
             }
         }
@@ -883,7 +883,7 @@
                 final PackageInstallerSession session = mSessions.valueAt(i);
                 if (Objects.equals(session.installerPackageName, installerPackageName)
                         && session.userId == userId) {
-                    result.add(session.generateInfo());
+                    result.add(session.generateInfo(false));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index f111db1..5c54ba8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -288,6 +288,10 @@
     }
 
     public SessionInfo generateInfo() {
+        return generateInfo(true);
+    }
+
+    public SessionInfo generateInfo(boolean includeIcon) {
         final SessionInfo info = new SessionInfo();
         synchronized (mLock) {
             info.sessionId = sessionId;
@@ -302,7 +306,9 @@
             info.installReason = params.installReason;
             info.sizeBytes = params.sizeBytes;
             info.appPackageName = params.appPackageName;
-            info.appIcon = params.appIcon;
+            if (includeIcon) {
+                info.appIcon = params.appIcon;
+            }
             info.appLabel = params.appLabel;
         }
         return info;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2b3bfc8..c971369 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -132,6 +132,7 @@
 import android.content.pm.ChangedPackages;
 import android.content.pm.FallbackCategoryProvider;
 import android.content.pm.FeatureInfo;
+import android.content.pm.IDexModuleRegisterCallback;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -3996,20 +3997,69 @@
     }
 
     @Override
-    public PermissionInfo getPermissionInfo(String name, int flags) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return null;
         }
         // reader
         synchronized (mPackages) {
             final BasePermission p = mSettings.mPermissions.get(name);
-            if (p != null) {
-                return generatePermissionInfo(p, flags);
+            if (p == null) {
+                return null;
             }
-            return null;
+            // If the caller is an app that targets pre 26 SDK drop protection flags.
+            final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
+            if (permissionInfo != null) {
+                permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
+                        permissionInfo.protectionLevel, packageName, callingUid);
+            }
+            return permissionInfo;
         }
     }
 
+    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
+            String packageName, int uid) {
+        // Signature permission flags area always reported
+        final int protectionLevelMasked = protectionLevel
+                & (PermissionInfo.PROTECTION_NORMAL
+                | PermissionInfo.PROTECTION_DANGEROUS
+                | PermissionInfo.PROTECTION_SIGNATURE);
+        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
+            return protectionLevel;
+        }
+
+        // System sees all flags.
+        final int appId = UserHandle.getAppId(uid);
+        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
+                || appId == Process.SHELL_UID) {
+            return protectionLevel;
+        }
+
+        // Normalize package name to handle renamed packages and static libs
+        packageName = resolveInternalPackageNameLPr(packageName,
+                PackageManager.VERSION_CODE_HIGHEST);
+
+        // Apps that target O see flags for all protection levels.
+        final PackageSetting ps = mSettings.mPackages.get(packageName);
+        if (ps == null) {
+            return protectionLevel;
+        }
+        if (ps.appId != appId) {
+            return protectionLevel;
+        }
+
+        final PackageParser.Package pkg = mPackages.get(packageName);
+        if (pkg == null) {
+            return protectionLevel;
+        }
+        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+            return protectionLevelMasked;
+        }
+
+        return protectionLevel;
+    }
+
     @Override
     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
             int flags) {
@@ -4228,10 +4278,7 @@
                     volumeUuid);
             final boolean aggressive = (storageFlags
                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
-            final boolean defyReserved = (storageFlags
-                    & StorageManager.FLAG_ALLOCATE_DEFY_RESERVED) != 0;
-            final long reservedBytes = (aggressive || defyReserved) ? 0
-                    : storage.getStorageCacheBytes(file);
+            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
 
             // 1. Pre-flight to determine if we have any chance to succeed
             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
@@ -8891,9 +8938,12 @@
             }
         }
 
-        boolean updatedPkgBetter = false;
+        final boolean isUpdatedPkg = updatedPkg != null;
+        final boolean isUpdatedSystemPkg = isUpdatedPkg
+                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
+        boolean isUpdatedPkgBetter = false;
         // First check if this is a system package that may involve an update
-        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
+        if (isUpdatedSystemPkg) {
             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
             // it needs to drop FLAG_PRIVILEGED.
             if (locationIsPrivileged(scanFile)) {
@@ -8937,10 +8987,6 @@
                             updatedChildPkg.versionCode = pkg.mVersionCode;
                         }
                     }
-
-                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
-                            + scanFile + " ignored: updated version " + ps.versionCode
-                            + " better than this " + pkg.mVersionCode);
                 } else {
                     // The current app on the system partition is better than
                     // what we have updated to on the data partition; switch
@@ -8967,12 +9013,44 @@
                     synchronized (mPackages) {
                         mSettings.enableSystemPackageLPw(ps.name);
                     }
-                    updatedPkgBetter = true;
+                    isUpdatedPkgBetter = true;
                 }
             }
         }
 
-        if (updatedPkg != null) {
+        String resourcePath = null;
+        String baseResourcePath = null;
+        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
+            if (ps != null && ps.resourcePathString != null) {
+                resourcePath = ps.resourcePathString;
+                baseResourcePath = ps.resourcePathString;
+            } else {
+                // Should not happen at all. Just log an error.
+                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
+            }
+        } else {
+            resourcePath = pkg.codePath;
+            baseResourcePath = pkg.baseCodePath;
+        }
+
+        // Set application objects path explicitly.
+        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+        pkg.setApplicationInfoCodePath(pkg.codePath);
+        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+        pkg.setApplicationInfoResourcePath(resourcePath);
+        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
+        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+
+        // throw an exception if we have an update to a system application, but, it's not more
+        // recent than the package we've already scanned
+        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
+            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
+                    + scanFile + " ignored: updated version " + ps.versionCode
+                    + " better than this " + pkg.mVersionCode);
+        }
+
+        if (isUpdatedPkg) {
             // An updated system app will not have the PARSE_IS_SYSTEM flag set
             // initially
             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
@@ -8992,7 +9070,7 @@
          * same name installed earlier.
          */
         boolean shouldHideSystemApp = false;
-        if (updatedPkg == null && ps != null
+        if (!isUpdatedPkg && ps != null
                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
             /*
              * Check to make sure the signatures match first. If they don't,
@@ -9047,31 +9125,6 @@
             }
         }
 
-        // TODO: extend to support forward-locked splits
-        String resourcePath = null;
-        String baseResourcePath = null;
-        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
-            if (ps != null && ps.resourcePathString != null) {
-                resourcePath = ps.resourcePathString;
-                baseResourcePath = ps.resourcePathString;
-            } else {
-                // Should not happen at all. Just log an error.
-                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
-            }
-        } else {
-            resourcePath = pkg.codePath;
-            baseResourcePath = pkg.baseCodePath;
-        }
-
-        // Set application objects path explicitly.
-        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
-        pkg.setApplicationInfoCodePath(pkg.codePath);
-        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
-        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
-        pkg.setApplicationInfoResourcePath(resourcePath);
-        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
-        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
-
         final int userId = ((user == null) ? 0 : user.getIdentifier());
         if (ps != null && ps.getInstantApp(userId)) {
             scanFlags |= SCAN_AS_INSTANT_APP;
@@ -9249,6 +9302,13 @@
         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
     }
 
+    /*
+     * Return the prebuilt profile path given a package base code path.
+     */
+    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
+        return pkg.baseCodePath + ".prof";
+    }
+
     /**
      * Performs dexopt on the set of packages in {@code packages} and returns an int array
      * containing statistics about the invocation. The array consists of three elements,
@@ -9267,6 +9327,27 @@
         for (PackageParser.Package pkg : pkgs) {
             numberOfPackagesVisited++;
 
+            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
+                // Copy over initial preopt profiles since we won't get any JIT samples for methods
+                // that are already compiled.
+                File profileFile = new File(getPrebuildProfilePath(pkg));
+                // Copy profile if it exists.
+                if (profileFile.exists()) {
+                    try {
+                        // We could also do this lazily before calling dexopt in
+                        // PackageDexOptimizer to prevent this happening on first boot. The issue
+                        // is that we don't have a good way to say "do this only once".
+                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
+                                pkg.applicationInfo.uid, pkg.packageName)) {
+                            Log.e(TAG, "Installer failed to copy system profile!");
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
+                                e);
+                    }
+                }
+            }
+
             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
                 if (DEBUG_DEXOPT) {
                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
@@ -9370,6 +9451,31 @@
     }
 
     @Override
+    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
+            IDexModuleRegisterCallback callback) {
+        int userId = UserHandle.getCallingUserId();
+        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
+        DexManager.RegisterDexModuleResult result;
+        if (ai == null) {
+            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
+                     " calling user. package=" + packageName + ", user=" + userId);
+            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
+        } else {
+            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
+        }
+
+        if (callback != null) {
+            mHandler.post(() -> {
+                try {
+                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
+                }
+            });
+        }
+    }
+
+    @Override
     public boolean performDexOpt(String packageName,
             boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
@@ -18954,8 +19060,9 @@
                 }
             }
             if (removedAppId >= 0) {
-                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
-                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
+                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
+                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
+                    null, null, broadcastUsers);
             }
         }
 
@@ -23509,7 +23616,10 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                mCloseGuard.warnIfOpen();
+                if (mCloseGuard != null) {
+                    mCloseGuard.warnIfOpen();
+                }
+
                 close();
             } finally {
                 super.finalize();
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f3a292b..20d7b28 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1018,7 +1018,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser);
+            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
             PrintWriter pw = getOutPrintWriter();
             if (ri == null) {
                 pw.println("No activity found");
@@ -1040,7 +1040,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1074,7 +1074,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
@@ -1108,7 +1108,7 @@
             throw new RuntimeException(e.getMessage(), e);
         }
         try {
-            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
                     mTargetUser).getList();
             PrintWriter pw = getOutPrintWriter();
             if (result == null || result.size() <= 0) {
diff --git a/services/core/java/com/android/server/pm/ShortcutDumpFiles.java b/services/core/java/com/android/server/pm/ShortcutDumpFiles.java
new file mode 100644
index 0000000..dc380cc
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutDumpFiles.java
@@ -0,0 +1,105 @@
+/*
+ * 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.pm;
+
+import android.util.Slog;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.function.Consumer;
+
+public class ShortcutDumpFiles {
+    private static final String TAG = ShortcutService.TAG;
+    private static final boolean DEBUG = ShortcutService.DEBUG;
+    private final ShortcutService mService;
+
+    public ShortcutDumpFiles(ShortcutService service) {
+        mService = service;
+    }
+
+    public boolean save(String filename, Consumer<PrintWriter> dumper) {
+        try {
+            final File directory = mService.getDumpPath();
+            directory.mkdirs();
+            if (!directory.exists()) {
+                Slog.e(TAG, "Failed to create directory: " + directory);
+                return false;
+            }
+
+            final File path = new File(directory, filename);
+
+            if (DEBUG) {
+                Slog.d(TAG, "Dumping to " + path);
+            }
+
+            try (PrintWriter pw = new PrintWriter(new BufferedOutputStream(
+                    new FileOutputStream(path)))) {
+                dumper.accept(pw);
+            }
+            return true;
+        } catch (RuntimeException|IOException e) {
+            Slog.w(TAG, "Failed to create dump file: " + filename, e);
+            return false;
+        }
+    }
+
+    public boolean save(String filename, byte[] utf8bytes) {
+        return save(filename, pw -> pw.println(StandardCharsets.UTF_8.decode(
+                ByteBuffer.wrap(utf8bytes)).toString()));
+    }
+
+    public void dumpAll(PrintWriter pw) {
+        try {
+            final File directory = mService.getDumpPath();
+            final File[] files = directory.listFiles(f -> f.isFile());
+            if (!directory.exists() || ArrayUtils.isEmpty(files)) {
+                pw.print("  No dump files found.");
+                return;
+            }
+            Arrays.sort(files, Comparator.comparing(f -> f.getName()));
+
+            for (File path : files) {
+                pw.print("*** Dumping: ");
+                pw.println(path.getName());
+
+                pw.print("mtime: ");
+                pw.println(ShortcutService.formatTime(path.lastModified()));
+
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(path)))) {
+                    String line = null;
+                    while ((line = reader.readLine()) != null) {
+                        pw.println(line);
+                    }
+                }
+            }
+        } catch (RuntimeException|IOException e) {
+            Slog.w(TAG, "Failed to print dump files", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 103b25d..6f70f4c 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -150,6 +150,10 @@
                 getPackageName(), getPackageUserId());
     }
 
+    public int getShortcutCount() {
+        return mShortcuts.size();
+    }
+
     @Override
     protected void onRestoreBlocked() {
         // Can't restore due to version/signature mismatch.  Remove all shortcuts.
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 6d48a05..7911972 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -181,6 +181,9 @@
     static final String DIRECTORY_PER_USER = "shortcut_service";
 
     @VisibleForTesting
+    static final String DIRECTORY_DUMP = "shortcut_dump";
+
+    @VisibleForTesting
     static final String FILENAME_USER_PACKAGES = "shortcuts.xml";
 
     static final String DIRECTORY_BITMAPS = "bitmaps";
@@ -308,6 +311,7 @@
 
     private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
     private final ShortcutBitmapSaver mShortcutBitmapSaver;
+    private final ShortcutDumpFiles mShortcutDumpFiles;
 
     @GuardedBy("mLock")
     final SparseIntArray mUidState = new SparseIntArray();
@@ -429,6 +433,7 @@
 
         mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
         mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
+        mShortcutDumpFiles = new ShortcutDumpFiles(this);
 
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
@@ -3395,6 +3400,16 @@
                 wtf("Can't restore: user " + userId + " is locked or not running");
                 return;
             }
+
+            // Note we print the file timestamps in dumpsys too, but also printing the timestamp
+            // in the files anyway.
+            mShortcutDumpFiles.save("restore-0-start.txt", pw -> {
+                pw.print("Start time: ");
+                dumpCurrentTime(pw);
+                pw.println();
+            });
+            mShortcutDumpFiles.save("restore-1-payload.xml", payload);
+
             // Actually do restore.
             final ShortcutUser restored;
             final ByteArrayInputStream is = new ByteArrayInputStream(payload);
@@ -3404,13 +3419,25 @@
                 Slog.w(TAG, "Restoration failed.", e);
                 return;
             }
+            mShortcutDumpFiles.save("restore-2.txt", this::dumpInner);
+
             getUserShortcutsLocked(userId).mergeRestoredFile(restored);
 
+            mShortcutDumpFiles.save("restore-3.txt", this::dumpInner);
+
             // Rescan all packages to re-publish manifest shortcuts and do other checks.
             rescanUpdatedPackagesLocked(userId,
                     0 // lastScanTime = 0; rescan all packages.
                     );
 
+            mShortcutDumpFiles.save("restore-4.txt", this::dumpInner);
+
+            mShortcutDumpFiles.save("restore-5-finish.txt", pw -> {
+                pw.print("Finish time: ");
+                dumpCurrentTime(pw);
+                pw.println();
+            });
+
             saveUserLocked(userId);
         }
     }
@@ -3425,23 +3452,54 @@
 
     @VisibleForTesting
     void dumpNoCheck(FileDescriptor fd, PrintWriter pw, String[] args) {
+
+        boolean dumpMain = true;
         boolean checkin = false;
         boolean clear = false;
+        boolean dumpUid = false;
+        boolean dumpFiles = false;
+
         if (args != null) {
             for (String arg : args) {
                 if ("-c".equals(arg)) {
                     checkin = true;
+
                 } else if ("--checkin".equals(arg)) {
                     checkin = true;
                     clear = true;
+
+                } else if ("-a".equals(arg) || "--all".equals(arg)) {
+                    dumpUid = true;
+                    dumpFiles = true;
+
+                } else if ("-u".equals(arg) || "--uid".equals(arg)) {
+                    dumpUid = true;
+
+                } else if ("-f".equals(arg) || "--files".equals(arg)) {
+                    dumpFiles = true;
+
+                } else if ("-n".equals(arg) || "--no-main".equals(arg)) {
+                    dumpMain = false;
                 }
             }
         }
 
         if (checkin) {
+            // Other flags are not supported for checkin.
             dumpCheckin(pw, clear);
         } else {
-            dumpInner(pw);
+            if (dumpMain) {
+                dumpInner(pw);
+                pw.println();
+            }
+            if (dumpUid) {
+                dumpUid(pw);
+                pw.println();
+            }
+            if (dumpFiles) {
+                dumpDumpFiles(pw);
+                pw.println();
+            }
         }
     }
 
@@ -3510,9 +3568,12 @@
                 pw.println();
                 mUsers.valueAt(i).dump(pw, "  ");
             }
+        }
+    }
 
-            pw.println();
-            pw.println("  UID state:");
+    private void dumpUid(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("** SHORTCUT MANAGER UID STATES (dumpsys shortcut -n -u)");
 
             for (int i = 0; i < mUidState.size(); i++) {
                 final int uid = mUidState.keyAt(i);
@@ -3537,6 +3598,10 @@
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
 
+    private void dumpCurrentTime(PrintWriter pw) {
+        pw.print(formatTime(injectCurrentTimeMillis()));
+    }
+
     private void dumpStatLS(PrintWriter pw, String prefix, int statId) {
         pw.print(prefix);
         final int count = mCountStats[statId];
@@ -3574,6 +3639,13 @@
         }
     }
 
+    private void dumpDumpFiles(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("** SHORTCUT MANAGER FILES (dumpsys shortcut -n -f)");
+            mShortcutDumpFiles.dumpAll(pw);
+        }
+    }
+
     // === Shell support ===
 
     @Override
@@ -3876,6 +3948,10 @@
         return new File(Environment.getDataSystemCeDirectory(userId), DIRECTORY_PER_USER);
     }
 
+    public File getDumpPath() {
+        return new File(injectUserDataPath(UserHandle.USER_SYSTEM), DIRECTORY_DUMP);
+    }
+
     @VisibleForTesting
     boolean injectIsLowRamDevice() {
         return ActivityManager.isLowRamDeviceStatic();
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 5d4bfa4..2c388c4 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -25,9 +25,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.server.pm.ShortcutService.InvalidFileFormatException;
@@ -492,6 +490,10 @@
         // without users interaction it's really not a big deal, so we just clear existing
         // ShortcutLauncher instances in mLaunchers and add all the restored ones here.
 
+        int[] restoredLaunchers = new int[1];
+        int[] restoredPackages = new int[1];
+        int[] restoredShortcuts = new int[1];
+
         mLaunchers.clear();
         restored.forAllLaunchers(sl -> {
             // If the app is already installed and allowbackup = false, then ignore the restored
@@ -501,6 +503,7 @@
                 return;
             }
             addLauncher(sl);
+            restoredLaunchers[0]++;
         });
         restored.forAllPackages(sp -> {
             // If the app is already installed and allowbackup = false, then ignore the restored
@@ -516,10 +519,16 @@
                         + " Existing non-manifeset shortcuts will be overwritten.");
             }
             addPackage(sp);
+            restoredPackages[0]++;
+            restoredShortcuts[0] += sp.getShortcutCount();
         });
         // Empty the launchers and packages in restored to avoid accidentally using them.
         restored.mLaunchers.clear();
         restored.mPackages.clear();
+
+        Slog.i(TAG, "Restored: L=" + restoredLaunchers[0]
+                + " P=" + restoredPackages[0]
+                + " S=" + restoredShortcuts[0]);
     }
 
     public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b115422..132b845 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -223,6 +223,7 @@
     // Tron counters
     private static final String TRON_GUEST_CREATED = "users_guest_created";
     private static final String TRON_USER_CREATED = "users_user_created";
+    private static final String TRON_DEMO_CREATED = "users_demo_created";
 
     private final Context mContext;
     private final PackageManagerService mPm;
@@ -2523,7 +2524,8 @@
             addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
             mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
                     android.Manifest.permission.MANAGE_USERS);
-            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);
+            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED
+                    : (isDemo ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -3650,7 +3652,7 @@
         public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
             UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL, null);
             // Keep this in sync with UserManager.createUser
-            if (user != null && !user.isAdmin()) {
+            if (user != null && !user.isAdmin() && !user.isDemo()) {
                 setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
                 setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id);
             }
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index c6667a7..a6b05d7 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -31,7 +31,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.service.persistentdata.PersistentDataBlockManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.util.Log;
@@ -519,22 +518,6 @@
                             android.provider.Settings.Global.SAFE_BOOT_DISALLOWED,
                             newValue ? 1 : 0);
                     break;
-                case UserManager.DISALLOW_FACTORY_RESET:
-                case UserManager.DISALLOW_OEM_UNLOCK:
-                    if (newValue) {
-                        PersistentDataBlockManager manager = (PersistentDataBlockManager) context
-                                .getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
-                        if (manager != null
-                                && manager.getOemUnlockEnabled()
-                                && manager.getFlashLockState()
-                                        != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
-                            // Only disable OEM unlock if the bootloader is locked. If it's already
-                            // unlocked, setting the OEM unlock enabled flag to false has no effect
-                            // (the bootloader would remain unlocked).
-                            manager.setOemUnlockEnabled(false);
-                        }
-                    }
-                    break;
             }
         } finally {
             Binder.restoreCallingIdentity(id);
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 9b44646..be50eee 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -30,6 +30,7 @@
 import com.android.server.pm.Installer;
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.PackageDexOptimizer;
+import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.PackageManagerServiceUtils;
 import com.android.server.pm.PackageManagerServiceCompilerMapping;
 
@@ -41,6 +42,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.dex.PackageDexUsage.PackageUseInfo;
 import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo;
 
@@ -437,6 +439,52 @@
         }
     }
 
+    public RegisterDexModuleResult registerDexModule(ApplicationInfo info, String dexPath,
+            boolean isUsedByOtherApps, int userId) {
+        // Find the owning package record.
+        DexSearchResult searchResult = getDexPackage(info, dexPath, userId);
+
+        if (searchResult.mOutcome == DEX_SEARCH_NOT_FOUND) {
+            return new RegisterDexModuleResult(false, "Package not found");
+        }
+        if (!info.packageName.equals(searchResult.mOwningPackageName)) {
+            return new RegisterDexModuleResult(false, "Dex path does not belong to package");
+        }
+        if (searchResult.mOutcome == DEX_SEARCH_FOUND_PRIMARY ||
+                searchResult.mOutcome == DEX_SEARCH_FOUND_SPLIT) {
+            return new RegisterDexModuleResult(false, "Main apks cannot be registered");
+        }
+
+        // We found the package. Now record the usage for all declared ISAs.
+        boolean update = false;
+        Set<String> isas = new HashSet<>();
+        for (String isa : getAppDexInstructionSets(info)) {
+            isas.add(isa);
+            boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
+                dexPath, userId, isa, isUsedByOtherApps, /*primaryOrSplit*/ false);
+            update |= newUpdate;
+        }
+        if (update) {
+            mPackageDexUsage.maybeWriteAsync();
+        }
+
+        // Try to optimize the package according to the install reason.
+        String compilerFilter = PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+                PackageManagerService.REASON_INSTALL);
+        int result = mPackageDexOptimizer.dexOptSecondaryDexPath(info, dexPath, isas,
+                compilerFilter, isUsedByOtherApps);
+
+        // If we fail to optimize the package log an error but don't propagate the error
+        // back to the app. The app cannot do much about it and the background job
+        // will rety again when it executes.
+        // TODO(calin): there might be some value to return the error here but it may
+        // cause red herrings since that doesn't mean the app cannot use the module.
+        if (result != PackageDexOptimizer.DEX_OPT_FAILED) {
+            Slog.e(TAG, "Failed to optimize dex module " + dexPath);
+        }
+        return new RegisterDexModuleResult(true, "Dex module registered successfully");
+    }
+
     /**
      * Return all packages that contain records of secondary dex files.
      */
@@ -518,6 +566,20 @@
         return existingValue == null ? newValue : existingValue;
     }
 
+    public static class RegisterDexModuleResult {
+        public RegisterDexModuleResult() {
+            this(false, null);
+        }
+
+        public RegisterDexModuleResult(boolean success, String message) {
+            this.success = success;
+            this.message = message;
+        }
+
+        public final boolean success;
+        public final String message;
+    }
+
     /**
      * Convenience class to store the different locations where a package might
      * own code.
@@ -597,6 +659,4 @@
             return mOwningPackageName + "-" + mOutcome;
         }
     }
-
-
 }
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
index 3e5e57b..0b54e5e 100644
--- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
+++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
@@ -78,6 +78,7 @@
 
     public AccessibilityShortcutController(Context context, Handler handler, int initialUserId) {
         mContext = context;
+        mUserId = initialUserId;
 
         // Keep track of state of shortcut settings
         final ContentObserver co = new ContentObserver(handler) {
@@ -153,7 +154,7 @@
             // Don't check if haptics are disabled, as we need to alert the user that their
             // way of interacting with the phone may change if they activate the shortcut
             long[] vibePattern = PhoneWindowManager.getLongIntArray(mContext.getResources(),
-                    R.array.config_safeModeDisabledVibePattern);
+                    R.array.config_longPressVibePattern);
             vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
         }
 
diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
index ebb9450..c6ec287 100644
--- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
@@ -19,6 +19,7 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -79,7 +80,7 @@
     boolean mVrModeEnabled = false;
 
     public ImmersiveModeConfirmation(Context context) {
-        mContext = context;
+        mContext = ActivityThread.currentActivityThread().getSystemUiContext();
         mHandler = new H();
         mShowDelayMs = getNavBarExitDuration() * 3;
         mPanicThresholdMs = context.getResources()
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index a71bc4c..14fabc5 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -228,6 +228,7 @@
                 R.string.global_actions_airplane_mode_on_status,
                 R.string.global_actions_airplane_mode_off_status) {
 
+            @Override
             void onToggle(boolean on) {
                 if (mHasTelephony && Boolean.parseBoolean(
                         SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
@@ -254,10 +255,12 @@
                 }
             }
 
+            @Override
             public boolean showDuringKeyguard() {
                 return true;
             }
 
+            @Override
             public boolean showBeforeProvisioning() {
                 return false;
             }
@@ -457,6 +460,7 @@
             return false;
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
@@ -616,6 +620,7 @@
                             com.android.internal.R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
                             + (isCurrentUser ? " \u2714" : "")) {
+                        @Override
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -624,10 +629,12 @@
                             }
                         }
 
+                        @Override
                         public boolean showDuringKeyguard() {
                             return true;
                         }
 
+                        @Override
                         public boolean showBeforeProvisioning() {
                             return false;
                         }
@@ -659,6 +666,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onDismiss(DialogInterface dialog) {
         if (mOnDismiss != null) {
             mOnDismiss.run();
@@ -674,6 +682,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onClick(DialogInterface dialog, int which) {
         if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
             dialog.dismiss();
@@ -689,6 +698,7 @@
      */
     private class MyAdapter extends BaseAdapter {
 
+        @Override
         public int getCount() {
             int count = 0;
 
@@ -716,6 +726,7 @@
             return false;
         }
 
+        @Override
         public Action getItem(int position) {
 
             int filteredPos = 0;
@@ -740,11 +751,12 @@
                     + ", provisioned=" + mDeviceProvisioned);
         }
 
-
+        @Override
         public long getItemId(int position) {
             return position;
         }
 
+        @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
             return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
@@ -817,6 +829,7 @@
             mIcon = icon;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -825,8 +838,10 @@
             return null;
         }
 
+        @Override
         abstract public void onPress();
 
+        @Override
         public CharSequence getLabelForAccessibility(Context context) {
             if (mMessage != null) {
                 return mMessage;
@@ -835,6 +850,7 @@
             }
         }
 
+        @Override
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_item, parent, false);
@@ -929,6 +945,7 @@
             return context.getString(mMessageResId);
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             willCreate();
@@ -963,6 +980,7 @@
             return v;
         }
 
+        @Override
         public final void onPress() {
             if (mState.inTransition()) {
                 Log.w(TAG, "shouldn't be able to toggle when in transition");
@@ -974,6 +992,7 @@
             changeStateFromPress(nowOn);
         }
 
+        @Override
         public boolean isEnabled() {
             return !mState.inTransition();
         }
@@ -1004,6 +1023,7 @@
                     R.string.global_action_silent_mode_off_status);
         }
 
+        @Override
         void onToggle(boolean on) {
             if (on) {
                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
@@ -1012,10 +1032,12 @@
             }
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
@@ -1050,6 +1072,7 @@
             return null;
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
@@ -1065,17 +1088,21 @@
             return v;
         }
 
+        @Override
         public void onPress() {
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -1083,6 +1110,7 @@
         void willCreate() {
         }
 
+        @Override
         public void onClick(View v) {
             if (!(v.getTag() instanceof Integer)) return;
 
@@ -1093,6 +1121,7 @@
     }
 
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
@@ -1146,6 +1175,7 @@
     private static final int DIALOG_DISMISS_DELAY = 300; // ms
 
     private Handler mHandler = new Handler() {
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case MESSAGE_DISMISS:
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8112f99..ae78d7c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -358,10 +358,6 @@
     private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER =
             "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver";
 
-    private static final int NAV_BAR_BOTTOM = 0;
-    private static final int NAV_BAR_RIGHT = 1;
-    private static final int NAV_BAR_LEFT = 2;
-
     /**
      * Keyguard stuff
      */
@@ -432,27 +428,12 @@
     // Vibrator pattern for haptic feedback of a long press.
     long[] mLongPressVibePattern;
 
-    // Vibrator pattern for haptic feedback of virtual key press.
-    long[] mVirtualKeyVibePattern;
-
-    // Vibrator pattern for a short vibration.
-    long[] mKeyboardTapVibePattern;
-
-    // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
-    long[] mClockTickVibePattern;
-
     // Vibrator pattern for a short vibration when tapping on a day/month/year date of a Calendar.
     long[] mCalendarDateVibePattern;
 
-    // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
-    long[] mSafeModeDisabledVibePattern;
-
     // Vibrator pattern for haptic feedback during boot when safe mode is enabled.
     long[] mSafeModeEnabledVibePattern;
 
-    // Vibrator pattern for haptic feedback of a context click.
-    long[] mContextClickVibePattern;
-
     /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
     boolean mEnableShiftMenuBugReports = false;
 
@@ -515,6 +496,7 @@
     volatile boolean mEndCallKeyHandled;
     volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
     volatile boolean mGoingToSleep;
+    volatile boolean mRequestedOrGoingToSleep;
     volatile boolean mRecentsVisible;
     volatile boolean mPictureInPictureVisible;
     // Written by vr manager thread, only read in this class.
@@ -575,7 +557,7 @@
     int mPanicPressOnBackBehavior;
     int mShortPressOnSleepBehavior;
     int mShortPressWindowBehavior;
-    boolean mAwake;
+    volatile boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
     ScreenOnListener mScreenOnListener;
@@ -835,6 +817,7 @@
     private static final int MSG_BUGREPORT_TV = 22;
     private static final int MSG_ACCESSIBILITY_TV = 23;
     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
+    private static final int MSG_SYSTEM_KEY_PRESS = 25;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -924,6 +907,9 @@
                 case MSG_DISPATCH_BACK_KEY_TO_AUTOFILL:
                     mAutofillManagerInternal.onBackKeyPressed();
                     break;
+                case MSG_SYSTEM_KEY_PRESS:
+                    sendSystemKeyToStatusBar(msg.arg1);
+                    break;
             }
         }
     }
@@ -1289,11 +1275,14 @@
         if (gestureService != null) {
             gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
                     mTmpBoolean);
-            if (mTmpBoolean.value && mGoingToSleep) {
+            if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
                 mCameraGestureTriggeredDuringGoingToSleep = true;
             }
         }
 
+        // Inform the StatusBar; but do not allow it to consume the event.
+        sendSystemKeyToStatusBarAsync(event.getKeyCode());
+
         // If the power key has still not yet been handled, then detect short
         // press, long press, or multi press and decide what to do.
         mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
@@ -1348,7 +1337,7 @@
                 Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
                         interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
                 msg.setAsynchronous(true);
-                mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
+                mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
                 return;
             }
 
@@ -1414,17 +1403,14 @@
                 case SHORT_PRESS_POWER_NOTHING:
                     break;
                 case SHORT_PRESS_POWER_GO_TO_SLEEP:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     break;
                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
-                    mPowerManager.goToSleep(eventTime,
-                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+                    goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                     launchHomeFromHotKey();
                     break;
@@ -1449,6 +1435,11 @@
         }
     }
 
+    private void goToSleep(long eventTime, int reason, int flags) {
+        mRequestedOrGoingToSleep = true;
+        mPowerManager.goToSleep(eventTime, reason, flags);
+    }
+
     private void shortPressPowerGoHome() {
         launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
         if (isKeyguardShowingAndNotOccluded()) {
@@ -1481,8 +1472,7 @@
                             Settings.Global.THEATER_MODE_ON, 1);
 
                     if (mGoToSleepOnButtonPressTheaterMode && interactive) {
-                        mPowerManager.goToSleep(eventTime,
-                                PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+                        goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                     }
                 }
                 break;
@@ -1565,8 +1555,7 @@
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
             case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
                 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
-                mPowerManager.goToSleep(eventTime,
-                       PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
+                goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
                 break;
         }
     }
@@ -1689,8 +1678,17 @@
     }
 
     boolean isUserSetupComplete() {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+        boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+        if (mHasFeatureLeanback) {
+            isSetupComplete &= isTvUserSetupComplete();
+        }
+        return isSetupComplete;
+    }
+
+    private boolean isTvUserSetupComplete() {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
     }
 
     private void handleShortPressOnHome() {
@@ -2071,20 +2069,10 @@
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_longPressVibePattern);
-        mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_virtualKeyVibePattern);
-        mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_keyboardTapVibePattern);
-        mClockTickVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_clockTickVibePattern);
         mCalendarDateVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_calendarDateVibePattern);
-        mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_safeModeDisabledVibePattern);
         mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_safeModeEnabledVibePattern);
-        mContextClickVibePattern = getLongIntArray(mContext.getResources(),
-                com.android.internal.R.array.config_contextClickVibePattern);
 
         mScreenshotChordEnabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_enableScreenshotChord);
@@ -3173,10 +3161,18 @@
 
     @Override
     public void selectRotationAnimationLw(int anim[]) {
+        // If the screen is off or non-interactive, force a jumpcut.
+        final boolean forceJumpcut = !mScreenOnFully || !okToAnimate();
         if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
                 + mTopFullscreenOpaqueWindowState + " rotationAnimation="
                 + (mTopFullscreenOpaqueWindowState == null ?
-                        "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation));
+                        "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)
+                + " forceJumpcut=" + forceJumpcut);
+        if (forceJumpcut) {
+            anim[0] = R.anim.rotation_animation_jump_exit;
+            anim[1] = R.anim.rotation_animation_enter;
+            return;
+        }
         if (mTopFullscreenOpaqueWindowState != null) {
             int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint();
             if (animationHint < 0 && mTopIsFullscreen) {
@@ -4189,7 +4185,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = false;
             try {
                 if (event instanceof MotionEvent
@@ -5059,17 +5055,27 @@
                 // A window that has requested to fill the entire screen just
                 // gets everything, period.
                 if (attrs.type == TYPE_STATUS_BAR_PANEL
-                        || attrs.type == TYPE_STATUS_BAR_SUB_PANEL
-                        || attrs.type == TYPE_VOLUME_OVERLAY) {
+                        || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
                     pf.left = df.left = of.left = cf.left = hasNavBar
                             ? mDockLeft : mUnrestrictedScreenLeft;
                     pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
                     pf.right = df.right = of.right = cf.right = hasNavBar
-                                        ? mRestrictedScreenLeft+mRestrictedScreenWidth
-                                        : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
+                            ? mRestrictedScreenLeft + mRestrictedScreenWidth
+                            : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar
-                                          ? mRestrictedScreenTop+mRestrictedScreenHeight
-                                          : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
+                            ? mRestrictedScreenTop + mRestrictedScreenHeight
+                            : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
+                    if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
+                            "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
+                            pf.left, pf.top, pf.right, pf.bottom));
+                } else if (attrs.type == TYPE_VOLUME_OVERLAY) {
+                    // Volume overlay covers everything, including the status and navbar
+                    pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft;
+                    pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop;
+                    pf.right = df.right = of.right = cf.right =
+                            mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
+                    pf.bottom = df.bottom = of.bottom = cf.bottom =
+                            mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
                     if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
                                     "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
                                     pf.left, pf.top, pf.right, pf.bottom));
@@ -5404,7 +5410,7 @@
             // represent should be hidden or if we should hide the lockscreen. For attached app
             // windows we defer the decision to the window it is attached to.
             if (appWindow && attached == null) {
-                if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) {
+                if (attrs.isFullscreen() && StackId.normallyFullscreenWindows(stackId)) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
                     if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -5443,7 +5449,7 @@
         // separately, because both the "real fullscreen" opaque window and the one for the docked
         // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
         if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null
-                && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) {
+                && attrs.isFullscreen() && stackId == DOCKED_STACK_ID) {
             mTopDockedOpaqueWindowState = win;
             if (mTopDockedOpaqueOrDimmingWindowState == null) {
                 mTopDockedOpaqueOrDimmingWindowState = win;
@@ -5468,12 +5474,6 @@
         }
     }
 
-    private boolean isFullscreen(WindowManager.LayoutParams attrs) {
-        return attrs.x == 0 && attrs.y == 0
-                && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
-                && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
-    }
-
     /** {@inheritDoc} */
     @Override
     public int finishPostLayoutPolicyLw() {
@@ -5980,6 +5980,8 @@
                     }
                 }
                 if (down) {
+                    sendSystemKeyToStatusBarAsync(event.getKeyCode());
+
                     TelecomManager telecomManager = getTelecommService();
                     if (telecomManager != null) {
                         if (telecomManager.isRinging()) {
@@ -6017,7 +6019,6 @@
                                 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
                         break;
                     }
-
                 }
                 if (mUseTvRouting || mHandleVolumeKeysInWM) {
                     // Defer special key handlings to
@@ -6060,7 +6061,7 @@
                             }
                             if ((mEndcallBehavior
                                     & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
-                                mPowerManager.goToSleep(event.getEventTime(),
+                                goToSleep(event.getEventTime(),
                                         PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                                 isWakeKey = false;
                             }
@@ -6223,20 +6224,36 @@
             if (!mAccessibilityManager.isEnabled()
                     || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) {
                 if (areSystemNavigationKeysEnabled()) {
-                    IStatusBarService sbar = getStatusBarService();
-                    if (sbar != null) {
-                        try {
-                            sbar.handleSystemNavigationKey(event.getKeyCode());
-                        } catch (RemoteException e1) {
-                            // oops, no statusbar. Ignore event.
-                        }
-                    }
+                    sendSystemKeyToStatusBarAsync(event.getKeyCode());
                 }
             }
         }
     }
 
     /**
+     * Notify the StatusBar that a system key was pressed.
+     */
+    private void sendSystemKeyToStatusBar(int keyCode) {
+        IStatusBarService statusBar = getStatusBarService();
+        if (statusBar != null) {
+            try {
+                statusBar.handleSystemKey(keyCode);
+            } catch (RemoteException e) {
+                // Oh well.
+            }
+        }
+    }
+
+    /**
+     * Notify the StatusBar that a system key was pressed without blocking the current thread.
+     */
+    private void sendSystemKeyToStatusBarAsync(int keyCode) {
+        Message message = mHandler.obtainMessage(MSG_SYSTEM_KEY_PRESS, keyCode, 0);
+        message.setAsynchronous(true);
+        mHandler.sendMessage(message);
+    }
+
+    /**
      * Returns true if the key can have global actions attached to it.
      * We reserve all power management keys for the system since they require
      * very careful handling.
@@ -6553,8 +6570,10 @@
     @Override
     public void startedGoingToSleep(int why) {
         if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
-        mCameraGestureTriggeredDuringGoingToSleep = false;
+
         mGoingToSleep = true;
+        mRequestedOrGoingToSleep = true;
+
         if (mKeyguardDelegate != null) {
             mKeyguardDelegate.onStartedGoingToSleep(why);
         }
@@ -6568,6 +6587,7 @@
         MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
 
         mGoingToSleep = false;
+        mRequestedOrGoingToSleep = false;
 
         // We must get this work done here because the power manager will drop
         // the wake lock and let the system suspend once this function returns.
@@ -6611,6 +6631,10 @@
     @Override
     public void finishedWakingUp() {
         if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
+
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.onFinishedWakingUp();
+        }
     }
 
     private void wakeUpFromPowerKey(long eventTime) {
@@ -6719,6 +6743,11 @@
     @Override
     public void screenTurningOff(ScreenOffListener screenOffListener) {
         mWindowManagerFuncs.screenTurningOff(screenOffListener);
+        synchronized (mLock) {
+            if (mKeyguardDelegate != null) {
+                mKeyguardDelegate.onScreenTurningOff();
+            }
+        }
     }
 
     private void reportScreenStateToVrManager(boolean isScreenOn) {
@@ -6814,6 +6843,11 @@
         }
     }
 
+    @Override
+    public boolean okToAnimate() {
+        return mAwake && !mGoingToSleep;
+    }
+
     /** {@inheritDoc} */
     @Override
     public void enableKeyguard(boolean enabled) {
@@ -6939,6 +6973,12 @@
     }
 
     @Override
+    public int getNavBarPosition() {
+        // TODO(multi-display): Support system decor on secondary displays.
+        return mNavigationBarPosition;
+    }
+
+    @Override
     public boolean isDockSideAllowed(int dockSide) {
 
         // We do not allow all dock sides at which the navigation bar touches the docked stack.
@@ -7013,6 +7053,12 @@
                 // Ignore sensor when demo rotation lock is enabled.
                 // Note that the dock orientation and HDMI rotation lock override this.
                 preferredRotation = mDemoRotation;
+            } else if (mPersistentVrModeEnabled) {
+                // While in VR, apps always prefer a portrait rotation. This does not change
+                // any apps that explicitly set landscape, but does cause sensors be ignored,
+                // and ignored any orientation lock that the user has set (this conditional
+                // should remain above the ORIENTATION_LOCKED conditional below).
+                preferredRotation = mPortraitRotation;
             } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
                 // Application just wants to remain locked in the last rotation.
                 preferredRotation = lastRotation;
@@ -7043,13 +7089,7 @@
                         || mAllowAllRotations == 1
                         || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
                         || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
-                    // In VrMode, we report the sensor as always being in default orientation so:
-                    // 1) The orientation doesn't change as the user moves their head.
-                    // 2) 2D apps within VR show in the device's default orientation.
-                    // This only overwrites the sensor-provided orientation and does not affect any
-                    // explicit orientation preferences specified by any activities.
-                    preferredRotation =
-                            mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation;
+                    preferredRotation = sensorRotation;
                 } else {
                     preferredRotation = lastRotation;
                 }
@@ -7193,9 +7233,9 @@
     @Override
     public void setSafeMode(boolean safeMode) {
         mSafeMode = safeMode;
-        performHapticFeedbackLw(null, safeMode
-                ? HapticFeedbackConstants.SAFE_MODE_ENABLED
-                : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
+        if (safeMode) {
+            performHapticFeedbackLw(null, HapticFeedbackConstants.SAFE_MODE_ENABLED, true);
+        }
     }
 
     static long[] getLongIntArray(Resources r, int resid) {
@@ -7462,8 +7502,7 @@
 
     private void applyLidSwitchState() {
         if (mLidState == LID_CLOSED && mLidControlsSleep) {
-            mPowerManager.goToSleep(SystemClock.uptimeMillis(),
-                    PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
+            goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
                     PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
         } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
             mWindowManagerFuncs.lockDeviceNow();
@@ -7710,20 +7749,19 @@
             case HapticFeedbackConstants.KEYBOARD_TAP:
                 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
             case HapticFeedbackConstants.CLOCK_TICK:
-                pattern = mClockTickVibePattern;
-                break;
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
             case HapticFeedbackConstants.CALENDAR_DATE:
                 pattern = mCalendarDateVibePattern;
                 break;
-            case HapticFeedbackConstants.SAFE_MODE_DISABLED:
-                pattern = mSafeModeDisabledVibePattern;
-                break;
             case HapticFeedbackConstants.SAFE_MODE_ENABLED:
                 pattern = mSafeModeEnabledVibePattern;
                 break;
             case HapticFeedbackConstants.CONTEXT_CLICK:
-                pattern = mContextClickVibePattern;
-                break;
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
+            case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE:
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
+            case HapticFeedbackConstants.TEXT_HANDLE_MOVE:
+                return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
             default:
                 return null;
         }
@@ -7824,21 +7862,17 @@
     }
 
     private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
-        WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded
-                ? mStatusBar
-                : opaqueOrDimming;
-
-        if (statusColorWin != null) {
-            if (statusColorWin == opaque) {
-                // If the top fullscreen-or-dimming window is also the top fullscreen, respect
-                // its light flag.
-                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-                vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
-                        & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            } else if (statusColorWin != null && statusColorWin.isDimming()) {
-                // Otherwise if it's dimming, clear the light flag.
-                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            }
+        final boolean onKeyguard = isStatusBarKeyguard() && !mKeyguardOccluded;
+        final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
+        if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
+            // If the top fullscreen-or-dimming window is also the top fullscreen, respect
+            // its light flag.
+            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+            vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null)
+                    & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else if (statusColorWin != null && statusColorWin.isDimming()) {
+            // Otherwise if it's dimming, clear the light flag.
+            vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
         }
         return vis;
     }
@@ -7848,7 +7882,7 @@
         final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw();
 
         final WindowState navColorWin;
-        if (imeWin != null && imeWin.isVisibleLw()) {
+        if (imeWin != null && imeWin.isVisibleLw() && mNavigationBarPosition == NAV_BAR_BOTTOM) {
             navColorWin = imeWin;
         } else {
             navColorWin = opaqueOrDimming;
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 0121ee1..50e5e7b 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -35,10 +35,12 @@
     private static final int SCREEN_STATE_OFF = 0;
     private static final int SCREEN_STATE_TURNING_ON = 1;
     private static final int SCREEN_STATE_ON = 2;
+    private static final int SCREEN_STATE_TURNING_OFF = 3;
 
     private static final int INTERACTIVE_STATE_SLEEP = 0;
-    private static final int INTERACTIVE_STATE_AWAKE = 1;
-    private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2;
+    private static final int INTERACTIVE_STATE_WAKING = 1;
+    private static final int INTERACTIVE_STATE_AWAKE = 2;
+    private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 3;
 
     protected KeyguardServiceWrapper mKeyguardService;
     private final Context mContext;
@@ -164,9 +166,13 @@
                     mKeyguardService.setCurrentUser(mKeyguardState.currentUser);
                 }
                 // This is used to hide the scrim once keyguard displays.
-                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE
+                        || mKeyguardState.interactiveState == INTERACTIVE_STATE_WAKING) {
                     mKeyguardService.onStartedWakingUp();
                 }
+                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+                    mKeyguardService.onFinishedWakingUp();
+                }
                 if (mKeyguardState.screenState == SCREEN_STATE_ON
                         || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
                     mKeyguardService.onScreenTurningOn(
@@ -277,9 +283,25 @@
             if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
             mKeyguardService.onStartedWakingUp();
         }
+        mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING;
+    }
+
+    public void onFinishedWakingUp() {
+        if (mKeyguardService != null) {
+            if (DEBUG) Log.v(TAG, "onFinishedWakingUp()");
+            mKeyguardService.onFinishedWakingUp();
+        }
         mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
     }
 
+    public void onScreenTurningOff() {
+        if (mKeyguardService != null) {
+            if (DEBUG) Log.v(TAG, "onScreenTurningOff()");
+            mKeyguardService.onScreenTurningOff();
+        }
+        mKeyguardState.screenState = SCREEN_STATE_TURNING_OFF;
+    }
+
     public void onScreenTurnedOff() {
         if (mKeyguardService != null) {
             if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 425be54..952e0b0 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -128,6 +128,15 @@
     }
 
     @Override
+    public void onFinishedWakingUp() {
+        try {
+            mService.onFinishedWakingUp();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    @Override
     public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
         try {
             mService.onScreenTurningOn(callback);
@@ -146,6 +155,15 @@
     }
 
     @Override
+    public void onScreenTurningOff() {
+        try {
+            mService.onScreenTurningOff();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    @Override
     public void onScreenTurnedOff() {
         try {
             mService.onScreenTurnedOff();
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index f5bb082..0ecf0e1 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
-import android.app.RetailDemoModeServiceInternal;
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
@@ -94,7 +93,6 @@
     private final ActivityManagerInternal mActivityManagerInternal;
     private final InputManagerInternal mInputManagerInternal;
     private final InputMethodManagerInternal mInputMethodManagerInternal;
-    private final RetailDemoModeServiceInternal mRetailDemoModeServiceInternal;
 
     private final NotifierHandler mHandler;
     private final Intent mScreenOnIntent;
@@ -140,7 +138,6 @@
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
         mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
-        mRetailDemoModeServiceInternal = LocalServices.getService(RetailDemoModeServiceInternal.class);
 
         mHandler = new NotifierHandler(looper);
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -587,9 +584,6 @@
             }
             mUserActivityPending = false;
         }
-        if (mRetailDemoModeServiceInternal != null) {
-            mRetailDemoModeServiceInternal.onUserActivity();
-        }
         mPolicy.userActivity();
     }
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 1f4517e..855c055 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -53,6 +53,7 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
@@ -197,6 +198,9 @@
     // System property indicating that the screen should remain off until an explicit user action
     private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
 
+    // System Property indicating that retail demo mode is currently enabled.
+    private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
+
     // Possible reasons for shutting down for use in data/misc/reboot/last_shutdown_reason
     private static final String REASON_SHUTDOWN = "shutdown";
     private static final String REASON_REBOOT = "reboot";
@@ -805,6 +809,9 @@
         resolver.registerContentObserver(Settings.Secure.getUriFor(
                 Settings.Secure.DOUBLE_TAP_TO_WAKE),
                 false, mSettingsObserver, UserHandle.USER_ALL);
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.DEVICE_DEMO_MODE),
+                false, mSettingsObserver, UserHandle.USER_SYSTEM);
         IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
         if (vrManager != null) {
             try {
@@ -912,6 +919,11 @@
             }
         }
 
+        final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0";
+        if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) {
+            SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
+        }
+
         final int oldScreenBrightnessSetting = getCurrentBrightnessSettingLocked();
 
         mScreenBrightnessForVrSetting = Settings.System.getIntForUser(resolver,
@@ -1398,13 +1410,16 @@
         try {
             switch (mWakefulness) {
                 case WAKEFULNESS_ASLEEP:
-                    Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from sleep (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DREAMING:
-                    Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dream (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DOZING:
-                    Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dozing (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
             }
 
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 02f2afc..0f61171 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -20,17 +20,22 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.IActivityManager;
+import android.app.KeyguardManager;
 import android.app.ProgressDialog;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.IBluetoothManager;
-import android.media.AudioAttributes;
-import android.nfc.NfcAdapter;
-import android.nfc.INfcAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.media.AudioAttributes;
+import android.nfc.INfcAdapter;
+import android.nfc.NfcAdapter;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.PowerManager;
@@ -39,24 +44,24 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.SystemVibrator;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.Vibrator;
-import android.os.SystemVibrator;
-import android.os.storage.IStorageShutdownObserver;
 import android.os.storage.IStorageManager;
-import android.system.ErrnoException;
-import android.system.Os;
+import android.os.storage.IStorageShutdownObserver;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.server.LocalServices;
 import com.android.server.pm.PackageManagerService;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
-import android.util.Log;
-import android.view.WindowManager;
-
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 
 public final class ShutdownThread extends Thread {
@@ -243,15 +248,7 @@
         shutdownInner(context, confirm);
     }
 
-    private static void beginShutdownSequence(Context context) {
-        synchronized (sIsStartedGuard) {
-            if (sIsStarted) {
-                Log.d(TAG, "Shutdown sequence already running, returning.");
-                return;
-            }
-            sIsStarted = true;
-        }
-
+    private static ProgressDialog showShutdownDialog(Context context) {
         // Throw up a system dialog to indicate the device is rebooting / shutting down.
         ProgressDialog pd = new ProgressDialog(context);
 
@@ -293,6 +290,9 @@
                 pd.setMessage(context.getText(
                             com.android.internal.R.string.reboot_to_update_prepare));
             } else {
+                if (showSysuiReboot()) {
+                    return null;
+                }
                 pd.setIndeterminate(true);
                 pd.setMessage(context.getText(
                             com.android.internal.R.string.reboot_to_update_reboot));
@@ -301,9 +301,12 @@
             // Factory reset path. Set the dialog message accordingly.
             pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
             pd.setMessage(context.getText(
-                        com.android.internal.R.string.reboot_to_reset_message));
+                    com.android.internal.R.string.reboot_to_reset_message));
             pd.setIndeterminate(true);
         } else {
+            if (showSysuiReboot()) {
+                return null;
+            }
             pd.setTitle(context.getText(com.android.internal.R.string.power_off));
             pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
             pd.setIndeterminate(true);
@@ -312,8 +315,36 @@
         pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
 
         pd.show();
+        return pd;
+    }
 
-        sInstance.mProgressDialog = pd;
+    private static boolean showSysuiReboot() {
+        Log.d(TAG, "Attempting to use SysUI shutdown UI");
+        try {
+            StatusBarManagerInternal service = LocalServices.getService(
+                    StatusBarManagerInternal.class);
+            if (service.showShutdownUi(mReboot, mReason)) {
+                // Sysui will handle shutdown UI.
+                Log.d(TAG, "SysUI handling shutdown UI");
+                return true;
+            }
+        } catch (Exception e) {
+            // If anything went wrong, ignore it and use fallback ui
+        }
+        Log.d(TAG, "SysUI is unavailable");
+        return false;
+    }
+
+    private static void beginShutdownSequence(Context context) {
+        synchronized (sIsStartedGuard) {
+            if (sIsStarted) {
+                Log.d(TAG, "Shutdown sequence already running, returning.");
+                return;
+            }
+            sIsStarted = true;
+        }
+
+        sInstance.mProgressDialog = showShutdownDialog(context);
         sInstance.mContext = context;
         sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
 
@@ -525,7 +556,7 @@
         Thread t = new Thread() {
             public void run() {
                 boolean nfcOff;
-                boolean bluetoothOff;
+                boolean bluetoothReadyForShutdown;
                 boolean radioOff;
 
                 final INfcAdapter nfc =
@@ -549,15 +580,15 @@
                 }
 
                 try {
-                    bluetoothOff = bluetooth == null ||
+                    bluetoothReadyForShutdown = bluetooth == null ||
                             bluetooth.getState() == BluetoothAdapter.STATE_OFF;
-                    if (!bluetoothOff) {
+                    if (!bluetoothReadyForShutdown) {
                         Log.w(TAG, "Disabling Bluetooth...");
                         bluetooth.disable(mContext.getPackageName(), false);  // disable but don't persist new state
                     }
                 } catch (RemoteException ex) {
                     Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-                    bluetoothOff = true;
+                    bluetoothReadyForShutdown = true;
                 }
 
                 try {
@@ -582,14 +613,19 @@
                         sInstance.setRebootProgress(status, null);
                     }
 
-                    if (!bluetoothOff) {
+                    if (!bluetoothReadyForShutdown) {
                         try {
-                            bluetoothOff = bluetooth.getState() == BluetoothAdapter.STATE_OFF;
+                          // BLE only mode can happen when BT is turned off
+                          // We will continue shutting down in such case
+                          bluetoothReadyForShutdown =
+                                  bluetooth.getState() == BluetoothAdapter.STATE_OFF ||
+                                  bluetooth.getState() == BluetoothAdapter.STATE_BLE_TURNING_OFF ||
+                                  bluetooth.getState() == BluetoothAdapter.STATE_BLE_ON;
                         } catch (RemoteException ex) {
                             Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
-                            bluetoothOff = true;
+                            bluetoothReadyForShutdown = true;
                         }
-                        if (bluetoothOff) {
+                        if (bluetoothReadyForShutdown) {
                             Log.i(TAG, "Bluetooth turned off.");
                         }
                     }
@@ -616,7 +652,7 @@
                         }
                     }
 
-                    if (radioOff && bluetoothOff && nfcOff) {
+                    if (radioOff && bluetoothReadyForShutdown && nfcOff) {
                         Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
                         done[0] = true;
                         break;
diff --git a/services/core/java/com/android/server/radio/RadioService.java b/services/core/java/com/android/server/radio/RadioService.java
new file mode 100644
index 0000000..34bbffd
--- /dev/null
+++ b/services/core/java/com/android/server/radio/RadioService.java
@@ -0,0 +1,75 @@
+/**
+ * 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.radio;
+
+import android.content.Context;
+import android.hardware.radio.IRadioService;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.util.Slog;
+
+import com.android.server.SystemService;
+
+public class RadioService extends SystemService {
+    // TODO(b/36863239): rename to RadioService when native service goes away
+    private static final String TAG = "RadioServiceJava";
+
+    private final RadioServiceImpl mServiceImpl = new RadioServiceImpl();
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext = nativeInit();
+
+    private final Object mLock = new Object();
+
+    public RadioService(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit();
+    private native void nativeFinalize(long nativeContext);
+    private native Tuner nativeOpenTuner(long nativeContext, int moduleId,
+            RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback);
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
+        Slog.v(TAG, "RadioService started");
+    }
+
+    private class RadioServiceImpl extends IRadioService.Stub {
+        @Override
+        public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
+                boolean withAudio, ITunerCallback callback) {
+            if (callback == null) {
+                throw new IllegalArgumentException("Callback must not be empty");
+            }
+            synchronized (mLock) {
+                // TODO(b/36863239): add death monitoring for binder
+                return nativeOpenTuner(mNativeContext, moduleId, bandConfig, withAudio, callback);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java
new file mode 100644
index 0000000..9915c34
--- /dev/null
+++ b/services/core/java/com/android/server/radio/Tuner.java
@@ -0,0 +1,225 @@
+/**
+ * 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.radio;
+
+import android.annotation.NonNull;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.util.Slog;
+
+import java.util.List;
+
+class Tuner extends ITuner.Stub {
+    // TODO(b/36863239): rename to RadioService.Tuner when native service goes away
+    private static final String TAG = "RadioServiceJava.Tuner";
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext;
+
+    @NonNull private final TunerCallback mTunerCallback;
+    private final Object mLock = new Object();
+    private boolean mIsClosed = false;
+    private boolean mIsMuted = false;
+    private int mRegion;  // TODO(b/36863239): find better solution to manage regions
+    private final boolean mWithAudio;
+
+    Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio) {
+        mTunerCallback = new TunerCallback(this, clientCallback, halRev);
+        mRegion = region;
+        mWithAudio = withAudio;
+        mNativeContext = nativeInit(halRev);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit(int halRev);
+    private native void nativeFinalize(long nativeContext);
+    private native void nativeClose(long nativeContext);
+
+    private native void nativeSetConfiguration(long nativeContext,
+            @NonNull RadioManager.BandConfig config);
+    private native RadioManager.BandConfig nativeGetConfiguration(long nativeContext, int region);
+
+    private native void nativeStep(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeScan(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeTune(long nativeContext, int channel, int subChannel);
+    private native void nativeCancel(long nativeContext);
+
+    private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
+    private native boolean nativeStartBackgroundScan(long nativeContext);
+    private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext,
+            String filter);
+
+    private native boolean nativeIsAnalogForced(long nativeContext);
+    private native void nativeSetAnalogForced(long nativeContext, boolean isForced);
+
+    private native boolean nativeIsAntennaConnected(long nativeContext);
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mIsClosed) return;
+            mTunerCallback.detach();
+            nativeClose(mNativeContext);
+            mIsClosed = true;
+        }
+    }
+
+    private void checkNotClosedLocked() {
+        if (mIsClosed) {
+            throw new IllegalStateException("Tuner is closed, no further operations are allowed");
+        }
+    }
+
+    @Override
+    public void setConfiguration(RadioManager.BandConfig config) {
+        if (config == null) {
+            throw new IllegalArgumentException("The argument must not be a null pointer");
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeSetConfiguration(mNativeContext, config);
+            mRegion = config.getRegion();
+        }
+    }
+
+    @Override
+    public RadioManager.BandConfig getConfiguration() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeGetConfiguration(mNativeContext, mRegion);
+        }
+    }
+
+    @Override
+    public void setMuted(boolean mute) {
+        if (!mWithAudio) {
+            throw new IllegalStateException("Can't operate on mute - no audio requested");
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            if (mIsMuted == mute) return;
+            mIsMuted = mute;
+
+            // TODO(b/34348946): notifify audio policy manager of media activity on radio audio
+            // device. This task is pulled directly from previous implementation of native service.
+        }
+    }
+
+    @Override
+    public boolean isMuted() {
+        if (!mWithAudio) {
+            Slog.w(TAG, "Tuner did not request audio, pretending it was muted");
+            return true;
+        }
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return mIsMuted;
+        }
+    }
+
+    @Override
+    public void step(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeStep(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void scan(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeScan(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void tune(int channel, int subChannel) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeTune(mNativeContext, channel, subChannel);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeCancel(mNativeContext);
+        }
+    }
+
+    @Override
+    public RadioManager.ProgramInfo getProgramInformation() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeGetProgramInformation(mNativeContext);
+        }
+    }
+
+    @Override
+    public boolean startBackgroundScan() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeStartBackgroundScan(mNativeContext);
+        }
+    }
+
+    @Override
+    public List<RadioManager.ProgramInfo> getProgramList(String filter) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter);
+            if (list == null) {
+                throw new IllegalStateException("Program list is not ready");
+            }
+            return list;
+        }
+    }
+
+    @Override
+    public boolean isAnalogForced() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAnalogForced(mNativeContext);
+        }
+    }
+
+    @Override
+    public void setAnalogForced(boolean isForced) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeSetAnalogForced(mNativeContext, isForced);
+        }
+    }
+
+    @Override
+    public boolean isAntennaConnected() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAntennaConnected(mNativeContext);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/radio/TunerCallback.java b/services/core/java/com/android/server/radio/TunerCallback.java
new file mode 100644
index 0000000..fcc874b
--- /dev/null
+++ b/services/core/java/com/android/server/radio/TunerCallback.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 com.android.server.radio;
+
+import android.annotation.NonNull;
+import android.hardware.radio.ITuner;
+import android.hardware.radio.ITunerCallback;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioTuner;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+class TunerCallback implements ITunerCallback {
+    // TODO(b/36863239): rename to RadioService.TunerCallback when native service goes away
+    private static final String TAG = "RadioServiceJava.TunerCallback";
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private final long mNativeContext;
+
+    @NonNull private final Tuner mTuner;
+    @NonNull private final ITunerCallback mClientCallback;
+
+    TunerCallback(@NonNull Tuner tuner, @NonNull ITunerCallback clientCallback, int halRev) {
+        mTuner = tuner;
+        mClientCallback = clientCallback;
+        mNativeContext = nativeInit(tuner, halRev);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeFinalize(mNativeContext);
+        super.finalize();
+    }
+
+    private native long nativeInit(@NonNull Tuner tuner, int halRev);
+    private native void nativeFinalize(long nativeContext);
+    private native void nativeDetach(long nativeContext);
+
+    public void detach() {
+        nativeDetach(mNativeContext);
+    }
+
+    // called from native side
+    private void handleHwFailure() {
+        onError(RadioTuner.ERROR_HARDWARE_FAILURE);
+        mTuner.close();
+    }
+
+    @Override
+    public void onError(int status) {
+        try {
+            mClientCallback.onError(status);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged(RadioManager.BandConfig config) {
+        try {
+            mClientCallback.onConfigurationChanged(config);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
+        try {
+            mClientCallback.onProgramInfoChanged(info);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "client died", e);
+        }
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new RuntimeException("Not a binder");
+    }
+}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 5e322da..866fdad 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -80,6 +80,8 @@
     void setGlobalActionsListener(GlobalActionsListener listener);
     void showGlobalActions();
 
+    boolean showShutdownUi(boolean isReboot, String requestString);
+
     public interface GlobalActionsListener {
         /**
          * Called when sysui starts and connects its status bar, or when the status bar binder
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 32871bb..5b252e8 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
@@ -329,6 +330,20 @@
                 } catch (RemoteException ex) {}
             }
         }
+
+        @Override
+        public boolean showShutdownUi(boolean isReboot, String reason) {
+            if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) {
+                return false;
+            }
+            if (mBar != null) {
+                try {
+                    mBar.showShutdownUi(isReboot, reason);
+                    return true;
+                } catch (RemoteException ex) {}
+            }
+            return false;
+        }
     };
 
     // ================================================================================
@@ -404,12 +419,12 @@
     }
 
     @Override
-    public void handleSystemNavigationKey(int key) throws RemoteException {
+    public void handleSystemKey(int key) throws RemoteException {
         enforceExpandStatusBar();
 
         if (mBar != null) {
             try {
-                mBar.handleSystemNavigationKey(key);
+                mBar.handleSystemKey(key);
             } catch (RemoteException ex) {
             }
         }
@@ -783,7 +798,7 @@
             mHandler.post(() -> {
                 // ShutdownThread displays UI, so give it a UI context.
                 if (safeMode) {
-                    ShutdownThread.rebootSafeMode(getUiContext(), false);
+                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                 } else {
                     ShutdownThread.reboot(getUiContext(),
                             PowerManager.SHUTDOWN_USER_REQUESTED, false);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index e12dc1d..8ce59ed 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -49,6 +49,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -104,6 +105,7 @@
     private static final int MSG_UNLOCK_USER = 11;
     private static final int MSG_STOP_USER = 12;
     private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
+    private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
 
     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
 
@@ -123,9 +125,13 @@
     @GuardedBy("mDeviceLockedForUser")
     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
 
-    @GuardedBy("mDeviceLockedForUser")
+    @GuardedBy("mTrustUsuallyManagedForUser")
     private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
 
+    // set to true only if user can skip bouncer
+    @GuardedBy("mUsersUnlockedByFingerprint")
+    private final SparseBooleanArray mUsersUnlockedByFingerprint = new SparseBooleanArray();
+
     private final StrongAuthTracker mStrongAuthTracker;
 
     private boolean mTrustAgentsCanRun = false;
@@ -407,7 +413,6 @@
                     + " must be USER_ALL or a specific user.", new Throwable("here"));
             userId = UserHandle.USER_ALL;
         }
-
         List<UserInfo> userInfos;
         if (userId == UserHandle.USER_ALL) {
             userInfos = mUserManager.getUsers(true /* excludeDying */);
@@ -430,13 +435,19 @@
             boolean secure = mLockPatternUtils.isSecure(id);
             boolean trusted = aggregateIsTrusted(id);
             boolean showingKeyguard = true;
+            boolean fingerprintAuthenticated = false;
+
             if (mCurrentUser == id) {
+                synchronized(mUsersUnlockedByFingerprint) {
+                    fingerprintAuthenticated = mUsersUnlockedByFingerprint.get(id, false);
+                }
                 try {
                     showingKeyguard = wm.isKeyguardLocked();
                 } catch (RemoteException e) {
                 }
             }
-            boolean deviceLocked = secure && showingKeyguard && !trusted;
+            boolean deviceLocked = secure && showingKeyguard && !trusted &&
+                    !fingerprintAuthenticated;
             setDeviceLockedForUser(id, deviceLocked);
         }
     }
@@ -583,16 +594,24 @@
         }
         PackageManager pm = mContext.getPackageManager();
         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
+        ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
+        boolean shouldUseDefaultAgent = defaultAgent != null;
         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            ComponentName componentName = getComponentName(resolveInfo);
-            int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
-            if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
-                        + "is not a system package.");
-                continue;
+
+        if (shouldUseDefaultAgent) {
+            discoveredAgents.add(defaultAgent);
+            Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
+        } else { // A default agent is not set; perform regular trust agent discovery
+            for (ResolveInfo resolveInfo : resolveInfos) {
+                ComponentName componentName = getComponentName(resolveInfo);
+                int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
+                if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                    Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
+                            + "is not a system package.");
+                    continue;
+                }
+                discoveredAgents.add(componentName);
             }
-            discoveredAgents.add(componentName);
         }
 
         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
@@ -604,6 +623,19 @@
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
     }
 
+    /**
+     * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
+     * is no trust agent set.
+     */
+    private static ComponentName getDefaultFactoryTrustAgent(Context context) {
+        String defaultTrustAgent = context.getResources()
+            .getString(com.android.internal.R.string.config_defaultTrustAgent);
+        if (TextUtils.isEmpty(defaultTrustAgent)) {
+            return null;
+        }
+        return ComponentName.unflattenFromString(defaultTrustAgent);
+    }
+
     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
                 PackageManager.GET_META_DATA |
@@ -965,6 +997,26 @@
                     "query trust state");
             return isTrustUsuallyManagedInternal(userId);
         }
+
+        @Override
+        public void unlockedByFingerprintForUser(int userId) {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.put(userId, true);
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
+                    0 /* arg2 */).sendToTarget();
+        }
+
+        @Override
+        public void clearAllFingerprints() {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.clear();
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
+                    0 /* arg2 */).sendToTarget();
+        }
     };
 
     private boolean isTrustUsuallyManagedInternal(int userId) {
@@ -1052,6 +1104,9 @@
                         }
                     }
                     break;
+                case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
+                    refreshDeviceLockedForUser(msg.arg1);
+                    break;
             }
         }
     };
@@ -1111,6 +1166,9 @@
                     synchronized (mTrustUsuallyManagedForUser) {
                         mTrustUsuallyManagedForUser.delete(userId);
                     }
+                    synchronized (mUsersUnlockedByFingerprint) {
+                        mUsersUnlockedByFingerprint.delete(userId);
+                    }
                     refreshAgentList(userId);
                     refreshDeviceLockedForUser(userId);
                 }
diff --git a/services/core/java/com/android/server/tv/UinputBridge.java b/services/core/java/com/android/server/tv/UinputBridge.java
index f910332..1a984f9 100644
--- a/services/core/java/com/android/server/tv/UinputBridge.java
+++ b/services/core/java/com/android/server/tv/UinputBridge.java
@@ -63,7 +63,7 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (mPtr != 0) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
             }
             close(mToken);
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 4a1297f..8f50a39 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -24,6 +24,7 @@
 import android.service.vr.IVrManager;
 import android.util.Log;
 import android.view.Surface;
+import android.view.WindowManagerInternal;
 
 import com.android.server.vr.VrManagerService;
 
@@ -35,7 +36,6 @@
     private final static String TAG = "Vr2dDisplay";
     private final static boolean DEBUG = false;
 
-    // TODO: Go over these values and figure out what is best
     private int mVirtualDisplayHeight;
     private int mVirtualDisplayWidth;
     private int mVirtualDisplayDpi;
@@ -55,17 +55,17 @@
     /**
      * The default width of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400;
 
     /**
      * The default height of the VR virtual display
      */
-    public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1800;
 
     /**
      * The default height of the VR virtual dpi.
      */
-    public static final int DEFAULT_VR_DISPLAY_DPI = 320;
+    public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320;
 
     /**
      * The minimum height, width and dpi of VR virtual display.
@@ -75,6 +75,7 @@
     public static final int MIN_VR_DISPLAY_DPI = 1;
 
     private final ActivityManagerInternal mActivityManagerInternal;
+    private final WindowManagerInternal mWindowManagerInternal;
     private final DisplayManager mDisplayManager;
     private final IVrManager mVrManager;
     private final Object mVdLock = new Object();
@@ -87,8 +88,8 @@
             new IPersistentVrStateCallbacks.Stub() {
         @Override
         public void onPersistentVrStateChanged(boolean enabled) {
-            if (enabled != mIsVrModeEnabled) {
-                mIsVrModeEnabled = enabled;
+            if (enabled != mIsPersistentVrModeEnabled) {
+                mIsPersistentVrModeEnabled = enabled;
                 updateVirtualDisplay();
             }
         }
@@ -98,25 +99,35 @@
     private Surface mSurface;
     private ImageReader mImageReader;
     private Runnable mStopVDRunnable;
-    private boolean mIsVrModeOverrideEnabled;
-    private boolean mIsVrModeEnabled;
+    private boolean mIsVrModeOverrideEnabled;  // debug override to set vr mode.
+    private boolean mIsVirtualDisplayAllowed = true;  // Virtual-display feature toggle
+    private boolean mIsPersistentVrModeEnabled;  // indicates we are in vr persistent mode.
+    private boolean mBootsToVr = false;  // The device boots into VR (standalone VR device)
 
     public Vr2dDisplay(DisplayManager displayManager,
-           ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
+           ActivityManagerInternal activityManagerInternal,
+           WindowManagerInternal windowManagerInternal, IVrManager vrManager) {
         mDisplayManager = displayManager;
         mActivityManagerInternal = activityManagerInternal;
+        mWindowManagerInternal = windowManagerInternal;
         mVrManager = vrManager;
-        mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH;
-        mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT;
-        mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI;
+        mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH;
+        mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT;
+        mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI;
     }
 
     /**
      * Initializes the compabilitiy display by listening to VR mode changes.
      */
-    public void init(Context context) {
+    public void init(Context context, boolean bootsToVr) {
         startVrModeListener();
         startDebugOnlyBroadcastReceiver(context);
+        mBootsToVr = bootsToVr;
+        if (mBootsToVr) {
+          // If we are booting into VR, we need to start the virtual display immediately. This
+          // ensures that the virtual display is up by the time Setup Wizard is started.
+          updateVirtualDisplay();
+        }
     }
 
     /**
@@ -124,10 +135,13 @@
      */
     private void updateVirtualDisplay() {
         if (DEBUG) {
-            Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled);
+            Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: "
+                    + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed
+                    + ", bootsToVr: " + mBootsToVr);
         }
 
-        if (mIsVrModeEnabled || mIsVrModeOverrideEnabled) {
+        if (shouldRunVirtualDisplay()) {
+            Log.i(TAG, "Attempting to start virtual display");
             // TODO: Consider not creating the display until ActivityManager needs one on
             // which to display a 2D application.
             startVirtualDisplay();
@@ -190,33 +204,43 @@
      *
      * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
      *
-     * @param compatDisplayProperties Properties of the virtual display for 2D applications
+     * @param displayProperties Properties of the virtual display for 2D applications
      * in VR mode.
      */
-    public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) {
+    public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) {
         synchronized(mVdLock) {
             if (DEBUG) {
-                Log.i(TAG, "VD setVirtualDisplayProperties: res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight() + ", dpi = "
-                        + compatDisplayProperties.getDpi());
+                Log.i(TAG, "VD setVirtualDisplayProperties: " +
+                        displayProperties.toString());
             }
 
-            if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH ||
-                compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT ||
-                compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) {
-                throw new IllegalArgumentException (
-                        "Illegal argument: height, width, dpi cannot be negative. res = "
-                        + compatDisplayProperties.getWidth() + "X"
-                        + compatDisplayProperties.getHeight()
-                        + ", dpi = " + compatDisplayProperties.getDpi());
+            int width = displayProperties.getWidth();
+            int height = displayProperties.getHeight();
+            int dpi = displayProperties.getDpi();
+            boolean resized = false;
+
+            if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT ||
+                    dpi < MIN_VR_DISPLAY_DPI) {
+                Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + ","
+                        + dpi);
+            } else {
+                Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi);
+                mVirtualDisplayWidth = width;
+                mVirtualDisplayHeight = height;
+                mVirtualDisplayDpi = dpi;
+                resized = true;
             }
 
-            mVirtualDisplayWidth = compatDisplayProperties.getWidth();
-            mVirtualDisplayHeight = compatDisplayProperties.getHeight();
-            mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+            if ((displayProperties.getFlags() & Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = true;
+            } else if ((displayProperties.getRemovedFlags() &
+                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
+                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
+                mIsVirtualDisplayAllowed = false;
+            }
 
-            if (mVirtualDisplay != null) {
+            if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) {
                 mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
                     mVirtualDisplayDpi);
                 ImageReader oldImageReader = mImageReader;
@@ -224,6 +248,9 @@
                 startImageReader();
                 oldImageReader.close();
             }
+
+            // Start/Stop the virtual display in case the updates indicated that we should.
+            updateVirtualDisplay();
         }
     }
 
@@ -266,19 +293,19 @@
             }
 
             int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
             mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
                     DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
                     null /* surface */, flags, null /* callback */, null /* handler */,
                     UNIQUE_DISPLAY_ID);
 
             if (mVirtualDisplay != null) {
-                mActivityManagerInternal.setVr2dDisplayId(
-                    mVirtualDisplay.getDisplay().getDisplayId());
+                updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
                 // Now create the ImageReader to supply a Surface to the new virtual display.
                 startImageReader();
             } else {
                 Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
-                mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+                updateDisplayId(INVALID_DISPLAY);
                 return;
             }
         }
@@ -286,6 +313,11 @@
         Log.i(TAG, "VD created: " + mVirtualDisplay);
     }
 
+    private void updateDisplayId(int displayId) {
+        mActivityManagerInternal.setVr2dDisplayId(displayId);
+        mWindowManagerInternal.setVr2dDisplayId(displayId);
+    }
+
     /**
      * Stops the virtual display with a {@link #STOP_VIRTUAL_DISPLAY_DELAY_MILLIS} timeout.
      * The timeout prevents the virtual display from bouncing in cases where VrMode goes in and out
@@ -296,12 +328,12 @@
            mStopVDRunnable = new Runnable() {
                @Override
                public void run() {
-                    if (mIsVrModeEnabled) {
+                    if (shouldRunVirtualDisplay()) {
                         Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on.");
                     } else {
                         Log.i(TAG, "Stopping Virtual Display");
                         synchronized (mVdLock) {
-                            mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
+                            updateDisplayId(INVALID_DISPLAY);
                             setSurfaceLocked(null); // clean up and release the surface first.
                             if (mVirtualDisplay != null) {
                                 mVirtualDisplay.release();
@@ -365,4 +397,14 @@
             mImageReader = null;
         }
     }
+
+    private boolean shouldRunVirtualDisplay() {
+        // Virtual Display should run whenever:
+        // * Virtual Display is allowed/enabled AND
+        // (1) BootsToVr is set indicating the device never leaves VR
+        // (2) VR (persistent) mode is enabled
+        // (3) VR mode is overridden to be enabled.
+        return mIsVirtualDisplayAllowed &&
+                (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled);
+    }
 }
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 1f75640..bdd9de0 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -52,10 +52,11 @@
      * @param enabled {@code true} to enable VR mode.
      * @param packageName The package name of the requested VrListenerService to bind.
      * @param userId the user requesting the VrListenerService component.
+     * @param processId the process the component is running in.
      * @param calling the component currently using VR mode, or null to leave unchanged.
      */
     public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName,
-            int userId, @NonNull ComponentName calling);
+            int userId, int processId, @NonNull ComponentName calling);
 
     /**
      * Set whether the system has acquired a sleep token.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index b937f9d..030b74c 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -24,9 +24,12 @@
 import android.app.Vr2dDisplayProperties;
 import android.app.NotificationManager;
 import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -39,6 +42,7 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -52,6 +56,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.WindowManagerInternal;
 
 import com.android.internal.R;
 import com.android.internal.util.DumpUtils;
@@ -121,6 +126,8 @@
     private boolean mVrModeAllowed;
     private boolean mVrModeEnabled;
     private boolean mPersistentVrModeEnabled;
+    private boolean mRunning2dInVr;
+    private int mVrAppProcessId;
     private EnabledComponentsObserver mComponentObserver;
     private ManagedApplicationService mCurrentVrService;
     private ComponentName mDefaultVrService;
@@ -140,7 +147,13 @@
     private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
     /** Tracks the state of the screen and keyguard UI.*/
     private int mSystemSleepFlags = FLAG_AWAKE;
+    /**
+     * Set when ACTION_USER_UNLOCKED is fired. We shouldn't try to bind to the
+     * vr service before then.
+     */
+    private boolean mUserUnlocked;
     private Vr2dDisplay mVr2dDisplay;
+    private boolean mBootsToVr;
 
     private static final int MSG_VR_STATE_CHANGE = 0;
     private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -152,15 +165,20 @@
      * If VR mode is not allowed to be enabled, calls to set VR mode will be cached.  When VR mode
      * is again allowed to be enabled, the most recent cached state will be applied.
      *
-     * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to
-     *   enter VR mode.
      */
-    private void setVrModeAllowedLocked(boolean allowed) {
+    private void updateVrModeAllowedLocked() {
+        boolean allowed = mSystemSleepFlags == FLAG_ALL && mUserUnlocked;
         if (mVrModeAllowed != allowed) {
             mVrModeAllowed = allowed;
             if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
             if (mVrModeAllowed) {
+                if (mBootsToVr) {
+                    setPersistentVrModeEnabled(true);
+                }
                 consumeAndApplyPendingStateLocked();
+                if (mBootsToVr && !mVrModeEnabled) {
+                  setVrMode(true, mDefaultVrService, 0, -1, null);
+                }
             } else {
                 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
                 // exit persistent VR mode when screen is turned off.
@@ -168,12 +186,12 @@
 
                 // Set pending state to current state.
                 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
-                    ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
-                        mCurrentVrService.getUserId(), mCurrentVrModeComponent)
+                    ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
+                        mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
                     : null;
 
                 // Unbind current VR service and do necessary callbacks.
-                updateCurrentVrServiceLocked(false, null, 0, null);
+                updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
             }
         }
     }
@@ -187,7 +205,7 @@
                 mSystemSleepFlags &= ~FLAG_AWAKE;
             }
 
-            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
+            updateVrModeAllowedLocked();
         }
     }
 
@@ -198,7 +216,14 @@
             } else {
                 mSystemSleepFlags &= ~FLAG_SCREEN_ON;
             }
-            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
+            updateVrModeAllowedLocked();
+        }
+    }
+
+    private void setUserUnlocked() {
+        synchronized(mLock) {
+            mUserUnlocked = true;
+            updateVrModeAllowedLocked();
         }
     }
 
@@ -248,26 +273,33 @@
 
     private static class VrState {
         final boolean enabled;
+        final boolean running2dInVr;
         final int userId;
+        final int processId;
         final ComponentName targetPackageName;
         final ComponentName callingPackage;
         final long timestamp;
         final boolean defaultPermissionsGranted;
 
-        VrState(boolean enabled, ComponentName targetPackageName, int userId,
-                ComponentName callingPackage) {
+
+        VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+                int processId, ComponentName callingPackage) {
             this.enabled = enabled;
+            this.running2dInVr = running2dInVr;
             this.userId = userId;
+            this.processId = processId;
             this.targetPackageName = targetPackageName;
             this.callingPackage = callingPackage;
             this.defaultPermissionsGranted = false;
             this.timestamp = System.currentTimeMillis();
         }
 
-        VrState(boolean enabled, ComponentName targetPackageName, int userId,
-            ComponentName callingPackage, boolean defaultPermissionsGranted) {
+        VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+            int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
             this.enabled = enabled;
+            this.running2dInVr = running2dInVr;
             this.userId = userId;
+            this.processId = processId;
             this.targetPackageName = targetPackageName;
             this.callingPackage = callingPackage;
             this.defaultPermissionsGranted = defaultPermissionsGranted;
@@ -368,8 +400,9 @@
             }
 
             // There is an active service, update it if needed
-            updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
-                    mCurrentVrService.getUserId(), mCurrentVrModeComponent);
+            updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
+                    mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
+                    mVrAppProcessId, mCurrentVrModeComponent);
         }
     }
 
@@ -505,9 +538,9 @@
      */
     private final class LocalService extends VrManagerInternal {
         @Override
-        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
+        public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
                 ComponentName callingPackage) {
-            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
+            VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
         }
 
         @Override
@@ -563,6 +596,7 @@
             mContext = getContext();
         }
 
+        mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
         publishLocalService(VrManagerInternal.class, new LocalService());
         publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
     }
@@ -594,13 +628,23 @@
 
             DisplayManager dm =
                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
-            ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
-            mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager);
-            mVr2dDisplay.init(getContext());
-        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
-            synchronized (mLock) {
-                mVrModeAllowed = true;
-            }
+            mVr2dDisplay = new Vr2dDisplay(
+                    dm,
+                    LocalServices.getService(ActivityManagerInternal.class),
+                    LocalServices.getService(WindowManagerInternal.class),
+                    mVrManager);
+            mVr2dDisplay.init(getContext(), mBootsToVr);
+
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+            getContext().registerReceiver(new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+                            VrManagerService.this.setUserUnlocked();
+                        }
+                    }
+                }, intentFilter);
         }
     }
 
@@ -674,14 +718,16 @@
      * Note: Must be called while holding {@code mLock}.
      *
      * @param enabled new state for VR mode.
+     * @param running2dInVr true if we have a top-level 2D intent.
      * @param component new component to be bound as a VR listener.
      * @param userId user owning the component to be bound.
-     * @param calling the component currently using VR mode.
+     * @param processId the process hosting the activity specified by calling.
+     * @param calling the component currently using VR mode or a 2D intent.
      *
      * @return {@code true} if the component/user combination specified is valid.
      */
-    private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
-            int userId, ComponentName calling) {
+    private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
+            @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
 
         boolean sendUpdatedCaller = false;
         final long identity = Binder.clearCallingIdentity();
@@ -737,10 +783,13 @@
             }
 
             if ((calling != null || mPersistentVrModeEnabled)
-                    && !Objects.equals(calling, mCurrentVrModeComponent)) {
+                    && !Objects.equals(calling, mCurrentVrModeComponent)
+                    || mRunning2dInVr != running2dInVr) {
                 sendUpdatedCaller = true;
             }
             mCurrentVrModeComponent = calling;
+            mRunning2dInVr = running2dInVr;
+            mVrAppProcessId = processId;
 
             if (mCurrentVrModeUser != userId) {
                 mCurrentVrModeUser = userId;
@@ -758,11 +807,13 @@
 
             if (mCurrentVrService != null && sendUpdatedCaller) {
                 final ComponentName c = mCurrentVrModeComponent;
+                final boolean b = running2dInVr;
+                final int pid = processId;
                 mCurrentVrService.sendEvent(new PendingEvent() {
                     @Override
                     public void runEvent(IInterface service) throws RemoteException {
                         IVrListener l = (IVrListener) service;
-                        l.focusedActivityChanged(c);
+                        l.focusedActivityChanged(c, b, pid);
                     }
                 });
             }
@@ -987,20 +1038,20 @@
      */
     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
         if (mPendingState != null) {
-            updateCurrentVrServiceLocked(mPendingState.enabled,
-                    mPendingState.targetPackageName, mPendingState.userId,
+            updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
+                    mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
                     mPendingState.callingPackage);
             mPendingState = null;
         } else if (disconnectIfNoPendingState) {
-            updateCurrentVrServiceLocked(false, null, 0, null);
+            updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
         }
     }
 
     private void logStateLocked() {
         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
             mCurrentVrService.getComponent();
-        VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
-            mCurrentVrModeComponent, mWasDefaultGranted);
+        VrState current = new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
+            mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted);
         if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
             mLoggingDeque.removeFirst();
         }
@@ -1044,27 +1095,24 @@
      * Implementation of VrManagerInternal calls.  These are callable from system services.
      */
     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
-            int userId, @NonNull ComponentName callingPackage) {
+            int userId, int processId, @NonNull ComponentName callingPackage) {
 
         synchronized (mLock) {
             VrState pending;
             ComponentName targetListener;
-            ComponentName foregroundVrComponent;
 
             // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
             // and the system default VR listener is used.
             boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
-            if (!enabled && mPersistentVrModeEnabled) {
+            boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
+            if (running2dInVr) {
                 targetListener = mDefaultVrService;
-
-                // Current foreground component isn't a VR one (in 2D app case)
-                foregroundVrComponent = null;
             } else {
                 targetListener = targetPackageName;
-                foregroundVrComponent = callingPackage;
             }
-            pending = new VrState(
-                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+
+            pending = new VrState(targetEnabledState, running2dInVr, targetListener,
+                    userId, processId, callingPackage);
 
             if (!mVrModeAllowed) {
                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
@@ -1089,17 +1137,17 @@
                 mPendingState = null;
             }
 
-            updateCurrentVrServiceLocked(
-                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+            updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
+                    userId, processId, callingPackage);
         }
     }
 
     private void setPersistentVrModeEnabled(boolean enabled) {
         synchronized(mLock) {
             setPersistentModeAndNotifyListenersLocked(enabled);
-            // Disabling persistent mode when not showing a VR should disable the overall vr mode.
-            if (!enabled && mCurrentVrModeComponent == null) {
-                setVrMode(false, null, 0, null);
+            // Disabling persistent mode should disable the overall vr mode.
+            if (!enabled) {
+                setVrMode(false, null, 0, -1, null);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 39b902e..e0ad8f5 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -25,6 +25,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -32,6 +33,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;
@@ -52,6 +54,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -61,9 +64,10 @@
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IInterface;
 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;
@@ -111,6 +115,7 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -220,6 +225,7 @@
             // lock-only changes happen on the dedicated lock wallpaper input file
             final boolean sysWallpaperChanged = (mWallpaperFile.equals(changedFile));
             final boolean lockWallpaperChanged = (mWallpaperLockFile.equals(changedFile));
+            int notifyColorsWhich = 0;
             WallpaperData wallpaper = dataForEvent(sysWallpaperChanged, lockWallpaperChanged);
 
             if (DEBUG) {
@@ -241,6 +247,7 @@
                 }
                 SELinux.restorecon(changedFile);
                 notifyLockWallpaperChanged();
+                notifyWallpaperColorsChanged(wallpaper, FLAG_LOCK);
                 return;
             }
 
@@ -285,6 +292,7 @@
                                 // If this was the system wallpaper, rebind...
                                 bindWallpaperComponentLocked(mImageWallpaper, true,
                                         false, wallpaper, null);
+                                notifyColorsWhich |= FLAG_SYSTEM;
                             }
                             if (lockWallpaperChanged
                                     || (wallpaper.whichPending & FLAG_LOCK) != 0) {
@@ -299,12 +307,19 @@
                                 }
                                 // and in any case, tell keyguard about it
                                 notifyLockWallpaperChanged();
+                                notifyColorsWhich |= FLAG_LOCK;
                             }
+
                             saveSettingsLocked(wallpaper.userId);
                         }
                     }
                 }
             }
+
+            // Outside of the lock since it will synchronize itself
+            if (notifyColorsWhich != 0) {
+                notifyWallpaperColorsChanged(wallpaper, notifyColorsWhich);
+            }
         }
     }
 
@@ -319,6 +334,139 @@
         }
     }
 
+    private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
+        boolean needsExtraction;
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
+                    mColorsChangedListeners.get(wallpaper.userId);
+            final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
+                    mColorsChangedListeners.get(UserHandle.USER_ALL);
+            // No-op until someone is listening to it.
+            if (emptyCallbackList(currentUserColorListeners)  &&
+                    emptyCallbackList(userAllColorListeners)) {
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.v(TAG, "notifyWallpaperColorsChanged " + which);
+            }
+
+            needsExtraction = wallpaper.primaryColors == null;
+        }
+
+        // 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, wallpaper.userId);
+
+        if (needsExtraction) {
+            extractColors(wallpaper);
+            synchronized (mLock) {
+                // Don't need to notify if nothing changed.
+                if (wallpaper.primaryColors == null) {
+                    return;
+                }
+            }
+            notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId);
+        }
+    }
+
+    private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) {
+        return (list == null || list.getRegisteredCallbackCount() == 0);
+    }
+
+    private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which,
+            int userId) {
+        final IWallpaperManagerCallback keyguardListener;
+        final ArrayList<IWallpaperManagerCallback> colorListeners = new ArrayList<>();
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
+                    mColorsChangedListeners.get(userId);
+            final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners =
+                    mColorsChangedListeners.get(UserHandle.USER_ALL);
+            keyguardListener = mKeyguardListener;
+
+            if (currentUserColorListeners != null) {
+                final int count = currentUserColorListeners.beginBroadcast();
+                for (int i = 0; i < count; i++) {
+                    colorListeners.add(currentUserColorListeners.getBroadcastItem(i));
+                }
+                currentUserColorListeners.finishBroadcast();
+            }
+
+            if (userAllColorListeners != null) {
+                final int count = userAllColorListeners.beginBroadcast();
+                for (int i = 0; i < count; i++) {
+                    colorListeners.add(userAllColorListeners.getBroadcastItem(i));
+                }
+                userAllColorListeners.finishBroadcast();
+            }
+        }
+
+        final int count = colorListeners.size();
+        for (int i = 0; i < count; i++) {
+            try {
+                colorListeners.get(i).onWallpaperColorsChanged(wallpaperColors, which, userId);
+            } 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, userId);
+            } catch (RemoteException e) {
+                // Oh well it went away; no big deal
+            }
+        }
+    }
+
+    /**
+     * We can easily extract colors from an ImageWallpaper since it's only a bitmap.
+     * In this case, using the crop is more than enough. Live wallpapers are just ignored.
+     *
+     * @param wallpaper a wallpaper representation
+     */
+    private void extractColors(WallpaperData wallpaper) {
+        String cropFile = null;
+        int wallpaperId;
+
+        synchronized (mLock) {
+            // Not having a wallpaperComponent means it's a lock screen wallpaper.
+            final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
+                    || wallpaper.wallpaperComponent == null;
+            if (imageWallpaper && wallpaper.cropFile != null && wallpaper.cropFile.exists()) {
+                cropFile = wallpaper.cropFile.getAbsolutePath();
+            }
+            wallpaperId = wallpaper.wallpaperId;
+        }
+
+        WallpaperColors colors = null;
+        if (cropFile != null) {
+            Bitmap bitmap = BitmapFactory.decodeFile(cropFile);
+            if (bitmap != null) {
+                colors = WallpaperColors.fromBitmap(bitmap);
+                bitmap.recycle();
+            }
+        }
+
+        if (colors == null) {
+            Slog.w(TAG, "Cannot extract colors because wallpaper could not be read.");
+            return;
+        }
+
+        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");
+            }
+        }
+    }
+
     /**
      * Once a new wallpaper has been written via setWallpaper(...), it needs to be cropped
      * for display.
@@ -482,6 +630,11 @@
     final IPackageManager mIPackageManager;
     final MyPackageMonitor mMonitor;
     final AppOpsManager mAppOpsManager;
+    /**
+     * Map of color listeners per user id.
+     * The key will be the id of a user or UserHandle.USER_ALL - for wildcard listeners.
+     */
+    final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> mColorsChangedListeners;
     WallpaperData mLastWallpaper;
     IWallpaperManagerCallback mKeyguardListener;
     boolean mWaitingForUnlock;
@@ -558,6 +711,11 @@
          */
         int wallpaperId;
 
+        /**
+         * Primary colors histogram
+         */
+        WallpaperColors primaryColors;
+
         WallpaperConnection connection;
         long lastDiedTime;
         boolean wallpaperUpdating;
@@ -733,6 +891,35 @@
             }
         }
 
+        /**
+         * Called by a live wallpaper if its colors have changed.
+         * @param primaryColors representation of wallpaper primary colors
+         */
+        @Override
+        public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
+            int which;
+            synchronized (mLock) {
+                // Do not broadcast changes on ImageWallpaper since it's handled
+                // internally by this class.
+                if (mImageWallpaper.equals(mWallpaper.wallpaperComponent)) {
+                    return;
+                }
+
+                mWallpaper.primaryColors = primaryColors;
+
+                // Live wallpapers always are system wallpapers.
+                which = FLAG_SYSTEM;
+                // It's also the lock screen wallpaper when we don't have a bitmap in there
+                WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId);
+                if (lockedWallpaper == null) {
+                    which |= FLAG_LOCK;
+                }
+            }
+            if (which != 0) {
+                notifyWallpaperColorsChanged(mWallpaper, which);
+            }
+        }
+
         @Override
         public void attachEngine(IWallpaperEngine engine) {
             synchronized (mLock) {
@@ -753,6 +940,13 @@
                     }
                     mPaddingChanged = false;
                 }
+                try {
+                    // This will trigger onComputeColors in the wallpaper engine.
+                    // It's fine to be locked in here since the binder is oneway.
+                    mEngine.requestWallpaperColors();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to request wallpaper colors", e);
+                }
             }
         }
 
@@ -943,6 +1137,7 @@
         mMonitor.register(context, null, UserHandle.ALL, true);
         getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
         loadSettingsLocked(UserHandle.USER_SYSTEM, false);
+        mColorsChangedListeners = new SparseArray<>();
     }
 
     private static File getWallpaperDir(int userId) {
@@ -1098,16 +1293,24 @@
     }
 
     void switchUser(int userId, IRemoteCallback reply) {
+        WallpaperData systemWallpaper;
+        WallpaperData lockWallpaper;
         synchronized (mLock) {
             mCurrentUserId = userId;
-            WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
-            // Not started watching yet, in case wallpaper data was loaded for other reasons.
-            if (wallpaper.wallpaperObserver == null) {
-                wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
-                wallpaper.wallpaperObserver.startWatching();
+            systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+            lockWallpaper = mLockWallpaperMap.get(userId);
+            if (lockWallpaper == null) {
+                lockWallpaper = systemWallpaper;
             }
-            switchWallpaper(wallpaper, reply);
+            // Not started watching yet, in case wallpaper data was loaded for other reasons.
+            if (systemWallpaper.wallpaperObserver == null) {
+                systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
+                systemWallpaper.wallpaperObserver.startWatching();
+            }
+            switchWallpaper(systemWallpaper, reply);
         }
+        notifyWallpaperColorsChanged(systemWallpaper, FLAG_SYSTEM);
+        notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK);
     }
 
     void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
@@ -1154,8 +1357,21 @@
         userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                 Binder.getCallingUid(), userId, false, true, "clearWallpaper", null);
 
+        WallpaperData data = null;
         synchronized (mLock) {
             clearWallpaperLocked(false, which, userId, null);
+
+            if (which == FLAG_LOCK) {
+                data = mLockWallpaperMap.get(userId);
+            }
+            if (which == FLAG_SYSTEM || data == null) {
+                data = mWallpaperMap.get(userId);
+            }
+        }
+
+        // When clearing a wallpaper, broadcast new valid colors
+        if (data != null) {
+            notifyWallpaperColorsChanged(data, which);
         }
     }
 
@@ -1211,6 +1427,7 @@
 
             RuntimeException e = null;
             try {
+                wallpaper.primaryColors = null;
                 wallpaper.imageWallpaperPending = false;
                 if (userId != mCurrentUserId) return;
                 if (bindWallpaperComponentLocked(defaultFailed
@@ -1449,6 +1666,34 @@
     }
 
     @Override
+    public void registerWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "registerWallpaperColorsCallback", null);
+        synchronized (mLock) {
+            RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+                    mColorsChangedListeners.get(userId);
+            if (userColorsChangedListeners == null) {
+                userColorsChangedListeners = new RemoteCallbackList<>();
+                mColorsChangedListeners.put(userId, userColorsChangedListeners);
+            }
+            userColorsChangedListeners.register(cb);
+        }
+    }
+
+    @Override
+    public void unregisterWallpaperColorsCallback(IWallpaperManagerCallback cb, int userId) {
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, "unregisterWallpaperColorsCallback", null);
+        synchronized (mLock) {
+            final RemoteCallbackList<IWallpaperManagerCallback> userColorsChangedListeners =
+                    mColorsChangedListeners.get(userId);
+            if (userColorsChangedListeners != null) {
+                userColorsChangedListeners.unregister(cb);
+            }
+        }
+    }
+
+    @Override
     public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
         checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
         synchronized (mLock) {
@@ -1458,6 +1703,43 @@
     }
 
     @Override
+    public WallpaperColors getWallpaperColors(int which, int userId) throws RemoteException {
+        if (which != FLAG_LOCK && which != FLAG_SYSTEM) {
+            throw new IllegalArgumentException("which should be either FLAG_LOCK or FLAG_SYSTEM");
+        }
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, false, true, "getWallpaperColors", null);
+
+        WallpaperData wallpaperData = null;
+        boolean shouldExtract;
+
+        synchronized (mLock) {
+            if (which == FLAG_LOCK) {
+                wallpaperData = mLockWallpaperMap.get(userId);
+            }
+
+            // Try to get the system wallpaper anyway since it might
+            // also be the lock screen wallpaper
+            if (wallpaperData == null) {
+                wallpaperData = mWallpaperMap.get(userId);
+            }
+
+            if (wallpaperData == null) {
+                return null;
+            }
+            shouldExtract = wallpaperData.primaryColors == null;
+        }
+
+        if (shouldExtract) {
+            extractColors(wallpaperData);
+        }
+
+        synchronized (mLock) {
+            return wallpaperData.primaryColors;
+        }
+    }
+
+    @Override
     public ParcelFileDescriptor setWallpaper(String name, String callingPackage,
             Rect cropHint, boolean allowBackup, Bundle extras, int which,
             IWallpaperManagerCallback completion, int userId) {
@@ -1536,6 +1818,7 @@
         lockWP.width = sysWP.width;
         lockWP.height = sysWP.height;
         lockWP.allowBackup = sysWP.allowBackup;
+        lockWP.primaryColors = sysWP.primaryColors;
 
         // Migrate the bitmap files outright; no need to copy
         try {
@@ -1573,6 +1856,8 @@
             if (extras != null) {
                 extras.putInt(WallpaperManager.EXTRA_NEW_WALLPAPER_ID, wallpaper.wallpaperId);
             }
+            // Nullify field to require new computation
+            wallpaper.primaryColors = null;
             if (DEBUG) {
                 Slog.v(TAG, "updateWallpaperBitmapLocked() : id=" + wallpaper.wallpaperId
                         + " name=" + name + " file=" + wallpaper.wallpaperFile.getName());
@@ -1604,9 +1889,13 @@
                 false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
         checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
 
+        int which = FLAG_SYSTEM;
+        boolean shouldNotifyColors = false;
+        WallpaperData wallpaper;
+
         synchronized (mLock) {
             if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
-            WallpaperData wallpaper = mWallpaperMap.get(userId);
+            wallpaper = mWallpaperMap.get(userId);
             if (wallpaper == null) {
                 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
             }
@@ -1624,16 +1913,47 @@
                 }
             }
 
+            // New live wallpaper is also a lock wallpaper if nothing is set
+            if (mLockWallpaperMap.get(userId) == null) {
+                which |= FLAG_LOCK;
+            }
+
             try {
                 wallpaper.imageWallpaperPending = false;
+                boolean same = changingToSame(name, wallpaper);
                 if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
+                    if (!same) {
+                        wallpaper.primaryColors = null;
+                    }
                     wallpaper.wallpaperId = makeWallpaperIdLocked();
                     notifyCallbacksLocked(wallpaper);
+                    shouldNotifyColors = true;
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
+
+        if (shouldNotifyColors) {
+            notifyWallpaperColorsChanged(wallpaper, which);
+        }
+    }
+
+    private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) {
+        if (wallpaper.connection != null) {
+            if (wallpaper.wallpaperComponent == null) {
+                if (componentName == null) {
+                    if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
+                    // Still using default wallpaper.
+                    return true;
+                }
+            } else if (wallpaper.wallpaperComponent.equals(componentName)) {
+                // Changing to same wallpaper.
+                if (DEBUG) Slog.v(TAG, "same wallpaper");
+                return true;
+            }
+        }
+        return false;
     }
 
     boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
@@ -1642,20 +1962,8 @@
             Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
         }
         // Has the component changed?
-        if (!force) {
-            if (wallpaper.connection != null) {
-                if (wallpaper.wallpaperComponent == null) {
-                    if (componentName == null) {
-                        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
-                        // Still using default wallpaper.
-                        return true;
-                    }
-                } else if (wallpaper.wallpaperComponent.equals(componentName)) {
-                    // Changing to same wallpaper.
-                    if (DEBUG) Slog.v(TAG, "same wallpaper");
-                    return true;
-                }
-            }
+        if (!force && changingToSame(componentName, wallpaper)) {
+            return true;
         }
 
         try {
@@ -1837,6 +2145,7 @@
             }
         }
         wallpaper.callbacks.finishBroadcast();
+
         final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
         mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
     }
@@ -1927,6 +2236,9 @@
 
     private void writeWallpaperAttributes(XmlSerializer out, String tag, WallpaperData wallpaper)
             throws IllegalArgumentException, IllegalStateException, IOException {
+        if (DEBUG) {
+            Slog.v(TAG, "writeWallpaperAttributes");
+        }
         out.startTag(null, tag);
         out.attribute(null, "id", Integer.toString(wallpaper.wallpaperId));
         out.attribute(null, "width", Integer.toString(wallpaper.width));
@@ -1950,6 +2262,19 @@
             out.attribute(null, "paddingBottom", Integer.toString(wallpaper.padding.bottom));
         }
 
+        if (wallpaper.primaryColors != null) {
+            int colorsCount = wallpaper.primaryColors.getMainColors().size();
+            out.attribute(null, "colorsCount", Integer.toString(colorsCount));
+            if (colorsCount > 0) {
+                for (int i = 0; i < colorsCount; i++) {
+                    final Color wc = wallpaper.primaryColors.getMainColors().get(i);
+                    out.attribute(null, "colorValue"+i, Integer.toString(wc.toArgb()));
+                }
+            }
+            out.attribute(null, "colorHints",
+                    Integer.toString(wallpaper.primaryColors.getColorHints()));
+        }
+
         out.attribute(null, "name", wallpaper.name);
         if (wallpaper.wallpaperComponent != null
                 && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
@@ -2081,6 +2406,7 @@
                             Slog.v(TAG, "mWidth:" + wallpaper.width);
                             Slog.v(TAG, "mHeight:" + wallpaper.height);
                             Slog.v(TAG, "cropRect:" + wallpaper.cropHint);
+                            Slog.v(TAG, "primaryColors:" + wallpaper.primaryColors);
                             Slog.v(TAG, "mName:" + wallpaper.name);
                             Slog.v(TAG, "mNextWallpaperComponent:"
                                     + wallpaper.nextWallpaperComponent);
@@ -2179,6 +2505,24 @@
         wallpaper.padding.top = getAttributeInt(parser, "paddingTop", 0);
         wallpaper.padding.right = getAttributeInt(parser, "paddingRight", 0);
         wallpaper.padding.bottom = getAttributeInt(parser, "paddingBottom", 0);
+        int colorsCount = getAttributeInt(parser, "colorsCount", 0);
+        if (colorsCount > 0) {
+            Color primary = null, secondary = null, tertiary = null;
+            for (int i = 0; i < colorsCount; i++) {
+                Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
+                if (i == 0) {
+                    primary = color;
+                } else if (i == 1) {
+                    secondary = color;
+                } else if (i == 2) {
+                    tertiary = color;
+                } else {
+                    break;
+                }
+            }
+            int colorHints = getAttributeInt(parser, "colorHints", 0);
+            wallpaper.primaryColors = new WallpaperColors(primary, secondary, tertiary, colorHints);
+        }
         wallpaper.name = parser.getAttributeValue(null, "name");
         wallpaper.allowBackup = "true".equals(parser.getAttributeValue(null, "backup"));
     }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index fe90ba9..d4949b6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -278,6 +278,7 @@
         pw.println("Current WebView Update Service state");
         pw.println(String.format("  Fallback logic enabled: %b",
                 mSystemInterface.isFallbackLogicEnabled()));
+        pw.println(String.format("  Multiprocess enabled: %b", isMultiProcessEnabled()));
         mWebViewUpdater.dumpState(pw);
     }
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index 37479c8..203bbf6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -68,7 +68,7 @@
     // The WebView package currently in use (or the one we are preparing).
     private PackageInfo mCurrentWebViewPackage = null;
 
-    private Object mLock = new Object();
+    private final Object mLock = new Object();
 
     WebViewUpdater(Context context, SystemInterface systemInterface) {
         mContext = context;
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f138add..805250a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
+
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -418,13 +421,7 @@
         public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) {
             MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked();
             if (spec != null && !spec.isNop()) {
-                WindowManagerPolicy policy = mWindowManagerService.mPolicy;
-                final int windowType = windowState.mAttrs.type;
-                if (!policy.isTopLevelWindow(windowType) && windowState.isChildWindow()
-                        && !policy.canMagnifyWindow(windowType)) {
-                    return null;
-                }
-                if (!policy.canMagnifyWindow(windowState.mAttrs.type)) {
+                if (!mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) {
                     return null;
                 }
             }
@@ -540,8 +537,9 @@
                 final int visibleWindowCount = visibleWindows.size();
                 for (int i = visibleWindowCount - 1; i >= 0; i--) {
                     WindowState windowState = visibleWindows.valueAt(i);
-                    if (windowState.mAttrs.type == WindowManager
-                            .LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
+                    if ((windowState.mAttrs.type == TYPE_MAGNIFICATION_OVERLAY)
+                            || ((windowState.mAttrs.privateFlags
+                            & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) {
                         continue;
                     }
 
@@ -715,7 +713,7 @@
                     mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
                             .getLayerStack());
                     mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw(
-                            WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
+                            TYPE_MAGNIFICATION_OVERLAY)
                             * WindowManagerService.TYPE_LAYER_MULTIPLIER);
                     mSurfaceControl.setPosition(0, 0);
                     mSurface.copyFrom(mSurfaceControl);
@@ -1313,7 +1311,7 @@
                     && windowType != WindowManager.LayoutParams.TYPE_DRAG
                     && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
                     && windowType != WindowManager.LayoutParams.TYPE_POINTER
-                    && windowType != WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
+                    && windowType != TYPE_MAGNIFICATION_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index f769261..ddbbde1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -198,6 +198,14 @@
         return animation != null || mAppToken.inPendingTransaction;
     }
 
+    /**
+     * @return whether an animation is about to start, i.e. the animation is set already but we
+     *         haven't processed the first frame yet.
+     */
+    boolean isAnimationStarting() {
+        return animation != null && !animating;
+    }
+
     public int getTransit() {
         return mTransit;
     }
@@ -350,7 +358,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 +424,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 5f34c60..e9696d2 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -115,41 +115,6 @@
         mListener.onWindowsGone();
     };
 
-    private final Runnable mRemoveStartingWindow = () -> {
-        StartingSurface surface = null;
-        synchronized (mWindowMap) {
-            if (mContainer == null) {
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
-                        + " remove starting window");
-                return;
-            }
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting " + mContainer
-                    + ": startingWindow=" + mContainer.startingWindow
-                    + " startingView=" + mContainer.startingSurface);
-            if (mContainer.startingData != null) {
-                surface = mContainer.startingSurface;
-                mContainer.startingData = null;
-                mContainer.startingSurface = null;
-                mContainer.startingWindow = null;
-                mContainer.startingDisplayed = false;
-                if (surface == null && DEBUG_STARTING_WINDOW) {
-                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
-                            + "remove");
-                }
-            } else if (DEBUG_STARTING_WINDOW) {
-                Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
-                        + mContainer);
-            }
-        }
-        if (surface != null) {
-            try {
-                surface.remove();
-            } catch (Exception e) {
-                Slog.w(TAG_WM, "Exception when removing starting window", e);
-            }
-        }
-    };
-
     private final Runnable mAddStartingWindow = () -> {
         final StartingData startingData;
         final AppWindowToken container;
@@ -436,7 +401,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
@@ -522,9 +487,8 @@
             }
 
             final WindowState mainWin = mContainer.findMainWindow();
-            if (mainWin != null && mainWin.isVisible() && mainWin.isDrawnLw()) {
-                // App already has a visible window that is drawn...why would you want a starting
-                // window?
+            if (mainWin != null && mainWin.mWinAnimator.getShown()) {
+                // App already has a visible window...why would you want a starting window?
                 return false;
             }
 
@@ -614,7 +578,7 @@
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return snapshot == null ? STARTING_WINDOW_TYPE_NONE
-                    : snapshotOrientationSameAsDisplay(snapshot) || fromRecents
+                    : snapshotOrientationSameAsTask(snapshot) || fromRecents
                             ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else {
             return STARTING_WINDOW_TYPE_NONE;
@@ -640,35 +604,15 @@
         return true;
     }
 
-    private boolean snapshotOrientationSameAsDisplay(TaskSnapshot snapshot) {
+    private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
-        final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(),
-                snapshot.getSnapshot().getHeight());
-        rect.inset(snapshot.getContentInsets());
-        final Rect taskBoundsWithoutInsets = new Rect();
-        mContainer.getTask().getBounds(taskBoundsWithoutInsets);
-        final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo();
-        final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight);
-        final Rect stableInsets = new Rect();
-        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
-                stableInsets);
-        displayBounds.inset(stableInsets);
-        final boolean snapshotInLandscape = rect.width() >= rect.height();
-        final boolean displayInLandscape = displayBounds.width() >= displayBounds.height();
-        return snapshotInLandscape == displayInLandscape;
+        return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
     }
 
     public void removeStartingWindow() {
         synchronized (mWindowMap) {
-            if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
-                // Already scheduled.
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Trying to remove starting window but "
-                        + "already scheduled");
-                return;
-            }
-
             if (mContainer.startingWindow == null) {
                 if (mContainer.startingData != null) {
                     // Starting window has not been added yet, but it is scheduled to be added.
@@ -680,9 +624,39 @@
                 return;
             }
 
+            final StartingSurface surface;
+            if (mContainer.startingData != null) {
+                surface = mContainer.startingSurface;
+                mContainer.startingData = null;
+                mContainer.startingSurface = null;
+                mContainer.startingWindow = null;
+                mContainer.startingDisplayed = false;
+                if (surface == null && DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
+                            + "remove");
+                }
+            } else {
+                if (DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
+                            + mContainer);
+                }
+                return;
+            }
+
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer
-                    + " startingWindow=" + mContainer.startingWindow);
-            mHandler.post(mRemoveStartingWindow);
+                    + " startingWindow=" + mContainer.startingWindow
+                    + " startingView=" + mContainer.startingSurface);
+
+            // Use the same thread to remove the window as we used to add it, as otherwise we end up
+            // with things in the view hierarchy being called from different threads.
+            mHandler.post(() -> {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
+                try {
+                    surface.remove();
+                } catch (Exception e) {
+                    Slog.w(TAG_WM, "Exception when removing starting window", e);
+                }
+            });
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index bd37934..2e4de8c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -193,6 +193,11 @@
 
     Task mLastParent;
 
+    /**
+     * See {@link #canTurnScreenOn()}
+     */
+    private boolean mCanTurnScreenOn = true;
+
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
             boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -290,7 +295,7 @@
         boolean nowGone = mReportedVisibilityResults.nowGone;
 
         boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
-        boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+        boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !hidden;
         if (!nowGone) {
             // If the app is not yet gone, then it can only become visible/drawn.
             if (!nowDrawn) {
@@ -431,11 +436,18 @@
                 mEnteringAnimation = true;
                 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
             }
+
             // If we are hidden but there is no delay needed we immediately
             // apply the Surface transaction so that the ActivityManager
-            // can have some guarantee on the Surface state
-            // following setting the visibility.
-            if (hidden && !delayed) {
+            // can have some guarantee on the Surface state following
+            // setting the visibility. This captures cases like dismissing
+            // the docked or pinned stack where there is no app transition.
+            //
+            // In the case of a "Null" animation, there will be
+            // no animation but there will still be a transition set.
+            // We still need to delay hiding the surface such that it
+            // can be synchronized with showing the next surface in the transition.
+            if (hidden && !delayed && !mService.mAppTransition.isTransitionSet()) {
                 SurfaceControl.openTransaction();
                 for (int i = mChildren.size() - 1; i >= 0; i--) {
                     mChildren.get(i).mWinAnimator.hide("immediately hidden");
@@ -637,6 +649,8 @@
         if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
                 + " " + this);
         mAppStopped = false;
+        // Allow the window to turn the screen on once the app is resumed again.
+        setCanTurnScreenOn(true);
         if (!wasStopped) {
             destroySurfaces(true /*cleanupOnResume*/);
         }
@@ -937,8 +951,6 @@
             // Update keyguard flags upon finishing relaunch.
             checkKeyguardFlagsChanged();
         }
-
-        updateAllDrawn();
     }
 
     void clearRelaunching() {
@@ -1301,7 +1313,7 @@
         // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
         // an Activity in another task being started in the wrong orientation during the transition.
         if (!(sendingToBottom || mService.mClosingApps.contains(this))
-                && (isVisible() || mService.mOpeningApps.contains(this))) {
+                && (isVisible() || mService.mOpeningApps.contains(this) || isOnTop())) {
             return mOrientation;
         }
 
@@ -1344,12 +1356,41 @@
         }
     }
 
+    /**
+     * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
+     * child {@link WindowState}. A child is considered if it has been passed into
+     * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
+     * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
+     * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
+     *
+     * @return {@code true} If all children have been considered, {@code false}.
+     */
+    private boolean allDrawnStatesConsidered() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowState child = mChildren.get(i);
+            if (child.mightAffectAllDrawn(false /*visibleOnly*/ )
+                    && !child.getDrawnStateEvaluated()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     *  Determines if the token has finished drawing. This should only be called from
+     *  {@link DisplayContent#applySurfaceChangesTransaction}
+     */
     void updateAllDrawn() {
         if (!allDrawn) {
             // Number of drawn windows can be less when a window is being relaunched, wait for
-            // all windows to be launched and drawn for this token be considered all drawn
+            // all windows to be launched and drawn for this token be considered all drawn.
             final int numInteresting = mNumInterestingWindows;
-            if (numInteresting > 0 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
+
+            // We must make sure that all present children have been considered (determined by
+            // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
+            // drawn.
+            if (numInteresting > 0 && allDrawnStatesConsidered()
+                    && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
                 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
                         + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
                 allDrawn = true;
@@ -1394,6 +1435,8 @@
      *         windows in this app token where not considered drawn as of the last pass.
      */
     boolean updateDrawnWindowStates(WindowState w) {
+        w.setDrawnStateEvaluated(true /*evaluated*/);
+
         if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
             Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
                     + " allDrawn=" + allDrawn + " freezingScreen=" + mAppAnimator.freezingScreen);
@@ -1571,6 +1614,17 @@
         return null;
     }
 
+    int getLowestAnimLayer() {
+        for (int i = 0; i < mChildren.size(); i++) {
+            final WindowState w = mChildren.get(i);
+            if (w.mRemoved) {
+                continue;
+            }
+            return w.mWinAnimator.mAnimLayer;
+        }
+        return Integer.MAX_VALUE;
+    }
+
     WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
         WindowState candidate = null;
         for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
@@ -1594,6 +1648,24 @@
     }
 
     /**
+     * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+     */
+    void setCanTurnScreenOn(boolean canTurnScreenOn) {
+        mCanTurnScreenOn = canTurnScreenOn;
+    }
+
+    /**
+     * Indicates whether the current launch can turn the screen on. This is to prevent multiple
+     * relayouts from turning the screen back on. The screen should only turn on at most
+     * once per activity resume.
+     *
+     * @return true if the screen can be turned on.
+     */
+    boolean canTurnScreenOn() {
+        return mCanTurnScreenOn;
+    }
+
+    /**
      * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
      * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
      * we can't take a snapshot for other reasons, for example, if we have a secure window.
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 015c084..708973d 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -81,6 +81,12 @@
         boolean isAttachedToDisplay();
         /** Gets the bounds of the dim layer user. */
         void getDimBounds(Rect outBounds);
+        /** Returns the layer to place a dim layer. */
+        default int getLayerForDim(WindowStateAnimator animator, int layerOffset,
+                int defaultLayer) {
+            return defaultLayer;
+        }
+
         String toShortString();
     }
     /** The user of this dim layer. */
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index d44cd13..7414928 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -261,7 +261,8 @@
                 dimLayer = state.animator.mAnimLayer + LAYER_OFFSET_DIM;
                 dimAmount = DEFAULT_DIM_AMOUNT_DEAD_WINDOW;
             } else {
-                dimLayer = state.animator.mAnimLayer - LAYER_OFFSET_DIM;
+                dimLayer = dimLayerUser.getLayerForDim(state.animator, LAYER_OFFSET_DIM,
+                        state.animator.mAnimLayer - LAYER_OFFSET_DIM);
                 dimAmount = state.animator.mWin.mAttrs.dimAmount;
             }
         }
@@ -289,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 54983c8..5bc4a6b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -210,6 +210,7 @@
     final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
     /** @see #computeCompatSmallestWidth(boolean, int, int, int, int) */
     private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
+
     /**
      * Compat metrics computed based on {@link #mDisplayMetrics}.
      * @see #updateDisplayAndOrientation(int)
@@ -226,6 +227,7 @@
      * @see #updateRotationUnchecked(boolean)
      */
     private int mRotation = 0;
+
     /**
      * Last applied orientation of the display.
      * Constants as per {@link android.content.pm.ActivityInfo.ScreenOrientation}.
@@ -233,6 +235,7 @@
      * @see WindowManagerService#updateOrientationFromAppTokensLocked(boolean, int)
      */
     private int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
     /**
      * Flag indicating that the application is receiving an orientation that has different metrics
      * than it expected. E.g. Portrait instead of Landscape.
@@ -240,6 +243,7 @@
      * @see #updateRotationUnchecked(boolean)
      */
     private boolean mAltOrientation = false;
+
     /**
      * Orientation forced by some window. If there is no visible window that specifies orientation
      * it is set to {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
@@ -247,6 +251,7 @@
      * @see NonAppWindowContainers#getOrientation()
      */
     private int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
     /**
      * Last orientation forced by the keyguard. It is applied when keyguard is shown and is not
      * occluded.
@@ -255,6 +260,11 @@
      */
     private int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
+    /**
+     * Keep track of wallpaper visibility to notify changes.
+     */
+    private boolean mLastWallpaperVisible = false;
+
     private Rect mBaseDisplayRect = new Rect();
     private Rect mContentRect = new Rect();
 
@@ -1063,7 +1073,7 @@
             }
             if (w.mHasSurface && !rotateSeamlessly) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
-                w.mOrientationChanging = true;
+                w.setOrientationChanging(true);
                 mService.mRoot.mOrientationChangeComplete = false;
                 w.mLastFreezeDuration = 0;
             }
@@ -1173,6 +1183,7 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
+
         config.screenWidthDp =
                 (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
                         config.uiMode, mDisplayId) / mDisplayMetrics.density);
@@ -1207,7 +1218,7 @@
                 (displayInfo.isHdr()
                         ? Configuration.COLOR_MODE_HDR_YES
                         : Configuration.COLOR_MODE_HDR_NO)
-                        | (displayInfo.isWideColorGamut()
+                        | (displayInfo.isWideColorGamut() && mService.hasWideColorGamutSupport()
                         ? Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES
                         : Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);
 
@@ -2667,10 +2678,10 @@
         mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
 
         forAllWindows(w -> {
-            if (!w.mOrientationChanging) {
+            if (!w.getOrientationChanging()) {
                 return;
             }
-            w.mOrientationChanging = false;
+            w.orientationChangeTimedOut();
             w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             Slog.w(TAG_WM, "Force clearing orientation change: " + w);
@@ -2765,6 +2776,12 @@
 
         stopDimmingIfNeeded();
 
+        final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
+        if (wallpaperVisible != mLastWallpaperVisible) {
+            mLastWallpaperVisible = wallpaperVisible;
+            mService.mWallpaperVisibilityListeners.notifyWallpaperVisibilityChanged(this);
+        }
+
         while (!mTmpUpdateAllDrawn.isEmpty()) {
             final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
             // See if any windows have been drawn, so they (and others associated with them)
@@ -2974,14 +2991,14 @@
                 // Don't include wallpaper in bounds calculation
                 if (!w.mIsWallpaper && !mutableIncludeFullDisplay.value) {
                     if (includeDecor) {
-                        final TaskStack stack = w.getStack();
-                        if (stack != null) {
-                            stack.getBounds(frame);
-                        }
+                        final Task task = w.getTask();
+                        if (task != null) {
+                            task.getBounds(frame);
+                        } else {
 
-                        // We want to screenshot with the exact bounds of the surface of the app. Thus,
-                        // intersect it with the frame.
-                        frame.intersect(w.mFrame);
+                            // No task bounds? Too bad! Ain't no screenshot then.
+                            return true;
+                        }
                     } else {
                         final Rect wf = w.mFrame;
                         final Rect cr = w.mContentInsets;
@@ -3291,6 +3308,13 @@
             setLayoutNeeded();
         }
 
+
+        @Override
+        boolean isOnTop() {
+            // Considered always on top
+            return true;
+        }
+
         @Override
         void positionChildAt(int position, TaskStack child, boolean includingParents) {
             if (StackId.isAlwaysOnTop(child.mStackId) && position != POSITION_TOP) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2d7fc68..6b51455 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -427,8 +427,9 @@
                 inputMethodManagerInternal.hideCurrentInputMethod();
                 mImeHideRequested = true;
             }
+            return;
         }
-        setMinimizedDockedStack(false, false /* animate */);
+        setMinimizedDockedStack(false /* minimizedDock */, false /* animate */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
index 6b0e4c9..484987e 100644
--- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java
+++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
@@ -36,11 +36,11 @@
     }
 
     @Override
-    public void onInputEvent(InputEvent event) {
+    public void onInputEvent(InputEvent event, int displayId) {
         try {
             if (event instanceof MotionEvent
                     && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                final MotionEvent motionEvent = (MotionEvent)event;
+                final MotionEvent motionEvent = (MotionEvent) event;
                 PointerEventListener[] listeners;
                 synchronized (mListeners) {
                     if (mListenersArray == null) {
@@ -50,7 +50,7 @@
                     listeners = mListenersArray;
                 }
                 for (int i = 0; i < listeners.length; ++i) {
-                    listeners[i].onPointerEvent(motionEvent);
+                    listeners[i].onPointerEvent(motionEvent, displayId);
                 }
             }
         } finally {
diff --git a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
index 0508fdf..a12c2c4 100644
--- a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
+++ b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
@@ -32,7 +32,7 @@
 // the surface control.
 //
 // See cts/hostsidetests/../../SurfaceTraceReceiver.java for parsing side.
-class RemoteSurfaceTrace extends SurfaceControl {
+class RemoteSurfaceTrace extends SurfaceControlWithBackground {
     static final String TAG = "RemoteSurfaceTrace";
 
     final FileDescriptor mWriteFd;
@@ -41,7 +41,8 @@
     final WindowManagerService mService;
     final WindowState mWindow;
 
-    RemoteSurfaceTrace(FileDescriptor fd, SurfaceControl wrapped, WindowState window) {
+    RemoteSurfaceTrace(FileDescriptor fd, SurfaceControlWithBackground wrapped,
+            WindowState window) {
         super(wrapped);
 
         mWriteFd = fd;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75b..7bcad9f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.hardware.power.V1_0.PowerHint;
 import android.os.Binder;
 import android.os.Debug;
@@ -51,6 +52,7 @@
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
@@ -243,12 +245,24 @@
                     displayId, displayInfo);
             mService.configureDisplayPolicyLocked(dc);
 
-            // TODO(multi-display): Create an input channel for each display with touch capability.
-            if (displayId == DEFAULT_DISPLAY && mService.canDispatchPointerEvents()) {
-                dc.mTapDetector = new TaskTapPointerEventListener(
-                        mService, dc);
+            // Tap Listeners are supported for:
+            // 1. All physical displays (multi-display).
+            // 2. VirtualDisplays that support virtual touch input. (Only VR for now)
+            // TODO(multi-display): Support VirtualDisplays with no virtual touch input.
+            if ((display.getType() != Display.TYPE_VIRTUAL
+                    || (display.getType() == Display.TYPE_VIRTUAL
+                        // Only VR VirtualDisplays
+                        && displayId == mService.mVr2dDisplayId))
+                    && mService.canDispatchPointerEvents()) {
+                if (DEBUG_DISPLAY) {
+                    Slog.d(TAG,
+                            "Registering PointerEventListener for DisplayId: " + displayId);
+                }
+                dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
                 mService.registerPointerEventListener(dc.mTapDetector);
-                mService.registerPointerEventListener(mService.mMousePositionTracker);
+                if (displayId == DEFAULT_DISPLAY) {
+                    mService.registerPointerEventListener(mService.mMousePositionTracker);
+                }
             }
         }
 
@@ -754,6 +768,15 @@
             } else {
                 mUpdateRotation = false;
             }
+            // Update rotation of VR virtual display separately. Currently this is the only kind of
+            // secondary display that can be rotated because of the single-display limitations in
+            // PhoneWindowManager.
+            final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
+                    ? getDisplayContent(mService.mVr2dDisplayId) : null;
+            if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
+                mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
+                        .sendToTarget();
+            }
         }
 
         if (mService.mWaitingForDrawnCallback != null ||
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 7e575bf..22b0f5b 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -162,6 +162,7 @@
         }
     }
 
+    @Override
     public void binderDied() {
         // Note: it is safe to call in to the input method manager
         // here because we are not holding our lock.
@@ -208,6 +209,7 @@
             outContentInsets, outStableInsets, null /* outOutsets */, null);
     }
 
+    @Override
     public void remove(IWindow window) {
         mService.removeWindow(this, window);
     }
@@ -217,6 +219,7 @@
         mService.setWillReplaceWindows(appToken, childrenOnly);
     }
 
+    @Override
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
             int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
@@ -235,42 +238,50 @@
         return res;
     }
 
+    @Override
     public boolean outOfMemory(IWindow window) {
         return mService.outOfMemoryWindow(this, window);
     }
 
+    @Override
     public void setTransparentRegion(IWindow window, Region region) {
         mService.setTransparentRegionWindow(this, window, region);
     }
 
+    @Override
     public void setInsets(IWindow window, int touchableInsets,
             Rect contentInsets, Rect visibleInsets, Region touchableArea) {
         mService.setInsetsWindow(this, window, touchableInsets, contentInsets,
                 visibleInsets, touchableArea);
     }
 
+    @Override
     public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
         mService.getWindowDisplayFrame(this, window, outDisplayFrame);
     }
 
+    @Override
     public void finishDrawing(IWindow window) {
         if (WindowManagerService.localLOGV) Slog.v(
             TAG_WM, "IWindow finishDrawing called for " + window);
         mService.finishDrawingWindow(this, window);
     }
 
+    @Override
     public void setInTouchMode(boolean mode) {
         synchronized(mService.mWindowMap) {
             mService.mInTouchMode = mode;
         }
     }
 
+    @Override
     public boolean getInTouchMode() {
         synchronized(mService.mWindowMap) {
             return mService.mInTouchMode;
         }
     }
 
+    @Override
     public boolean performHapticFeedback(IWindow window, int effectId,
             boolean always) {
         synchronized(mService.mWindowMap) {
@@ -286,12 +297,14 @@
     }
 
     /* Drag/drop */
+    @Override
     public IBinder prepareDrag(IWindow window, int flags,
             int width, int height, Surface outSurface) {
         return mService.prepareDragSurface(window, mSurfaceSession, flags,
                 width, height, outSurface);
     }
 
+    @Override
     public boolean performDrag(IWindow window, IBinder dragToken,
             int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data) {
@@ -375,6 +388,7 @@
         return true;    // success!
     }
 
+    @Override
     public boolean startMovingTask(IWindow window, float startX, float startY) {
         if (DEBUG_TASK_POSITIONING) Slog.d(
                 TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
@@ -387,6 +401,7 @@
         }
     }
 
+    @Override
     public void reportDropResult(IWindow window, boolean consumed) {
         IBinder token = window.asBinder();
         if (DEBUG_DRAG) {
@@ -427,6 +442,7 @@
         }
     }
 
+    @Override
     public void cancelDragAndDrop(IBinder dragToken) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "cancelDragAndDrop");
@@ -455,18 +471,21 @@
         }
     }
 
+    @Override
     public void dragRecipientEntered(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void dragRecipientExited(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -480,12 +499,14 @@
         }
     }
 
+    @Override
     public void wallpaperOffsetsComplete(IBinder window) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window);
         }
     }
 
+    @Override
     public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -498,6 +519,7 @@
         }
     }
 
+    @Override
     public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, Bundle extras, boolean sync) {
         synchronized(mService.mWindowMap) {
@@ -512,12 +534,14 @@
         }
     }
 
+    @Override
     public void wallpaperCommandComplete(IBinder window, Bundle result) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperCommandComplete(window);
         }
     }
 
+    @Override
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
         synchronized(mService.mWindowMap) {
             final long identity = Binder.clearCallingIdentity();
@@ -529,6 +553,7 @@
         }
     }
 
+    @Override
     public IWindowId getWindowId(IBinder window) {
         return mService.getWindowId(window);
     }
diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
new file mode 100644
index 0000000..b0eaf14
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
@@ -0,0 +1,333 @@
+/*
+ * 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.wm;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
+
+/**
+ * SurfaceControl extension that has black background behind navigation bar area for fullscreen
+ * letterboxed apps.
+ */
+class SurfaceControlWithBackground extends SurfaceControl {
+    // SurfaceControl that holds the background.
+    private SurfaceControl mBackgroundControl;
+
+    // Flag that defines whether the background should be shown.
+    private boolean mVisible;
+
+    // Way to communicate with corresponding window.
+    private WindowSurfaceController mWindowSurfaceController;
+
+    // Rect to hold task bounds when computing metrics for background.
+    private Rect mTmpContainerRect = new Rect();
+
+    // Last metrics applied to the main SurfaceControl.
+    private float mLastWidth, mLastHeight;
+    private float mLastDsDx = 1, mLastDsDy = 1;
+    private float mLastX, mLastY;
+
+    // SurfaceFlinger doesn't support crop rectangles where width or height is non-positive.
+    // If we just set an empty crop it will behave as if there is no crop at all.
+    // To fix this we explicitly hide the surface and won't let it to be shown.
+    private boolean mHiddenForCrop = false;
+
+    public SurfaceControlWithBackground(SurfaceControlWithBackground other) {
+        super(other);
+        mBackgroundControl = other.mBackgroundControl;
+        mVisible = other.mVisible;
+        mWindowSurfaceController = other.mWindowSurfaceController;
+    }
+
+    public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format,
+            int flags, int windowType, int ownerUid,
+            WindowSurfaceController windowSurfaceController) throws OutOfResourcesException {
+        super(s, name, w, h, format, flags, windowType, ownerUid);
+
+        // We should only show background behind app windows that are letterboxed in a task.
+        if ((windowType != TYPE_BASE_APPLICATION && windowType != TYPE_APPLICATION_STARTING)
+                || !windowSurfaceController.mAnimator.mWin.isLetterboxedAppWindow()) {
+            return;
+        }
+        mWindowSurfaceController = windowSurfaceController;
+        mLastWidth = w;
+        mLastHeight = h;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl = new SurfaceControl(s, "Background for - " + name,
+                mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE,
+                flags | SurfaceControl.FX_SURFACE_DIM);
+    }
+
+    @Override
+    public void setAlpha(float alpha) {
+        super.setAlpha(alpha);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setAlpha(alpha);
+    }
+
+    @Override
+    public void setLayer(int zorder) {
+        super.setLayer(zorder);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        // TODO: Use setRelativeLayer(Integer.MIN_VALUE) when it's fixed.
+        mBackgroundControl.setLayer(zorder - 1);
+    }
+
+    @Override
+    public void setPosition(float x, float y) {
+        super.setPosition(x, y);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mLastX = x;
+        mLastY = y;
+        updateBgPosition();
+    }
+
+    private void updateBgPosition() {
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+        final float offsetX = (mTmpContainerRect.left - winFrame.left) * mLastDsDx;
+        final float offsetY = (mTmpContainerRect.top - winFrame.top) * mLastDsDy;
+        mBackgroundControl.setPosition(mLastX + offsetX, mLastY + offsetY);
+    }
+
+    @Override
+    public void setSize(int w, int h) {
+        super.setSize(w, h);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mLastWidth = w;
+        mLastHeight = h;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl.setSize(mTmpContainerRect.width(), mTmpContainerRect.height());
+    }
+
+    @Override
+    public void setWindowCrop(Rect crop) {
+        super.setWindowCrop(crop);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        calculateBgCrop(crop);
+        mBackgroundControl.setWindowCrop(mTmpContainerRect);
+        mHiddenForCrop = mTmpContainerRect.isEmpty();
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void setFinalCrop(Rect crop) {
+        super.setFinalCrop(crop);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        mBackgroundControl.setFinalCrop(mTmpContainerRect);
+    }
+
+    /**
+     * Compute background crop based on current animation progress for main surface control and
+     * update {@link #mTmpContainerRect} with new values.
+     */
+    private void calculateBgCrop(Rect crop) {
+        // Track overall progress of animation by computing cropped portion of status bar.
+        final Rect contentInsets = mWindowSurfaceController.mAnimator.mWin.mContentInsets;
+        float d = contentInsets.top == 0 ? 0 : (float) crop.top / contentInsets.top;
+        if (d > 1.f) {
+            // We're running expand animation from launcher, won't compute custom bg crop here.
+            mTmpContainerRect.setEmpty();
+            return;
+        }
+
+        // Compute new scaled width and height for background that will depend on current animation
+        // progress. Those consist of current crop rect for the main surface + scaled areas outside
+        // of letterboxed area.
+        // TODO: Because the progress is computed with low precision we're getting smaller values
+        // for background width/height then screen size at the end of the animation. Will round when
+        // the value is smaller then some empiric epsilon. However, this should be fixed by
+        // computing correct frames for letterboxed windows in WindowState.
+        d = d < 0.025f ? 0 : d;
+        mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+        int backgroundWidth = 0, backgroundHeight = 0;
+        // Compute additional offset for the background when app window is positioned not at (0,0).
+        // E.g. landscape with navigation bar on the left.
+        final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+        int offsetX = (int)((winFrame.left - mTmpContainerRect.left) * mLastDsDx),
+                offsetY = (int) ((winFrame.top - mTmpContainerRect.top) * mLastDsDy);
+
+        // Position and size background.
+        final int bgPosition = mWindowSurfaceController.mAnimator.mService.getNavBarPosition();
+
+        switch (bgPosition) {
+            case NAV_BAR_LEFT:
+                backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+                backgroundHeight = crop.height();
+                offsetX += crop.left - backgroundWidth;
+                offsetY += crop.top;
+                break;
+            case NAV_BAR_RIGHT:
+                backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+                backgroundHeight = crop.height();
+                offsetX += crop.right;
+                offsetY += crop.top;
+                break;
+            case NAV_BAR_BOTTOM:
+                backgroundWidth = crop.width();
+                backgroundHeight = (int) ((mTmpContainerRect.height() - mLastHeight) * (1 - d)
+                        + 0.5);
+                offsetX += crop.left;
+                offsetY += crop.bottom;
+                break;
+        }
+        mTmpContainerRect.set(offsetX, offsetY, offsetX + backgroundWidth,
+                offsetY + backgroundHeight);
+    }
+
+    @Override
+    public void setLayerStack(int layerStack) {
+        super.setLayerStack(layerStack);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setLayerStack(layerStack);
+    }
+
+    @Override
+    public void setOpaque(boolean isOpaque) {
+        super.setOpaque(isOpaque);
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void setSecure(boolean isSecure) {
+        super.setSecure(isSecure);
+    }
+
+    @Override
+    public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
+        super.setMatrix(dsdx, dtdx, dtdy, dsdy);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
+        mLastDsDx = dsdx;
+        mLastDsDy = dsdy;
+        updateBgPosition();
+    }
+
+    @Override
+    public void hide() {
+        super.hide();
+        mVisible = false;
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void show() {
+        super.show();
+        mVisible = true;
+        updateBackgroundVisibility();
+    }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.destroy();
+    }
+
+    @Override
+    public void release() {
+        super.release();
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.release();
+    }
+
+    @Override
+    public void setTransparentRegionHint(Region region) {
+        super.setTransparentRegionHint(region);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.setTransparentRegionHint(region);
+    }
+
+    @Override
+    public void deferTransactionUntil(IBinder handle, long frame) {
+        super.deferTransactionUntil(handle, frame);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.deferTransactionUntil(handle, frame);
+    }
+
+    @Override
+    public void deferTransactionUntil(Surface barrier, long frame) {
+        super.deferTransactionUntil(barrier, frame);
+
+        if (mBackgroundControl == null) {
+            return;
+        }
+        mBackgroundControl.deferTransactionUntil(barrier, frame);
+    }
+
+    private void updateBackgroundVisibility() {
+        if (mBackgroundControl == null) {
+            return;
+        }
+        final AppWindowToken appWindowToken = mWindowSurfaceController.mAnimator.mWin.mAppToken;
+        if (!mHiddenForCrop && mVisible && appWindowToken != null && appWindowToken.fillsParent()) {
+            mBackgroundControl.show();
+        } else {
+            mBackgroundControl.hide();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bfebca8..e5055e9 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -23,6 +23,8 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
 import static com.android.server.EventLogTags.WM_TASK_REMOVED;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -39,6 +41,7 @@
 import android.view.Surface;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.DimLayer.DimLayerUser;
 
 import java.io.PrintWriter;
 import java.util.function.Consumer;
@@ -621,6 +624,17 @@
         return token != null ? token.findMainWindow() : null;
     }
 
+    AppWindowToken getTopFullscreenAppToken() {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final AppWindowToken token = mChildren.get(i);
+            final WindowState win = token.findMainWindow();
+            if (win != null && win.mAttrs.isFullscreen()) {
+                return token;
+            }
+        }
+        return null;
+    }
+
     AppWindowToken getTopVisibleAppToken() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken token = mChildren.get(i);
@@ -637,6 +651,18 @@
         return isFullscreen();
     }
 
+    @Override
+    public int getLayerForDim(WindowStateAnimator animator, int layerOffset, int defaultLayer) {
+        // If the dim layer is for a starting window, move the dim layer back in the z-order behind
+        // the lowest activity window to ensure it does not occlude the main window if it is
+        // translucent
+        final AppWindowToken appToken = animator.mWin.mAppToken;
+        if (animator.mAttrType == TYPE_APPLICATION_STARTING && hasChild(appToken) ) {
+            return Math.min(defaultLayer, appToken.getLowestAnimLayer() - layerOffset);
+        }
+        return defaultLayer;
+    }
+
     boolean isFullscreen() {
         if (useCurrentBounds()) {
             return mFillsParent;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 0c68e2c..c58212c 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -133,7 +133,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             if (!(event instanceof MotionEvent)
                     || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
                 return;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index bf8fabd..b8b9b9a 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -18,6 +18,9 @@
 
 import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
@@ -29,6 +32,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.util.ArraySet;
+import android.util.Slog;
 import android.view.DisplayListCanvas;
 import android.view.RenderNode;
 import android.view.ThreadedRenderer;
@@ -57,6 +61,7 @@
  * To access this class, acquire the global window manager lock.
  */
 class TaskSnapshotController {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotController" : TAG_WM;
 
     /**
      * Return value for {@link #getSnapshotMode}: We are allowed to take a real screenshot to be
@@ -147,10 +152,17 @@
                     break;
             }
             if (snapshot != null) {
-                mCache.putSnapshot(task, snapshot);
-                mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
-                if (task.getController() != null) {
-                    task.getController().reportSnapshotChanged(snapshot);
+                final GraphicBuffer buffer = snapshot.getSnapshot();
+                if (buffer.getWidth() == 0 || buffer.getHeight() == 0) {
+                    buffer.destroy();
+                    Slog.e(TAG, "Invalid task snapshot dimensions " + buffer.getWidth() + "x"
+                            + buffer.getHeight());
+                } else {
+                    mCache.putSnapshot(task, snapshot);
+                    mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
+                    if (task.getController() != null) {
+                        task.getController().reportSnapshotChanged(snapshot);
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 297e288..f90b3fb 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -25,6 +25,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
 import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -290,7 +291,6 @@
                 failed = true;
             }
             if (!writeBuffer()) {
-                writeBuffer();
                 failed = true;
             }
             if (failed) {
@@ -325,6 +325,11 @@
             final File file = getBitmapFile(mTaskId, mUserId);
             final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
+            if (bitmap == null) {
+                Slog.e(TAG, "Invalid task snapshot hw bitmap");
+                return false;
+            }
+
             final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
             final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
                     (int) (bitmap.getWidth() * REDUCED_SCALE),
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index a96d224..d7f0496 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -20,6 +20,7 @@
 import static android.graphics.Color.alpha;
 import static android.view.SurfaceControl.HIDDEN;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
 import static android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE;
@@ -150,15 +151,29 @@
         final int currentOrientation;
         synchronized (service.mWindowMap) {
             final WindowState mainWindow = token.findMainWindow();
-            if (mainWindow == null) {
+            final Task task = token.getTask();
+            if (task == null) {
+                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find task for token="
+                        + token);
+                return null;
+            }
+            final AppWindowToken topFullscreenToken = token.getTask().getTopFullscreenAppToken();
+            if (topFullscreenToken == null) {
+                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find top fullscreen for task="
+                        + task);
+                return null;
+            }
+            final WindowState topFullscreenWindow = topFullscreenToken.findMainWindow();
+            if (mainWindow == null || topFullscreenWindow == null) {
                 Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find main window for token="
                         + token);
                 return null;
             }
-            sysUiVis = mainWindow.getSystemUiVisibility();
-            windowFlags = mainWindow.getAttrs().flags;
-            windowPrivateFlags = mainWindow.getAttrs().privateFlags;
+            sysUiVis = topFullscreenWindow.getSystemUiVisibility();
+            windowFlags = topFullscreenWindow.getAttrs().flags;
+            windowPrivateFlags = topFullscreenWindow.getAttrs().privateFlags;
 
+            layoutParams.dimAmount = mainWindow.getAttrs().dimAmount;
             layoutParams.type = TYPE_APPLICATION_STARTING;
             layoutParams.format = snapshot.getSnapshot().getFormat();
             layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
@@ -170,22 +185,17 @@
             layoutParams.width = LayoutParams.MATCH_PARENT;
             layoutParams.height = LayoutParams.MATCH_PARENT;
             layoutParams.systemUiVisibility = sysUiVis;
-            final Task task = token.getTask();
-            if (task != null) {
-                layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
+            layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
 
-                final TaskDescription taskDescription = task.getTaskDescription();
-                if (taskDescription != null) {
-                    backgroundColor = taskDescription.getBackgroundColor();
-                    statusBarColor = taskDescription.getStatusBarColor();
-                    navigationBarColor = taskDescription.getNavigationBarColor();
-                }
-                taskBounds = new Rect();
-                task.getBounds(taskBounds);
-            } else {
-                taskBounds = null;
+            final TaskDescription taskDescription = task.getTaskDescription();
+            if (taskDescription != null) {
+                backgroundColor = taskDescription.getBackgroundColor();
+                statusBarColor = taskDescription.getStatusBarColor();
+                navigationBarColor = taskDescription.getNavigationBarColor();
             }
-            currentOrientation = mainWindow.getConfiguration().orientation;
+            taskBounds = new Rect();
+            task.getBounds(taskBounds);
+            currentOrientation = topFullscreenWindow.getConfiguration().orientation;
         }
         try {
             final int res = session.addToDisplay(window, window.mSeq, layoutParams,
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index dd9ba73..42a2d9d 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -24,6 +24,7 @@
 
 import com.android.server.wm.WindowManagerService.H;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.PointerIcon.TYPE_NOT_SPECIFIED;
 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
@@ -45,6 +46,13 @@
     }
 
     @Override
+    public void onPointerEvent(MotionEvent motionEvent, int displayId) {
+        if (displayId == getDisplayId()) {
+            onPointerEvent(motionEvent);
+        }
+    }
+
+    @Override
     public void onPointerEvent(MotionEvent motionEvent) {
         final int action = motionEvent.getAction();
         switch (action & MotionEvent.ACTION_MASK) {
@@ -104,4 +112,8 @@
            mTouchExcludeRegion.set(newRegion);
         }
     }
+
+    private int getDisplayId() {
+        return mDisplayContent.getDisplayId();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 9f02485..54a6cc0 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -80,7 +80,9 @@
             final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
                     supportsPictureInPicture, homeTask, taskDescription);
             final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
-            stack.addTask(task, position, showForAllUsers, true /* moveParents */);
+            // We only want to move the parents to the parents if we are creating this task at the
+            // top of its stack.
+            stack.addTask(task, position, showForAllUsers, toTop /* moveParents */);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java b/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java
new file mode 100644
index 0000000..2c06851
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WallpaperVisibilityListeners.java
@@ -0,0 +1,79 @@
+/*
+ * 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.wm;
+
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.SparseArray;
+import android.view.IWallpaperVisibilityListener;
+
+/**
+ * Manages and trigger wallpaper visibility listeners.
+ */
+class WallpaperVisibilityListeners {
+
+    /**
+     * A map of displayIds and its listeners.
+     */
+    private final SparseArray<RemoteCallbackList<IWallpaperVisibilityListener>> mDisplayListeners =
+            new SparseArray<>();
+
+    void registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        RemoteCallbackList<IWallpaperVisibilityListener> listeners =
+                mDisplayListeners.get(displayId);
+        if (listeners == null) {
+            listeners = new RemoteCallbackList<>();
+            mDisplayListeners.append(displayId, listeners);
+        }
+        listeners.register(listener);
+    }
+
+    void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        RemoteCallbackList<IWallpaperVisibilityListener> listeners =
+                mDisplayListeners.get(displayId);
+        if (listeners == null) {
+            return;
+        }
+        listeners.unregister(listener);
+    }
+
+    void notifyWallpaperVisibilityChanged(DisplayContent displayContent) {
+        final int displayId = displayContent.getDisplayId();
+        final boolean visible = displayContent.mWallpaperController.isWallpaperVisible();
+        RemoteCallbackList<IWallpaperVisibilityListener> displayListeners =
+                mDisplayListeners.get(displayId);
+
+        // No listeners for this display.
+        if (displayListeners == null) {
+            return;
+        }
+
+        int i = displayListeners.beginBroadcast();
+        while (i > 0) {
+            i--;
+            IWallpaperVisibilityListener listener = displayListeners.getBroadcastItem(i);
+            try {
+                listener.onWallpaperVisibilityChanged(visible, displayId);
+            } catch (RemoteException e) {
+                // Nothing to do in here, RemoteCallbackListener will clean it up.
+            }
+        }
+        displayListeners.finishBroadcast();
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index fe5b7f2..079ae40 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -33,7 +33,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 
-import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
 import com.android.server.AnimationThread;
 
 import java.io.PrintWriter;
@@ -134,26 +133,38 @@
      * sure other threads can make progress if this happens.
      */
     private void animate(long frameTimeNs) {
-        boolean transactionOpen = false;
-        try {
-            synchronized (mService.mWindowMap) {
-                if (!mInitialized) {
-                    return;
-                }
 
-                mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
-                mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
-                mAnimating = false;
-                mAppWindowAnimating = false;
-                if (DEBUG_WINDOW_TRACE) {
-                    Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
-                }
+        synchronized (mService.mWindowMap) {
+            if (!mInitialized) {
+                return;
+            }
 
-                if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
-                mService.openSurfaceTransaction();
-                transactionOpen = true;
-                SurfaceControl.setAnimationTransaction();
+            // Schedule next frame already such that back-pressure happens continuously
+            scheduleAnimation();
+        }
 
+        // Simulate back-pressure by opening and closing an empty animation transaction. This makes
+        // sure that an animation frame is at least presented once on the screen. We do this outside
+        // of the regular transaction such that we can avoid holding the window manager lock in case
+        // we receive back-pressure from SurfaceFlinger. Since closing an animation transaction
+        // without the window manager locks leads to ordering issues (as the transaction will be
+        // processed only at the beginning of the next frame which may result in another transaction
+        // that was executed later in WM side gets executed first on SF side), we don't update any
+        // Surface properties here such that reordering doesn't cause issues.
+        mService.executeEmptyAnimationTransaction();
+
+        synchronized (mService.mWindowMap) {
+            mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
+            mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
+            mAnimating = false;
+            mAppWindowAnimating = false;
+            if (DEBUG_WINDOW_TRACE) {
+                Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
+            }
+
+            if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
+            mService.openSurfaceTransaction();
+            try {
                 final AccessibilityController accessibilityController =
                         mService.mAccessibilityController;
                 final int numDisplays = mDisplayContentsAnimators.size();
@@ -216,27 +227,20 @@
                     mAnimating |= mService.mDragState.stepAnimationLocked(mCurrentTime);
                 }
 
-                if (mAnimating) {
-                    mService.scheduleAnimationLocked();
+                if (!mAnimating) {
+                    cancelAnimation();
                 }
 
                 if (mService.mWatermark != null) {
                     mService.mWatermark.drawIfNeeded();
                 }
-            }
-        } catch (RuntimeException e) {
-            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
-        } finally {
-            if (transactionOpen) {
-
-                // Do not hold window manager lock while closing the transaction, as this might be
-                // blocking until the next frame, which can lead to total lock starvation.
-                mService.closeSurfaceTransaction(false /* withLockHeld */);
+            } catch (RuntimeException e) {
+                Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+            } finally {
+                mService.closeSurfaceTransaction();
                 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
             }
-        }
 
-        synchronized (mService.mWindowMap) {
             boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
             boolean doRequest = false;
             if (mBulkUpdateParams != 0) {
@@ -404,6 +408,13 @@
         }
     }
 
+    private void cancelAnimation() {
+        if (mAnimationFrameCallbackScheduled) {
+            mAnimationFrameCallbackScheduled = false;
+            mChoreographer.removeFrameCallback(mAnimationFrameCallback);
+        }
+    }
+
     private class DisplayContentsAnimator {
         ScreenRotationAnimation mScreenRotationAnimation = null;
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 600bc5c..3df73d7 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -472,6 +472,13 @@
         return false;
     }
 
+    /**
+a     * Returns whether this child is on top of the window hierarchy.
+     */
+    boolean isOnTop() {
+        return getParent().getTopChild() == this && getParent().isOnTop();
+    }
+
     /** Returns the top child container. */
     E getTopChild() {
         return mChildren.peekLast();
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index 01a3143..5dc79f8 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -17,13 +17,14 @@
 package com.android.server.wm;
 
 import android.util.Slog;
-import android.view.Display;
 
 import java.util.ArrayDeque;
 import java.util.function.Consumer;
 
+import static android.app.ActivityManager.StackId;
 import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -56,7 +57,6 @@
         mService = service;
     }
 
-    private int mHighestApplicationLayer = 0;
     private ArrayDeque<WindowState> mPinnedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mDockedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mAssistantWindows = new ArrayDeque<>();
@@ -66,6 +66,8 @@
     private int mCurBaseLayer;
     private int mCurLayer;
     private boolean mAnyLayerChanged;
+    private int mHighestApplicationLayer;
+    private int mHighestDockedAffectedLayer;
     private int mHighestLayerInImeTargetBaseLayer;
     private WindowState mImeTarget;
     private boolean mAboveImeTarget;
@@ -98,6 +100,10 @@
             mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
                     w.mWinAnimator.mAnimLayer);
         }
+        if (w.getAppToken() != null && StackId.isResizeableByDockedStack(w.getStackId())) {
+            mHighestDockedAffectedLayer = Math.max(mHighestDockedAffectedLayer,
+                    w.mWinAnimator.mAnimLayer);
+        }
 
         collectSpecialWindows(w);
 
@@ -135,7 +141,6 @@
     }
 
     private void reset() {
-        mHighestApplicationLayer = 0;
         mPinnedWindows.clear();
         mInputMethodWindows.clear();
         mDockedWindows.clear();
@@ -147,8 +152,10 @@
         mCurLayer = 0;
         mAnyLayerChanged = false;
 
-        mImeTarget = mService.mInputMethodTarget;
+        mHighestApplicationLayer = 0;
+        mHighestDockedAffectedLayer = 0;
         mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
+        mImeTarget = mService.mInputMethodTarget;
         mAboveImeTarget = false;
         mAboveImeTargetAppWindows.clear();
     }
@@ -179,32 +186,41 @@
             }
         }
 
-        final Task task = w.getTask();
-        if (task == null) {
-            return;
-        }
-        final TaskStack stack = task.mStack;
-        if (stack == null) {
-            return;
-        }
-        if (stack.mStackId == PINNED_STACK_ID) {
+        final int stackId = w.getAppToken() != null ? w.getStackId() : INVALID_STACK_ID;
+        if (stackId == PINNED_STACK_ID) {
             mPinnedWindows.add(w);
-        } else if (stack.mStackId == DOCKED_STACK_ID) {
+        } else if (stackId == DOCKED_STACK_ID) {
             mDockedWindows.add(w);
-        } else if (stack.mStackId == ASSISTANT_STACK_ID) {
+        } else if (stackId == ASSISTANT_STACK_ID) {
             mAssistantWindows.add(w);
         }
     }
 
     private void adjustSpecialWindows() {
-        int layer = mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER;
-        // For pinned and docked stack window, we want to make them above other windows also when
-        // these windows are animating.
-        while (!mDockedWindows.isEmpty()) {
-            layer = assignAndIncreaseLayerIfNeeded(mDockedWindows.remove(), layer);
+        // The following adjustments are beyond the highest docked-affected layer
+        int layer = mHighestDockedAffectedLayer +  WINDOW_LAYER_MULTIPLIER;
+
+        // Adjust the docked stack windows and dock divider above only the windows that are affected
+        // by the docked stack. When this happens, also boost the assistant window layers, otherwise
+        // the docked stack windows & divider would be promoted above the assistant.
+        if (!mDockedWindows.isEmpty() && mHighestDockedAffectedLayer > 0) {
+            while (!mDockedWindows.isEmpty()) {
+                final WindowState window = mDockedWindows.remove();
+                layer = assignAndIncreaseLayerIfNeeded(window, layer);
+            }
+
+            layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
+
+            while (!mAssistantWindows.isEmpty()) {
+                final WindowState window = mAssistantWindows.remove();
+                if (window.mLayer > mHighestDockedAffectedLayer) {
+                    layer = assignAndIncreaseLayerIfNeeded(window, layer);
+                }
+            }
         }
 
-        layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
+        // The following adjustments are beyond the highest app layer or boosted layer
+        layer = Math.max(layer, mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER);
 
         // We know that we will be animating a relaunching window in the near future, which will
         // receive a z-order increase. We want the replaced window to immediately receive the same
@@ -213,12 +229,6 @@
             layer = assignAndIncreaseLayerIfNeeded(mReplacingWindows.remove(), layer);
         }
 
-        // Adjust the assistant stack windows to be above the docked and fullscreen stack windows,
-        // but under the pinned stack windows
-        while (!mAssistantWindows.isEmpty()) {
-            layer = assignAndIncreaseLayerIfNeeded(mAssistantWindows.remove(), layer);
-        }
-
         while (!mPinnedWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7a91d1e..8ba36d5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,16 +19,17 @@
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
+import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_USER_HANDLE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.os.UserHandle.USER_NULL;
@@ -48,7 +49,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -79,6 +79,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -132,6 +133,8 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
+import android.hardware.configstore.V1_0.ISurfaceFlingerConfigs;
+import android.hardware.configstore.V1_0.OptionalBool;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.input.InputManager;
@@ -182,6 +185,7 @@
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedStackListener;
 import android.view.IRotationWatcher;
+import android.view.IWallpaperVisibilityListener;
 import android.view.IWindow;
 import android.view.IWindowId;
 import android.view.IWindowManager;
@@ -228,7 +232,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.ThreadPriorityBooster;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
@@ -355,6 +358,8 @@
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
     boolean mKeyguardGoingAway;
+    // VR Vr2d Display Id.
+    int mVr2dDisplayId = INVALID_DISPLAY;
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -550,9 +555,9 @@
     }
 
     class RotationWatcher {
-        IRotationWatcher mWatcher;
-        IBinder.DeathRecipient mDeathRecipient;
-        int mDisplayId;
+        final IRotationWatcher mWatcher;
+        final IBinder.DeathRecipient mDeathRecipient;
+        final int mDisplayId;
         RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient,
                 int displayId) {
             mWatcher = watcher;
@@ -563,6 +568,8 @@
 
     ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
     int mDeferredRotationPauseCount;
+    final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
+            new WallpaperVisibilityListeners();
 
     int mSystemDecorLayer = 0;
     final Rect mScreenRect = new Rect();
@@ -713,6 +720,9 @@
     final DisplayManager mDisplayManager;
     private final Display[] mDisplays;
 
+    // Indicates whether this device supports wide color gamut rendering
+    private boolean mHasWideColorGamutSupport;
+
     // Who is holding the screen on.
     private Session mHoldingScreenOn;
     private PowerManager.WakeLock mHoldingScreenWakeLock;
@@ -757,7 +767,7 @@
         }
 
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             boolean handled = false;
             try {
                 if (mDragState == null) {
@@ -898,29 +908,16 @@
         }
     }
 
-    void closeSurfaceTransaction() {
-        closeSurfaceTransaction(true /* withLockHeld */);
-    }
-
     /**
      * Closes a surface transaction.
-     *
-     * @param withLockHeld Whether to acquire the window manager while doing so. In some cases
-     *                     holding the lock my lead to starvation in WM in case closeTransaction
-     *                     blocks and we call it repeatedly, like we do for animations.
      */
-    void closeSurfaceTransaction(boolean withLockHeld) {
+    void closeSurfaceTransaction() {
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
             synchronized (mWindowMap) {
                 if (mRoot.mSurfaceTraceEnabled) {
                     mRoot.mRemoteEventTrace.closeSurfaceTransaction();
                 }
-                if (withLockHeld) {
-                    SurfaceControl.closeTransaction();
-                }
-            }
-            if (!withLockHeld) {
                 SurfaceControl.closeTransaction();
             }
         } finally {
@@ -928,6 +925,34 @@
         }
     }
 
+    /**
+     * Executes an empty animation transaction without holding the WM lock to simulate
+     * back-pressure. See {@link WindowAnimator#animate} why this is needed.
+     */
+    void executeEmptyAnimationTransaction() {
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
+            synchronized (mWindowMap) {
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.openSurfaceTransaction();
+                }
+                SurfaceControl.openTransaction();
+                SurfaceControl.setAnimationTransaction();
+                if (mRoot.mSurfaceTraceEnabled) {
+                    mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+                }
+            }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
+            SurfaceControl.closeTransaction();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+    }
+
     /** Listener to notify activity manager about app transitions. */
     final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
             = new WindowManagerInternal.AppTransitionListener() {
@@ -2010,8 +2035,7 @@
                     win.setDisplayLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement(true);
                 }
-                result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
-                        oldVisibility);
+                result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
 
                 try {
                     result = createSurfaceControl(outSurface, result, win, winAnimator);
@@ -2149,6 +2173,15 @@
             if (!win.isGoneForLayoutLw()) {
                 win.mResizedWhileGone = false;
             }
+
+            // We must always send the latest {@link MergedConfiguration}, regardless of whether we
+            // have already reported it. The client might not have processed the previous value yet
+            // and needs process it before handling the corresponding window frame. the variable
+            // {@code mergedConfiguration} is an out parameter that will be passed back to the
+            // client over IPC and checked there.
+            win.getMergedConfiguration(mergedConfiguration);
+            win.setReportedConfiguration(mergedConfiguration);
+
             outFrame.set(win.mCompatFrame);
             outOverscanInsets.set(win.mOverscanInsets);
             outContentInsets.set(win.mContentInsets);
@@ -2307,7 +2340,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;
@@ -2387,6 +2420,10 @@
         return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn();
     }
 
+    boolean okToAnimate() {
+        return okToDisplay() && mPolicy.okToAnimate();
+    }
+
     @Override
     public void addWindowToken(IBinder binder, int type, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
@@ -2653,7 +2690,7 @@
         synchronized(mWindowMap) {
             boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
                     flags, forceOverride);
-            if (prepared && okToDisplay()) {
+            if (prepared && okToAnimate()) {
                 mSkipAppTransitionAnimation = false;
             }
         }
@@ -3071,6 +3108,10 @@
         return mPolicy.isKeyguardLocked();
     }
 
+    public boolean isKeyguardShowingAndNotOccluded() {
+        return mPolicy.isKeyguardShowingAndNotOccluded();
+    }
+
     @Override
     public boolean isKeyguardSecure() {
         int userId = UserHandle.getCallingUserId();
@@ -3445,21 +3486,11 @@
             }
 
             if (!mBootAnimationStopped) {
-                // Do this one time.
                 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
-                try {
-                    IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
-                    if (surfaceFlinger != null) {
-                        Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
-                        Parcel data = Parcel.obtain();
-                        data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                        surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
-                                data, null, 0);
-                        data.recycle();
-                    }
-                } catch (RemoteException ex) {
-                    Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
-                }
+                // stop boot animation
+                // formerly we would just kill the process, but we now ask it to exit so it
+                // can choose where to stop the animation.
+                SystemProperties.set("service.bootanim.exit", "1");
                 mBootAnimationStopped = true;
             }
 
@@ -3468,6 +3499,20 @@
                 return;
             }
 
+            try {
+                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+                if (surfaceFlinger != null) {
+                    Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+                    Parcel data = Parcel.obtain();
+                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
+                            data, null, 0);
+                    data.recycle();
+                }
+            } catch (RemoteException ex) {
+                Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
+            }
+
             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
             Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
             mDisplayEnabled = true;
@@ -3989,6 +4034,29 @@
         }
     }
 
+    @Override
+    public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+            if (displayContent == null) {
+                throw new IllegalArgumentException("Trying to register visibility event "
+                        + "for invalid display: " + displayId);
+            }
+            mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId);
+            return displayContent.mWallpaperController.isWallpaperVisible();
+        }
+    }
+
+    @Override
+    public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
+            int displayId) {
+        synchronized (mWindowMap) {
+            mWallpaperVisibilityListeners
+                    .unregisterWallpaperVisibilityListener(listener, displayId);
+        }
+    }
+
     /**
      * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
      * theme attribute) on devices that feature a physical options menu key attempt to position
@@ -4740,6 +4808,20 @@
     public void systemReady() {
         mPolicy.systemReady();
         mTaskSnapshotController.systemReady();
+        mHasWideColorGamutSupport = queryWideColorGamutSupport();
+    }
+
+    private static boolean queryWideColorGamutSupport() {
+        try {
+            ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
+            OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay();
+            if (hasWideColor != null) {
+                return hasWideColor.value;
+            }
+        } catch (RemoteException e) {
+            // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
+        }
+        return false;
     }
 
     // -------------------------------------------------------------
@@ -5729,7 +5811,7 @@
         // orientation.
         if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
-            w.mOrientationChanging = true;
+            w.setOrientationChanging(true);
             w.mLastFreezeDuration = 0;
             mRoot.mOrientationChangeComplete = false;
             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
@@ -5943,9 +6025,9 @@
             return;
         }
 
-        if (!displayContent.isReady() || !mPolicy.isScreenOn()) {
-            // No need to freeze the screen before the display is ready, system is ready, or if
-            // the screen is off.
+        if (!displayContent.isReady() || !mPolicy.isScreenOn() || !okToAnimate()) {
+            // No need to freeze the screen before the display is ready,  if the screen is off,
+            // or we can't currently animate.
             return;
         }
 
@@ -6232,6 +6314,22 @@
         }
     }
 
+    /**
+     * Used by ActivityManager to determine where to position an app with aspect ratio shorter then
+     * the screen is.
+     * @see WindowManagerPolicy#getNavBarPosition()
+     */
+    public int getNavBarPosition() {
+        synchronized (mWindowMap) {
+            // Perform layout if it was scheduled before to make sure that we get correct nav bar
+            // position when doing rotations.
+            final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
+            defaultDisplayContent.performLayout(false /* initial */,
+                    false /* updateInputWindows */);
+            return mPolicy.getNavBarPosition();
+        }
+    }
+
     @Override
     public WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
             InputEventReceiver.Factory inputEventReceiverFactory) {
@@ -6255,6 +6353,20 @@
     }
 
     @Override
+    public Region getCurrentImeTouchRegion() {
+        if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
+            throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
+        }
+        synchronized (mWindowMap) {
+            final Region r = new Region();
+            if (mInputMethodWindow != null) {
+                mInputMethodWindow.getTouchableRegion(r);
+            }
+            return r;
+        }
+    }
+
+    @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
     }
@@ -7298,6 +7410,11 @@
         }
 
         @Override
+        public boolean isKeyguardShowingAndNotOccluded() {
+            return WindowManagerService.this.isKeyguardShowingAndNotOccluded();
+        }
+
+        @Override
         public void showGlobalActions() {
             WindowManagerService.this.showGlobalActions();
         }
@@ -7447,6 +7564,16 @@
                 accessibilityController.performComputeChangedWindowsNotLocked();
             }
         }
+
+        @Override
+        public void setVr2dDisplayId(int vr2dDisplayId) {
+            if (DEBUG_DISPLAY) {
+                Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
+            }
+            synchronized (WindowManagerService.this) {
+                mVr2dDisplayId = vr2dDisplayId;
+            }
+        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {
@@ -7519,4 +7646,8 @@
             }
         }
     }
+
+    boolean hasWideColorGamutSupport() {
+        return mHasWideColorGamutSupport;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f74948f..96582fc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -441,7 +441,18 @@
      * Set when the orientation is changing and this window has not yet
      * been updated for the new orientation.
      */
-    boolean mOrientationChanging;
+    private boolean mOrientationChanging;
+
+    /**
+     * Sometimes in addition to the mOrientationChanging
+     * flag we report that the orientation is changing
+     * due to a mismatch in current and reported configuration.
+     *
+     * In the case of timeout we still need to make sure we
+     * leave the orientation changing state though, so we
+     * use this as a special time out escape hatch.
+     */
+    private boolean mOrientationChangeTimedOut;
 
     /**
      * The orientation during the last visible call to relayout. If our
@@ -560,6 +571,13 @@
     final Rect mLastSurfaceInsets = new Rect();
 
     /**
+     * A flag set by the {@link WindowState} parent to indicate that the parent has examined this
+     * {@link WindowState} in its overall drawing context. This book-keeping allows the parent to
+     * make sure all children have been considered.
+     */
+    private boolean mDrawnStateEvaluated;
+
+    /**
      * Compares two window sub-layers and returns -1 if the first is lesser than the second in terms
      * of z-order and 1 otherwise.
      */
@@ -675,6 +693,27 @@
         mSession.windowAddedLocked(mAttrs.packageName);
     }
 
+    /**
+     * Returns whether this {@link WindowState} has been considered for drawing by its parent.
+     */
+    boolean getDrawnStateEvaluated() {
+        return mDrawnStateEvaluated;
+    }
+
+    /**
+     * Sets whether this {@link WindowState} has been considered for drawing by its parent. Should
+     * be cleared when detached from parent.
+     */
+    void setDrawnStateEvaluated(boolean evaluated) {
+        mDrawnStateEvaluated = evaluated;
+    }
+
+    @Override
+    void onParentSet() {
+        super.onParentSet();
+        setDrawnStateEvaluated(false /*evaluated*/);
+    }
+
     @Override
     public int getOwningUid() {
         return mOwnerUid;
@@ -726,7 +765,7 @@
         // If the task has temp inset bounds set, we have to make sure all its windows uses
         // the temp inset frame. Otherwise different display frames get applied to the main
         // window and the child window, making them misaligned.
-        if (inFullscreenContainer) {
+        if (inFullscreenContainer || isLetterboxedAppWindow()) {
             mInsetFrame.setEmpty();
         } else if (task != null && isInMultiWindowMode()) {
             task.getTempInsetBounds(mInsetFrame);
@@ -1156,7 +1195,8 @@
             // 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 (mOrientationChanging || dragResizingChanged || isResizedWhileNotDragResizing()) {
+            if (getOrientationChanging() || 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
@@ -1171,17 +1211,40 @@
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
                 mService.mResizingWindows.add(this);
             }
-        } else if (mOrientationChanging) {
+        } else if (getOrientationChanging()) {
             if (isDrawnLw()) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
                         + this + ", surfaceController " + winAnimator.mSurfaceController);
-                mOrientationChanging = false;
+                setOrientationChanging(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 || (isVisible()
+                && getConfiguration().orientation != mLastReportedConfiguration.orientation))
+                && !mSeamlesslyRotated
+                && !mOrientationChangeTimedOut;
+    }
+
+    void setOrientationChanging(boolean changing) {
+        mOrientationChanging = changing;
+        mOrientationChangeTimedOut = false;
+    }
+
+    void orientationChangeTimedOut() {
+        mOrientationChangeTimedOut = true;
+    }
+
     DisplayContent getDisplayContent() {
         return mToken.getDisplayContent();
     }
@@ -1412,8 +1475,18 @@
     @Override
     public boolean canAffectSystemUiFlags() {
         final boolean shown = mWinAnimator.getShown();
-        final boolean exiting = mAnimatingExit || mDestroying
-                || mAppToken != null && mAppToken.hidden;
+
+        // We only consider the app to be exiting when the animation has started. After the app
+        // transition is executed the windows are marked exiting before the new windows have been
+        // shown. Thus, wait considering a window to be exiting after the animation has actually
+        // started.
+        final boolean appAnimationStarting = mAppToken != null
+                && mAppToken.mAppAnimator.isAnimationStarting();
+        final boolean exitingSelf = mAnimatingExit && (!mWinAnimator.isAnimationStarting()
+                && !appAnimationStarting);
+        final boolean appExiting = mAppToken != null && mAppToken.hidden && !appAnimationStarting;
+
+        final boolean exiting = exitingSelf || mDestroying || appExiting;
         final boolean translucent = mAttrs.alpha == 0.0f;
         return shown && !exiting && !translucent;
     }
@@ -1633,7 +1706,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())
@@ -1802,7 +1875,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.
@@ -1942,6 +2015,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;
 
@@ -1975,6 +2054,11 @@
         if (dc == null) {
             return;
         }
+
+        // If layout is currently deferred, we want to hold of with updating the layers.
+        if (mService.mWindowPlacerLocked.isLayoutDeferred()) {
+            return;
+        }
         final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
         if (dimLayerUser != null && dc.mDimLayerController.isDimming(dimLayerUser, mWinAnimator)) {
             // Force an animation pass just to update the mDimLayer layer.
@@ -1987,7 +2071,7 @@
             super(inputChannel, mService.mH.getLooper());
         }
         @Override
-        public void onInputEvent(InputEvent event) {
+        public void onInputEvent(InputEvent event, int displayId) {
             finishInputEvent(event, true);
         }
     }
@@ -2207,8 +2291,7 @@
         }
     }
 
-    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
-            boolean wasVisible) {
+    void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
         if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
@@ -2227,19 +2310,19 @@
             mLayoutNeeded = true;
         }
 
-        if (isDrawnLw() && mService.okToDisplay()) {
+        if (isDrawnLw() && mService.okToAnimate()) {
             mWinAnimator.applyEnterAnimationLocked();
         }
+    }
 
-        if (isConfigChanged()) {
-            final Configuration globalConfig = mService.mRoot.getConfiguration();
-            final Configuration overrideConfig = getMergedOverrideConfiguration();
-            mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
-            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
-                    + " visible with new global config: " + globalConfig
-                    + " merged override config: " + overrideConfig);
-            mLastReportedConfiguration.setTo(getConfiguration());
-        }
+    void getMergedConfiguration(MergedConfiguration outConfiguration) {
+        final Configuration globalConfig = mService.mRoot.getConfiguration();
+        final Configuration overrideConfig = getMergedOverrideConfiguration();
+        outConfiguration.setConfiguration(globalConfig, overrideConfig);
+    }
+
+    void setReportedConfiguration(MergedConfiguration config) {
+        mLastReportedConfiguration.setTo(config.getMergedConfiguration());
     }
 
     void adjustStartingWindowFlags() {
@@ -2379,7 +2462,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
@@ -2409,7 +2492,7 @@
 
     boolean hideLw(boolean doAnimation, boolean requestAnim) {
         if (doAnimation) {
-            if (!mService.okToDisplay()) {
+            if (!mService.okToAnimate()) {
                 doAnimation = false;
             }
         }
@@ -2636,10 +2719,10 @@
 
         mAppFreezing = false;
 
-        if (mHasSurface && !mOrientationChanging
+        if (mHasSurface && !getOrientationChanging()
                 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
-            mOrientationChanging = true;
+            setOrientationChanging(true);
             mService.mRoot.mOrientationChangeComplete = false;
         }
         mLastFreezeDuration = 0;
@@ -3005,14 +3088,12 @@
         try {
             if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
                     + ": " + mCompatFrame);
-            final MergedConfiguration mergedConfiguration;
-            if (isConfigChanged()) {
-                mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(),
-                        getMergedOverrideConfiguration());
-                mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration());
-            } else {
-                mergedConfiguration = null;
-            }
+            final MergedConfiguration mergedConfiguration =
+                    new MergedConfiguration(mService.mRoot.getConfiguration(),
+                    getMergedOverrideConfiguration());
+
+            setReportedConfiguration(mergedConfiguration);
+
             if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
                 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
 
@@ -3060,7 +3141,7 @@
             mWinAnimator.mSurfaceResized = false;
             mReportOrientationChanged = false;
         } catch (RemoteException e) {
-            mOrientationChanging = false;
+            setOrientationChanging(false);
             mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             // We are assuming the hosting process is dead or in a zombie state.
@@ -3155,6 +3236,15 @@
         return !isInMultiWindowMode();
     }
 
+    /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+    boolean isLetterboxedAppWindow() {
+        final Task task = getTask();
+        final boolean taskIsFullscreen = task != null && task.isFullscreen();
+        final boolean appWindowIsFullscreen = mAppToken != null && !mAppToken.hasBounds();
+
+        return taskIsFullscreen && !appWindowIsFullscreen;
+    }
+
     /** Returns the appropriate bounds to use for computing frames. */
     private void getContainerBounds(Rect outBounds) {
         if (isInMultiWindowMode()) {
@@ -3319,7 +3409,11 @@
                 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
                 pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()=");
                 pw.print(isAnimatingWithSavedSurface());
-                pw.print(" mAppDied=");pw.println(mAppDied);
+                pw.print(" mAppDied=");pw.print(mAppDied);
+                pw.print(prefix); pw.print("drawnStateEvaluated=");
+                        pw.print(getDrawnStateEvaluated());
+                pw.print(prefix); pw.print("mightAffectAllDrawn=");
+                        pw.println(mightAffectAllDrawn(false /*visibleOnly*/));
             }
             pw.print(prefix); pw.print("mViewVisibility=0x");
             pw.print(Integer.toHexString(mViewVisibility));
@@ -3419,10 +3513,13 @@
                     pw.print(" mDestroying="); pw.print(mDestroying);
                     pw.print(" mRemoved="); pw.println(mRemoved);
         }
-        if (mOrientationChanging || mAppFreezing || mTurnOnScreen
+        if (getOrientationChanging() || 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);
@@ -3459,6 +3556,8 @@
         if (computeDragResizing()) {
             pw.print(prefix); pw.println("computeDragResizing=" + computeDragResizing());
         }
+        pw.print(prefix); pw.println("isOnScreen=" + isOnScreen());
+        pw.print(prefix); pw.println("isVisible=" + isVisible());
     }
 
     @Override
@@ -4342,8 +4441,7 @@
         return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
     }
 
-    int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges,
-            int oldVisibility) {
+    int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
         final boolean wasVisible = isVisibleLw();
 
         result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4366,7 +4464,7 @@
 
         mWinAnimator.mEnteringAnimation = true;
 
-        prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+        prepareWindowToDisplayDuringRelayout(wasVisible);
 
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 33cb908..86265c29 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,6 +20,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -368,7 +369,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) {
@@ -631,6 +632,10 @@
             return mSurfaceController;
         }
 
+        if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
+            windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
+        }
+
         w.setHasSurface(false);
 
         if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
@@ -1195,7 +1200,8 @@
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                 + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
 
-        final boolean fullscreen = w.fillsDisplay();
+        final Task task = w.getTask();
+        final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
         final boolean isFreeformResizing =
                 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
 
@@ -1521,17 +1527,30 @@
         }
     }
 
+    /**
+     * Get rect of the task this window is currently in. If there is no task, rect will be set to
+     * empty.
+     */
+    void getContainerRect(Rect rect) {
+        final Task task = mWin.getTask();
+        if (task != null) {
+            task.getDimBounds(rect);
+        } else {
+            rect.left = rect.top = rect.right = rect.bottom = 0;
+        }
+    }
+
     void prepareSurfaceLocked(final boolean recoveringMemory) {
         final WindowState w = mWin;
         if (!hasSurface()) {
 
             // 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.mOrientationChanging && w.isGoneForLayoutLw()) {
+            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
                 if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
                 }
-                w.mOrientationChanging = false;
+                w.setOrientationChanging(false);
             }
             return;
         }
@@ -1564,8 +1583,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.mOrientationChanging && w.isGoneForLayoutLw()) {
-                w.mOrientationChanging = false;
+            if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
+                w.setOrientationChanging(false);
                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation change skips hidden " + w);
             }
@@ -1604,21 +1623,38 @@
                         recoveringMemory);
             mSurfaceController.setLayer(mAnimLayer);
 
-            if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
-                if (showSurfaceRobustlyLocked()) {
-                    markPreservedSurfaceForDestroy();
-                    mAnimator.requestRemovalOfReplacedWindows(w);
-                    mLastHidden = false;
-                    if (mIsWallpaper) {
-                        w.dispatchWallpaperVisibility(true);
+            if (prepared && mDrawState == HAS_DRAWN) {
+                if (mLastHidden) {
+                    if (showSurfaceRobustlyLocked()) {
+                        markPreservedSurfaceForDestroy();
+                        mAnimator.requestRemovalOfReplacedWindows(w);
+                        mLastHidden = false;
+                        if (mIsWallpaper) {
+                            w.dispatchWallpaperVisibility(true);
+                        }
+                        // This draw means the difference between unique content and mirroring.
+                        // Run another pass through performLayout to set mHasContent in the
+                        // LogicalDisplay.
+                        mAnimator.setPendingLayoutChanges(w.getDisplayId(),
+                                WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
+                    } else {
+                        w.setOrientationChanging(false);
                     }
-                    // This draw means the difference between unique content and mirroring.
-                    // Run another pass through performLayout to set mHasContent in the
-                    // LogicalDisplay.
-                    mAnimator.setPendingLayoutChanges(w.getDisplayId(),
-                            WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-                } else {
-                    w.mOrientationChanging = false;
+                }
+                // We process mTurnOnScreen even for windows which have already
+                // been shown, to handle cases where windows are not necessarily
+                // hidden while the screen is turning off.
+                // TODO(b/63773439): These cases should be eliminated, though we probably still
+                // want to process mTurnOnScreen in this way for clarity.
+                if (mWin.mTurnOnScreen && mWin.mAppToken.canTurnScreenOn()) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
+                    mWin.mTurnOnScreen = false;
+
+                    // The window should only turn the screen on once per resume, but
+                    // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to
+                    // false so the window doesn't turn the screen on again during this resume.
+                    mWin.mAppToken.setCanTurnScreenOn(false);
+                    mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
                 }
             }
             if (hasSurface()) {
@@ -1631,14 +1667,14 @@
             displayed = true;
         }
 
-        if (w.mOrientationChanging) {
+        if (w.getOrientationChanging()) {
             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.mOrientationChanging = false;
+                w.setOrientationChanging(false);
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
             }
         }
@@ -1730,11 +1766,6 @@
         if (!shown)
             return false;
 
-        if (mWin.mTurnOnScreen) {
-            if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
-            mWin.mTurnOnScreen = false;
-            mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
-        }
         return true;
     }
 
@@ -1781,7 +1812,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/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 27927e6..4819c0f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -52,7 +52,7 @@
 
     final WindowStateAnimator mAnimator;
 
-    private SurfaceControl mSurfaceControl;
+    private SurfaceControlWithBackground mSurfaceControl;
 
     // Should only be set from within setShown().
     private boolean mSurfaceShown = false;
@@ -99,15 +99,10 @@
         mWindowType = windowType;
         mWindowSession = win.mSession;
 
-        if (DEBUG_SURFACE_TRACE) {
-            mSurfaceControl = new SurfaceTrace(
-                    s, name, w, h, format, flags, windowType, ownerUid);
-        } else {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
-            mSurfaceControl = new SurfaceControl(
-                    s, name, w, h, format, flags, windowType, ownerUid);
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
+        mSurfaceControl = new SurfaceControlWithBackground(
+                s, name, w, h, format, flags, windowType, ownerUid, this);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
 
         if (mService.mRoot.mSurfaceTraceEnabled) {
             mSurfaceControl = new RemoteSurfaceTrace(
@@ -120,7 +115,7 @@
     }
 
     void removeRemoteTrace() {
-        mSurfaceControl = new SurfaceControl(mSurfaceControl);
+        mSurfaceControl = new SurfaceControlWithBackground(mSurfaceControl);
     }
 
 
@@ -293,30 +288,30 @@
         mSurfaceControl.setGeometryAppliesWithResize();
     }
 
-    void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
+    void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
             boolean recoveringMemory) {
         final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
-                                      mLastDsdy != dsdy || mLastDtdy != dtdy;
+                                      mLastDtdy != dtdy || mLastDsdy != dsdy;
         if (!matrixChanged) {
             return;
         }
 
         mLastDsdx = dsdx;
         mLastDtdx = dtdx;
-        mLastDsdy = dsdy;
         mLastDtdy = dtdy;
+        mLastDsdy = dsdy;
 
         try {
             if (SHOW_TRANSACTIONS) logSurface(
-                    "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+                    "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
             mSurfaceControl.setMatrix(
-                    dsdx, dtdx, dsdy, dtdy);
+                    dsdx, dtdx, dtdy, dsdy);
         } catch (RuntimeException e) {
             // If something goes wrong with the surface (such
             // as running out of memory), don't take down the
             // entire system.
             Slog.e(TAG, "Error setting matrix on surface surface" + title
-                    + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+                    + " MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
             if (!recoveringMemory) {
                 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
             }
@@ -423,6 +418,10 @@
         }
     }
 
+    void getContainerRect(Rect rect) {
+        mAnimator.getContainerRect(rect);
+    }
+
     boolean showRobustlyInTransaction() {
         if (SHOW_TRANSACTIONS) logSurface(
                 "SHOW (performLayout)", null);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 82c862f..581b044 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -127,6 +127,10 @@
         }
     }
 
+    boolean isLayoutDeferred() {
+        return mDeferDepth > 0;
+    }
+
     final void performSurfacePlacement() {
         performSurfacePlacement(false /* force */);
     }
@@ -233,7 +237,7 @@
      */
     int handleAppTransitionReadyLocked() {
         int appsCount = mService.mOpeningApps.size();
-        if (!transitionGoodToGo(appsCount)) {
+        if (!transitionGoodToGo(appsCount, mTempTransitionReasons)) {
             return 0;
         }
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
@@ -375,6 +379,9 @@
                 true /*updateInputWindows*/);
         mService.mFocusMayChange = false;
 
+        mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING,
+                mTempTransitionReasons.clone()).sendToTarget();
+
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
 
         return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
@@ -499,7 +506,7 @@
         }
     }
 
-    private boolean transitionGoodToGo(int appsCount) {
+    private boolean transitionGoodToGo(int appsCount, SparseIntArray outReasons) {
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "Checking " + appsCount + " opening apps (frozen="
                         + mService.mDisplayFrozen + " timeout="
@@ -508,7 +515,7 @@
             mService.mAnimator.getScreenRotationAnimationLocked(
                     Display.DEFAULT_DISPLAY);
 
-        final SparseIntArray reasons = mTempTransitionReasons;
+        outReasons.clear();
         if (!mService.mAppTransition.isTimeout()) {
             // Imagine the case where we are changing orientation due to an app transition, but a previous
             // orientation change is still in progress. We won't process the orientation change
@@ -542,10 +549,10 @@
                 final TaskStack stack = wtoken.getStack();
                 final int stackId = stack != null ? stack.mStackId : INVALID_STACK_ID;
                 if (allDrawn) {
-                    reasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
+                    outReasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
                             : APP_TRANSITION_SAVED_SURFACE);
                 } else {
-                    reasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
+                    outReasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
                             ? APP_TRANSITION_SPLASH_SCREEN
                             : APP_TRANSITION_SNAPSHOT);
                 }
@@ -569,13 +576,10 @@
             boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
                     mWallpaperControllerLocked.wallpaperTransitionReady();
             if (wallpaperReady) {
-                mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone())
-                        .sendToTarget();
                 return true;
             }
             return false;
         }
-        mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone()).sendToTarget();
         return true;
     }
 
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index c0757ce..e2a82b7 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -5,6 +5,8 @@
 LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 
 LOCAL_SRC_FILES += \
+    $(LOCAL_REL_DIR)/JavaRef.cpp \
+    $(LOCAL_REL_DIR)/NativeCallbackThread.cpp \
     $(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
@@ -18,15 +20,20 @@
     $(LOCAL_REL_DIR)/com_android_server_lights_LightsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_ContextHubService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_GnssLocationProvider.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_locksettings_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_RadioService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_Tuner.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_Tuner_TunerCallback.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_radio_convert.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \
-    $(LOCAL_REL_DIR)/com_android_server_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_storage_AppFuseBridge.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \
     $(LOCAL_REL_DIR)/com_android_server_tv_TvUinputBridge.cpp \
     $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \
     $(LOCAL_REL_DIR)/com_android_server_vr_VrManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_UsbDescriptorParser.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbMidiDevice.cpp \
     $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
@@ -59,7 +66,6 @@
     libhardware \
     libhardware_legacy \
     libhidlbase \
-    libhidltransport \
     libkeystore_binder \
     libnativehelper \
     libutils \
@@ -77,19 +83,26 @@
     libEGL \
     libGLESv2 \
     libnetutils \
+    libhidlbase \
+    libhidltransport \
     libhwbinder \
+    libutils \
     libhwui \
     android.hardware.audio.common@2.0 \
+    android.hardware.broadcastradio@1.0 \
+    android.hardware.broadcastradio@1.1 \
     android.hardware.contexthub@1.0 \
     android.hardware.gnss@1.0 \
     android.hardware.ir@1.0 \
     android.hardware.light@2.0 \
     android.hardware.power@1.0 \
+    android.hardware.power@1.1 \
     android.hardware.tetheroffload.config@1.0 \
     android.hardware.thermal@1.0 \
     android.hardware.tv.cec@1.0 \
     android.hardware.tv.input@1.0 \
     android.hardware.vibrator@1.0 \
+    android.hardware.vibrator@1.1 \
     android.hardware.vr@1.0 \
     android.frameworks.schedulerservice@1.0 \
     android.frameworks.sensorservice@1.0 \
diff --git a/services/core/jni/JavaRef.cpp b/services/core/jni/JavaRef.cpp
new file mode 100644
index 0000000..ad07afa
--- /dev/null
+++ b/services/core/jni/JavaRef.cpp
@@ -0,0 +1,30 @@
+/**
+ * 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 "JavaRef"
+//#define LOG_NDEBUG 0
+
+#include "JavaRef.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+EnvWrapper::EnvWrapper(JNIEnv *env) : mEnv(env) {
+    ALOGE_IF(env == nullptr, "Environment is a nullptr");
+}
+
+} // namespace android
diff --git a/services/core/jni/JavaRef.h b/services/core/jni/JavaRef.h
new file mode 100644
index 0000000..8a572e2
--- /dev/null
+++ b/services/core/jni/JavaRef.h
@@ -0,0 +1,57 @@
+/**
+ * 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 _ANDROID_JAVA_REF_H
+#define _ANDROID_JAVA_REF_H
+
+#include <android-base/macros.h>
+#include <functional>
+#include <jni.h>
+#include <memory>
+#include <type_traits>
+
+namespace android {
+
+template <typename T>
+using JavaRef = std::unique_ptr<typename std::remove_pointer<T>::type, std::function<void(T)>>;
+
+template <typename T>
+JavaRef<T> make_javaref(JNIEnv *env, T ref) {
+    return JavaRef<T>(ref, [env](T ref) {
+        if (env && ref) {
+            env->DeleteLocalRef(ref);
+        }
+    });
+}
+
+class EnvWrapper {
+public:
+    EnvWrapper(JNIEnv *env);
+
+    template <typename T>
+    JavaRef<T> operator() (T ref) const {
+        return make_javaref(mEnv, ref);
+    }
+
+private:
+    JNIEnv *mEnv;
+
+    DISALLOW_COPY_AND_ASSIGN(EnvWrapper);
+};
+
+} // namespace android
+
+#endif // _ANDROID_JAVA_REF_H
diff --git a/services/core/jni/NativeCallbackThread.cpp b/services/core/jni/NativeCallbackThread.cpp
new file mode 100644
index 0000000..7d668e3
--- /dev/null
+++ b/services/core/jni/NativeCallbackThread.cpp
@@ -0,0 +1,116 @@
+/**
+ * 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 "NativeCallbackThread"
+//#define LOG_NDEBUG 0
+
+#include "NativeCallbackThread.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mExitting(false), mvm(vm) {
+    auto res = pthread_create(&mThread, nullptr, main, this);
+    if (res != 0) {
+        ALOGE("Couldn't start NativeCallbackThread");
+        mThread = 0;
+        return;
+    }
+    ALOGD("Started native callback thread %p", this);
+}
+
+NativeCallbackThread::~NativeCallbackThread() {
+    ALOGV("~NativeCallbackThread %p", this);
+    stop();
+}
+
+void* NativeCallbackThread::main(void *args) {
+    auto self = reinterpret_cast<NativeCallbackThread*>(args);
+    self->main();
+    return nullptr;
+}
+
+void NativeCallbackThread::main() {
+    ALOGV("NativeCallbackThread::main()");
+
+    JNIEnv *env = nullptr;
+    JavaVMAttachArgs aargs = {JNI_VERSION_1_4, "NativeCallbackThread", nullptr};
+    if (mvm->AttachCurrentThread(&env, &aargs) != JNI_OK || env == nullptr) {
+        ALOGE("Couldn't attach thread");
+        return;
+    }
+
+    while (!mExitting) {
+        ALOGV("Waiting for task...");
+        Task task;
+        {
+            AutoMutex _l(mQueueMutex);
+            auto res = mQueueCond.wait(mQueueMutex);
+            ALOGE_IF(res != 0, "Wait failed: %d", res);
+            if (mExitting || res != 0) break;
+
+            if (mQueue.empty()) continue;
+            task = mQueue.front();
+            mQueue.pop();
+        }
+
+        ALOGV("Executing task...");
+        task(env);
+        if (env->ExceptionCheck()) {
+            ALOGE("Unexpected exception:");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+        }
+    }
+
+    auto res = mvm->DetachCurrentThread();
+    ALOGE_IF(res != JNI_OK, "Couldn't detach thread");
+
+    ALOGV("Native callback thread %p finished", this);
+}
+
+void NativeCallbackThread::enqueue(const Task &task) {
+    AutoMutex _l(mQueueMutex);
+
+    if (mThread == 0 || mExitting) {
+        ALOGW("Callback thread %p is not serving calls", this);
+        return;
+    }
+
+    mQueue.push(task);
+    mQueueCond.signal();
+}
+
+void NativeCallbackThread::stop() {
+    ALOGV("stop() %p", this);
+
+    {
+        AutoMutex _l(mQueueMutex);
+
+        if (mThread == 0 || mExitting) return;
+
+        mExitting = true;
+        mQueueCond.signal();
+    }
+
+    auto ret = pthread_join(mThread, nullptr);
+    ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
+
+    ALOGD("Stopped native callback thread %p", this);
+}
+
+} // namespace android
diff --git a/services/core/jni/NativeCallbackThread.h b/services/core/jni/NativeCallbackThread.h
new file mode 100644
index 0000000..4e03b11
--- /dev/null
+++ b/services/core/jni/NativeCallbackThread.h
@@ -0,0 +1,56 @@
+/**
+ * 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 _ANDROID_NATIVE_CALLBACK_THREAD_H
+#define _ANDROID_NATIVE_CALLBACK_THREAD_H
+
+#include <android-base/macros.h>
+#include <functional>
+#include <jni.h>
+#include <pthread.h>
+#include <queue>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+class NativeCallbackThread {
+    typedef std::function<void(JNIEnv*)> Task;
+
+    pthread_t mThread;
+    Mutex mQueueMutex;
+    Condition mQueueCond;
+    std::atomic<bool> mExitting;
+
+    JavaVM *mvm;
+    std::queue<Task> mQueue;
+
+    static void* main(void *args);
+    void main();
+
+    DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread);
+
+public:
+    NativeCallbackThread(JavaVM *vm);
+    virtual ~NativeCallbackThread();
+
+    void enqueue(const Task &task);
+    void stop();
+};
+
+} // namespace android
+
+#endif // _ANDROID_NATIVE_CALLBACK_THREAD_H
diff --git a/services/core/jni/com_android_server_GraphicsStatsService.cpp b/services/core/jni/com_android_server_GraphicsStatsService.cpp
index 7d779a6..8385020 100644
--- a/services/core/jni/com_android_server_GraphicsStatsService.cpp
+++ b/services/core/jni/com_android_server_GraphicsStatsService.cpp
@@ -43,8 +43,9 @@
     std::string path;
     const ProfileData* data = nullptr;
     LOG_ALWAYS_FATAL_IF(jdata == nullptr && jpath == nullptr, "Path and data can't both be null");
+    ScopedByteArrayRO buffer{env};
     if (jdata != nullptr) {
-        ScopedByteArrayRO buffer(env, jdata);
+        buffer.reset(jdata);
         LOG_ALWAYS_FATAL_IF(buffer.size() != sizeof(ProfileData),
                 "Buffer size %zu doesn't match expected %zu!", buffer.size(), sizeof(ProfileData));
         data = reinterpret_cast<const ProfileData*>(buffer.get());
diff --git a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
deleted file mode 100644
index a9f7b9f..0000000
--- a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
+++ /dev/null
@@ -1,90 +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.
- */
-
-#define LOG_TAG "SyntheticPasswordManager"
-
-#include "JNIHelp.h"
-#include "jni.h"
-
-#include <android_runtime/Log.h>
-#include <utils/Timers.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/Log.h>
-#include <gatekeeper/password_handle.h>
-
-
-extern "C" {
-#include "crypto_scrypt.h"
-}
-
-namespace android {
-
-static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
-
-    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
-
-    if (data != NULL) {
-        const gatekeeper::password_handle_t *handle =
-                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
-        jlong sid = handle->user_id;
-        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
-        return sid;
-    } else {
-        return 0;
-    }
-}
-
-static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
-    if (!password || !salt) {
-        return NULL;
-    }
-
-    int passwordLen = env->GetArrayLength(password);
-    int saltLen = env->GetArrayLength(salt);
-    jbyteArray ret = env->NewByteArray(outLen);
-
-    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
-    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
-    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
-
-    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
-                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
-                       outLen);
-    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(ret, retPtr, 0);
-
-    if (!rc) {
-        return ret;
-    } else {
-        SLOGE("scrypt failed");
-        return NULL;
-    }
-}
-
-static const JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
-    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
-};
-
-int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/server/SyntheticPasswordManager",
-                                    sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/services/core/jni/com_android_server_UsbDescriptorParser.cpp b/services/core/jni/com_android_server_UsbDescriptorParser.cpp
new file mode 100644
index 0000000..98c5ec1
--- /dev/null
+++ b/services/core/jni/com_android_server_UsbDescriptorParser.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.
+ */
+
+#define LOG_TAG "UsbHostManagerJNI"
+#include "utils/Log.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <usbhost/usbhost.h>
+
+#define MAX_DESCRIPTORS_LENGTH 16384
+
+// com.android.server.usb.descriptors
+extern "C" {
+jbyteArray JNICALL Java_com_android_server_usb_descriptors_UsbDescriptorParser_getRawDescriptors(
+        JNIEnv* env, jobject thiz, jstring deviceAddr) {
+    const char *deviceAddrStr = env->GetStringUTFChars(deviceAddr, NULL);
+    struct usb_device* device = usb_device_open(deviceAddrStr);
+    env->ReleaseStringUTFChars(deviceAddr, deviceAddrStr);
+
+    if (!device) {
+        ALOGE("usb_device_open failed");
+        return NULL;
+    }
+
+    int fd = usb_device_get_fd(device);
+    if (fd < 0) {
+        return NULL;
+    }
+
+    // from android_hardware_UsbDeviceConnection_get_desc()
+    jbyte buffer[MAX_DESCRIPTORS_LENGTH];
+    lseek(fd, 0, SEEK_SET);
+    int numBytes = read(fd, buffer, sizeof(buffer));
+
+    usb_device_close(device);
+
+    jbyteArray ret = NULL;
+    if (numBytes != 0) {
+        ret = env->NewByteArray(numBytes);
+        env->SetByteArrayRegion(ret, 0, numBytes, buffer);
+    }
+    return ret;
+}
+
+} // extern "C"
+
+
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 810d785..0370490 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -18,6 +18,7 @@
 
 #include <android/hardware/vibrator/1.0/IVibrator.h>
 #include <android/hardware/vibrator/1.0/types.h>
+#include <android/hardware/vibrator/1.1/IVibrator.h>
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
@@ -35,96 +36,129 @@
 using android::hardware::vibrator::V1_0::EffectStrength;
 using android::hardware::vibrator::V1_0::IVibrator;
 using android::hardware::vibrator::V1_0::Status;
+using android::hardware::vibrator::V1_1::Effect_1_1;
+using IVibrator_1_1 = android::hardware::vibrator::V1_1::IVibrator;
 
 namespace android
 {
 
-static sp<IVibrator> mHal;
+static constexpr int NUM_TRIES = 2;
+
+// Creates a Return<R> with STATUS::EX_NULL_POINTER.
+template<class R>
+inline Return<R> NullptrStatus() {
+    using ::android::hardware::Status;
+    return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
+}
+
+// Helper used to transparently deal with the vibrator HAL becoming unavailable.
+template<class R, class I, class... Args0, class... Args1>
+Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+    // Assume that if getService returns a nullptr, HAL is not available on the
+    // device.
+    static sp<I> sHal = I::getService();
+    static bool sAvailable = sHal != nullptr;
+
+    if (!sAvailable) {
+        return NullptrStatus<R>();
+    }
+
+    // Return<R> doesn't have a default constructor, so make a Return<R> with
+    // STATUS::EX_NONE.
+    using ::android::hardware::Status;
+    Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+
+    // Note that ret is guaranteed to be changed after this loop.
+    for (int i = 0; i < NUM_TRIES; ++i) {
+        ret = (sHal == nullptr) ? NullptrStatus<R>()
+                : (*sHal.*fn)(std::forward<Args1>(args1)...);
+
+        if (ret.isOk()) {
+            break;
+        }
+
+        ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+        // Restoring connection to the HAL.
+        sHal = I::tryGetService();
+    }
+    return ret;
+}
 
 static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
 {
-    /* TODO(b/31632518) */
-    if (mHal != nullptr) {
-        return;
-    }
-    mHal = IVibrator::getService();
+    halCall(&IVibrator::ping).isOk();
 }
 
 static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
+    return halCall(&IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
 }
 
 static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->on(timeout_ms);
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to vibrate but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
 {
-    if (mHal != nullptr) {
-        Status retStatus = mHal->off();
-        if (retStatus != Status::OK) {
-            ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
-        }
-    } else {
-        ALOGW("Tried to stop vibrating but there is no vibrator device.");
+    Status retStatus = halCall(&IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
+    if (retStatus != Status::OK) {
+        ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
     }
 }
 
 static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) {
-    if (mHal != nullptr) {
-        return mHal->supportsAmplitudeControl();
-    } else {
-        ALOGW("Unable to get max vibration amplitude, there is no vibrator device.");
-    }
-    return false;
+    return halCall(&IVibrator::supportsAmplitudeControl).withDefault(false);
 }
 
 static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) {
-    if (mHal != nullptr) {
-        Status status = mHal->setAmplitude(static_cast<uint32_t>(amplitude));
-        if (status != Status::OK) {
-            ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
-                    static_cast<uint32_t>(status));
-        }
-    } else {
-        ALOGW("Unable to set vibration amplitude, there is no vibrator device.");
+    Status status = halCall(&IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
+        .withDefault(Status::UNKNOWN_ERROR);
+    if (status != Status::OK) {
+      ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
+            static_cast<uint32_t>(status));
     }
 }
 
 static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
-    if (mHal != nullptr) {
-        Status status;
-        uint32_t lengthMs;
-        mHal->perform(static_cast<Effect>(effect), static_cast<EffectStrength>(strength),
-                [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
-                    status = retStatus;
-                    lengthMs = retLengthMs;
-                });
-        if (status == Status::OK) {
-            return lengthMs;
-        } else if (status != Status::UNSUPPORTED_OPERATION) {
-            // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
-            // doesn't have a pre-defined waveform to perform for it, so we should just fall back
-            // to the framework waveforms.
-            ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
-                    ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
-                    static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+    Status status;
+    uint32_t lengthMs;
+    auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
+        status = retStatus;
+        lengthMs = retLengthMs;
+    };
+    EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+
+    if (effect < 0  || effect > static_cast<uint32_t>(Effect_1_1::TICK)) {
+        ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+                static_cast<int32_t>(effect));
+    } else if (effect == static_cast<uint32_t>(Effect_1_1::TICK)) {
+        auto ret = halCall(&IVibrator_1_1::perform_1_1, static_cast<Effect_1_1>(effect),
+                           effectStrength, callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 "), insufficient HAL version",
+                    static_cast<int32_t>(effect));
         }
     } else {
-        ALOGW("Unable to perform haptic effect, there is no vibrator device.");
+        auto ret = halCall(&IVibrator::perform, static_cast<Effect>(effect), effectStrength,
+                           callback);
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
+        }
+    }
+
+    if (status == Status::OK) {
+        return lengthMs;
+    } else if (status != Status::UNSUPPORTED_OPERATION) {
+        // Don't warn on UNSUPPORTED_OPERATION, that's a normal even and just means the motor
+        // doesn't have a pre-defined waveform to perform for it, so we should just fall back
+        // to the framework waveforms.
+        ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+                ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
+                static_cast<int32_t>(strength), static_cast<uint32_t>(status));
     }
     return -1;
 }
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index fbd4141..2dc388a 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -29,6 +29,7 @@
 #include <unistd.h>
 
 #include <android/hardware/power/1.0/IPower.h>
+#include <android/hardware/power/1.1/IPower.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <jni.h>
 
@@ -46,6 +47,8 @@
 using android::hardware::power::V1_0::PowerStatePlatformSleepState;
 using android::hardware::power::V1_0::PowerStateVoter;
 using android::hardware::power::V1_0::Status;
+using android::hardware::power::V1_1::PowerStateSubsystem;
+using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
 using android::hardware::hidl_vec;
 
 namespace android
@@ -56,7 +59,7 @@
 
 static bool wakeup_init = false;
 static sem_t wakeup_sem;
-extern sp<IPower> gPowerHal;
+extern sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0;
 extern std::mutex gPowerHalMutex;
 extern bool getPowerHal();
 
@@ -200,7 +203,7 @@
             return -1;
         }
 
-        Return<void> ret = gPowerHal->getPlatformLowPowerStats(
+        Return<void> ret = gPowerHalV1_0->getPlatformLowPowerStats(
             [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
                     Status status) {
                 if (status != Status::SUCCESS)
@@ -254,7 +257,7 @@
 
         if (!ret.isOk()) {
             ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
-            gPowerHal = nullptr;
+            gPowerHalV1_0 = nullptr;
             return -1;
         }
     }
@@ -263,9 +266,111 @@
     return total_added;
 }
 
+static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
+    char *output = (char*)env->GetDirectBufferAddress(outBuf);
+    char *offset = output;
+    int remaining = (int)env->GetDirectBufferCapacity(outBuf);
+    int total_added = -1;
+
+	//This is a IPower 1.1 API
+    sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 = nullptr;
+
+    if (outBuf == NULL) {
+        jniThrowException(env, "java/lang/NullPointerException", "null argument");
+        return -1;
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(gPowerHalMutex);
+        if (!getPowerHal()) {
+            ALOGE("Power Hal not loaded");
+            return -1;
+        }
+
+        //Trying to cast to 1.1, this will succeed only for devices supporting 1.1
+        gPowerHal_1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
+    	if (gPowerHal_1_1 == nullptr) {
+            //This device does not support IPower@1.1, exiting gracefully
+            return 0;
+    	}
+
+        Return<void> ret = gPowerHal_1_1->getSubsystemLowPowerStats(
+           [&offset, &remaining, &total_added](hidl_vec<PowerStateSubsystem> subsystems,
+                Status status) {
+
+            if (status != Status::SUCCESS)
+                return;
+
+            if (subsystems.size() > 0) {
+                int added = snprintf(offset, remaining, "SubsystemPowerState ");
+                offset += added;
+                remaining -= added;
+                total_added += added;
+
+                for (size_t i = 0; i < subsystems.size(); i++) {
+                    const PowerStateSubsystem &subsystem = subsystems[i];
+
+                    added = snprintf(offset, remaining,
+                                     "subsystem_%zu name=%s ", i + 1, subsystem.name.c_str());
+                    if (added < 0) {
+                        break;
+                    }
+
+                    if (added > remaining) {
+                        added = remaining;
+                    }
+
+                    offset += added;
+                    remaining -= added;
+                    total_added += added;
+
+                    for (size_t j = 0; j < subsystem.states.size(); j++) {
+                        const PowerStateSubsystemSleepState& state = subsystem.states[j];
+                        added = snprintf(offset, remaining,
+                                         "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " last entry=%" PRIu64 " ",
+                                         j + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+                                         state.totalTransitions, state.lastEntryTimestampMs);
+                        if (added < 0) {
+                            break;
+                        }
+
+                        if (added > remaining) {
+                            added = remaining;
+                        }
+
+                        offset += added;
+                        remaining -= added;
+                        total_added += added;
+                    }
+
+                    if (remaining <= 0) {
+                        /* rewrite NULL character*/
+                        offset--;
+                        total_added--;
+                        ALOGE("PowerHal: buffer not enough");
+                        break;
+                    }
+                }
+            }
+        }
+        );
+
+        if (!ret.isOk()) {
+            ALOGE("getSubsystemLowPowerStats() failed: power HAL service not available");
+            gPowerHalV1_0 = nullptr;
+            return -1;
+        }
+    }
+
+    *offset = 0;
+    total_added += 1;
+    return total_added;
+}
+
 static const JNINativeMethod method_table[] = {
     { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
     { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
+    { "getSubsystemLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getSubsystemLowPowerStats },
 };
 
 int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index ad617bc..c210e14 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -36,6 +36,7 @@
 #include <utils/Log.h>
 #include <utils/Looper.h>
 #include <utils/threads.h>
+#include <utils/SortedVector.h>
 
 #include <input/PointerController.h>
 #include <input/SpriteController.h>
@@ -158,7 +159,12 @@
     status_t status = android_view_PointerIcon_loadSystemIcon(env,
             contextObj, style, outPointerIcon);
     if (!status) {
-        outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
+        SkBitmap* bitmapCopy = &outSpriteIcon->bitmap;
+        SkImageInfo bitmapCopyInfo = outPointerIcon->bitmap.info().makeColorType(kN32_SkColorType);
+        if (bitmapCopy->tryAllocPixels(bitmapCopyInfo)) {
+            outPointerIcon->bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
+                    bitmapCopy->rowBytes(), 0, 0);
+        }
         outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
         outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
     }
@@ -203,6 +209,7 @@
     void setInputDispatchMode(bool enabled, bool frozen);
     void setSystemUiVisibility(int32_t visibility);
     void setPointerSpeed(int32_t speed);
+    void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
     void setShowTouches(bool enabled);
     void setInteractive(bool interactive);
     void reloadCalibration();
@@ -288,6 +295,9 @@
 
         // Pointer controller singleton, created and destroyed as needed.
         wp<PointerController> pointerController;
+
+        // Input devices to be disabled
+        SortedVector<int32_t> disabledInputDevices;
     } mLocked;
 
     std::atomic<bool> mInteractive;
@@ -512,6 +522,8 @@
         outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL,
                 mLocked.externalViewport);
         outConfig->setVirtualDisplayViewports(mLocked.virtualViewports);
+
+        outConfig->disabledDevices = mLocked.disabledInputDevices;
     } // release lock
 }
 
@@ -801,6 +813,24 @@
             InputReaderConfiguration::CHANGE_POINTER_SPEED);
 }
 
+void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ssize_t index = mLocked.disabledInputDevices.indexOf(deviceId);
+        bool currentlyEnabled = index < 0;
+        if (!enabled && currentlyEnabled) {
+            mLocked.disabledInputDevices.add(deviceId);
+        }
+        if (enabled && !currentlyEnabled) {
+            mLocked.disabledInputDevices.remove(deviceId);
+        }
+    } // release lock
+
+    mInputManager->getReader()->requestRefreshConfiguration(
+            InputReaderConfiguration::CHANGE_ENABLED_STATE);
+}
+
 void NativeInputManager::setShowTouches(bool enabled) {
     { // acquire lock
         AutoMutex _l(mLock);
@@ -1382,6 +1412,7 @@
 static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
          jlong ptr, jint deviceId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
 }
 
@@ -1402,6 +1433,7 @@
 static void nativeSetPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
         jboolean enabled) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->setPointerCapture(enabled);
 }
 
@@ -1463,6 +1495,7 @@
 
 static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->reloadCalibration();
 }
 
@@ -1529,13 +1562,36 @@
     im->getInputManager()->getDispatcher()->monitor();
 }
 
+static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    return im->getInputManager()->getReader()->isInputDeviceEnabled(deviceId);
+}
+
+static void nativeEnableInputDevice(JNIEnv* /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->setInputDeviceEnabled(deviceId, true);
+}
+
+static void nativeDisableInputDevice(JNIEnv* /* env */,
+        jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->setInputDeviceEnabled(deviceId, false);
+}
+
 static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->setPointerIconType(iconId);
 }
 
 static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
     im->reloadPointerIcons();
 }
 
@@ -1551,7 +1607,11 @@
     }
 
     SpriteIcon spriteIcon;
-    pointerIcon.bitmap.copyTo(&spriteIcon.bitmap, kN32_SkColorType);
+    SkImageInfo spriteInfo = pointerIcon.bitmap.info().makeColorType(kN32_SkColorType);
+    if (spriteIcon.bitmap.tryAllocPixels(spriteInfo)) {
+        pointerIcon.bitmap.readPixels(spriteInfo, spriteIcon.bitmap.getPixels(),
+                spriteIcon.bitmap.rowBytes(), 0, 0);
+    }
     spriteIcon.hotSpotX = pointerIcon.hotSpotX;
     spriteIcon.hotSpotY = pointerIcon.hotSpotY;
     im->setCustomPointerIcon(spriteIcon);
@@ -1621,6 +1681,12 @@
             (void*) nativeDump },
     { "nativeMonitor", "(J)V",
             (void*) nativeMonitor },
+    { "nativeIsInputDeviceEnabled", "(JI)Z",
+            (void*) nativeIsInputDeviceEnabled },
+    { "nativeEnableInputDevice", "(JI)V",
+            (void*) nativeEnableInputDevice },
+    { "nativeDisableInputDevice", "(JI)V",
+            (void*) nativeDisableInputDevice },
     { "nativeSetPointerIconType", "(JI)V",
             (void*) nativeSetPointerIconType },
     { "nativeReloadPointerIcons", "(J)V",
diff --git a/services/core/jni/com_android_server_location_ContextHubService.cpp b/services/core/jni/com_android_server_location_ContextHubService.cpp
index 09ccf6b..d90b011 100644
--- a/services/core/jni/com_android_server_location_ContextHubService.cpp
+++ b/services/core/jni/com_android_server_location_ContextHubService.cpp
@@ -513,7 +513,7 @@
 
     if (!txnInfo || instanceId < 0) {
         returnId(instanceId);
-        free(txnInfo);
+        delete txnInfo;
         return -1;
     }
 
@@ -526,7 +526,7 @@
 
     if (db.txnManager.addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) {
         returnId(instanceId);
-        free(txnInfo);
+        delete txnInfo;
         return -1;
     }
 
@@ -543,7 +543,7 @@
     *txnData = appInstanceHandle;
 
     if (db.txnManager.addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) {
-        free(txnData);
+        delete txnData;
         ALOGW("Cannot start transaction to unload app");
         return -1;
     }
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 2b1225c..1f1324a 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1523,6 +1523,10 @@
                           << " satellites:: " << std::endl;
         }
 
+        internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
+                      << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
+                      << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
+                      << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
         for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
             internalState << "svid: " << data.satelliteDataArray[i].svid
                           << ", constellation: "
diff --git a/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
new file mode 100644
index 0000000..248dedb
--- /dev/null
+++ b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SyntheticPasswordManager"
+
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <android_runtime/Log.h>
+#include <utils/Timers.h>
+#include <utils/misc.h>
+#include <utils/String8.h>
+#include <utils/Log.h>
+#include <gatekeeper/password_handle.h>
+
+
+extern "C" {
+#include "crypto_scrypt.h"
+}
+
+namespace android {
+
+static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
+
+    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
+
+    if (data != NULL) {
+        const gatekeeper::password_handle_t *handle =
+                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
+        jlong sid = handle->user_id;
+        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
+        return sid;
+    } else {
+        return 0;
+    }
+}
+
+static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
+    if (!password || !salt) {
+        return NULL;
+    }
+
+    int passwordLen = env->GetArrayLength(password);
+    int saltLen = env->GetArrayLength(salt);
+    jbyteArray ret = env->NewByteArray(outLen);
+
+    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
+    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
+    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
+
+    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
+                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
+                       outLen);
+    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(ret, retPtr, 0);
+
+    if (!rc) {
+        return ret;
+    } else {
+        SLOGE("scrypt failed");
+        return NULL;
+    }
+}
+
+static const JNINativeMethod sMethods[] = {
+     /* name, signature, funcPtr */
+    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
+    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
+};
+
+int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/locksettings/SyntheticPasswordManager",
+                                    sMethods, NELEM(sMethods));
+}
+
+} /* namespace android */
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 935ced9..39f90ca 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -18,7 +18,7 @@
 
 //#define LOG_NDEBUG 0
 
-#include <android/hardware/power/1.0/IPower.h>
+#include <android/hardware/power/1.1/IPower.h>
 #include "JNIHelp.h"
 #include "jni.h"
 
@@ -41,7 +41,7 @@
 
 using android::hardware::Return;
 using android::hardware::Void;
-using android::hardware::power::V1_0::IPower;
+using android::hardware::power::V1_1::IPower;
 using android::hardware::power::V1_0::PowerHint;
 using android::hardware::power::V1_0::Feature;
 using android::String8;
@@ -57,13 +57,14 @@
 // ----------------------------------------------------------------------------
 
 static jobject gPowerManagerServiceObj;
-sp<IPower> gPowerHal = nullptr;
+sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
+sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
 bool gPowerHalExists = true;
 std::mutex gPowerHalMutex;
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
 // Throttling interval for user activity calls.
-static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 500 * 1000000L; // 500ms
+static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 100 * 1000000L; // 100ms
 
 // ----------------------------------------------------------------------------
 
@@ -80,16 +81,17 @@
 // Check validity of current handle to the power HAL service, and call getService() if necessary.
 // The caller must be holding gPowerHalMutex.
 bool getPowerHal() {
-    if (gPowerHalExists && gPowerHal == nullptr) {
-        gPowerHal = IPower::getService();
-        if (gPowerHal != nullptr) {
+    if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
+        gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
+        if (gPowerHalV1_0 != nullptr) {
+            gPowerHalV1_1 =  android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
             ALOGI("Loaded power HAL service");
         } else {
             ALOGI("Couldn't load power HAL service");
             gPowerHalExists = false;
         }
     }
-    return gPowerHal != nullptr;
+    return gPowerHalV1_0 != nullptr;
 }
 
 // Check if a call to a power HAL function failed; if so, log the failure and invalidate the
@@ -97,19 +99,11 @@
 static void processReturn(const Return<void> &ret, const char* functionName) {
     if (!ret.isOk()) {
         ALOGE("%s() failed: power HAL service not available.", functionName);
-        gPowerHal = nullptr;
+        gPowerHalV1_0 = nullptr;
     }
 }
 
 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
-    // Tell the power HAL when user activity occurs.
-    gPowerHalMutex.lock();
-    if (getPowerHal()) {
-        Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0);
-        processReturn(ret, "powerHint");
-    }
-    gPowerHalMutex.unlock();
-
     if (gPowerManagerServiceObj) {
         // Throttle calls into user activity by event type.
         // We're a little conservative about argument checking here in case the caller
@@ -124,6 +118,21 @@
                 return;
             }
             gLastEventTime[eventType] = eventTime;
+
+
+            // Tell the power HAL when user activity occurs.
+            gPowerHalMutex.lock();
+            if (getPowerHal()) {
+              Return<void> ret;
+              if (gPowerHalV1_1 != nullptr) {
+                ret = gPowerHalV1_1->powerHintAsync(PowerHint::INTERACTION, 0);
+              } else {
+                ret = gPowerHalV1_0->powerHint(PowerHint::INTERACTION, 0);
+              }
+              processReturn(ret, "powerHint");
+            }
+            gPowerHalMutex.unlock();
+
         }
 
         JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -159,7 +168,7 @@
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
         android::base::Timer t;
-        Return<void> ret = gPowerHal->setInteractive(enable);
+        Return<void> ret = gPowerHalV1_0->setInteractive(enable);
         processReturn(ret, "setInteractive");
         if (t.duration() > 20ms) {
             ALOGD("Excessive delay in setInteractive(%s) while turning screen %s",
@@ -187,7 +196,12 @@
 static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
-        Return<void> ret =  gPowerHal->powerHint((PowerHint)hintId, data);
+        Return<void> ret;
+        if (gPowerHalV1_1 != nullptr) {
+            ret =  gPowerHalV1_1->powerHintAsync((PowerHint)hintId, data);
+        } else {
+            ret =  gPowerHalV1_0->powerHint((PowerHint)hintId, data);
+        }
         processReturn(ret, "powerHint");
     }
 }
@@ -195,7 +209,7 @@
 static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
     std::lock_guard<std::mutex> lock(gPowerHalMutex);
     if (getPowerHal()) {
-        Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data));
+        Return<void> ret = gPowerHalV1_0->setFeature((Feature)featureId, static_cast<bool>(data));
         processReturn(ret, "setFeature");
     }
 }
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
new file mode 100644
index 0000000..73887bb
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -0,0 +1,208 @@
+/**
+ * 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 "radio.RadioService.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_RadioService.h"
+
+#include "com_android_server_radio_Tuner.h"
+#include "com_android_server_radio_convert.h"
+
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadio.h>
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace RadioService {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::Class;
+using V1_0::Result;
+
+using V1_0::BandConfig;
+using V1_0::ProgramInfo;
+using V1_0::MetaData;
+using V1_0::ITuner;
+
+static Mutex gContextMutex;
+
+static struct {
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } Tuner;
+} gjni;
+
+struct ServiceContext {
+    ServiceContext() {}
+
+    sp<V1_0::IBroadcastRadio> mModule;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ServiceContext);
+};
+
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static ServiceContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<ServiceContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto nativeContext = new ServiceContext();
+    static_assert(sizeof(jlong) >= sizeof(nativeContext), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(nativeContext);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<ServiceContext*>(nativeContext);
+    delete ctx;
+}
+
+static sp<V1_0::IBroadcastRadio> getModule(jlong nativeContext) {
+    ALOGV("getModule()");
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+
+    if (ctx.mModule != nullptr) {
+        return ctx.mModule;
+    }
+
+    // TODO(b/36863239): what about other HAL implementations?
+    auto factory = V1_0::IBroadcastRadioFactory::getService();
+    if (factory == nullptr) {
+        ALOGE("Can't retrieve radio HAL implementation");
+        return nullptr;
+    }
+
+    sp<V1_0::IBroadcastRadio> module = nullptr;
+    // TODO(b/36863239): not only AM/FM
+    factory->connectModule(Class::AM_FM, [&](Result retval,
+            const sp<V1_0::IBroadcastRadio>& result) {
+        if (retval == Result::OK) {
+            module = result;
+        }
+    });
+
+    ALOGE_IF(module == nullptr, "Couldn't connect module");
+    ctx.mModule = module;
+    return module;
+}
+
+static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jint moduleId,
+        jobject bandConfig, bool withAudio, jobject callback) {
+    ALOGV("nativeOpenTuner()");
+    EnvWrapper wrap(env);
+
+    if (callback == nullptr) {
+        ALOGE("Callback is empty");
+        return nullptr;
+    }
+
+    // TODO(b/36863239): use moduleId
+    auto module = getModule(nativeContext);
+    if (module == nullptr) {
+        return nullptr;
+    }
+
+    HalRevision halRev;
+    if (V1_1::IBroadcastRadio::castFrom(module).withDefault(nullptr) != nullptr) {
+        ALOGI("Opening tuner with broadcast radio HAL 1.1");
+        halRev = HalRevision::V1_1;
+    } else {
+        ALOGI("Opening tuner with broadcast radio HAL 1.0");
+        halRev = HalRevision::V1_0;
+    }
+
+    Region region;
+    BandConfig bandConfigHal = convert::BandConfigToHal(env, bandConfig, region);
+
+    auto tuner = wrap(env->NewObject(gjni.Tuner.clazz, gjni.Tuner.cstor,
+            callback, halRev, region, withAudio));
+    if (tuner == nullptr) {
+        ALOGE("Unable to create new tuner object.");
+        return nullptr;
+    }
+
+    auto tunerCb = Tuner::getNativeCallback(env, tuner);
+    Result halResult;
+    sp<ITuner> halTuner = nullptr;
+
+    auto hidlResult = module->openTuner(bandConfigHal, withAudio, tunerCb,
+            [&](Result result, const sp<ITuner>& tuner) {
+                halResult = result;
+                halTuner = tuner;
+            });
+    if (!hidlResult.isOk() || halResult != Result::OK || halTuner == nullptr) {
+        ALOGE("Couldn't open tuner");
+        ALOGE_IF(hidlResult.isOk(), "halResult = %d", halResult);
+        ALOGE_IF(!hidlResult.isOk(), "hidlResult = %s", hidlResult.description().c_str());
+        return nullptr;
+    }
+
+    Tuner::setHalTuner(env, tuner, halTuner);
+    ALOGI("Opened tuner %p", halTuner.get());
+    return tuner.release();
+}
+
+static const JNINativeMethod gRadioServiceMethods[] = {
+    { "nativeInit", "()J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeOpenTuner", "(JILandroid/hardware/radio/RadioManager$BandConfig;Z"
+            "Landroid/hardware/radio/ITunerCallback;)Lcom/android/server/radio/Tuner;",
+            (void*)nativeOpenTuner },
+};
+
+} // namespace RadioService
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_RadioService(JNIEnv *env) {
+    using namespace server::radio::RadioService;
+
+    register_android_server_radio_convert(env);
+
+    auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner");
+    gjni.Tuner.clazz = MakeGlobalRefOrDie(env, tunerClass);
+    gjni.Tuner.cstor = GetMethodIDOrDie(env, tunerClass, "<init>",
+            "(Landroid/hardware/radio/ITunerCallback;IIZ)V");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/RadioService",
+            gRadioServiceMethods, NELEM(gRadioServiceMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_RadioService.h b/services/core/jni/com_android_server_radio_RadioService.h
new file mode 100644
index 0000000..91e119c
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_RadioService.h
@@ -0,0 +1,28 @@
+/**
+ * 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 _ANDROID_SERVER_RADIO_RADIOSERVICE_H
+#define _ANDROID_SERVER_RADIO_RADIOSERVICE_H
+
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_RadioService(JNIEnv *env);
+
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_RADIOSERVICE_H
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
new file mode 100644
index 0000000..b92136a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -0,0 +1,384 @@
+/**
+ * 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 "radio.Tuner.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_Tuner.h"
+
+#include "com_android_server_radio_convert.h"
+#include "com_android_server_radio_Tuner_TunerCallback.h"
+
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace Tuner {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::BandConfig;
+using V1_0::MetaData;
+using V1_0::Result;
+using V1_1::ITunerCallback;
+using V1_1::ProgramListResult;
+
+static Mutex gContextMutex;
+
+static struct {
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID add;
+    } ArrayList;
+    struct {
+        jfieldID nativeContext;
+        jfieldID region;
+        jfieldID tunerCallback;
+    } Tuner;
+} gjni;
+
+struct TunerContext {
+    TunerContext() {}
+
+    HalRevision mHalRev;
+    sp<V1_0::ITuner> mHalTuner;
+    sp<V1_1::ITuner> mHalTuner11;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TunerContext);
+};
+
+static TunerContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<TunerContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static TunerContext& getNativeContext(JNIEnv *env, JavaRef<jobject> const &jTuner) {
+    return getNativeContext(env->GetLongField(jTuner.get(), gjni.Tuner.nativeContext));
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = new TunerContext();
+    ctx->mHalRev = static_cast<HalRevision>(halRev);
+
+    static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(ctx);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<TunerContext*>(nativeContext);
+    delete ctx;
+}
+
+void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner, sp<V1_0::ITuner> halTuner) {
+    ALOGV("setHalTuner(%p)", halTuner.get());
+    ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
+
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(env, jTuner);
+
+    ctx.mHalTuner = halTuner;
+    ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
+    ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
+            "Provided tuner does not implement 1.1 HAL");
+}
+
+sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    auto tuner = getNativeContext(nativeContext).mHalTuner;
+    LOG_ALWAYS_FATAL_IF(tuner == nullptr, "HAL tuner is not open");
+    return tuner;
+}
+
+sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    return getNativeContext(nativeContext).mHalTuner11;
+}
+
+sp<ITunerCallback> getNativeCallback(JNIEnv *env, JavaRef<jobject> const &tuner) {
+    return TunerCallback::getNativeCallback(env,
+            env->GetObjectField(tuner.get(), gjni.Tuner.tunerCallback));
+}
+
+Region getRegion(JNIEnv *env, jobject obj) {
+    return static_cast<Region>(env->GetIntField(obj, gjni.Tuner.region));
+}
+
+static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+    if (ctx.mHalTuner == nullptr) return;
+    ALOGI("Closing tuner %p", ctx.mHalTuner.get());
+    ctx.mHalTuner11 = nullptr;
+    ctx.mHalTuner = nullptr;
+}
+
+static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
+    ALOGV("nativeSetConfiguration()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    Region region_unused;
+    BandConfig bandConfigHal = convert::BandConfigToHal(env, config, region_unused);
+
+    convert::ThrowIfFailed(env, halTuner->setConfiguration(bandConfigHal));
+}
+
+static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
+        Region region) {
+    ALOGV("nativeSetConfiguration()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return nullptr;
+
+    BandConfig halConfig;
+    Result halResult;
+    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
+        halResult = result;
+        halConfig = config;
+    });
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) {
+        return nullptr;
+    }
+
+    return convert::BandConfigFromHal(env, halConfig, region).release();
+}
+
+static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeStep()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->step(dir, skipSubChannel));
+}
+
+static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeScan()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->scan(dir, skipSubChannel));
+}
+
+static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext,
+        jint channel, jint subChannel) {
+    ALOGV("nativeTune(%d, %d)", channel, subChannel);
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    convert::ThrowIfFailed(env, halTuner->tune(channel, subChannel));
+}
+
+static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeCancel()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return;
+
+    convert::ThrowIfFailed(env, halTuner->cancel());
+}
+
+static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeGetProgramInformation()");
+    auto halTuner10 = getHalTuner(nativeContext);
+    auto halTuner11 = getHalTuner11(nativeContext);
+    if (halTuner10 == nullptr) return nullptr;
+
+    JavaRef<jobject> jInfo;
+    Result halResult;
+    Return<void> hidlResult;
+    if (halTuner11 != nullptr) {
+        hidlResult = halTuner11->getProgramInformation_1_1([&](Result result,
+                const V1_1::ProgramInfo& info) {
+            halResult = result;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
+        });
+    } else {
+        hidlResult = halTuner10->getProgramInformation([&](Result result,
+                const V1_0::ProgramInfo& info) {
+            halResult = result;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
+        });
+    }
+
+    if (jInfo != nullptr) return jInfo.release();
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return nullptr;
+}
+
+static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeStartBackgroundScan()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Background scan is not supported with HAL < 1.1");
+        return false;
+    }
+
+    auto halResult = halTuner->startBackgroundScan();
+
+    if (halResult.isOk() && halResult == ProgramListResult::UNAVAILABLE) return false;
+    return !convert::ThrowIfFailed(env, halResult);
+}
+
+static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
+    ALOGV("nativeGetProgramList()");
+    EnvWrapper wrap(env);
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Program list is not supported with HAL < 1.1");
+        return nullptr;
+    }
+
+    JavaRef<jobject> jList;
+    ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED;
+    auto filter = env->GetStringUTFChars(jFilter, nullptr);
+    auto hidlResult = halTuner->getProgramList(filter,
+            [&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) {
+        halResult = result;
+        if (halResult != ProgramListResult::OK) return;
+
+        jList = wrap(env->NewObject(gjni.ArrayList.clazz, gjni.ArrayList.cstor));
+        for (auto& program : programList) {
+            auto jProgram = convert::ProgramInfoFromHal(env, program);
+            env->CallBooleanMethod(jList.get(), gjni.ArrayList.add, jProgram.get());
+        }
+    });
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return nullptr;
+
+    return jList.release();
+}
+
+static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return false;
+    }
+
+    bool isForced;
+    Result halResult;
+    auto hidlResult = halTuner->isAnalogForced([&](Result result, bool isForcedRet) {
+        halResult = result;
+        isForced = isForcedRet;
+    });
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return false;
+
+    return isForced;
+}
+
+static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
+    ALOGV("nativeSetAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return;
+    }
+
+    auto halResult = halTuner->setAnalogForced(isForced);
+    convert::ThrowIfFailed(env, halResult);
+}
+
+static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAntennaConnected()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return false;
+
+    bool isConnected = false;
+    Result halResult;
+    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
+        halResult = result;
+        isConnected = config.antennaConnected;
+    });
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return isConnected;
+}
+
+static const JNINativeMethod gTunerMethods[] = {
+    { "nativeInit", "(I)J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeClose", "(J)V", (void*)nativeClose },
+    { "nativeSetConfiguration", "(JLandroid/hardware/radio/RadioManager$BandConfig;)V",
+            (void*)nativeSetConfiguration },
+    { "nativeGetConfiguration", "(JI)Landroid/hardware/radio/RadioManager$BandConfig;",
+            (void*)nativeGetConfiguration },
+    { "nativeStep", "(JZZ)V", (void*)nativeStep },
+    { "nativeScan", "(JZZ)V", (void*)nativeScan },
+    { "nativeTune", "(JII)V", (void*)nativeTune },
+    { "nativeCancel", "(J)V", (void*)nativeCancel },
+    { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
+            (void*)nativeGetProgramInformation },
+    { "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan },
+    { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;",
+            (void*)nativeGetProgramList },
+    { "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
+    { "nativeSetAnalogForced", "(JZ)V", (void*)nativeSetAnalogForced },
+    { "nativeIsAntennaConnected", "(J)Z", (void*)nativeIsAntennaConnected },
+};
+
+} // namespace Tuner
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_Tuner(JavaVM *vm, JNIEnv *env) {
+    using namespace server::radio::Tuner;
+
+    register_android_server_radio_TunerCallback(vm, env);
+
+    auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner");
+    gjni.Tuner.nativeContext = GetFieldIDOrDie(env, tunerClass, "mNativeContext", "J");
+    gjni.Tuner.region = GetFieldIDOrDie(env, tunerClass, "mRegion", "I");
+    gjni.Tuner.tunerCallback = GetFieldIDOrDie(env, tunerClass, "mTunerCallback",
+            "Lcom/android/server/radio/TunerCallback;");
+
+    auto arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
+    gjni.ArrayList.clazz = MakeGlobalRefOrDie(env, arrayListClass);
+    gjni.ArrayList.cstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
+    gjni.ArrayList.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/Tuner",
+            gTunerMethods, NELEM(gTunerMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_Tuner.h b/services/core/jni/com_android_server_radio_Tuner.h
new file mode 100644
index 0000000..f653832
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner.h
@@ -0,0 +1,50 @@
+/**
+ * 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 _ANDROID_SERVER_RADIO_TUNER_H
+#define _ANDROID_SERVER_RADIO_TUNER_H
+
+#include "com_android_server_radio_types.h"
+
+#include "JavaRef.h"
+
+#include <android/hardware/broadcastradio/1.1/ITuner.h>
+#include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
+#include <jni.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+void register_android_server_radio_Tuner(JavaVM *vm, JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace Tuner {
+
+void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner,
+        sp<hardware::broadcastradio::V1_0::ITuner> halTuner);
+
+sp<hardware::broadcastradio::V1_1::ITunerCallback>
+getNativeCallback(JNIEnv *env, JavaRef<jobject> const &tuner);
+
+Region getRegion(JNIEnv *env, jobject obj);
+
+} // namespace Tuner
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TUNER_H
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
new file mode 100644
index 0000000..1290c7a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
@@ -0,0 +1,319 @@
+/**
+ * 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 "radio.TunerCallback.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_Tuner_TunerCallback.h"
+
+#include "com_android_server_radio_convert.h"
+#include "com_android_server_radio_Tuner.h"
+
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace TunerCallback {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+using V1_0::BandConfig;
+using V1_0::MetaData;
+using V1_0::Result;
+using V1_1::ITunerCallback;
+using V1_1::ProgramListResult;
+
+static JavaVM *gvm = nullptr;
+
+static struct {
+    struct {
+        jclass clazz;
+        jfieldID nativeContext;
+        jmethodID handleHwFailure;
+        jmethodID onError;
+        jmethodID onConfigurationChanged;
+        jmethodID onProgramInfoChanged;
+    } TunerCallback;
+} gjni;
+
+// from frameworks/base/core/java/android/hardware/radio/RadioTuner.java
+enum class TunerError : jint {
+    HARDWARE_FAILURE = 0,
+    SERVER_DIED = 1,
+    CANCELLED = 2,
+    SCAN_TIMEOUT = 3,
+    CONFIG = 4,
+};
+
+static Mutex gContextMutex;
+
+class NativeCallback : public ITunerCallback {
+    jobject mJTuner;
+    jobject mJCallback;
+    NativeCallbackThread mCallbackThread;
+    HalRevision mHalRev;
+
+    DISALLOW_COPY_AND_ASSIGN(NativeCallback);
+
+public:
+    NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev);
+    virtual ~NativeCallback();
+
+    void detach();
+
+    virtual Return<void> hardwareFailure();
+    virtual Return<void> configChange(Result result, const BandConfig& config);
+    virtual Return<void> tuneComplete(Result result, const V1_0::ProgramInfo& info);
+    virtual Return<void> afSwitch(const V1_0::ProgramInfo& info);
+    virtual Return<void> antennaStateChange(bool connected);
+    virtual Return<void> trafficAnnouncement(bool active);
+    virtual Return<void> emergencyAnnouncement(bool active);
+    virtual Return<void> newMetadata(uint32_t channel, uint32_t subChannel,
+            const hidl_vec<MetaData>& metadata);
+    virtual Return<void> tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info);
+    virtual Return<void> afSwitch_1_1(const V1_1::ProgramInfo& info);
+    virtual Return<void> backgroundScanAvailable(bool isAvailable);
+    virtual Return<void> backgroundScanComplete(ProgramListResult result);
+    virtual Return<void> programListChanged();
+};
+
+struct TunerCallbackContext {
+    TunerCallbackContext() {}
+
+    sp<NativeCallback> mNativeCallback;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TunerCallbackContext);
+};
+
+NativeCallback::NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev)
+        : mCallbackThread(gvm), mHalRev(halRev) {
+    ALOGV("NativeCallback()");
+    mJTuner = env->NewGlobalRef(jTuner);
+    mJCallback = env->NewGlobalRef(jCallback);
+}
+
+NativeCallback::~NativeCallback() {
+    ALOGV("~NativeCallback()");
+
+    // stop callback thread before dereferencing client callback
+    mCallbackThread.stop();
+
+    JNIEnv *env = nullptr;
+    gvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4);
+    if (env != nullptr) {
+        env->DeleteGlobalRef(mJTuner);
+        env->DeleteGlobalRef(mJCallback);
+    }
+}
+
+void NativeCallback::detach() {
+    // stop callback thread to ignore further calls
+    mCallbackThread.stop();
+}
+
+Return<void> NativeCallback::hardwareFailure() {
+    mCallbackThread.enqueue([this](JNIEnv *env) {
+        env->CallVoidMethod(mJCallback, gjni.TunerCallback.handleHwFailure);
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::configChange(Result result, const BandConfig& config) {
+    ALOGV("configChange(%d)", result);
+
+    mCallbackThread.enqueue([result, config, this](JNIEnv *env) {
+        if (result == Result::OK) {
+            auto region = Tuner::getRegion(env, mJTuner);
+            auto jConfig = convert::BandConfigFromHal(env, config, region);
+            if (jConfig == nullptr) return;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onConfigurationChanged,
+                    jConfig.get());
+        } else {
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, TunerError::CONFIG);
+        }
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
+    ALOGV("tuneComplete(%d)", result);
+
+    if (mHalRev > HalRevision::V1_0) {
+        ALOGD("1.0 callback was ignored");
+        return Return<void>();
+    }
+
+    V1_1::ProgramInfo info_1_1 {
+        .base = info,
+    };
+    return tuneComplete_1_1(result, info_1_1);
+}
+
+Return<void> NativeCallback::tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info) {
+    ALOGV("tuneComplete_1_1(%d)", result);
+
+    mCallbackThread.enqueue([result, info, this](JNIEnv *env) {
+        if (result == Result::OK) {
+            auto jInfo = convert::ProgramInfoFromHal(env, info);
+            if (jInfo == nullptr) return;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged, jInfo.get());
+        } else {
+            TunerError cause = TunerError::CANCELLED;
+            if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
+            env->CallVoidMethod(mJCallback, gjni.TunerCallback.onError, cause);
+        }
+    });
+
+    return Return<void>();
+}
+
+Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
+    ALOGE("Not implemented: afSwitch");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
+    ALOGE("Not implemented: afSwitch_1_1");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::antennaStateChange(bool connected) {
+    ALOGE("Not implemented: antennaStateChange");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::trafficAnnouncement(bool active) {
+    ALOGE("Not implemented: trafficAnnouncement");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::emergencyAnnouncement(bool active) {
+    ALOGE("Not implemented: emergencyAnnouncement");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
+        const hidl_vec<MetaData>& metadata) {
+    ALOGE("Not implemented: newMetadata");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
+    ALOGE("Not implemented: backgroundScanAvailable");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
+    ALOGE("Not implemented: backgroundScanComplete");
+    return Return<void>();
+}
+
+Return<void> NativeCallback::programListChanged() {
+    ALOGE("Not implemented: programListChanged");
+    return Return<void>();
+}
+
+static TunerCallbackContext& getNativeContext(jlong nativeContextHandle) {
+    auto nativeContext = reinterpret_cast<TunerCallbackContext*>(nativeContextHandle);
+    LOG_ALWAYS_FATAL_IF(nativeContext == nullptr, "Native context not initialized");
+    return *nativeContext;
+}
+
+/**
+ * Always lock gContextMutex when using native context.
+ */
+static TunerCallbackContext& getNativeContext(JNIEnv *env, jobject jTunerCb) {
+    return getNativeContext(env->GetLongField(jTunerCb, gjni.TunerCallback.nativeContext));
+}
+
+static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev) {
+    ALOGV("nativeInit()");
+    AutoMutex _l(gContextMutex);
+
+    auto halRev = static_cast<HalRevision>(jHalRev);
+
+    auto ctx = new TunerCallbackContext();
+    ctx->mNativeCallback = new NativeCallback(env, jTuner, obj, halRev);
+
+    static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
+    return reinterpret_cast<jlong>(ctx);
+}
+
+static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeFinalize()");
+    AutoMutex _l(gContextMutex);
+
+    auto ctx = reinterpret_cast<TunerCallbackContext*>(nativeContext);
+    delete ctx;
+}
+
+static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeDetach()");
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(nativeContext);
+
+    if (ctx.mNativeCallback == nullptr) return;
+    ctx.mNativeCallback->detach();
+    ctx.mNativeCallback = nullptr;
+}
+
+sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject jTunerCallback) {
+    AutoMutex _l(gContextMutex);
+    auto& ctx = getNativeContext(env, jTunerCallback);
+    return ctx.mNativeCallback;
+}
+
+static const JNINativeMethod gTunerCallbackMethods[] = {
+    { "nativeInit", "(Lcom/android/server/radio/Tuner;I)J", (void*)nativeInit },
+    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
+    { "nativeDetach", "(J)V", (void*)nativeDetach },
+};
+
+} // namespace TunerCallback
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_TunerCallback(JavaVM *vm, JNIEnv *env) {
+    using namespace server::radio::TunerCallback;
+
+    gvm = vm;
+
+    auto tunerCbClass = FindClassOrDie(env, "com/android/server/radio/TunerCallback");
+    gjni.TunerCallback.clazz = MakeGlobalRefOrDie(env, tunerCbClass);
+    gjni.TunerCallback.nativeContext = GetFieldIDOrDie(env, tunerCbClass, "mNativeContext", "J");
+    gjni.TunerCallback.handleHwFailure = GetMethodIDOrDie(env, tunerCbClass, "handleHwFailure", "()V");
+    gjni.TunerCallback.onError = GetMethodIDOrDie(env, tunerCbClass, "onError", "(I)V");
+    gjni.TunerCallback.onConfigurationChanged = GetMethodIDOrDie(env, tunerCbClass,
+            "onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
+    gjni.TunerCallback.onProgramInfoChanged = GetMethodIDOrDie(env, tunerCbClass,
+            "onProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
+
+    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/TunerCallback",
+            gTunerCallbackMethods, NELEM(gTunerCallbackMethods));
+    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
new file mode 100644
index 0000000..35a4d69
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
@@ -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.
+ */
+
+// TODO(b/36863239): rename s/_Tuner_TunerCallback/_TunerCallback/, as this
+// module is no longer a part of Tuner - it's an independent java class.
+#ifndef _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
+#define _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
+
+#include "JavaRef.h"
+#include "NativeCallbackThread.h"
+#include "com_android_server_radio_types.h"
+
+#include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_TunerCallback(JavaVM *vm, JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace TunerCallback {
+
+sp<hardware::broadcastradio::V1_1::ITunerCallback>
+getNativeCallback(JNIEnv *env, jobject jTunerCallback);
+
+} // namespace TunerCallback
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TUNERCALLBACK_H
diff --git a/services/core/jni/com_android_server_radio_convert.cpp b/services/core/jni/com_android_server_radio_convert.cpp
new file mode 100644
index 0000000..19abf8a
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_convert.cpp
@@ -0,0 +1,397 @@
+/**
+ * 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 "radio.convert.jni"
+#define LOG_NDEBUG 0
+
+#include "com_android_server_radio_convert.h"
+
+#include <core_jni_helpers.h>
+#include <utils/Log.h>
+#include <JNIHelp.h>
+
+namespace android {
+namespace server {
+namespace radio {
+namespace convert {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+using V1_0::Band;
+using V1_0::Deemphasis;
+using V1_0::Direction;
+using V1_0::MetadataType;
+using V1_0::Result;
+using V1_0::Rds;
+using V1_1::ProgramListResult;
+
+static struct {
+    struct {
+        jfieldID descriptor;
+    } BandConfig;
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jfieldID stereo;
+        jfieldID rds;
+        jfieldID ta;
+        jfieldID af;
+        jfieldID ea;
+    } FmBandConfig;
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jfieldID stereo;
+    } AmBandConfig;
+
+    struct {
+        jfieldID region;
+        jfieldID type;
+        jfieldID lowerLimit;
+        jfieldID upperLimit;
+        jfieldID spacing;
+    } BandDescriptor;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ProgramInfo;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID putIntFromNative;
+        jmethodID putStringFromNative;
+        jmethodID putBitmapFromNative;
+        jmethodID putClockFromNative;
+    } RadioMetadata;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } RuntimeException;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ParcelableException;
+} gjni;
+
+bool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
+    if (hidlResult.isOk()) return false;
+
+    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
+    return true;
+}
+
+bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
+    switch (halResult) {
+        case Result::OK:
+            return false;
+        case Result::NOT_INITIALIZED:
+            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
+            return true;
+        case Result::INVALID_ARGUMENTS:
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    "Result::INVALID_ARGUMENTS");
+            return true;
+        case Result::INVALID_STATE:
+            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
+            return true;
+        case Result::TIMEOUT:
+            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
+            return true;
+        default:
+            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
+                    + std::to_string(static_cast<int32_t>(halResult)));
+            return true;
+    }
+}
+
+bool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
+    switch (halResult) {
+        case ProgramListResult::NOT_READY:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan is in progress");
+            return true;
+        case ProgramListResult::NOT_STARTED:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
+            return true;
+        case ProgramListResult::UNAVAILABLE:
+            ThrowParcelableRuntimeException(env,
+                    "ProgramListResult::UNAVAILABLE (unexpected here)");
+            return true;
+        default:
+            return __ThrowIfFailed(env, static_cast<Result>(halResult));
+    }
+}
+
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
+    EnvWrapper wrap(env);
+
+    auto jMsg = wrap(env->NewStringUTF(msg.c_str()));
+    auto runtimeExc = wrap(env->NewObject(gjni.RuntimeException.clazz,
+            gjni.RuntimeException.cstor, jMsg.get()));
+    auto parcelableExc = wrap(env->NewObject(gjni.ParcelableException.clazz,
+            gjni.ParcelableException.cstor, runtimeExc.get()));
+
+    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
+    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
+}
+
+static Rds RdsForRegion(bool rds, Region region) {
+    if (!rds) return Rds::NONE;
+
+    switch(region) {
+        case Region::ITU_1:
+        case Region::OIRT:
+        case Region::JAPAN:
+        case Region::KOREA:
+            return Rds::WORLD;
+        case Region::ITU_2:
+            return Rds::US;
+        default:
+            ALOGE("Unexpected region: %d", region);
+            return Rds::NONE;
+    }
+}
+
+static Deemphasis DeemphasisForRegion(Region region) {
+    switch(region) {
+        case Region::KOREA:
+        case Region::ITU_2:
+            return Deemphasis::D75;
+        case Region::ITU_1:
+        case Region::OIRT:
+        case Region::JAPAN:
+            return Deemphasis::D50;
+        default:
+            ALOGE("Unexpected region: %d", region);
+            return Deemphasis::D50;
+    }
+}
+
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
+    ALOGV("BandConfigFromHal()");
+    EnvWrapper wrap(env);
+
+    jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
+    ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
+
+    switch (config.type) {
+        case Band::FM:
+        case Band::FM_HD: {
+            auto& fm = config.ext.fm;
+            return wrap(env->NewObject(gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor,
+                    region, config.type, config.lowerLimit, config.upperLimit, spacing,
+                    fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
+        }
+        case Band::AM:
+        case Band::AM_HD: {
+            auto& am = config.ext.am;
+            return wrap(env->NewObject(gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor,
+                    region, config.type, config.lowerLimit, config.upperLimit, spacing,
+                    am.stereo));
+        }
+        default:
+            ALOGE("Unsupported band type: %d", config.type);
+            return nullptr;
+    }
+}
+
+V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
+    ALOGV("BandConfigToHal()");
+    auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
+    if (jDescriptor == nullptr) {
+        ALOGE("Descriptor is missing");
+        return {};
+    }
+
+    region = static_cast<Region>(env->GetIntField(jDescriptor, gjni.BandDescriptor.region));
+
+    V1_0::BandConfig config = {};
+    config.type = static_cast<Band>(env->GetIntField(jDescriptor, gjni.BandDescriptor.type));
+    config.antennaConnected = false;  // just don't set it
+    config.lowerLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.lowerLimit);
+    config.upperLimit = env->GetIntField(jDescriptor, gjni.BandDescriptor.upperLimit);
+    config.spacings = hidl_vec<uint32_t>({
+        static_cast<uint32_t>(env->GetIntField(jDescriptor, gjni.BandDescriptor.spacing))
+    });
+
+    if (env->IsInstanceOf(jConfig, gjni.FmBandConfig.clazz)) {
+        auto& fm = config.ext.fm;
+        fm.deemphasis = DeemphasisForRegion(region);
+        fm.stereo = env->GetBooleanField(jConfig, gjni.FmBandConfig.stereo);
+        fm.rds = RdsForRegion(env->GetBooleanField(jConfig, gjni.FmBandConfig.rds), region);
+        fm.ta = env->GetBooleanField(jConfig, gjni.FmBandConfig.ta);
+        fm.af = env->GetBooleanField(jConfig, gjni.FmBandConfig.af);
+        fm.ea = env->GetBooleanField(jConfig, gjni.FmBandConfig.ea);
+    } else if (env->IsInstanceOf(jConfig, gjni.AmBandConfig.clazz)) {
+        auto& am = config.ext.am;
+        am.stereo = env->GetBooleanField(jConfig, gjni.AmBandConfig.stereo);
+    } else {
+        ALOGE("Unexpected band config type");
+        return {};
+    }
+
+    return config;
+}
+
+Direction DirectionToHal(bool directionDown) {
+    return directionDown ? Direction::DOWN : Direction::UP;
+}
+
+static JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> metadata) {
+    ALOGV("MetadataFromHal()");
+    EnvWrapper wrap(env);
+
+    if (metadata.size() == 0) return nullptr;
+
+    auto jMetadata = wrap(env->NewObject(gjni.RadioMetadata.clazz, gjni.RadioMetadata.cstor));
+
+    for (auto& item : metadata) {
+        jint key = static_cast<jint>(item.key);
+        jint status = 0;
+        switch (item.type) {
+            case MetadataType::INT:
+                ALOGV("metadata INT %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putIntFromNative,
+                        key, item.intValue);
+                break;
+            case MetadataType::TEXT: {
+                ALOGV("metadata TEXT %d", key);
+                auto value = wrap(env->NewStringUTF(item.stringValue.c_str()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putStringFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::RAW: {
+                ALOGV("metadata RAW %d", key);
+                auto len = item.rawValue.size();
+                if (len == 0) break;
+                auto value = wrap(env->NewByteArray(len));
+                if (value == nullptr) {
+                    ALOGE("Failed to allocate byte array of len %zu", len);
+                    break;
+                }
+                env->SetByteArrayRegion(value.get(), 0, len,
+                        reinterpret_cast<const jbyte*>(item.rawValue.data()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putBitmapFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::CLOCK:
+                ALOGV("metadata CLOCK %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putClockFromNative,
+                        key, item.clockValue.utcSecondsSinceEpoch,
+                        item.clockValue.timezoneOffsetInMinutes);
+                break;
+            default:
+                ALOGW("invalid metadata type %d", item.type);
+        }
+        ALOGE_IF(status != 0, "Failed inserting metadata %d (of type %d)", key, item.type);
+    }
+
+    return jMetadata;
+}
+
+static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
+        const V1_1::ProgramInfo *info11) {
+    ALOGV("ProgramInfoFromHal()");
+    EnvWrapper wrap(env);
+
+    auto jMetadata = MetadataFromHal(env, info10.metadata);
+    auto jVendorExtension = info11 ?
+            wrap(env->NewStringUTF(info11->vendorExension.c_str())) : nullptr;
+
+    return wrap(env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor, info10.channel,
+            info10.subChannel, info10.tuned, info10.stereo, info10.digital, info10.signalStrength,
+            jMetadata.get(), info11 ? info11->flags : 0, jVendorExtension.get()));
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info, nullptr);
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info.base, &info);
+}
+
+} // namespace convert
+} // namespace radio
+} // namespace server
+
+void register_android_server_radio_convert(JNIEnv *env) {
+    using namespace server::radio::convert;
+
+    auto bandConfigClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$BandConfig");
+    gjni.BandConfig.descriptor = GetFieldIDOrDie(env, bandConfigClass,
+            "mDescriptor", "Landroid/hardware/radio/RadioManager$BandDescriptor;");
+
+    auto fmBandConfigClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$FmBandConfig");
+    gjni.FmBandConfig.clazz = MakeGlobalRefOrDie(env, fmBandConfigClass);
+    gjni.FmBandConfig.cstor = GetMethodIDOrDie(env, fmBandConfigClass,
+            "<init>", "(IIIIIZZZZZ)V");
+    gjni.FmBandConfig.stereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
+    gjni.FmBandConfig.rds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
+    gjni.FmBandConfig.ta = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
+    gjni.FmBandConfig.af = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
+    gjni.FmBandConfig.ea = GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");
+
+    auto amBandConfigClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$AmBandConfig");
+    gjni.AmBandConfig.clazz = MakeGlobalRefOrDie(env, amBandConfigClass);
+    gjni.AmBandConfig.cstor = GetMethodIDOrDie(env, amBandConfigClass, "<init>", "(IIIIIZ)V");
+    gjni.AmBandConfig.stereo = GetFieldIDOrDie(env, amBandConfigClass, "mStereo", "Z");
+
+    auto bandDescriptorClass = FindClassOrDie(env,
+            "android/hardware/radio/RadioManager$BandDescriptor");
+    gjni.BandDescriptor.region = GetFieldIDOrDie(env, bandDescriptorClass, "mRegion", "I");
+    gjni.BandDescriptor.type = GetFieldIDOrDie(env, bandDescriptorClass, "mType", "I");
+    gjni.BandDescriptor.lowerLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
+    gjni.BandDescriptor.upperLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
+    gjni.BandDescriptor.spacing = GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");
+
+    auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
+    gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
+    gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
+            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
+
+    auto radioMetadataClass = FindClassOrDie(env, "android/hardware/radio/RadioMetadata");
+    gjni.RadioMetadata.clazz = MakeGlobalRefOrDie(env, radioMetadataClass);
+    gjni.RadioMetadata.cstor = GetMethodIDOrDie(env, radioMetadataClass, "<init>", "()V");
+    gjni.RadioMetadata.putIntFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putIntFromNative", "(II)I");
+    gjni.RadioMetadata.putStringFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putStringFromNative", "(ILjava/lang/String;)I");
+    gjni.RadioMetadata.putBitmapFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putBitmapFromNative", "(I[B)I");
+    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putClockFromNative", "(IJI)I");
+
+    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
+    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
+    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
+            "(Ljava/lang/String;)V");
+
+    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
+    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
+    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
+            "(Ljava/lang/Throwable;)V");
+}
+
+} // namespace android
diff --git a/services/core/jni/com_android_server_radio_convert.h b/services/core/jni/com_android_server_radio_convert.h
new file mode 100644
index 0000000..6f6774b
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_convert.h
@@ -0,0 +1,69 @@
+/**
+ * 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 _ANDROID_SERVER_RADIO_CONVERT_H
+#define _ANDROID_SERVER_RADIO_CONVERT_H
+
+#include "JavaRef.h"
+#include "com_android_server_radio_types.h"
+
+#include <android/hardware/broadcastradio/1.1/types.h>
+#include <jni.h>
+
+namespace android {
+
+void register_android_server_radio_convert(JNIEnv *env);
+
+namespace server {
+namespace radio {
+namespace convert {
+
+namespace V1_0 = hardware::broadcastradio::V1_0;
+namespace V1_1 = hardware::broadcastradio::V1_1;
+
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
+V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region);
+
+V1_0::Direction DirectionToHal(bool directionDown);
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info);
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);
+
+
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg);
+
+// These three are only for internal use by template functions below.
+bool __ThrowIfFailedHidl(JNIEnv *env,
+        const hardware::details::return_status &hidlResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_0::Result halResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_1::ProgramListResult halResult);
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult, const T halResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, halResult);
+}
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<T> &hidlResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, static_cast<T>(hidlResult));
+}
+
+} // namespace convert
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_CONVERT_H
diff --git a/services/core/jni/com_android_server_radio_types.h b/services/core/jni/com_android_server_radio_types.h
new file mode 100644
index 0000000..36f7643
--- /dev/null
+++ b/services/core/jni/com_android_server_radio_types.h
@@ -0,0 +1,60 @@
+/**
+ * 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 _ANDROID_SERVER_RADIO_TYPES_H
+#define _ANDROID_SERVER_RADIO_TYPES_H
+
+#include <jni.h>
+
+namespace android {
+namespace server {
+namespace radio {
+
+/* Most of these enums are dereived from Java code, based at
+ * frameworks/base/core/java/android/hardware/radio/RadioManager.java.
+ */
+
+enum class HalRevision : jint {
+    V1_0,
+    V1_1,
+};
+
+// Keep in sync with STATUS_* constants from RadioManager.java.
+enum class Status : jint {
+    OK = 0,
+    ERROR = -0x80000000ll,  // Integer.MIN_VALUE
+    PERMISSION_DENIED = -1,  // -EPERM
+    NO_INIT = -19,  // -ENODEV
+    BAD_VALUE = -22,  // -EINVAL
+    DEAD_OBJECT = -32,  // -EPIPE
+    INVALID_OPERATION = -38,  // -ENOSYS
+    TIMED_OUT = -110,  // -ETIMEDOUT
+};
+
+// Keep in sync with REGION_* constants from RadioManager.java.
+enum class Region : jint {
+    ITU_1 = 0,
+    ITU_2 = 1,
+    OIRT = 2,
+    JAPAN = 3,
+    KOREA = 4,
+};
+
+} // namespace radio
+} // namespace server
+} // namespace android
+
+#endif // _ANDROID_SERVER_RADIO_TYPES_H
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 69e46e7..6e648c9 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -19,6 +19,9 @@
 #include "utils/Log.h"
 #include "utils/misc.h"
 
+#include "com_android_server_radio_RadioService.h"
+#include "com_android_server_radio_Tuner.h"
+
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryStatsService(JNIEnv* env);
@@ -64,6 +67,8 @@
     }
     ALOG_ASSERT(env, "Could not retrieve the env!");
 
+    register_android_server_radio_RadioService(env);
+    register_android_server_radio_Tuner(vm, env);
     register_android_server_PowerManagerService(env);
     register_android_server_SerialService(env);
     register_android_server_InputApplicationHandle(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 911bb2a..d249b0a9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -43,6 +43,7 @@
 import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
@@ -254,6 +255,8 @@
 
     private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token";
 
+    private static final String TAG_PASSWORD_VALIDITY = "password-validity";
+
     private static final int REQUEST_EXPIRE_PASSWORD = 5571;
 
     private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
@@ -478,6 +481,8 @@
     public static class DevicePolicyData {
         @NonNull PasswordMetrics mActivePasswordMetrics = new PasswordMetrics();
         int mFailedPasswordAttempts = 0;
+        boolean mPasswordStateHasBeenSetSinceBoot = false;
+        boolean mPasswordValidAtLastCheckpoint = false;
 
         int mUserHandle;
         int mPasswordOwner = -1;
@@ -521,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;
 
@@ -1687,9 +1692,9 @@
             mContext.getSystemService(PowerManager.class).reboot(reason);
         }
 
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            RecoverySystem.rebootWipeUserData(mContext, shutdown, reason, force, wipeEuicc);
         }
 
         boolean systemPropertiesGetBoolean(String key, boolean def) {
@@ -2379,6 +2384,9 @@
             BroadcastReceiver result) {
         Intent intent = new Intent(action);
         intent.setComponent(admin.info.getComponent());
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        }
         if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
             intent.putExtra("expiration", admin.passwordExpirationDate);
         }
@@ -2574,19 +2582,14 @@
                 out.endTag(null, "failed-password-attempts");
             }
 
-            // Don't save metrics for FBE devices
-            final PasswordMetrics metrics = policy.mActivePasswordMetrics;
-            if (!mInjector.storageManagerIsFileBasedEncryptionEnabled() && !metrics.isDefault()) {
-                out.startTag(null, "active-password");
-                out.attribute(null, "quality", Integer.toString(metrics.quality));
-                out.attribute(null, "length", Integer.toString(metrics.length));
-                out.attribute(null, "uppercase", Integer.toString(metrics.upperCase));
-                out.attribute(null, "lowercase", Integer.toString(metrics.lowerCase));
-                out.attribute(null, "letters", Integer.toString(metrics.letters));
-                out.attribute(null, "numeric", Integer.toString(metrics.numeric));
-                out.attribute(null, "symbols", Integer.toString(metrics.symbols));
-                out.attribute(null, "nonletter", Integer.toString(metrics.nonLetter));
-                out.endTag(null, "active-password");
+            // For FDE devices only, we save this flag so we can report on password sufficiency
+            // before the user enters their password for the first time after a reboot.  For
+            // security reasons, we don't want to store the full set of active password metrics.
+            if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
+                out.startTag(null, TAG_PASSWORD_VALIDITY);
+                out.attribute(null, ATTR_VALUE,
+                        Boolean.toString(policy.mPasswordValidAtLastCheckpoint));
+                out.endTag(null, TAG_PASSWORD_VALIDITY);
             }
 
             for (int i = 0; i < policy.mAcceptedCaCertificates.size(); i++) {
@@ -2864,19 +2867,14 @@
                 } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) {
                     policy.mInitBundle = PersistableBundle.restoreFromXml(parser);
                 } else if ("active-password".equals(tag)) {
-                    if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
-                        // Remove this from FBE devices
-                        needsRewrite = true;
-                    } else {
-                        final PasswordMetrics m = policy.mActivePasswordMetrics;
-                        m.quality = Integer.parseInt(parser.getAttributeValue(null, "quality"));
-                        m.length = Integer.parseInt(parser.getAttributeValue(null, "length"));
-                        m.upperCase = Integer.parseInt(parser.getAttributeValue(null, "uppercase"));
-                        m.lowerCase = Integer.parseInt(parser.getAttributeValue(null, "lowercase"));
-                        m.letters = Integer.parseInt(parser.getAttributeValue(null, "letters"));
-                        m.numeric = Integer.parseInt(parser.getAttributeValue(null, "numeric"));
-                        m.symbols = Integer.parseInt(parser.getAttributeValue(null, "symbols"));
-                        m.nonLetter = Integer.parseInt(parser.getAttributeValue(null, "nonletter"));
+                    // Remove password metrics from saved settings, as we no longer wish to store
+                    // these on disk
+                    needsRewrite = true;
+                } else if (TAG_PASSWORD_VALIDITY.equals(tag)) {
+                    if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
+                        // This flag is only used for FDE devices
+                        policy.mPasswordValidAtLastCheckpoint = Boolean.parseBoolean(
+                                parser.getAttributeValue(null, ATTR_VALUE));
                     }
                 } else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) {
                     policy.mPasswordTokenHandle = Long.parseLong(
@@ -3453,11 +3451,24 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.quality != quality) {
                 ap.minimumPasswordMetrics.quality = quality;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
+    /**
+     * Updates flag in memory that tells us whether the user's password currently satisfies the
+     * requirements set by all of the user's active admins.  This should be called before
+     * {@link #saveSettingsLocked} whenever the password or the admin policies have changed.
+     */
+    @GuardedBy("DevicePolicyManagerService.this")
+    private void updatePasswordValidityCheckpointLocked(int userHandle) {
+        DevicePolicyData policy = getUserData(userHandle);
+        policy.mPasswordValidAtLastCheckpoint = isActivePasswordSufficientForUserLocked(
+                policy, policy.mUserHandle, false);
+    }
+
     @Override
     public int getPasswordQuality(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
@@ -3540,6 +3551,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.length != length) {
                 ap.minimumPasswordMetrics.length = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3584,6 +3596,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.passwordHistoryLength != length) {
                 ap.passwordHistoryLength = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3796,6 +3809,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.upperCase != length) {
                 ap.minimumPasswordMetrics.upperCase = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3837,6 +3851,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.lowerCase != length) {
                 ap.minimumPasswordMetrics.lowerCase = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3881,6 +3896,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.letters != length) {
                 ap.minimumPasswordMetrics.letters = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3928,6 +3944,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.numeric != length) {
                 ap.minimumPasswordMetrics.numeric = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -3975,6 +3992,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.symbols != length) {
                 ap.minimumPasswordMetrics.symbols = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -4022,6 +4040,7 @@
                     who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordMetrics.nonLetter != length) {
                 ap.minimumPasswordMetrics.nonLetter = length;
+                updatePasswordValidityCheckpointLocked(mInjector.userHandleGetCallingUserId());
                 saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
@@ -4093,6 +4112,16 @@
             DevicePolicyData policy, int userHandle, boolean parent) {
         enforceUserUnlocked(userHandle, parent);
 
+        if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()
+                && !policy.mPasswordStateHasBeenSetSinceBoot) {
+            // Before user enters their password for the first time after a reboot, return the
+            // value of this flag, which tells us whether the password was valid the last time
+            // settings were saved.  If DPC changes password requirements on boot so that the
+            // current password no longer meets the requirements, this value will be stale until
+            // the next time the password is entered.
+            return policy.mPasswordValidAtLastCheckpoint;
+        }
+
         final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
         if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) {
             return false;
@@ -4229,6 +4258,7 @@
             mInjector.binderRestoreCallingIdentity(token);
         }
     }
+
     @Override
     public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
         final int callingUid = mInjector.binderGetCallingUid();
@@ -5277,7 +5307,7 @@
         }
     }
 
-    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason) {
+    private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
         wtfIfInLock();
 
         if (wipeExtRequested) {
@@ -5287,7 +5317,7 @@
         }
         try {
             mInjector.recoverySystemRebootWipeUserData(
-                    /*shutdown=*/ false, reason, /*force=*/ true);
+                    /*shutdown=*/ false, reason, /*force=*/ true, /*wipeEuicc=*/ wipeEuicc);
         } catch (IOException | SecurityException e) {
             Slog.w(LOG_TAG, "Failed requesting data wipe", e);
         }
@@ -5364,7 +5394,7 @@
             // removes that user (but still clears FRP...)
             if (userId == UserHandle.USER_SYSTEM) {
                 forceWipeDeviceNoLock(/*wipeExtRequested=*/ (flags & WIPE_EXTERNAL_STORAGE) != 0,
-                        reason);
+                        reason, /*wipeEuicc=*/ (flags & WIPE_EUICC) != 0);
             } else {
                 forceWipeUser(userId);
             }
@@ -5436,6 +5466,7 @@
         DevicePolicyData policy = getUserData(userHandle);
         synchronized (this) {
             policy.mActivePasswordMetrics = metrics;
+            policy.mPasswordStateHasBeenSetSinceBoot = true;
         }
     }
 
@@ -5460,6 +5491,7 @@
         try {
             synchronized (this) {
                 policy.mFailedPasswordAttempts = 0;
+                updatePasswordValidityCheckpointLocked(userId);
                 saveSettingsLocked(userId);
                 updatePasswordExpirationsLocked(userId);
                 setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false);
@@ -7347,9 +7379,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,
@@ -8103,8 +8134,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.");
         }
@@ -8116,9 +8149,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) {
@@ -8443,6 +8479,8 @@
             enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                     DELEGATION_ENABLE_SYSTEM_APP);
 
+            final boolean isDemo = isCurrentUserDemo();
+
             int userId = UserHandle.getCallingUserId();
             long id = mInjector.binderClearCallingIdentity();
 
@@ -8453,14 +8491,19 @@
                 }
 
                 int parentUserId = getProfileParentId(userId);
-                if (!isSystemApp(mIPackageManager, packageName, parentUserId)) {
+                if (!isDemo && !isSystemApp(mIPackageManager, packageName, parentUserId)) {
                     throw new IllegalArgumentException("Only system apps can be enabled this way.");
                 }
 
                 // Install the app.
                 mIPackageManager.installExistingPackageAsUser(packageName, userId,
                         0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
-
+                if (isDemo) {
+                    // Ensure the app is also ENABLED for demo users.
+                    mIPackageManager.setApplicationEnabledSetting(packageName,
+                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                            PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
+                }
             } catch (RemoteException re) {
                 // shouldn't happen
                 Slog.wtf(LOG_TAG, "Failed to install " + packageName, re);
@@ -8905,7 +8948,8 @@
                 return;
             }
 
-            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
+            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)
+                    && !UserManager.isDeviceInDemoMode(mContext)) {
                 throw new SecurityException(String.format(
                         "Permission denial: device owners cannot update %1$s", setting));
             }
@@ -8937,11 +8981,12 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             if (isDeviceOwner(who, callingUserId)) {
-                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
+                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)
+                        && !isCurrentUserDemo()) {
                     throw new SecurityException(String.format(
                             "Permission denial: Device owners cannot update %1$s", setting));
                 }
-            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting)) {
+            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting) && !isCurrentUserDemo()) {
                 throw new SecurityException(String.format(
                         "Permission denial: Profile owners cannot update %1$s", setting));
             }
@@ -9392,12 +9437,6 @@
 
     @Override
     public SystemUpdatePolicy getSystemUpdatePolicy() {
-        if (UserManager.isDeviceInDemoMode(mContext)) {
-            // Pretending to have an automatic update policy when the device is in retail demo
-            // mode. This will allow the device to download and install an ota without
-            // any user interaction.
-            return SystemUpdatePolicy.createAutomaticInstallPolicy();
-        }
         synchronized (this) {
             SystemUpdatePolicy policy =  mOwners.getSystemUpdatePolicy();
             if (policy != null && !policy.isValid()) {
@@ -10404,6 +10443,19 @@
         }
     }
 
+    private boolean isCurrentUserDemo() {
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            final int userId = mInjector.userHandleGetCallingUserId();
+            final long callingIdentity = mInjector.binderClearCallingIdentity();
+            try {
+                return mUserManager.getUserInfo(userId).isDemo();
+            } finally {
+                mInjector.binderRestoreCallingIdentity(callingIdentity);
+            }
+        }
+        return false;
+    }
+
     private void removePackageIfRequired(final String packageName, final int userId) {
         if (!packageHasActiveAdmins(packageName, userId)) {
             // Will not do anything if uninstall was not requested or was already started.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e58..6086354 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -60,16 +60,21 @@
     /** Delay after which older batches get discarded after a retrieval. */
     private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
 
+    /** Do not call into mDpm with locks held */
     private final DevicePolicyManagerService mDpm;
     private final AlarmManager mAlarmManager;
 
     private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
         @Override
         public void onAlarm() {
-            Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+            Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
                     + mNetworkEvents.size() + " pending events.");
+            Bundle notificationExtras = null;
             synchronized (NetworkLoggingHandler.this) {
-                finalizeBatchAndNotifyDeviceOwnerLocked();
+                notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+            }
+            if (notificationExtras != null) {
+                notifyDeviceOwner(notificationExtras);
             }
         }
     };
@@ -110,17 +115,21 @@
             case LOG_NETWORK_EVENT_MSG: {
                 final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
                 if (networkEvent != null) {
+                    Bundle notificationExtras = null;
                     synchronized (NetworkLoggingHandler.this) {
                         mNetworkEvents.add(networkEvent);
                         if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
-                            finalizeBatchAndNotifyDeviceOwnerLocked();
+                            notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
                         }
                     }
+                    if (notificationExtras != null) {
+                        notifyDeviceOwner(notificationExtras);
+                    }
                 }
                 break;
             }
             default: {
-                Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+                Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
                 break;
             }
         }
@@ -133,40 +142,48 @@
         mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
                 BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
                 mBatchTimeoutAlarmListener, this);
-        Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+        Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
                 + "ms from now.");
     }
 
     synchronized void pause() {
-        Log.d(TAG, "Paused network logging");
+        Slog.d(TAG, "Paused network logging");
         mPaused = true;
     }
 
-    synchronized void resume() {
-        if (!mPaused) {
-            Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
-            return;
+    void resume() {
+        Bundle notificationExtras = null;
+        synchronized (this) {
+            if (!mPaused) {
+                Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+                return;
+            }
+
+            Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+                    + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+            mPaused = false;
+
+            // If there is a batch ready that the device owner hasn't been notified about, do it now.
+            if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+                scheduleBatchFinalization();
+                notificationExtras = buildDeviceOwnerMessageLocked();
+            }
         }
-
-        Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
-                + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
-        mPaused = false;
-
-        // If there is a batch ready that the device owner hasn't been notified about, do it now.
-        if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
-            scheduleBatchFinalization();
-            notifyDeviceOwnerLocked();
+        if (notificationExtras != null) {
+            notifyDeviceOwner(notificationExtras);
         }
     }
 
     synchronized void discardLogs() {
         mBatches.clear();
         mNetworkEvents = new ArrayList<>();
-        Log.d(TAG, "Discarded all network logs");
+        Slog.d(TAG, "Discarded all network logs");
     }
 
     @GuardedBy("this")
-    private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+    /** @returns extras if a message should be sent to the device owner */
+    private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+        Bundle notificationExtras = null;
         if (mNetworkEvents.size() > 0) {
             // Finalize the batch and start a new one from scratch.
             if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@
             mBatches.append(mCurrentBatchToken, mNetworkEvents);
             mNetworkEvents = new ArrayList<>();
             if (!mPaused) {
-                notifyDeviceOwnerLocked();
+                notificationExtras = buildDeviceOwnerMessageLocked();
             }
         } else {
             // Don't notify the DO, since there are no events; DPC can still retrieve
             // the last full batch if not paused.
-            Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+            Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
                     + " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
         }
         // Regardless of whether the batch was non-empty schedule a new finalization after timeout.
         scheduleBatchFinalization();
+        return notificationExtras;
     }
 
-    /** Sends a notification to the DO. Should only be called when there is a batch available. */
     @GuardedBy("this")
-    private void notifyDeviceOwnerLocked() {
+    /** Build extras notification to the DO. Should only be called when there
+        is a batch available. */
+    private Bundle buildDeviceOwnerMessageLocked() {
         final Bundle extras = new Bundle();
         final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
         extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
         extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
-        Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
-                + mCurrentBatchToken);
+        return extras;
+    }
+
+    /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+        call into NetworkLoggingHandler. */
+    private void notifyDeviceOwner(Bundle extras) {
+        Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+                + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+        if (Thread.holdsLock(this)) {
+            Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+            return;
+        }
         mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index be85fc9..d89f6d0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -34,6 +34,7 @@
 import android.os.FileUtils;
 import android.os.IIncidentManager;
 import android.os.Looper;
+import android.os.Message;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
@@ -62,6 +63,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.audio.AudioService;
 import com.android.server.camera.CameraServiceProxy;
+import com.android.server.car.CarServiceHelperService;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.coverage.CoverageService;
@@ -82,6 +84,7 @@
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
 import com.android.server.notification.NotificationManagerService;
+import com.android.server.oemlock.OemLockService;
 import com.android.server.om.OverlayManagerService;
 import com.android.server.os.DeviceIdentifiersPolicyService;
 import com.android.server.os.SchedulingPolicyService;
@@ -95,8 +98,8 @@
 import com.android.server.policy.PhoneWindowManager;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
+import com.android.server.radio.RadioService;
 import com.android.server.restrictions.RestrictionsManagerService;
-import com.android.server.retaildemo.RetailDemoModeService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
 import com.android.server.soundtrigger.SoundTriggerService;
@@ -173,7 +176,7 @@
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
-            "com.android.server.LockSettingsService$Lifecycle";
+            "com.android.server.locksettings.LockSettingsService$Lifecycle";
     private static final String STORAGE_MANAGER_SERVICE_CLASS =
             "com.android.server.StorageManagerService$Lifecycle";
     private static final String STORAGE_STATS_SERVICE_CLASS =
@@ -184,6 +187,8 @@
             "com.google.android.clockwork.ThermalObserver";
     private static final String WEAR_CONNECTIVITY_SERVICE_CLASS =
             "com.google.android.clockwork.connectivity.WearConnectivityService";
+    private static final String WEAR_DISPLAY_SERVICE_CLASS =
+            "com.google.android.clockwork.display.WearDisplayService";
     private static final String WEAR_TIME_SERVICE_CLASS =
             "com.google.android.clockwork.time.WearTimeService";
     private static final String ACCOUNT_SERVICE_CLASS =
@@ -455,7 +460,20 @@
                     }
                 }
             }
-            ShutdownThread.rebootOrShutdown(null, reboot, reason);
+            Runnable runnable = new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (this) {
+                        ShutdownThread.rebootOrShutdown(null, reboot, reason);
+                    }
+                }
+            };
+
+            // ShutdownThread must run on a looper capable of displaying the UI.
+            Message msg = Message.obtain(UiThread.getHandler(), runnable);
+            msg.setAsynchronous(true);
+            UiThread.getHandler().sendMessage(msg);
+
         }
     }
 
@@ -697,6 +715,8 @@
         boolean disableVrManager = SystemProperties.getBoolean("config.disable_vrmanager", false);
         boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
                 false);
+        // TODO(b/36863239): Remove when transitioned from native service.
+        boolean enableRadioService = SystemProperties.getBoolean("config.enable_java_radio", false);
 
         boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
@@ -754,13 +774,6 @@
 
             mContentResolver = context.getContentResolver();
 
-            if (!disableCameraService) {
-                Slog.i(TAG, "Camera Service Proxy");
-                traceBeginAndSlog("StartCameraServiceProxy");
-                mSystemServiceManager.startService(CameraServiceProxy.class);
-                traceEnd();
-            }
-
             // The AccountManager must come before the ContentService
             traceBeginAndSlog("StartAccountManagerService");
             mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
@@ -963,12 +976,15 @@
                 }
                 traceEnd();
 
-                if (!SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("")) {
+                final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
+                if (hasPdb) {
                     traceBeginAndSlog("StartPersistentDataBlock");
                     mSystemServiceManager.startService(PersistentDataBlockService.class);
                     traceEnd();
+                }
 
-                    // Implementation depends on persistent data block
+                if (hasPdb || OemLockService.isHalPresent()) {
+                    // Implementation depends on pdb or the OemLock HAL
                     traceBeginAndSlog("StartOemLockService");
                     mSystemServiceManager.startService(OemLockService.class);
                     traceEnd();
@@ -1196,6 +1212,13 @@
             mSystemServiceManager.startService(AudioService.Lifecycle.class);
             traceEnd();
 
+            if (enableRadioService &&
+                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_RADIO)) {
+                traceBeginAndSlog("StartRadioService");
+                mSystemServiceManager.startService(RadioService.class);
+                traceEnd();
+            }
+
             if (!disableNonCoreServices) {
                 traceBeginAndSlog("StartDockObserver");
                 mSystemServiceManager.startService(DockObserver.class);
@@ -1494,11 +1517,18 @@
 
             if (!disableNonCoreServices) {
                 traceBeginAndSlog("StartWearTimeService");
+                mSystemServiceManager.startService(WEAR_DISPLAY_SERVICE_CLASS);
                 mSystemServiceManager.startService(WEAR_TIME_SERVICE_CLASS);
                 traceEnd();
             }
         }
 
+        if (!disableCameraService) {
+            traceBeginAndSlog("StartCameraServiceProxy");
+            mSystemServiceManager.startService(CameraServiceProxy.class);
+            traceEnd();
+        }
+
         // Before things start rolling, be sure we have decided whether
         // we are in safe mode.
         final boolean safeMode = wm.detectSafeMode();
@@ -1520,10 +1550,6 @@
         mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
         traceEnd();
 
-        traceBeginAndSlog("StartRetailDemoModeService");
-        mSystemServiceManager.startService(RetailDemoModeService.class);
-        traceEnd();
-
         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) {
             traceBeginAndSlog("StartAutoFillService");
             mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
@@ -1667,6 +1693,12 @@
                 }, WEBVIEW_PREPARATION);
             }
 
+            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                traceBeginAndSlog("StartCarServiceHelperService");
+                mSystemServiceManager.startService(CarServiceHelperService.class);
+                traceEnd();
+            }
+
             traceBeginAndSlog("StartSystemUI");
             try {
                 startSystemUi(context, windowManagerF);
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 100e459..51478b3 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -325,9 +325,6 @@
                 }
                 IBinder binder = server.asBinder();
                 try {
-                    if (mDeviceInfo == null) {
-                        mDeviceInfo = server.getDeviceInfo();
-                    }
                     binder.linkToDeath(this, 0);
                     mServer = server;
                 } catch (RemoteException e) {
diff --git a/services/profile-classes b/services/profile-classes
index b0d2da7..a2189bc 100644
--- a/services/profile-classes
+++ b/services/profile-classes
@@ -277,7 +277,6 @@
 Landroid/app/ResourcesManager$1;
 Landroid/app/ResultInfo;
 Landroid/app/ResultInfo$1;
-Landroid/app/RetailDemoModeServiceInternal;
 Landroid/app/SearchableInfo;
 Landroid/app/SearchableInfo$1;
 Landroid/app/SearchManager;
@@ -5085,11 +5084,6 @@
 Lcom/android/server/RescueParty$Threshold;
 Lcom/android/server/restrictions/RestrictionsManagerService;
 Lcom/android/server/restrictions/RestrictionsManagerService$RestrictionsManagerImpl;
-Lcom/android/server/retaildemo/RetailDemoModeService;
-Lcom/android/server/retaildemo/RetailDemoModeService$1;
-Lcom/android/server/retaildemo/RetailDemoModeService$Injector;
-Lcom/android/server/retaildemo/RetailDemoModeService$MainHandler;
-Lcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;
 Lcom/android/server/SamplingProfilerService;
 Lcom/android/server/SamplingProfilerService$1;
 Lcom/android/server/SamplingProfilerService$SamplingProfilerSettingsObserver;
diff --git a/services/retaildemo/Android.mk b/services/retaildemo/Android.mk
deleted file mode 100644
index 670c6bf..0000000
--- a/services/retaildemo/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := services.retaildemo
-
-LOCAL_SRC_FILES += \
-      $(call all-java-files-under,java)
-
-LOCAL_JAVA_LIBRARIES := services.core
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
deleted file mode 100644
index 90c58d0..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
+++ /dev/null
@@ -1,178 +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.server.retaildemo;
-
-import android.app.AppGlobals;
-import android.app.PackageInstallObserver;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Helper class for installing preloaded APKs
- */
-class PreloadAppsInstaller {
-    private static final String SYSTEM_SERVER_PACKAGE_NAME = "android";
-    private static String TAG = PreloadAppsInstaller.class.getSimpleName();
-    private static final String PRELOAD_APK_EXT = ".apk.preload";
-    private static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final IPackageManager mPackageManager;
-    private final File preloadsAppsDirectory;
-    private final Context mContext;
-
-    private final Map<String, String> mApkToPackageMap;
-
-    PreloadAppsInstaller(Context context) {
-        this(context, AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory());
-    }
-
-    @VisibleForTesting
-    PreloadAppsInstaller(Context context, IPackageManager packageManager, File preloadsAppsDirectory) {
-        mContext = context;
-        mPackageManager = packageManager;
-        mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>());
-        this.preloadsAppsDirectory = preloadsAppsDirectory;
-    }
-
-    void installApps(int userId) {
-        File[] files = preloadsAppsDirectory.listFiles();
-        AppInstallCounter counter = new AppInstallCounter(mContext, userId);
-        if (ArrayUtils.isEmpty(files)) {
-            counter.setExpectedAppsCount(0);
-            return;
-        }
-        int expectedCount = 0;
-        for (File file : files) {
-            String apkName = file.getName();
-            if (apkName.endsWith(PRELOAD_APK_EXT) && file.isFile()) {
-                String packageName = mApkToPackageMap.get(apkName);
-                if (packageName != null) {
-                    try {
-                        expectedCount++;
-                        installExistingPackage(packageName, userId, counter);
-                    } catch (Exception e) {
-                        Slog.e(TAG, "Failed to install existing package " + packageName, e);
-                    }
-                } else {
-                    try {
-                        installPackage(file, userId, counter);
-                        expectedCount++;
-                    } catch (Exception e) {
-                        Slog.e(TAG, "Failed to install package from " + file, e);
-                    }
-                }
-            }
-        }
-        counter.setExpectedAppsCount(expectedCount);
-    }
-
-    private void installExistingPackage(String packageName, int userId,
-            AppInstallCounter counter) {
-        if (DEBUG) {
-            Log.d(TAG, "installExistingPackage " + packageName + " u" + userId);
-        }
-        try {
-            mPackageManager.installExistingPackageAsUser(packageName, userId,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } finally {
-            counter.appInstallFinished();
-        }
-    }
-
-    private void installPackage(File file, final int userId, AppInstallCounter counter)
-            throws IOException, RemoteException {
-        final String apkName = file.getName();
-        if (DEBUG) {
-            Log.d(TAG, "installPackage " + apkName + " u" + userId);
-        }
-        mPackageManager.installPackageAsUser(file.getPath(), new PackageInstallObserver() {
-            @Override
-            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
-                    Bundle extras) {
-                if (DEBUG) {
-                    Log.d(TAG, "Package " + basePackageName + " installed u" + userId
-                            + " returnCode: " + returnCode + " msg: " + msg);
-                }
-                // Don't notify the counter for now, we'll do it in installExistingPackage
-                if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                    mApkToPackageMap.put(apkName, basePackageName);
-                    // Install on user 0 so that the package is cached when demo user is re-created
-                    installExistingPackage(basePackageName, UserHandle.USER_SYSTEM, counter);
-                } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) {
-                    // This can only happen in first session after a reboot
-                    if (!mApkToPackageMap.containsKey(apkName)) {
-                        mApkToPackageMap.put(apkName, basePackageName);
-                    }
-                    installExistingPackage(basePackageName, userId, counter);
-                } else {
-                    Log.e(TAG, "Package " + basePackageName + " cannot be installed from "
-                            + apkName + ": " + msg + " (returnCode " + returnCode + ")");
-                    counter.appInstallFinished();
-                }
-            }
-        }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId);
-    }
-
-    private static class AppInstallCounter {
-        private int expectedCount = -1; // -1 means expectedCount not set
-        private int finishedCount;
-        private final Context mContext;
-        private final int userId;
-
-        AppInstallCounter(Context context, int userId) {
-            mContext = context;
-            this.userId = userId;
-        }
-
-        synchronized void appInstallFinished() {
-            this.finishedCount++;
-            checkIfAllFinished();
-        }
-
-        synchronized void setExpectedAppsCount(int expectedCount) {
-            this.expectedCount = expectedCount;
-            checkIfAllFinished();
-        }
-
-        private void checkIfAllFinished() {
-            if (expectedCount == finishedCount) {
-                Log.i(TAG, "All preloads finished installing for user " + userId);
-                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, "1", userId);
-            }
-        }
-    }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
deleted file mode 100644
index 711d4d9d..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ /dev/null
@@ -1,868 +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.server.retaildemo;
-
-import android.Manifest;
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.RetailDemoModeServiceInternal;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.KeyValueListParser;
-import android.util.Slog;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LocalServices;
-import com.android.server.PreloadsFileCacheExpirationJobService;
-import com.android.server.ServiceThread;
-import com.android.server.SystemService;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.retaildemo.UserInactivityCountdownDialog.OnCountDownExpiredListener;
-
-import java.io.File;
-import java.util.ArrayList;
-
-public class RetailDemoModeService extends SystemService {
-    private static final boolean DEBUG = false;
-
-    private static final String TAG = RetailDemoModeService.class.getSimpleName();
-    private static final String DEMO_USER_NAME = "Demo";
-    private static final String ACTION_RESET_DEMO =
-            "com.android.server.retaildemo.ACTION_RESET_DEMO";
-    @VisibleForTesting
-    static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
-
-    private static final int MSG_TURN_SCREEN_ON = 0;
-    private static final int MSG_INACTIVITY_TIME_OUT = 1;
-    private static final int MSG_START_NEW_SESSION = 2;
-
-    private static final long SCREEN_WAKEUP_DELAY = 2500;
-    private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000;
-    private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000;
-    private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0;
-    private static final long MILLIS_PER_SECOND = 1000;
-
-    @VisibleForTesting
-    static final int[] VOLUME_STREAMS_TO_MUTE = {
-            AudioSystem.STREAM_RING,
-            AudioSystem.STREAM_MUSIC
-    };
-
-    // Tron Vars
-    private static final String DEMO_SESSION_COUNT = "retail_demo_session_count";
-    private static final String DEMO_SESSION_DURATION = "retail_demo_session_duration";
-
-    boolean mDeviceInDemoMode;
-    boolean mIsCarrierDemoMode;
-    int mCurrentUserId = UserHandle.USER_SYSTEM;
-    long mUserInactivityTimeout;
-    long mWarningDialogTimeout;
-    private Injector mInjector;
-    Handler mHandler;
-    private ServiceThread mHandlerThread;
-    private String[] mCameraIdsWithFlash;
-    private PreloadAppsInstaller mPreloadAppsInstaller;
-
-    final Object mActivityLock = new Object();
-    // Whether the newly created demo user has interacted with the screen yet
-    @GuardedBy("mActivityLock")
-    boolean mUserUntouched;
-    @GuardedBy("mActivityLock")
-    long mFirstUserActivityTime;
-    @GuardedBy("mActivityLock")
-    long mLastUserActivityTime;
-
-    private boolean mSafeBootRestrictionInitialState;
-    private int mPackageVerifierEnableInitialState;
-
-    private IntentReceiver mBroadcastReceiver = null;
-
-    private final class IntentReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!mDeviceInDemoMode) {
-                return;
-            }
-            final String action = intent.getAction();
-            switch (action) {
-                case Intent.ACTION_SCREEN_OFF:
-                    mHandler.removeMessages(MSG_TURN_SCREEN_ON);
-                    mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY);
-                    break;
-                case ACTION_RESET_DEMO:
-                    mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-                    break;
-            }
-        }
-    };
-
-    final class MainHandler extends Handler {
-
-        MainHandler(Looper looper) {
-            super(looper, null, true);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (!mDeviceInDemoMode) {
-                return;
-            }
-            switch (msg.what) {
-                case MSG_TURN_SCREEN_ON:
-                    if (mInjector.isWakeLockHeld()) {
-                        mInjector.releaseWakeLock();
-                    }
-                    mInjector.acquireWakeLock();
-                    break;
-                case MSG_INACTIVITY_TIME_OUT:
-                    if (!mIsCarrierDemoMode && isDemoLauncherDisabled()) {
-                        Slog.i(TAG, "User inactivity timeout reached");
-                        showInactivityCountdownDialog();
-                    }
-                    break;
-                case MSG_START_NEW_SESSION:
-                    if (DEBUG) {
-                        Slog.d(TAG, "Switching to a new demo user");
-                    }
-                    removeMessages(MSG_START_NEW_SESSION);
-                    removeMessages(MSG_INACTIVITY_TIME_OUT);
-                    if (!mIsCarrierDemoMode && mCurrentUserId != UserHandle.USER_SYSTEM) {
-                        logSessionDuration();
-                    }
-
-                    final UserManager um = mInjector.getUserManager();
-                    UserInfo demoUser = null;
-                    if (mIsCarrierDemoMode) {
-                        // Re-use the existing demo user in carrier demo mode.
-                        for (UserInfo user : um.getUsers()) {
-                            if (user.isDemo()) {
-                                demoUser = user;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (demoUser == null) {
-                        // User in carrier demo mode should survive reboots.
-                        final int flags = UserInfo.FLAG_DEMO
-                                | (mIsCarrierDemoMode ? 0 : UserInfo.FLAG_EPHEMERAL);
-                        demoUser = um.createUser(DEMO_USER_NAME, flags);
-                    }
-
-                    if (demoUser != null && mCurrentUserId != demoUser.id) {
-                        setupDemoUser(demoUser);
-                        mInjector.switchUser(demoUser.id);
-                    }
-                    break;
-            }
-        }
-    }
-
-    @VisibleForTesting
-    class SettingsObserver extends ContentObserver {
-
-        private final static String KEY_USER_INACTIVITY_TIMEOUT = "user_inactivity_timeout_ms";
-        private final static String KEY_WARNING_DIALOG_TIMEOUT = "warning_dialog_timeout_ms";
-
-        private final Uri mDeviceDemoModeUri = Settings.Global
-                .getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        private final Uri mDeviceProvisionedUri = Settings.Global
-                .getUriFor(Settings.Global.DEVICE_PROVISIONED);
-        private final Uri mRetailDemoConstantsUri = Settings.Global
-                .getUriFor(Settings.Global.RETAIL_DEMO_MODE_CONSTANTS);
-
-        private final KeyValueListParser mParser = new KeyValueListParser(',');
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register() {
-            final ContentResolver cr = mInjector.getContentResolver();
-            cr.registerContentObserver(mDeviceDemoModeUri, false, this, UserHandle.USER_SYSTEM);
-            cr.registerContentObserver(mDeviceProvisionedUri, false, this, UserHandle.USER_SYSTEM);
-            cr.registerContentObserver(mRetailDemoConstantsUri, false, this,
-                    UserHandle.USER_SYSTEM);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (mRetailDemoConstantsUri.equals(uri)) {
-                refreshTimeoutConstants();
-                return;
-            }
-
-            // If device is provisioned and left demo mode - run the cleanup in demo folder
-            if (isDeviceProvisioned()) {
-                if (UserManager.isDeviceInDemoMode(getContext())) {
-                    startDemoMode();
-                } else {
-                    mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "0");
-
-                    // Run on the bg thread to not block the fg thread
-                    BackgroundThread.getHandler().post(() -> {
-                        if (!deletePreloadsFolderContents()) {
-                            Slog.w(TAG, "Failed to delete preloads folder contents");
-                        }
-                        PreloadsFileCacheExpirationJobService.schedule(mInjector.getContext());
-                    });
-
-                    stopDemoMode();
-
-                    if (mInjector.isWakeLockHeld()) {
-                        mInjector.releaseWakeLock();
-                    }
-                }
-            }
-        }
-
-        private void refreshTimeoutConstants() {
-            try {
-                mParser.setString(Settings.Global.getString(mInjector.getContentResolver(),
-                        Settings.Global.RETAIL_DEMO_MODE_CONSTANTS));
-            } catch (IllegalArgumentException exc) {
-                Slog.e(TAG, "Invalid string passed to KeyValueListParser");
-                // Consuming the exception to fall back to default values.
-            }
-            mWarningDialogTimeout = mParser.getLong(KEY_WARNING_DIALOG_TIMEOUT,
-                    WARNING_DIALOG_TIMEOUT_DEFAULT);
-            mUserInactivityTimeout = mParser.getLong(KEY_USER_INACTIVITY_TIMEOUT,
-                    USER_INACTIVITY_TIMEOUT_DEFAULT);
-            mUserInactivityTimeout = Math.max(mUserInactivityTimeout, USER_INACTIVITY_TIMEOUT_MIN);
-        }
-    }
-
-    private void showInactivityCountdownDialog() {
-        UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(),
-                mWarningDialogTimeout, MILLIS_PER_SECOND);
-        dialog.setNegativeButtonClickListener(null);
-        dialog.setPositiveButtonClickListener(new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-            }
-        });
-        dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() {
-            @Override
-            public void onCountDownExpired() {
-                mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-            }
-        });
-        dialog.show();
-    }
-
-    public RetailDemoModeService(Context context) {
-        this(new Injector(context));
-    }
-
-    @VisibleForTesting
-    RetailDemoModeService(Injector injector) {
-        super(injector.getContext());
-
-        mInjector = injector;
-        synchronized (mActivityLock) {
-            mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis();
-        }
-    }
-
-    boolean isDemoLauncherDisabled() {
-        int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
-        try {
-            final IPackageManager iPm = mInjector.getIPackageManager();
-            final String demoLauncherComponent =
-                    getContext().getString(R.string.config_demoModeLauncherComponent);
-            enabledState = iPm.getComponentEnabledSetting(
-                    ComponentName.unflattenFromString(demoLauncherComponent), mCurrentUserId);
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Error retrieving demo launcher enabled setting", re);
-        }
-        return enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
-    }
-
-    private void setupDemoUser(UserInfo userInfo) {
-        final UserManager um = mInjector.getUserManager();
-        final UserHandle user = UserHandle.of(userInfo.id);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
-        um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
-        // Set this to false because the default is true on user creation
-        um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
-        // Disallow rebooting in safe mode - controlled by user 0
-        um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
-        if (mIsCarrierDemoMode) {
-            // Enable SMS in carrier demo mode.
-            um.setUserRestriction(UserManager.DISALLOW_SMS, false, user);
-        }
-
-        Settings.Secure.putIntForUser(mInjector.getContentResolver(),
-                Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
-        Settings.Global.putInt(mInjector.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
-
-        grantRuntimePermissionToCamera(user);
-        clearPrimaryCallLog();
-
-        if (!mIsCarrierDemoMode) {
-            // Enable demo launcher.
-            final String demoLauncher = getContext().getString(
-                    R.string.config_demoModeLauncherComponent);
-            if (!TextUtils.isEmpty(demoLauncher)) {
-                final ComponentName componentToEnable =
-                        ComponentName.unflattenFromString(demoLauncher);
-                final String packageName = componentToEnable.getPackageName();
-                try {
-                    final IPackageManager iPm = AppGlobals.getPackageManager();
-                    iPm.setComponentEnabledSetting(componentToEnable,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id);
-                    iPm.setApplicationEnabledSetting(packageName,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
-                } catch (RemoteException re) {
-                    // Internal, shouldn't happen
-                }
-            }
-        } else {
-            // Set the carrier demo mode setting for the demo user.
-            final String carrierDemoModeSetting = getContext().getString(
-                    R.string.config_carrierDemoModeSetting);
-            Settings.Secure.putIntForUser(getContext().getContentResolver(),
-                    carrierDemoModeSetting, 1, userInfo.id);
-
-            // Enable packages for carrier demo mode.
-            final String packageList = getContext().getString(
-                    R.string.config_carrierDemoModePackages);
-            final String[] packageNames = packageList == null ? new String[0]
-                    : TextUtils.split(packageList, ",");
-            final IPackageManager iPm = AppGlobals.getPackageManager();
-            for (String packageName : packageNames) {
-                try {
-                    iPm.setApplicationEnabledSetting(packageName,
-                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
-                } catch (RemoteException re) {
-                    Slog.e(TAG, "Error enabling application: " + packageName, re);
-                }
-            }
-        }
-    }
-
-    private void grantRuntimePermissionToCamera(UserHandle user) {
-        final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-        final PackageManager pm = mInjector.getPackageManager();
-        final ResolveInfo handler = pm.resolveActivityAsUser(cameraIntent,
-                PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                user.getIdentifier());
-        if (handler == null || handler.activityInfo == null) {
-            return;
-        }
-        try {
-            pm.grantRuntimePermission(handler.activityInfo.packageName,
-                    Manifest.permission.ACCESS_FINE_LOCATION, user);
-        } catch (Exception e) {
-            // Ignore
-        }
-    }
-
-    private void clearPrimaryCallLog() {
-        final ContentResolver resolver = mInjector.getContentResolver();
-
-        // Deleting primary user call log so that it doesn't get copied to the new demo user
-        final Uri uri = CallLog.Calls.CONTENT_URI;
-        try {
-            resolver.delete(uri, null, null);
-        } catch (Exception e) {
-            Slog.w(TAG, "Deleting call log failed: " + e);
-        }
-    }
-
-    void logSessionDuration() {
-        final int sessionDuration;
-        synchronized (mActivityLock) {
-            sessionDuration = (int) ((mLastUserActivityTime - mFirstUserActivityTime) / 1000);
-        }
-        mInjector.logSessionDuration(sessionDuration);
-    }
-
-    private boolean isDeviceProvisioned() {
-        return Settings.Global.getInt(
-                mInjector.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-    }
-
-    /**
-     * Deletes contents of {@link Environment#getDataPreloadsDirectory()},
-     * but leave {@link Environment#getDataPreloadsFileCacheDirectory()}
-     * @return true if contents was sucessfully deleted
-     */
-    private boolean deletePreloadsFolderContents() {
-        final File dir = mInjector.getDataPreloadsDirectory();
-        final File[] files = FileUtils.listFilesOrEmpty(dir);
-        final File fileCacheDirectory = mInjector.getDataPreloadsFileCacheDirectory();
-        Slog.i(TAG, "Deleting contents of " + dir);
-        boolean success = true;
-        for (File file : files) {
-            if (file.isFile()) {
-                if (!file.delete()) {
-                    success = false;
-                    Slog.w(TAG, "Cannot delete file " + file);
-                }
-            } else {
-                // Do not remove file_cache dir
-                if (!file.equals(fileCacheDirectory)) {
-                    if (!FileUtils.deleteContentsAndDir(file)) {
-                        success = false;
-                        Slog.w(TAG, "Cannot delete dir and its content " + file);
-                    }
-                } else {
-                    Slog.i(TAG, "Skipping directory with file cache " + file);
-                }
-            }
-        }
-        return success;
-    }
-
-    private void registerBroadcastReceiver() {
-        if (mBroadcastReceiver != null) {
-            return;
-        }
-
-        final IntentFilter filter = new IntentFilter();
-        if (!mIsCarrierDemoMode) {
-            filter.addAction(Intent.ACTION_SCREEN_OFF);
-        }
-        filter.addAction(ACTION_RESET_DEMO);
-        mBroadcastReceiver = new IntentReceiver();
-        getContext().registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    private void unregisterBroadcastReceiver() {
-        if (mBroadcastReceiver != null) {
-            getContext().unregisterReceiver(mBroadcastReceiver);
-            mBroadcastReceiver = null;
-        }
-    }
-
-    private String[] getCameraIdsWithFlash() {
-        ArrayList<String> cameraIdsList = new ArrayList<String>();
-        final CameraManager cm = mInjector.getCameraManager();
-        if (cm != null) {
-            try {
-                for (String cameraId : cm.getCameraIdList()) {
-                    CameraCharacteristics c = cm.getCameraCharacteristics(cameraId);
-                    if (Boolean.TRUE.equals(c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) {
-                        cameraIdsList.add(cameraId);
-                    }
-                }
-            } catch (CameraAccessException e) {
-                Slog.e(TAG, "Unable to access camera while getting camera id list", e);
-            }
-        }
-        return cameraIdsList.toArray(new String[cameraIdsList.size()]);
-    }
-
-    private void muteVolumeStreams() {
-        for (int stream : VOLUME_STREAMS_TO_MUTE) {
-            mInjector.getAudioManager().setStreamVolume(stream,
-                    mInjector.getAudioManager().getStreamMinVolume(stream), 0);
-        }
-    }
-
-    private void startDemoMode() {
-        mDeviceInDemoMode = true;
-
-        mPreloadAppsInstaller = mInjector.getPreloadAppsInstaller();
-        mInjector.initializeWakeLock();
-        if (mCameraIdsWithFlash == null) {
-            mCameraIdsWithFlash = getCameraIdsWithFlash();
-        }
-        registerBroadcastReceiver();
-
-        final String carrierDemoModeSetting =
-                getContext().getString(R.string.config_carrierDemoModeSetting);
-        mIsCarrierDemoMode = !TextUtils.isEmpty(carrierDemoModeSetting)
-                && (Settings.Secure.getInt(getContext().getContentResolver(),
-                        carrierDemoModeSetting, 0) == 1);
-
-        mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "1");
-        mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-
-        mSafeBootRestrictionInitialState = mInjector.getUserManager().hasUserRestriction(
-                UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM);
-        mPackageVerifierEnableInitialState = Settings.Global.getInt(mInjector.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
-    }
-
-    private void stopDemoMode() {
-        mPreloadAppsInstaller = null;
-        mCameraIdsWithFlash = null;
-        mInjector.destroyWakeLock();
-        unregisterBroadcastReceiver();
-
-        if (mDeviceInDemoMode) {
-            mInjector.getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT,
-                    mSafeBootRestrictionInitialState, UserHandle.SYSTEM);
-            Settings.Global.putInt(mInjector.getContentResolver(),
-                        Settings.Global.PACKAGE_VERIFIER_ENABLE,
-                        mPackageVerifierEnableInitialState);
-        }
-
-        mDeviceInDemoMode = false;
-        mIsCarrierDemoMode = false;
-    }
-
-    @Override
-    public void onStart() {
-        if (DEBUG) {
-            Slog.d(TAG, "Service starting up");
-        }
-        mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
-                false);
-        mHandlerThread.start();
-        mHandler = new MainHandler(mHandlerThread.getLooper());
-        mInjector.publishLocalService(this, mLocalService);
-    }
-
-    @Override
-    public void onBootPhase(int bootPhase) {
-        switch (bootPhase) {
-            case PHASE_THIRD_PARTY_APPS_CAN_START:
-                final SettingsObserver settingsObserver = new SettingsObserver(mHandler);
-                settingsObserver.register();
-                settingsObserver.refreshTimeoutConstants();
-                break;
-            case PHASE_BOOT_COMPLETED:
-                if (UserManager.isDeviceInDemoMode(getContext())) {
-                    startDemoMode();
-                }
-                break;
-        }
-    }
-
-    @Override
-    public void onSwitchUser(int userId) {
-        if (!mDeviceInDemoMode) {
-            return;
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "onSwitchUser: " + userId);
-        }
-        final UserInfo ui = mInjector.getUserManager().getUserInfo(userId);
-        if (!ui.isDemo()) {
-            Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
-            return;
-        }
-        if (!mIsCarrierDemoMode && !mInjector.isWakeLockHeld()) {
-            mInjector.acquireWakeLock();
-        }
-        mCurrentUserId = userId;
-        mInjector.getActivityManagerInternal().updatePersistentConfigurationForUser(
-                mInjector.getSystemUsersConfiguration(), userId);
-
-        mInjector.turnOffAllFlashLights(mCameraIdsWithFlash);
-        muteVolumeStreams();
-        if (!mInjector.getWifiManager().isWifiEnabled()) {
-            mInjector.getWifiManager().setWifiEnabled(true);
-        }
-
-        // Disable lock screen for demo users.
-        mInjector.getLockPatternUtils().setLockScreenDisabled(true, userId);
-
-        if (!mIsCarrierDemoMode) {
-            // Show reset notification (except in carrier demo mode).
-            mInjector.getNotificationManager().notifyAsUser(TAG, SystemMessage.NOTE_RETAIL_RESET,
-                    mInjector.createResetNotification(), UserHandle.of(userId));
-
-            synchronized (mActivityLock) {
-                mUserUntouched = true;
-            }
-            mInjector.logSessionCount(1);
-            mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mPreloadAppsInstaller.installApps(userId);
-                }
-            });
-        }
-    }
-
-    private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
-        private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000;
-
-        @Override
-        public void onUserActivity() {
-            if (!mDeviceInDemoMode || mIsCarrierDemoMode) {
-                return;
-            }
-            long timeOfActivity = SystemClock.uptimeMillis();
-            synchronized (mActivityLock) {
-                if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) {
-                    return;
-                }
-                mLastUserActivityTime = timeOfActivity;
-                if (mUserUntouched && isDemoLauncherDisabled()) {
-                    Slog.d(TAG, "retail_demo first touch");
-                    mUserUntouched = false;
-                    mFirstUserActivityTime = timeOfActivity;
-                }
-            }
-            mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
-            mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, mUserInactivityTimeout);
-        }
-    };
-
-    static class Injector {
-        private Context mContext;
-        private UserManager mUm;
-        private PackageManager mPm;
-        private NotificationManager mNm;
-        private ActivityManagerService mAms;
-        private ActivityManagerInternal mAmi;
-        private AudioManager mAudioManager;
-        private PowerManager mPowerManager;
-        private CameraManager mCameraManager;
-        private PowerManager.WakeLock mWakeLock;
-        private WifiManager mWifiManager;
-        private Configuration mSystemUserConfiguration;
-        private PendingIntent mResetDemoPendingIntent;
-        private PreloadAppsInstaller mPreloadAppsInstaller;
-
-        Injector(Context context) {
-            mContext = context;
-        }
-
-        Context getContext() {
-            return mContext;
-        }
-
-        WifiManager getWifiManager() {
-            if (mWifiManager == null) {
-                mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-            }
-            return mWifiManager;
-        }
-
-        UserManager getUserManager() {
-            if (mUm == null) {
-                mUm = getContext().getSystemService(UserManager.class);
-            }
-            return mUm;
-        }
-
-        void switchUser(int userId) {
-            if (mAms == null) {
-                mAms = (ActivityManagerService) ActivityManager.getService();
-            }
-            mAms.switchUser(userId);
-        }
-
-        AudioManager getAudioManager() {
-            if (mAudioManager == null) {
-                mAudioManager = getContext().getSystemService(AudioManager.class);
-            }
-            return mAudioManager;
-        }
-
-        private PowerManager getPowerManager() {
-            if (mPowerManager == null) {
-                mPowerManager = (PowerManager) getContext().getSystemService(
-                        Context.POWER_SERVICE);
-            }
-            return mPowerManager;
-        }
-
-        NotificationManager getNotificationManager() {
-            if (mNm == null) {
-                mNm = NotificationManager.from(getContext());
-            }
-            return mNm;
-        }
-
-        ActivityManagerInternal getActivityManagerInternal() {
-            if (mAmi == null) {
-                mAmi = LocalServices.getService(ActivityManagerInternal.class);
-            }
-            return mAmi;
-        }
-
-        CameraManager getCameraManager() {
-            if (mCameraManager == null) {
-                mCameraManager = (CameraManager) getContext().getSystemService(
-                        Context.CAMERA_SERVICE);
-            }
-            return mCameraManager;
-        }
-
-        PackageManager getPackageManager() {
-            if (mPm == null) {
-                mPm = getContext().getPackageManager();
-            }
-            return mPm;
-        }
-
-        IPackageManager getIPackageManager() {
-            return AppGlobals.getPackageManager();
-        }
-
-        ContentResolver getContentResolver() {
-            return getContext().getContentResolver();
-        }
-
-        PreloadAppsInstaller getPreloadAppsInstaller() {
-            if (mPreloadAppsInstaller == null) {
-                mPreloadAppsInstaller = new PreloadAppsInstaller(getContext());
-            }
-            return mPreloadAppsInstaller;
-        }
-
-        void systemPropertiesSet(String key, String value) {
-            SystemProperties.set(key, value);
-        }
-
-        void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
-            for (String cameraId : cameraIdsWithFlash) {
-                try {
-                    getCameraManager().setTorchMode(cameraId, false);
-                } catch (CameraAccessException e) {
-                    Slog.e(TAG, "Unable to access camera " + cameraId
-                            + " while turning off flash", e);
-                }
-            }
-        }
-
-        void initializeWakeLock() {
-            if (mWakeLock == null) {
-                mWakeLock = getPowerManager().newWakeLock(
-                        PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
-            }
-        }
-
-        void destroyWakeLock() {
-            mWakeLock = null;
-        }
-
-        boolean isWakeLockHeld() {
-            return mWakeLock != null && mWakeLock.isHeld();
-        }
-
-        void acquireWakeLock() {
-            mWakeLock.acquire();
-        }
-
-        void releaseWakeLock() {
-            mWakeLock.release();
-        }
-
-        void logSessionDuration(int duration) {
-            MetricsLogger.histogram(getContext(), DEMO_SESSION_DURATION, duration);
-        }
-
-        void logSessionCount(int count) {
-            MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, count);
-        }
-
-        Configuration getSystemUsersConfiguration() {
-            if (mSystemUserConfiguration == null) {
-                Settings.System.getConfiguration(getContentResolver(),
-                        mSystemUserConfiguration = new Configuration());
-            }
-            return mSystemUserConfiguration;
-        }
-
-        LockPatternUtils getLockPatternUtils() {
-            return new LockPatternUtils(getContext());
-        }
-
-        Notification createResetNotification() {
-            return new Notification.Builder(getContext(), SystemNotificationChannels.RETAIL_MODE)
-                    .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title))
-                    .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text))
-                    .setOngoing(true)
-                    .setSmallIcon(R.drawable.platlogo)
-                    .setShowWhen(false)
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setContentIntent(getResetDemoPendingIntent())
-                    .setColor(getContext().getColor(R.color.system_notification_accent_color))
-                    .build();
-        }
-
-        private PendingIntent getResetDemoPendingIntent() {
-            if (mResetDemoPendingIntent == null) {
-                Intent intent = new Intent(ACTION_RESET_DEMO);
-                mResetDemoPendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
-            }
-            return mResetDemoPendingIntent;
-        }
-
-        File getDataPreloadsDirectory() {
-            return Environment.getDataPreloadsDirectory();
-        }
-
-        File getDataPreloadsFileCacheDirectory() {
-            return Environment.getDataPreloadsFileCacheDirectory();
-        }
-
-        void publishLocalService(RetailDemoModeService service,
-                RetailDemoModeServiceInternal localService) {
-            service.publishLocalService(RetailDemoModeServiceInternal.class, localService);
-        }
-    }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
deleted file mode 100644
index 013eab8..0000000
--- a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
+++ /dev/null
@@ -1,105 +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.server.retaildemo;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.os.CountDownTimer;
-import android.view.WindowManager;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-public class UserInactivityCountdownDialog extends AlertDialog {
-
-    private OnCountDownExpiredListener mOnCountDownExpiredListener;
-    private CountDownTimer mCountDownTimer;
-    private long mCountDownDuration;
-    private long mRefreshInterval;
-
-    UserInactivityCountdownDialog(Context context, long duration, long refreshInterval) {
-        super(context);
-        mCountDownDuration = duration;
-        mRefreshInterval = refreshInterval;
-
-        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-        WindowManager.LayoutParams attrs = getWindow().getAttributes();
-        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        getWindow().setAttributes(attrs);
-
-        setTitle(R.string.demo_user_inactivity_timeout_title);
-        setMessage(getContext().getString(R.string.demo_user_inactivity_timeout_countdown,
-                duration));
-    }
-
-    public void setOnCountDownExpiredListener(
-            OnCountDownExpiredListener onCountDownExpiredListener) {
-        mOnCountDownExpiredListener = onCountDownExpiredListener;
-    }
-
-    public void setPositiveButtonClickListener(OnClickListener onClickListener) {
-        setButton(Dialog.BUTTON_POSITIVE,
-                getContext().getString(R.string.demo_user_inactivity_timeout_right_button),
-                onClickListener);
-    }
-
-    public void setNegativeButtonClickListener(OnClickListener onClickListener) {
-        setButton(Dialog.BUTTON_NEGATIVE,
-                getContext().getString(R.string.demo_user_inactivity_timeout_left_button),
-                onClickListener);
-    }
-
-    @Override
-    public void show() {
-        super.show();
-        final TextView messageView = findViewById(R.id.message);
-        messageView.post(new Runnable() {
-            @Override
-            public void run() {
-                mCountDownTimer = new CountDownTimer(mCountDownDuration, mRefreshInterval) {
-
-                    @Override
-                    public void onTick(long millisUntilFinished) {
-                        String msg = getContext().getString(
-                                R.string.demo_user_inactivity_timeout_countdown,
-                                millisUntilFinished / 1000);
-                        messageView.setText(msg);
-                    }
-
-                    @Override
-                    public void onFinish() {
-                        dismiss();
-                        if (mOnCountDownExpiredListener != null)
-                            mOnCountDownExpiredListener.onCountDownExpired();
-                    }
-                }.start();
-            }
-        });
-    }
-
-    @Override
-    public void onStop() {
-        if (mCountDownTimer != null) {
-            mCountDownTimer.cancel();
-        }
-    }
-
-    interface OnCountDownExpiredListener {
-        void onCountDownExpired();
-    }
-}
diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk
index 0ffe6e4..597a584 100644
--- a/services/tests/notification/Android.mk
+++ b/services/tests/notification/Android.mk
@@ -18,7 +18,6 @@
     services.core \
     services.devicepolicy \
     services.net \
-    services.retaildemo \
     services.usage \
     guava \
     android-support-test \
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
index 99d9c7b..c20020a 100644
--- a/services/tests/notification/AndroidManifest.xml
+++ b/services/tests/notification/AndroidManifest.xml
@@ -31,7 +31,7 @@
     </application>
 
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.frameworks.tests.notification"
         android:label="Notification Tests" />
 </manifest>
diff --git a/services/tests/notification/AndroidTest.xml b/services/tests/notification/AndroidTest.xml
index 46fdccc..fa77407 100644
--- a/services/tests/notification/AndroidTest.xml
+++ b/services/tests/notification/AndroidTest.xml
@@ -19,8 +19,9 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="FrameworksNotificationTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.notification" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
new file mode 100644
index 0000000..faf6a9b
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/AlertRateLimiterTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.notification;
+
+import static com.android.server.notification.AlertRateLimiter.ALLOWED_ALERT_INTERVAL;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+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;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AlertRateLimiterTest extends NotificationTestCase {
+
+    private long mTestStartTime;
+    private
+    AlertRateLimiter mLimiter;
+
+    @Before
+    public void setUp() {
+        mTestStartTime = 1225731600000L;
+        mLimiter = new AlertRateLimiter();
+    }
+
+    @Test
+    public void testFirstAlertAllowed() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+    }
+
+    @Test
+    public void testAllowedAfterSecond() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL));
+    }
+
+    @Test
+    public void testAllowedAfterSecondEvenWithBlockedEntries() throws Exception {
+        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.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime + ALLOWED_ALERT_INTERVAL - 1));
+    }
+
+    @Test
+    public void testDisallowedTimePast() throws Exception {
+        assertFalse(mLimiter.shouldRateLimitAlert(mTestStartTime));
+        assertTrue(mLimiter.shouldRateLimitAlert(mTestStartTime - ALLOWED_ALERT_INTERVAL));
+    }
+}
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index ae98274..ef347fd 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -23,18 +23,14 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 import android.app.ActivityManager;
 import android.app.Notification;
@@ -56,6 +52,8 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.server.lights.Light;
 
@@ -76,6 +74,7 @@
     @Mock android.media.IRingtonePlayer mRingtonePlayer;
     @Mock Light mLight;
     @Mock Handler mHandler;
+    @Mock NotificationUsageStats mUsageStats;
 
     private NotificationManagerService mService;
     private String mPkg = "com.android.server.notification";
@@ -108,6 +107,9 @@
 
     @Before
     public void setUp() {
+        // Magic to allow spying package-private methods on system classes
+        System.setProperty("dexmaker.share_classloader", "true");
+
         MockitoAnnotations.initMocks(this);
 
         when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
@@ -115,7 +117,10 @@
         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
 
-        mService = new NotificationManagerService(getContext());
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
+
+        mService = spy(new NotificationManagerService(getContext()));
+        doNothing().when(mService).sendAccessibilityEvent((Notification) any(), anyString());
         mService.setAudioManager(mAudioManager);
         mService.setVibrator(mVibrator);
         mService.setSystemReady(true);
@@ -123,6 +128,7 @@
         mService.setLights(mLight);
         mService.setScreenOn(false);
         mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
+        mService.setUsageStats(mUsageStats);
     }
 
     //
@@ -352,6 +358,16 @@
                 eq(CUSTOM_LIGHT_COLOR), anyInt(), eq(CUSTOM_LIGHT_ON), eq(CUSTOM_LIGHT_OFF));
     }
 
+    private void verifySendAccessibilityEvent() {
+        verify(mService, times(1))
+                .sendAccessibilityEvent((Notification) anyObject(), anyString());
+    }
+
+    private void verifyNoAccessibilityEvent() {
+        verify(mService, never())
+                .sendAccessibilityEvent((Notification) anyObject(), anyString());
+    }
+
     //
     // Tests
     //
@@ -374,6 +390,7 @@
 
         verifyBeepLooped();
         verifyNeverVibrate();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -383,6 +400,7 @@
         mService.buzzBeepBlinkLocked(r);
 
         verifyBeep();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -403,6 +421,7 @@
 
         verifyNeverBeep();
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -414,6 +433,7 @@
 
         verifyNeverBeep();
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -439,10 +459,12 @@
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mRingtonePlayer);
+        Mockito.reset(mService);
 
         // update should not beep
         mService.buzzBeepBlinkLocked(s);
         verifyNeverBeep();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -585,6 +607,7 @@
 
         verifyNeverBeep();
         verifyVibrate();
+        verifySendAccessibilityEvent();
     }
 
     @Test
@@ -683,10 +706,12 @@
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mVibrator);
+        Mockito.reset(mService);
 
         // update should not beep
         mService.buzzBeepBlinkLocked(s);
         verifyNeverVibrate();
+        verifyNoAccessibilityEvent();
     }
 
     @Test
@@ -806,6 +831,49 @@
         verifyNeverBeep();
     }
 
+    @Test
+    public void testRepeatedSoundOverLimitMuted() throws Exception {
+        when(mUsageStats.isAlertRateLimited(any())).thenReturn(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord r = getQuietNotification();
+        mService.buzzBeepBlinkLocked(r);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testPostingGroupSuppressedDoesNotAffectRateLimiting() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mService.buzzBeepBlinkLocked(summary);
+
+        verify(mUsageStats, never()).isAlertRateLimited(any());
+    }
+
+    @Test
+    public void testCrossUserSoundMuted() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        int userId = mUser.getIdentifier() + 1;
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyNeverBeep();
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java b/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
index 3007cb1..f457f6a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationChannelTest.java
@@ -25,8 +25,14 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.util.FastXmlSerializer;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -50,4 +56,15 @@
         channel.setBlockableSystem(true);
         assertEquals(true, channel.isBlockableSystem());
     }
+
+    @Test
+    public void testEmptyVibration_noException() throws Exception {
+        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
+        channel.setVibrationPattern(new long[0]);
+
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+        channel.writeXml(serializer);
+    }
 }
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 46c536c..3801697 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;
@@ -50,12 +51,14 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Color;
+import android.media.AudioManager;
 import android.os.Binder;
 import android.os.Process;
 import android.os.UserHandle;
 import android.provider.Settings.Secure;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -73,12 +76,12 @@
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 
+@SmallTest
 @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 final int mUid = Binder.getCallingUid();
     private NotificationManagerService mNotificationManagerService;
     private INotificationManager mBinderService;
     private NotificationManagerInternal mInternalService;
@@ -93,6 +96,8 @@
     private RankingHelper mRankingHelper;
     @Mock
     private NotificationUsageStats mUsageStats;
+    @Mock
+    private AudioManager mAudioManager;
     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
             TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
     @Mock
@@ -128,29 +133,36 @@
         // most tests assume badging is enabled
         Secure.putIntForUser(getContext().getContentResolver(),
                 Secure.NOTIFICATION_BADGING, 1,
-                UserHandle.getUserHandleForUid(uid).getIdentifier());
+                UserHandle.getUserHandleForUid(mUid).getIdentifier());
 
         mNotificationManagerService = new TestableNotificationManagerService(mContext);
 
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
         final ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = uid;
+        applicationInfo.uid = mUid;
         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
                 .thenReturn(applicationInfo);
         when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
                 .thenReturn(applicationInfo);
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         // Use this testable looper.
         mTestableLooper = TestableLooper.get(this);
 
         mListener = mNotificationListeners.new ManagedServiceInfo(
-                null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
+                null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
-        mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
-                mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr,
-                mSnoozeHelper, mUsageStats);
-
+        try {
+            mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
+                    mPackageManagerClient, mockLightsManager, mNotificationListeners,
+                    mCompanionMgr, mSnoozeHelper, mUsageStats);
+        } catch (SecurityException e) {
+            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+                throw e;
+            }
+        }
+        mNotificationManagerService.setAudioManager(mAudioManager);
         // Tests call directly into the Binder.
         mBinderService = mNotificationManagerService.getBinderService();
         mInternalService = mNotificationManagerService.getInternalService();
@@ -171,8 +183,8 @@
                 .setGroup(groupKey)
                 .setGroupSummary(isSummary);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", uid, 0,
-                nb.build(), new UserHandle(uid), null, 0);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
     }
     private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
@@ -190,8 +202,8 @@
         if (extender != null) {
             nb.extend(extender);
         }
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", uid, 0,
-                nb.build(), new UserHandle(uid), null, 0);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
     }
 
@@ -199,17 +211,17 @@
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
+                mBinderService.getNotificationChannel(PKG, "id");
         assertTrue(createdChannel != null);
     }
 
     @Test
     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
         try {
-            mBinderService.createNotificationChannels("test_pkg",
+            mBinderService.createNotificationChannels(PKG,
                     new ParceledListSlice(Arrays.asList(null)));
             fail("Exception should be thrown immediately.");
         } catch (NullPointerException e) {
@@ -223,28 +235,33 @@
                 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
-        assertTrue(mBinderService.getNotificationChannel("test_pkg", "id1") != null);
-        assertTrue(mBinderService.getNotificationChannel("test_pkg", "id2") != null);
+        assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
+        assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null);
     }
 
     @Test
-    public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
+    public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
             throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
 
-        // Recreating the channel doesn't throw, but ignores importance.
-        final NotificationChannel dupeChannel =
+        // The user modifies importance directly, can no longer be changed by the app.
+        final NotificationChannel updatedChannel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
+
+        // Recreating with a lower importance leaves channel unchanged.
+        final NotificationChannel dupeChannel =
+                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
-        assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
+                mBinderService.getNotificationChannel(PKG, "id");
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, createdChannel.getImportance());
     }
 
     @Test
@@ -254,10 +271,10 @@
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels("test_pkg",
+        mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel("test_pkg", "id");
+                mBinderService.getNotificationChannel(PKG, "id");
         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
@@ -288,7 +305,7 @@
     public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, uid, false);
+        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
 
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -302,9 +319,9 @@
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
         waitForIdle();
-        StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -316,6 +333,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -330,6 +348,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -342,6 +361,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -354,6 +374,43 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testUserInitiatedClearAll_noLeak() throws Exception {
+        final NotificationRecord n = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group", true);
+
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId());
+        waitForIdle();
+
+        mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(),
+                n.getUserId());
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(n.sbn.getPackageName());
+        assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testCancelAllNotificationsCancelsChildren() throws Exception {
+        final NotificationRecord parent = generateNotificationRecord(
+                mTestNotificationChannel, 1, "group1", true);
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, "group1", false);
+
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId());
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId());
+        waitForIdle();
+
+        mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId());
+        waitForIdle();
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -365,6 +422,8 @@
         }
         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
         waitForIdle();
+
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -391,6 +450,8 @@
                 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(),
                 parentAsChild.sbn.getUserId());
         waitForIdle();
+
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -404,6 +465,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -417,6 +479,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -429,6 +492,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(0, notifs.length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -442,6 +506,7 @@
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
         assertEquals(1, notifs.length);
+        assertEquals(1, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -471,6 +536,7 @@
         mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
         waitForIdle();
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
+        assertEquals(0, mNotificationManagerService.getNotificationRecordCount());
     }
 
     @Test
@@ -546,7 +612,7 @@
     public void testCreateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
@@ -571,7 +637,7 @@
     public void testCreateChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
         NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
@@ -591,7 +657,7 @@
     public void testUpdateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         mTestNotificationChannel.setLightColor(Color.CYAN);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
@@ -609,7 +675,7 @@
     public void testDeleteChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
@@ -625,7 +691,7 @@
     public void testDeleteChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
@@ -642,7 +708,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.updateNotificationChannelFromPrivilegedListener(
                 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
@@ -658,7 +724,7 @@
     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.updateNotificationChannelFromPrivilegedListener(
@@ -680,7 +746,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         mListener.component = new ComponentName(PKG, PKG);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
@@ -706,7 +772,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.getNotificationChannelsFromPrivilegedListener(
                 null, PKG, Process.myUserHandle());
@@ -719,7 +785,7 @@
     public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.getNotificationChannelsFromPrivilegedListener(
@@ -738,7 +804,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
@@ -760,7 +826,7 @@
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
                 null, PKG, Process.myUserHandle());
@@ -772,7 +838,7 @@
     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
 
         try {
             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
@@ -789,7 +855,7 @@
     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
-        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
@@ -949,4 +1015,66 @@
 
         verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString());
     }
+
+    @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", mUid, 0,
+                nb.build(), new UserHandle(mUid), 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", mUid, 0,
+                n, new UserHandle(mUid), 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(mUid).getIdentifier(), 0, null));
+        assertEquals(40, mNotificationManagerService.getNotificationCountLocked(
+                PKG, new UserHandle(mUid).getIdentifier(), 0, "tag2"));
+        assertEquals(2, mNotificationManagerService.getNotificationCountLocked(
+                "a", new UserHandle(mUid).getIdentifier(), 0, "banana"));
+
+        // exclude a known notification - it's excluded from only the posted list, not enqueued
+        assertEquals(39, mNotificationManagerService.getNotificationCountLocked(
+                PKG, new UserHandle(mUid).getIdentifier(), 0, "tag"));
+    }
 }
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 0167232..507b483 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -15,10 +15,10 @@
     frameworks-base-testutils \
     services.accessibility \
     services.appwidget \
+    services.backup \
     services.core \
     services.devicepolicy \
     services.net \
-    services.retaildemo \
     services.usage \
     guava \
     android-support-test \
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 4622d50..63f3b75 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksServicesTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.servicestests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/services/tests/servicestests/res/raw/backup_file_with_long_name b/services/tests/servicestests/res/raw/backup_file_with_long_name
new file mode 100644
index 0000000..265a0ba
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_file_with_long_name
Binary files differ
diff --git a/services/tests/servicestests/res/raw/backup_telephony_no_password b/services/tests/servicestests/res/raw/backup_telephony_no_password
new file mode 100644
index 0000000..12b6cbf
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_no_password
Binary files differ
diff --git a/services/tests/servicestests/res/raw/backup_telephony_with_password b/services/tests/servicestests/res/raw/backup_telephony_with_password
new file mode 100644
index 0000000..ce847a3
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_with_password
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
deleted file mode 100644
index d9d06ae..0000000
--- a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
+++ /dev/null
@@ -1,161 +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.server;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.IActivityManager;
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.pm.UserInfo;
-import android.os.FileUtils;
-import android.os.IProgressListener;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.security.KeyStore;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-
-public class BaseLockSettingsServiceTests extends AndroidTestCase {
-    protected static final int PRIMARY_USER_ID = 0;
-    protected static final int MANAGED_PROFILE_USER_ID = 12;
-    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
-    protected static final int SECONDARY_USER_ID = 20;
-
-    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
-    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED);
-
-    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
-
-    LockSettingsService mService;
-
-    MockLockSettingsContext mContext;
-    LockSettingsStorageTestable mStorage;
-
-    LockPatternUtils mLockPatternUtils;
-    MockGateKeeperService mGateKeeperService;
-    NotificationManager mNotificationManager;
-    UserManager mUserManager;
-    MockStorageManager mStorageManager;
-    IActivityManager mActivityManager;
-    DevicePolicyManager mDevicePolicyManager;
-    KeyStore mKeyStore;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mLockPatternUtils = mock(LockPatternUtils.class);
-        mGateKeeperService = new MockGateKeeperService();
-        mNotificationManager = mock(NotificationManager.class);
-        mUserManager = mock(UserManager.class);
-        mStorageManager = new MockStorageManager();
-        mActivityManager = mock(IActivityManager.class);
-        mDevicePolicyManager = mock(DevicePolicyManager.class);
-        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
-                mDevicePolicyManager, mock(StorageManager.class));
-        mStorage = new LockSettingsStorageTestable(mContext,
-                new File(getContext().getFilesDir(), "locksettings"));
-        File storageDir = mStorage.mStorageDir;
-        if (storageDir.exists()) {
-            FileUtils.deleteContents(storageDir);
-        } else {
-            storageDir.mkdirs();
-        }
-
-        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
-                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager);
-        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
-        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
-        installChildProfile(MANAGED_PROFILE_USER_ID);
-        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
-        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
-        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
-
-        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
-                new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws Throwable {
-                Object[] args = invocation.getArguments();
-                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
-                        (IProgressListener) args[3]);
-                return true;
-            }
-        });
-
-        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"));
-    }
-
-    private UserInfo installChildProfile(int profileId) {
-        final UserInfo userInfo = new UserInfo(
-            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
-        mPrimaryUserProfiles.add(userInfo);
-        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
-        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
-        return userInfo;
-    }
-
-    private UserInfo installAndTurnOffChildProfile(int profileId) {
-        final UserInfo userInfo = installChildProfile(profileId);
-        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
-        return userInfo;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-        File db = getContext().getDatabasePath("locksettings.db");
-        assertTrue(!db.exists() || db.delete());
-
-        File storageDir = mStorage.mStorageDir;
-        assertTrue(FileUtils.deleteContents(storageDir));
-    }
-
-    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
-        assertTrue(Arrays.equals(expected, actual));
-    }
-
-    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
-        assertFalse(Arrays.equals(expected, actual));
-    }
-}
-
diff --git a/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java b/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
index 362c47a..69c1499 100644
--- a/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
+++ b/services/tests/servicestests/src/com/android/server/BootReceiverFixFsckFsStatTest.java
@@ -52,13 +52,13 @@
                 " ",
                 "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
         };
-        doTestFsckFsStat(logs, 0x405, 5, 0, logs.length);
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
 
         final String[] doubleLogs = new String[logs.length * 2];
         System.arraycopy(logs, 0, doubleLogs, 0, logs.length);
         System.arraycopy(logs, 0, doubleLogs, logs.length, logs.length);
-        doTestFsckFsStat(doubleLogs, 0x401, 1, 0, logs.length);
-        doTestFsckFsStat(doubleLogs, 0x402, 2, logs.length, logs.length * 2);
+        doTestFsckFsStat(doubleLogs, 0x401, 0x1, 0, logs.length);
+        doTestFsckFsStat(doubleLogs, 0x402, 0x2, logs.length, logs.length * 2);
     }
 
     @Test
@@ -79,6 +79,7 @@
                 " ",
                 "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
         };
+        // quota fix without tree optimization is an error.
         doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
     }
 
@@ -103,6 +104,92 @@
         doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
     }
 
+    @Test
+    public void testTimestampAdjustment() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
+    @Test
+    public void testTimestampAdjustmentNoFixLine() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
+    @Test
+    public void testTimestampAdjustmentWithQuotaFix() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (71667712, 1000) != expected (71671808, 1000)",
+                "Update quota info for quota type 0? yes",
+                " ",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (59555840, 953) != expected (59559936, 953)",
+                "Update quota info for quota type 1? yes",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x405, 0, logs.length);
+    }
+
+    @Test
+    public void testAllNonFixes() {
+        final String[] logs = {
+                "e2fsck 1.43.3 (04-Sep-2016)",
+                "Pass 1: Checking inodes, blocks, and sizes",
+                "Timestamp(s) on inode 508580 beyond 2310-04-04 are likely pre-1970.",
+                "Fix? yes",
+                "Inode 877141 extent tree (at level 1) could be shorter.  Fix? yes",
+                " ",
+                "Pass 1E: Optimizing extent trees",
+                "Pass 2: Checking directory structure",
+                "Pass 3: Checking directory connectivity",
+                "Pass 4: Checking reference counts",
+                "Pass 5: Checking group summary information",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (71667712, 1000) != expected (71671808, 1000)",
+                "Update quota info for quota type 0? yes",
+                " ",
+                "[QUOTA WARNING] Usage inconsistent for ID 10038:actual (59555840, 953) != expected (59559936, 953)",
+                "Update quota info for quota type 1? yes",
+                " ",
+                "/dev/block/platform/soc/624000.ufshc/by-name/userdata: ***** FILE SYSTEM WAS MODIFIED *****"
+        };
+        doTestFsckFsStat(logs, 0x405, 0x5, 0, logs.length);
+    }
+
     private void doTestFsckFsStat(String[] lines, int statOrg, int statUpdated, int startLineNumber,
             int endLineNumber) {
         assertEquals(statUpdated, BootReceiver.fixFsckFsStat(PARTITION, statOrg, lines,
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
new file mode 100644
index 0000000..33e4165
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -0,0 +1,846 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+import android.view.KeyEvent;
+import android.util.MutableBoolean;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link GestureLauncherService}.
+ * runtest frameworks-services -c com.android.server.GestureLauncherServiceTest
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GestureLauncherServiceTest {
+
+    private static final int FAKE_USER_ID = 1337;
+    private static final int FAKE_SOURCE = 1982;
+    private static final long INITIAL_EVENT_TIME_MILLIS = 20000L;
+    private static final long IGNORED_DOWN_TIME = 1234L;
+    private static final int IGNORED_ACTION = 13;
+    private static final int IGNORED_CODE = 1999;
+    private static final int IGNORED_REPEAT = 42;
+
+    private @Mock Context mContext;
+    private @Mock Resources mResources;
+    private @Mock StatusBarManagerInternal mStatusBarManagerInternal;
+    private @Mock MetricsLogger mMetricsLogger;
+    private MockContentResolver mContentResolver;
+    private GestureLauncherService mGestureLauncherService;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+        LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal);
+
+        final Context originalContext = InstrumentationRegistry.getContext();
+        when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
+        when(mContext.getResources()).thenReturn(mResources);
+        mContentResolver = new MockContentResolver(mContext);
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+        mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger);
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerEnabled_configFalse() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerEnabled_configTrue() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingDisabled() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingEnabled() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingDisabled() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingEnabled() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+                mContext, FAKE_USER_ID));
+    }
+
+    @Test
+    public void testHandleCameraLaunchGesture_userSetupComplete() {
+        withUserSetupCompleteValue(true);
+
+        boolean useWakeLock = false;
+        assertTrue(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE);
+    }
+
+    @Test
+    public void testHandleCameraLaunchGesture_userSetupNotComplete() {
+        withUserSetupCompleteValue(false);
+
+        boolean useWakeLock = false;
+        assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS +
+                GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+        verify(mMetricsLogger).histogram("power_consecutive_short_tap_count", 1);
+        verify(mMetricsLogger).histogram("power_double_tap_interval", (int) eventTime);
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(true);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = false;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertTrue(intercepted);
+        assertTrue(outLaunched.value);
+
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
+                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+        verify(mMetricsLogger)
+            .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(false);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(false);
+        withCameraDoubleTapPowerDisableSettingValue(1);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(true);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertTrue(outLaunched.value);
+
+        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
+                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+        verify(mMetricsLogger)
+            .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void
+    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(false);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        // The interval is too long to launch the camera, but short enough to count as a
+        // sequential tap.
+        assertEquals(2, tapCounts.get(1).intValue());
+    }
+
+    @Test
+    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = false;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        long interval = GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        outLaunched.value = true;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+            .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+        assertEquals((int) interval, intervals.get(1).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(2)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+        assertEquals(1, tapCounts.get(1).intValue());
+    }
+
+    private void withCameraDoubleTapPowerEnableConfigValue(boolean enableConfigValue) {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled))
+                .thenReturn(enableConfigValue);
+    }
+
+    private void withCameraDoubleTapPowerDisableSettingValue(int disableSettingValue) {
+        Settings.Secure.putIntForUser(
+                mContentResolver,
+                Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
+                disableSettingValue,
+                UserHandle.USER_CURRENT);
+    }
+
+    private void withUserSetupCompleteValue(boolean userSetupComplete) {
+        int userSetupCompleteValue = userSetupComplete ? 1 : 0;
+        Settings.Secure.putIntForUser(
+                mContentResolver,
+                Settings.Secure.USER_SETUP_COMPLETE,
+                userSetupCompleteValue,
+                UserHandle.USER_CURRENT);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
deleted file mode 100644
index cfdb5b1..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
+++ /dev/null
@@ -1,138 +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
- */
-
-package com.android.server;
-
-import static org.mockito.Mockito.mock;
-
-import android.app.IActivityManager;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.storage.IStorageManager;
-import android.security.KeyStore;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.FileNotFoundException;
-
-public class LockSettingsServiceTestable extends LockSettingsService {
-
-    private static class MockInjector extends LockSettingsService.Injector {
-
-        private LockSettingsStorage mLockSettingsStorage;
-        private KeyStore mKeyStore;
-        private IActivityManager mActivityManager;
-        private LockPatternUtils mLockPatternUtils;
-        private IStorageManager mStorageManager;
-        private MockGateKeeperService mGatekeeper;
-
-        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
-                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
-                IStorageManager storageManager, MockGateKeeperService gatekeeper) {
-            super(context);
-            mLockSettingsStorage = storage;
-            mKeyStore = keyStore;
-            mActivityManager = activityManager;
-            mLockPatternUtils = lockPatternUtils;
-            mStorageManager = storageManager;
-            mGatekeeper = gatekeeper;
-        }
-
-        @Override
-        public Handler getHandler() {
-            return mock(Handler.class);
-        }
-
-        @Override
-        public LockSettingsStorage getStorage() {
-            return mLockSettingsStorage;
-        }
-
-        @Override
-        public LockSettingsStrongAuth getStrongAuth() {
-            return mock(LockSettingsStrongAuth.class);
-        }
-
-        @Override
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return mock(SynchronizedStrongAuthTracker.class);
-        }
-
-        @Override
-        public IActivityManager getActivityManager() {
-            return mActivityManager;
-        }
-
-        @Override
-        public LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        public KeyStore getKeyStore() {
-            return mKeyStore;
-        }
-
-        @Override
-        public IStorageManager getStorageManager() {
-            return mStorageManager;
-        }
-
-        @Override
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return new MockSyntheticPasswordManager(storage, mGatekeeper);
-        }
-
-        @Override
-        public int binderGetCallingUid() {
-            return Process.SYSTEM_UID;
-        }
-
-
-    }
-
-    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
-            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
-            IStorageManager storageManager, IActivityManager mActivityManager) {
-        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
-                storageManager, gatekeeper));
-        mGateKeeperService = gatekeeper;
-    }
-
-    @Override
-    protected void tieProfileLockToParent(int userId, String password) {
-        mStorage.writeChildProfileLock(userId, password.getBytes());
-    }
-
-    @Override
-    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException, KeyPermanentlyInvalidatedException {
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        try {
-            if (mGateKeeperService.getSecureUserId(userId) == 0) {
-                throw new KeyPermanentlyInvalidatedException();
-            }
-        } catch (RemoteException e) {
-            // shouldn't happen.
-        }
-        return new String(storedData);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
deleted file mode 100644
index 25cc426..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
+++ /dev/null
@@ -1,245 +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.server;
-
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.MockGateKeeperService.VerifyHandle;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsServiceTests
- */
-public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testCreatePasswordPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testCreatePatternPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
-                "asdfghjk", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testChangePatternPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
-                "1596321", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordFailPrimaryUser() throws RemoteException {
-        final long sid = 1234;
-        final String FAILED_MESSAGE = "Failed to enroll password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
-
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
-                    PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null, 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);
-    }
-
-    public void testClearPasswordPrimaryUser() throws RemoteException {
-        final String PASSWORD = "password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
-        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD, PRIMARY_USER_ID);
-        assertFalse(mService.havePassword(PRIMARY_USER_ID));
-        assertFalse(mService.havePattern(PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testManagedProfileUnifiedChallenge() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                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);
-        final long turnedOffProfileSid =
-                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-        assertTrue(turnedOffProfileSid != 0);
-        assertTrue(turnedOffProfileSid != primarySid);
-        assertTrue(turnedOffProfileSid != profileSid);
-
-        // clear auth token and wait for verify challenge from primary user to re-generate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
-        // verify credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-
-        // Verify that we have a new auth token for the profile
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
-        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
-
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        // Change primary password and verify that profile SID remains
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                UnifiedPassword, 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,
-                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));
-    }
-
-    public void testManagedProfileSeparateChallenge() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
-        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                MANAGED_PROFILE_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // clear auth token and make sure verify challenge from primary user does not regenerate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        // verify primary credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-
-        // verify profile credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Change primary credential and make sure we don't affect profile
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                primaryPassword, PRIMARY_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-    }
-
-    private void testCreateCredential(int userId, String credential, int type)
-            throws RemoteException {
-        mService.setLockCredential(credential, type, null, userId);
-        assertVerifyCredentials(userId, credential, type, -1);
-    }
-
-    private void testChangeCredentials(int userId, String newCredential, int newType,
-            String oldCredential, int oldType) throws RemoteException {
-        final long sid = 1234;
-        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
-        mService.setLockCredential(newCredential, newType, oldCredential, userId);
-        assertVerifyCredentials(userId, newCredential, newType, sid);
-    }
-
-    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
-            throws RemoteException{
-        final long challenge = 54321;
-        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
-                userId);
-
-        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
-        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
-        final int incorrectType;
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            assertTrue(mService.havePassword(userId));
-            assertFalse(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
-            assertFalse(mService.havePassword(userId));
-            assertTrue(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        } else {
-            assertFalse(mService.havePassword(userId));
-            assertFalse(mService.havePassword(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        }
-        // check for bad type
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
-                incorrectType, challenge, userId).getResponseCode());
-        // check for bad credential
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
-                type, challenge, userId).getResponseCode());
-    }
-
-    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
-        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
-        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/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
deleted file mode 100644
index 84ebb19..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
+++ /dev/null
@@ -1,142 +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.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import static junit.framework.Assert.*;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.io.FileDescriptor.*;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-
-/**
- * Test class for {@link LockSettingsShellCommand}.
- *
- * runtest frameworks-services -c com.android.server.LockSettingsShellCommandTest
- */
-@SmallTest
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class LockSettingsShellCommandTest {
-
-    private LockSettingsShellCommand mCommand;
-
-    private @Mock LockPatternUtils mLockPatternUtils;
-    private int mUserId;
-    private final Binder mBinder = new Binder();
-    private final ShellCallback mShellCallback = new ShellCallback();
-    private final ResultReceiver mResultReceiver = new ResultReceiver(
-            new Handler(Looper.getMainLooper()));
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mUserId = ActivityManager.getCurrentUser();
-        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
-    }
-
-    @Test
-    public void testWrongPassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
-        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
-                new String[] { "set-pin", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
-    }
-
-    @Test
-    public void testChangePin() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pin", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-password", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePattern() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pattern", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
-    }
-
-    @Test
-    public void testClear() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "clear", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).clearLock("1234", mUserId);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
deleted file mode 100644
index 18da1a5..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
+++ /dev/null
@@ -1,66 +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
- */
-
-package com.android.server;
-
-import android.content.Context;
-
-import java.io.File;
-
-public class LockSettingsStorageTestable extends LockSettingsStorage {
-
-    public File mStorageDir;
-
-    public LockSettingsStorageTestable(Context context, File storageDir) {
-        super(context);
-        mStorageDir = storageDir;
-    }
-
-    @Override
-    String getLockPatternFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPatternFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getLockPasswordFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPasswordFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getChildProfileLockFile(int userId) {
-        return makeDirs(mStorageDir,
-                super.getChildProfileLockFile(userId)).getAbsolutePath();
-    }
-
-    @Override
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
-                userId).getAbsolutePath());
-    }
-
-    private File makeDirs(File baseDir, String filePath) {
-        File path = new File(filePath);
-        if (path.getParent() == null) {
-            return new File(baseDir, filePath);
-        } else {
-            File mappedDir = new File(baseDir, path.getParent());
-            mappedDir.mkdirs();
-            return new File(mappedDir, path.getName());
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
deleted file mode 100644
index f242b26..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
+++ /dev/null
@@ -1,373 +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.android.server;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.UserInfo;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.FileUtils;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
- */
-public class LockSettingsStorageTests extends AndroidTestCase {
-    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
-    private final byte[] PASSWORD_1 = "password1".getBytes();
-    private final byte[] PATTERN_0 = "123654".getBytes();
-    private final byte[] PATTERN_1 = "147852369".getBytes();
-
-    LockSettingsStorage mStorage;
-    File mStorageDir;
-
-    private File mDb;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
-        mDb = getContext().getDatabasePath("locksettings.db");
-
-        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
-        assertTrue(FileUtils.deleteContents(mStorageDir));
-        assertTrue(!mDb.exists() || mDb.delete());
-
-        final UserManager mockUserManager = mock(UserManager.class);
-        // User 2 is a profile of user 1.
-        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
-        // User 3 is a profile of user 0.
-        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
-
-        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
-                mock(NotificationManager.class), mock(DevicePolicyManager.class),
-                mock(StorageManager.class));
-        mStorage = new LockSettingsStorageTestable(context,
-                new File(getContext().getFilesDir(), "locksettings"));
-        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                    @Override
-                    public void initialize(SQLiteDatabase db) {
-                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
-                    }
-                });
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-    }
-
-    public void testKeyValue_InitializeWorked() {
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-        mStorage.clearCache();
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-    }
-
-    public void testKeyValue_WriteThenRead() {
-        mStorage.writeKeyValue("key", "value", 0);
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-        mStorage.clearCache();
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-    }
-
-    public void testKeyValue_DefaultValue() {
-        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
-        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
-    }
-
-    public void testKeyValue_Concurrency() {
-        final Object monitor = new Object();
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    synchronized (monitor) {
-                        try {
-                            monitor.wait();
-                        } catch (InterruptedException e) {
-                            return;
-                        }
-                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        mStorage.writeKeyValue("key", "initalValue", 0);
-        synchronized (monitor) {
-            monitor.notifyAll();
-        }
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-        mStorage.clearCache();
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-    }
-
-    public void testKeyValue_CacheStarvedWriter() {
-        final CountDownLatch latch = new CountDownLatch(1);
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        latch.await();
-                    } catch (InterruptedException e) {
-                        return;
-                    }
-                    if (threadId == 50) {
-                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
-                    } else {
-                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        latch.countDown();
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        String cached = mStorage.readKeyValue("key", "default", 0);
-        mStorage.clearCache();
-        String storage = mStorage.readKeyValue("key", "default", 0);
-        assertEquals("Cached value didn't match stored value", storage, cached);
-    }
-
-    public void testRemoveUser() {
-        mStorage.writeKeyValue("key", "value", 0);
-        writePasswordBytes(PASSWORD_0, 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.writeKeyValue("key", "value", 1);
-        writePasswordBytes(PASSWORD_1, 1);
-        writePatternBytes(PATTERN_1, 1);
-
-        mStorage.removeUser(0);
-
-        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
-        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
-        assertPatternBytes(PATTERN_1, 1);
-    }
-
-    public void testCredential_Default() {
-        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
-    }
-
-    public void testPassword_Write() {
-        writePasswordBytes(PASSWORD_0, 0);
-
-        assertPasswordBytes(PASSWORD_0, 0);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 0);
-    }
-
-    public void testPassword_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 1);
-        writePasswordBytes(PASSWORD_1, 2);
-
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-    }
-
-    public void testLockType_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 10);
-        writePatternBytes(PATTERN_0, 20);
-
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-        mStorage.clearCache();
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-    }
-
-    public void testPassword_WriteParentWritesProfile() {
-        writePasswordBytes(PASSWORD_0, 2);
-        writePasswordBytes(PASSWORD_1, 1);
-
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-    }
-
-    public void testProfileLock_ReadWriteChildProfileLock() {
-        assertFalse(mStorage.hasChildProfileLock(20));
-        mStorage.writeChildProfileLock(20, PASSWORD_0);
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-        mStorage.clearCache();
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-    }
-
-    public void testPattern_Write() {
-        writePatternBytes(PATTERN_0, 0);
-
-        assertPatternBytes(PATTERN_0, 0);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testPattern_WriteProfileWritesParent() {
-        writePatternBytes(PATTERN_0, 1);
-        writePatternBytes(PATTERN_1, 2);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPattern_WriteParentWritesProfile() {
-        writePatternBytes(PATTERN_1, 2);
-        writePatternBytes(PATTERN_0, 1);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPrefetch() {
-        mStorage.writeKeyValue("key", "toBeFetched", 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.clearCache();
-        mStorage.prefetchUser(0);
-
-        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testFileLocation_Owner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
-        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
-        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
-        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
-    }
-
-    public void testFileLocation_SecondaryUser() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
-        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
-    }
-
-    public void testFileLocation_ProfileToSecondary() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
-        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
-    }
-
-    public void testFileLocation_ProfileToOwner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
-        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
-    }
-
-    public void testSyntheticPasswordState() {
-        final byte[] data = {1,2,3,4};
-        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
-        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
-
-        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
-        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-    }
-
-    private static void assertArrayEquals(byte[] expected, byte[] actual) {
-        if (!Arrays.equals(expected, actual)) {
-            fail("expected:<" + Arrays.toString(expected) +
-                    "> but was:<" + Arrays.toString(actual) + ">");
-        }
-    }
-
-    private void writePasswordBytes(byte[] password, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
-    }
-
-    private void writePatternBytes(byte[] pattern, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
-    }
-
-    private void assertPasswordBytes(byte[] password, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
-        assertArrayEquals(password, cred.hash);
-    }
-
-    private void assertPatternBytes(byte[] pattern, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
-        assertArrayEquals(pattern, cred.hash);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
deleted file mode 100644
index bc93341..0000000
--- a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
+++ /dev/null
@@ -1,194 +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
- */
-
-package com.android.server;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-public class MockGateKeeperService implements IGateKeeperService {
-    static class VerifyHandle {
-        public byte[] password;
-        public long sid;
-
-        public VerifyHandle(byte[] password, long sid) {
-            this.password = password;
-            this.sid = sid;
-        }
-
-        public VerifyHandle(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            sid = buffer.getLong();
-            password = new byte[buffer.remaining()];
-            buffer.get(password);
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
-            buffer.put((byte)0);
-            buffer.putLong(sid);
-            buffer.put(password);
-            return buffer.array();
-        }
-    }
-
-    static class AuthToken {
-        public long challenge;
-        public long sid;
-
-        public AuthToken(long challenge, long sid) {
-            this.challenge = challenge;
-            this.sid = sid;
-        }
-
-        public AuthToken(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            challenge = buffer.getLong();
-            sid = buffer.getLong();
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
-            buffer.put((byte)0);
-            buffer.putLong(challenge);
-            buffer.putLong(sid);
-            return buffer.array();
-        }
-    }
-
-    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
-    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
-
-    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
-
-    @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)) {
-                // Trusted enroll
-                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
-                refreshSid(uid, handle.sid, false);
-                handleMap.put(uid, newHandle.toBytes());
-                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-            } else {
-                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);
-        }
-    }
-
-    @Override
-    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
-            byte[] providedPassword) throws android.os.RemoteException {
-        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
-    }
-
-    @Override
-    public GateKeeperResponse verifyChallenge(int uid, long challenge,
-            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
-
-        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
-        if (Arrays.equals(handle.password, providedPassword)) {
-            byte[] knownHandle = handleMap.get(uid);
-            if (knownHandle != null) {
-                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
-                    throw new AssertionFailedError("Got correct but obsolete handle");
-                }
-            }
-            refreshSid(uid, handle.sid, false);
-            AuthToken token = new AuthToken(challenge, handle.sid);
-            refreshAuthToken(uid, token);
-            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
-        } else {
-            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
-        }
-    }
-
-    private void refreshAuthToken(int uid, AuthToken token) {
-        authTokenMap.put(uid, token);
-    }
-
-    public AuthToken getAuthToken(int uid) {
-        return authTokenMap.get(uid);
-    }
-
-    public AuthToken getAuthTokenForSid(long sid) {
-        for(AuthToken token : authTokenMap.values()) {
-            if (token.sid == sid) {
-                return token;
-            }
-        }
-        return null;
-    }
-
-    public void clearAuthToken(int uid) {
-        authTokenMap.remove(uid);
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearSecureUserId(int userId) throws RemoteException {
-        sidMap.remove(userId);
-    }
-
-    @Override
-    public long getSecureUserId(int userId) throws RemoteException {
-        if (sidMap.containsKey(userId)) {
-            return sidMap.get(userId);
-        } else {
-            return 0L;
-        }
-    }
-
-    private void refreshSid(int uid, long sid, boolean force) {
-        if (!sidMap.containsKey(uid) || force) {
-            sidMap.put(uid, sid);
-        } else{
-            if (sidMap.get(uid) != sid) {
-                throw new AssertionFailedError("Inconsistent SID");
-            }
-        }
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
deleted file mode 100644
index 9dede3b..0000000
--- a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
+++ /dev/null
@@ -1,63 +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
- */
-
-package com.android.server;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-
-public class MockLockSettingsContext extends ContextWrapper {
-
-    private UserManager mUserManager;
-    private NotificationManager mNotificationManager;
-    private DevicePolicyManager mDevicePolicyManager;
-    private StorageManager mStorageManager;
-
-    public MockLockSettingsContext(Context base, UserManager userManager,
-            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
-            StorageManager storageManager) {
-        super(base);
-        mUserManager = userManager;
-        mNotificationManager = notificationManager;
-        mDevicePolicyManager = devicePolicyManager;
-        mStorageManager = storageManager;
-    }
-
-    @Override
-    public Object getSystemService(String name) {
-        if (USER_SERVICE.equals(name)) {
-            return mUserManager;
-        } else if (NOTIFICATION_SERVICE.equals(name)) {
-            return mNotificationManager;
-        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
-            return mDevicePolicyManager;
-        } else if (STORAGE_SERVICE.equals(name)) {
-            return mStorageManager;
-        } else {
-            throw new RuntimeException("System service not mocked: " + name);
-        }
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String permission, String message) {
-        // Skip permission checks for unit tests.
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/MockStorageManager.java
deleted file mode 100644
index 3a17718..0000000
--- a/services/tests/servicestests/src/com/android/server/MockStorageManager.java
+++ /dev/null
@@ -1,508 +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
- */
-
-package com.android.server;
-
-import android.content.pm.IPackageMoveObserver;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.storage.DiskInfo;
-import android.os.storage.IObbActionListener;
-import android.os.storage.IStorageEventListener;
-import android.os.storage.IStorageManager;
-import android.os.storage.IStorageShutdownObserver;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.os.storage.VolumeRecord;
-import android.util.ArrayMap;
-import android.util.Pair;
-
-import com.android.internal.os.AppFuseMount;
-
-import junit.framework.AssertionFailedError;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class MockStorageManager implements IStorageManager {
-
-    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
-    private boolean mIgnoreBadUnlock;
-
-    @Override
-    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        getUserAuth(userId).add(new Pair<>(token, secret));
-    }
-
-    @Override
-    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
-        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
-        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
-        auths.clear();
-        auths.add(latest);
-    }
-
-    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
-        if (!mAuth.containsKey(userId)) {
-            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
-            auths.add(new Pair(null, null));
-            mAuth.put(userId,  auths);
-        }
-        return mAuth.get(userId);
-    }
-
-    public byte[] getUserUnlockToken(int userId) {
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (auths.size() != 1) {
-            throw new AssertionFailedError("More than one secret exists");
-        }
-        return auths.get(0).second;
-    }
-
-    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
-            throws RemoteException {
-        listener.onStarted(userId, null);
-        listener.onFinished(userId, null);
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (secret != null) {
-            if (auths.size() > 1) {
-                throw new AssertionFailedError("More than one secret exists");
-            }
-            Pair<byte[], byte[]> auth = auths.get(0);
-            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
-                throw new AssertionFailedError("Invalid secret to unlock user");
-            }
-        } else {
-            if (auths != null && auths.size() > 0) {
-                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
-            }
-        }
-    }
-
-    public void setIgnoreBadUnlock(boolean ignore) {
-        mIgnoreBadUnlock = ignore;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void registerListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageConnected() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageEnabled() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public int formatVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int[] getStorageUsers(String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getVolumeState(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
-            boolean external) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int finalizeSecureContainer(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int destroySecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isSecureContainerMounted(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerPath(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String[] getSecureContainerList() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void finishMediaUpdate() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
-            int nonce) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isObbMounted(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getMountedObbPath(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isExternalStorageEmulated() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int decryptStorage(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int encryptStorage(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int changeEncryptionPassword(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getEncryptionState() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int verifyEncryptionPassword(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int fixPermissionsSecureContainer(String id, int gid, String filename)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mkdirs(String callingPkg, String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getPasswordType() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public void setField(String field, String contents) throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public String getField(String field) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long lastMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void runMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void waitForAsecScan() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DiskInfo[] getDisks() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void format(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPublic(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPrivate(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionMixed(String diskId, int ratio) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetVolume(String fsUuid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetAllVolumes() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPrimaryStorageUuid() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long benchmark(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setDebugFlags(int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void lockUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserStorage(String volumeUuid, int userId, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isConvertibleToFBE() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void fstrim(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getAllocatableBytes(String path, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void allocateBytes(String path, long bytes, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void secdiscard(String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
deleted file mode 100644
index 93e3fc6..0000000
--- a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
+++ /dev/null
@@ -1,102 +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.
- */
-package com.android.server;
-
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
-public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
-
-    private MockGateKeeperService mGateKeeper;
-
-    public MockSyntheticPasswordManager(LockSettingsStorage storage,
-            MockGateKeeperService gatekeeper) {
-        super(storage);
-        mGateKeeper = gatekeeper;
-    }
-
-    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
-
-    @Override
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
-            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
-        buffer.put(blob, 0, blob.length);
-        buffer.flip();
-        int len;
-        len = buffer.getInt();
-        byte[] data = new byte[len];
-        buffer.get(data);
-        len = buffer.getInt();
-        byte[] appId = new byte[len];
-        buffer.get(appId);
-        long sid = buffer.getLong();
-        if (!Arrays.equals(appId, applicationId)) {
-            throw new AssertionFailedError("Invalid application id");
-        }
-        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
-            throw new AssertionFailedError("No valid auth token");
-        }
-        return data;
-    }
-
-    @Override
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
-                + applicationId.length + Long.BYTES);
-        buffer.putInt(data.length);
-        buffer.put(data);
-        buffer.putInt(applicationId.length);
-        buffer.put(applicationId);
-        buffer.putLong(sid);
-        byte[] result = buffer.array();
-        mBlobs.put(blobKeyName, result);
-        return result;
-    }
-
-    @Override
-    protected void destroySPBlobKey(String keyAlias) {
-    }
-
-    @Override
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return new MockGateKeeperService.VerifyHandle(handle).sid;
-    }
-
-    @Override
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        try {
-            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
-            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-            return f.generateSecret(spec).getEncoded();
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
deleted file mode 100644
index 3ec71e4..0000000
--- a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
+++ /dev/null
@@ -1,349 +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
- */
-
-package com.android.server;
-
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-
-/**
- * runtest frameworks-services -c com.android.server.SyntheticPasswordTests
- */
-public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testPasswordBasedSyntheticPassword() throws RemoteException {
-        final int USER_ID = 10;
-        final String PASSWORD = "user-password";
-        final String BADPASSWORD = "bad-password";
-        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
-        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
-                null, USER_ID);
-        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
-                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, USER_ID);
-
-        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
-        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
-
-        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
-        assertNull(result.authToken);
-    }
-
-    private void disableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-    }
-
-    private void enableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private boolean hasSyntheticPassword(int userId) throws RemoteException {
-        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
-    }
-
-    public void testPasswordMigration() throws RemoteException {
-        final String PASSWORD = "testPasswordMigration-password";
-
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        // Performs migration
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-
-        // SP-based verification
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
-        enableSyntheticPassword(userId);
-        mService.setLockCredential(password, password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE, null, userId);
-    }
-
-    public void testSyntheticPasswordChangeCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
-        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
-                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-    public void testSyntheticPasswordClearCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // Untrusted change password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // Verify the password
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-
-    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, 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);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
-        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, MANAGED_PROFILE_USER_ID);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testTokenBasedResetPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedClearPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String NEWPASSWORD = "password";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD, PRIMARY_USER_ID);
-
-        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        final String PASSWORD = "password";
-        // Set up pre-SP user password
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        // Token not activated immediately since user password exists
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        // Activate token (password gets migrated to SP at the same time)
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                        PRIMARY_USER_ID).getResponseCode());
-        // Verify token is activated
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-    }
-
-    // b/34600579
-    //TODO: add non-migration work profile case, and unify/un-unify transition.
-    //TODO: test token after user resets password
-    //TODO: test token based reset after unified work challenge
-    //TODO: test clear password after unified work challenge
-}
-
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index f75d49c..2252c85 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -16,10 +16,15 @@
 
 package com.android.server.am;
 
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -94,4 +99,36 @@
 
         return -1;
     }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarBottom() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f,
+                new Rect(0, 0, 1000, 1500));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarLeft() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(500, 0, 2000, 1000));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarRight() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(0, 0, 1500, 1000));
+    }
+
+    private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
+            float aspectRatio, Rect expectedActivityBounds) {
+        final ActivityManagerService service = createActivityManagerService();
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
+        final ActivityRecord record = createActivity(service, testActivityComponent, task);
+
+        // Verify with nav bar on the right.
+        when(service.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
+        task.getConfiguration().setAppBounds(taskBounds);
+        record.info.maxAspectRatio = aspectRatio;
+        record.ensureActivityConfigurationLocked(0 /* globalChanges */, false /* preserveWindow */);
+        assertEquals(expectedActivityBounds, record.getBounds());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index bac1216..16bc011 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -120,6 +120,7 @@
                 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo());
         final ActivityStack stack = service.mStackSupervisor.getStack(stackId,
                 true /*createStaticStackIfNeeded*/, true /*onTop*/);
+        service.mStackSupervisor.setFocusStackUnchecked("test", stack);
         stack.addTask(task, true, "creating test task");
         task.setStack(stack);
         task.setWindowContainerController(mock(TaskWindowContainerController.class));
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index 2f202d98..da30c11 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -34,6 +34,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.AppOpsService;
 
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
@@ -59,7 +60,6 @@
  * Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \
  *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
-@Ignore
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class CoreSettingsObserverTest {
@@ -79,11 +79,17 @@
 
     @BeforeClass
     public static void setupOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
         CoreSettingsObserver.sSecureSettingToTypeMap.put(TEST_SETTING_SECURE_INT, int.class);
         CoreSettingsObserver.sGlobalSettingToTypeMap.put(TEST_SETTING_GLOBAL_FLOAT, float.class);
         CoreSettingsObserver.sSystemSettingToTypeMap.put(TEST_SETTING_SYSTEM_STRING, String.class);
     }
 
+    @AfterClass
+    public static void tearDownOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
+    }
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
index f287386..54f93a8 100644
--- a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -32,6 +32,7 @@
 import android.os.Looper;
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
 
 import org.mockito.ArgumentMatchers;
@@ -40,6 +41,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 
+@SmallTest
 public class PersistentConnectionTest extends AndroidTestCase {
     private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
         public long uptimeMillis = 12345;
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
index 984a484..ea207f1 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -58,7 +58,7 @@
     }
 
     public void testTaskIdsPersistence() {
-        SparseBooleanArray taskIdsOnFile = mTaskPersister.loadPersistedTaskIdsForUser(testUserId);
+        SparseBooleanArray taskIdsOnFile = new SparseBooleanArray();
         for (int i = 0; i < 100; i++) {
             taskIdsOnFile.put(getRandomTaskIdForUser(testUserId), true);
         }
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
new file mode 100644
index 0000000..27ef9d7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -0,0 +1,915 @@
+/*
+ * 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.backup;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.backup.BackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.app.backup.IFullBackupRestoreObserver;
+import android.app.backup.ISelectBackupTransportCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TrampolineTest {
+    private static final String PACKAGE_NAME = "some.package.name";
+    private static final String TRANSPORT_NAME = "some.transport.name";
+    private static final String CURRENT_PASSWORD = "current_password";
+    private static final String NEW_PASSWORD = "new_password";
+    private static final String ENCRYPTION_PASSWORD = "encryption_password";
+    private static final String DATA_MANAGEMENT_LABEL = "data_management_label";
+    private static final String DESTINATION_STRING = "destination_string";
+    private static final String[] PACKAGE_NAMES =
+            new String[]{"some.package.name._1", "some.package.name._2"};
+    private static final String[] TRANSPORTS =
+            new String[]{"some.transport.name._1", "some.transport.name._2"};
+    private static final ComponentName TRANSPORT_COMPONENT_NAME = new ComponentName("package",
+            "class");
+    private static final ComponentName[] TRANSPORT_COMPONENTS = new ComponentName[]{
+            new ComponentName("package1", "class1"),
+            new ComponentName("package2", "class2")
+    };
+    private final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
+
+    @Mock private BackupManagerService mBackupManagerServiceMock;
+    @Mock private RefactoredBackupManagerService mRefactoredBackupManagerServiceMock;
+    @Mock private Context mContextMock;
+    @Mock private File mSuppressFileMock;
+    @Mock private File mSuppressFileParentMock;
+    @Mock private IBinder mAgentMock;
+    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
+    @Mock private IBackupObserver mBackupObserverMock;
+    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+    @Mock private PrintWriter mPrintWriterMock;
+
+    private FileDescriptor mFileDescriptorStub = new FileDescriptor();
+
+    private TrampolineTestable mTrampoline;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        TrampolineTestable.sRefactoredBackupManagerServiceMock =
+                mRefactoredBackupManagerServiceMock;
+        TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
+        TrampolineTestable.sSuppressFile = mSuppressFileMock;
+        TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
+        TrampolineTestable.sRefactoredServiceEnabled = false;
+        TrampolineTestable.sBackupDisabled = false;
+
+        when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
+
+        mTrampoline = new TrampolineTestable(mContextMock);
+    }
+
+    @Test
+    public void constructor_createsSuppressFileDirectory() {
+        verify(mSuppressFileParentMock).mkdirs();
+    }
+
+    @Test
+    public void initialize_forUserSystem_successfullyInitialized() {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    // The BackupManagerService can only be initialized by USER_SYSTEM, so we check that if any
+    // other user trying to initialize it leaves it non-active.
+    @Test
+    public void initialize_forNonUserSystem_nonInitialized() {
+        mTrampoline.initialize(NON_USER_SYSTEM);
+
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
+    }
+
+    @Test
+    public void initialize_globallyDisabled_nonInitialized() {
+        TrampolineTestable.sBackupDisabled = true;
+
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+        trampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    // Verify that BackupManagerService is not initialized if suppress file exists.
+    @Test
+    public void initialize_suppressFileExists_nonInitialized() {
+        when(mSuppressFileMock.exists()).thenReturn(true);
+
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+        trampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void isBackupServiceActive_calledBeforeInitialize_returnsFalse() {
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void createService_refactoredServiceEnabled() {
+        TrampolineTestable.sRefactoredServiceEnabled = true;
+
+        assertEquals(mRefactoredBackupManagerServiceMock, mTrampoline.createService());
+    }
+
+    @Test
+    public void createService_refactoredServiceDisabled() {
+        TrampolineTestable.sRefactoredServiceEnabled = false;
+
+        assertEquals(mBackupManagerServiceMock, mTrampoline.createService());
+    }
+
+    @Test
+    public void setBackupServiceActive_callerSystemUid_serviceCreated() {
+        TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_callerRootUid_serviceCreated() {
+        TrampolineTestable.sCallingUid = Process.ROOT_UID;
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_callerNonRootNonSystem_securityExceptionThrown() {
+        TrampolineTestable.sCallingUid = Process.FIRST_APPLICATION_UID;
+
+        try {
+            mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+            fail();
+        } catch (SecurityException expected) {
+        }
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_backupDisabled_ignored() {
+        TrampolineTestable.sBackupDisabled = true;
+        TrampolineTestable trampoline = new TrampolineTestable(mContextMock);
+
+        trampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_nonUserSystem_ignored() {
+        mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
+
+        assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM));
+    }
+
+    @Test
+    public void setBackupServiceActive_alreadyActive_ignored() {
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        assertEquals(1, mTrampoline.getCreateServiceCallsCount());
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        assertEquals(1, mTrampoline.getCreateServiceCallsCount());
+    }
+
+    @Test
+    public void setBackupServiceActive_makeActive_serviceCreatedAndSuppressFileDeleted() {
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).delete();
+    }
+
+    @Test
+    public void setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated()
+            throws IOException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).createNewFile();
+    }
+
+    @Test
+    public void
+    setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated_ioExceptionHandled()
+            throws IOException {
+        when(mSuppressFileMock.createNewFile()).thenThrow(new IOException());
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM));
+        verify(mSuppressFileMock).createNewFile();
+    }
+
+    @Test
+    public void setBackupServiceActive_makeNonActive_alreadyNonActive_ignored() throws IOException {
+        reset(mSuppressFileMock);
+
+        mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false);
+
+        verifyNoMoreInteractions(mSuppressFileMock);
+    }
+
+    @Test
+    public void dataChanged_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.dataChanged(PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dataChanged_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.dataChanged(PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).dataChanged(PACKAGE_NAME);
+    }
+
+    @Test
+    public void clearBackupData_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void clearBackupData_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).clearBackupData(TRANSPORT_NAME, PACKAGE_NAME);
+    }
+
+    @Test
+    public void agentConnected_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.agentConnected(PACKAGE_NAME, mAgentMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void agentConnected_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.agentConnected(PACKAGE_NAME, mAgentMock);
+        verify(mBackupManagerServiceMock).agentConnected(PACKAGE_NAME, mAgentMock);
+    }
+
+    @Test
+    public void agentDisconnected_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.agentDisconnected(PACKAGE_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void agentDisconnected_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.agentDisconnected(PACKAGE_NAME);
+        verify(mBackupManagerServiceMock).agentDisconnected(PACKAGE_NAME);
+    }
+
+    @Test
+    public void restoreAtInstall_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.restoreAtInstall(PACKAGE_NAME, 123);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void restoreAtInstall_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.restoreAtInstall(PACKAGE_NAME, 123);
+        verify(mBackupManagerServiceMock).restoreAtInstall(PACKAGE_NAME, 123);
+    }
+
+    @Test
+    public void setBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupEnabled(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupEnabled_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupEnabled(true);
+        verify(mBackupManagerServiceMock).setBackupEnabled(true);
+    }
+
+    @Test
+    public void setAutoRestore_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setAutoRestore(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setAutoRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setAutoRestore(true);
+        verify(mBackupManagerServiceMock).setAutoRestore(true);
+    }
+
+    @Test
+    public void setBackupProvisioned_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupProvisioned(true);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupProvisioned_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupProvisioned(true);
+        verify(mBackupManagerServiceMock).setBackupProvisioned(true);
+    }
+
+    @Test
+    public void isBackupEnabled_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.isBackupEnabled());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void isBackupEnabled_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.isBackupEnabled();
+        verify(mBackupManagerServiceMock).isBackupEnabled();
+    }
+
+    @Test
+    public void setBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void setBackupPassword_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+        verify(mBackupManagerServiceMock).setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD);
+    }
+
+    @Test
+    public void hasBackupPassword_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.hasBackupPassword());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void hasBackupPassword_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.hasBackupPassword();
+        verify(mBackupManagerServiceMock).hasBackupPassword();
+    }
+
+    @Test
+    public void backupNow_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.backupNow();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void backupNow_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.backupNow();
+        verify(mBackupManagerServiceMock).backupNow();
+    }
+
+    @Test
+    public void adbBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.adbBackup(mParcelFileDescriptorMock, true, true, true, true, true, true, true,
+                true,
+                PACKAGE_NAMES);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void adbBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.adbBackup(mParcelFileDescriptorMock, true, true, true, true, true, true, true,
+                true,
+                PACKAGE_NAMES);
+        verify(mBackupManagerServiceMock).adbBackup(mParcelFileDescriptorMock, true, true, true,
+                true,
+                true, true, true, true, PACKAGE_NAMES);
+    }
+
+    @Test
+    public void fullTransportBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.fullTransportBackup(PACKAGE_NAMES);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void fullTransportBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.fullTransportBackup(PACKAGE_NAMES);
+        verify(mBackupManagerServiceMock).fullTransportBackup(PACKAGE_NAMES);
+    }
+
+    @Test
+    public void adbRestore_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.adbRestore(mParcelFileDescriptorMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void adbRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.adbRestore(mParcelFileDescriptorMock);
+        verify(mBackupManagerServiceMock).adbRestore(mParcelFileDescriptorMock);
+    }
+
+    @Test
+    public void acknowledgeFullBackupOrRestore_calledBeforeInitialize_ignored()
+            throws RemoteException {
+        mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD,
+                mFullBackupRestoreObserverMock);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void acknowledgeFullBackupOrRestore_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD,
+                mFullBackupRestoreObserverMock);
+        verify(mBackupManagerServiceMock).acknowledgeAdbBackupOrRestore(123, true, CURRENT_PASSWORD,
+                ENCRYPTION_PASSWORD, mFullBackupRestoreObserverMock);
+    }
+
+    @Test
+    public void getCurrentTransport_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getCurrentTransport());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getCurrentTransport_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getCurrentTransport()).thenReturn(TRANSPORT_NAME);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        assertEquals(TRANSPORT_NAME, mTrampoline.getCurrentTransport());
+        verify(mBackupManagerServiceMock).getCurrentTransport();
+    }
+
+    @Test
+    public void listAllTransports_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.listAllTransports());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void listAllTransports_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.listAllTransports()).thenReturn(TRANSPORTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORTS, mTrampoline.listAllTransports());
+        verify(mBackupManagerServiceMock).listAllTransports();
+    }
+
+    @Test
+    public void listAllTransportComponents_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.listAllTransportComponents());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void listAllTransportComponents_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.listAllTransportComponents()).thenReturn(
+                TRANSPORT_COMPONENTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORT_COMPONENTS, mTrampoline.listAllTransportComponents());
+        verify(mBackupManagerServiceMock).listAllTransportComponents();
+    }
+
+    @Test
+    public void getTransportWhitelist_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getTransportWhitelist());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getTransportWhitelist_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getTransportWhitelist()).thenReturn(TRANSPORTS);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(TRANSPORTS, mTrampoline.getTransportWhitelist());
+        verify(mBackupManagerServiceMock).getTransportWhitelist();
+    }
+
+    @Test
+    public void selectBackupTransport_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.selectBackupTransport(TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void selectBackupTransport_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.selectBackupTransport(TRANSPORT_NAME);
+        verify(mBackupManagerServiceMock).selectBackupTransport(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored() throws Exception {
+        LinkedBlockingQueue<Integer> q = new LinkedBlockingQueue();
+        mTrampoline.selectBackupTransportAsync(
+                TRANSPORT_COMPONENT_NAME,
+                new ISelectBackupTransportCallback() {
+                    @Override
+                    public void onSuccess(String transportName) throws RemoteException {
+
+                    }
+
+                    @Override
+                    public void onFailure(int reason) throws RemoteException {
+                        q.offer(reason);
+                    }
+
+                    @Override
+                    public IBinder asBinder() {
+                        return null;
+                    }
+                });
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        Integer errorCode = q.poll(5, TimeUnit.SECONDS);
+        assertNotNull(errorCode);
+        assertEquals(BackupManager.ERROR_BACKUP_NOT_ALLOWED, (int) errorCode);
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored_nullListener()
+            throws Exception {
+        mTrampoline.selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME, null);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        // No crash.
+    }
+
+    @Test
+    public void selectBackupTransportAsync_calledBeforeInitialize_ignored_listenerThrowException()
+            throws Exception {
+        mTrampoline.selectBackupTransportAsync(
+                TRANSPORT_COMPONENT_NAME,
+                new ISelectBackupTransportCallback() {
+                    @Override
+                    public void onSuccess(String transportName) throws RemoteException {
+
+                    }
+
+                    @Override
+                    public void onFailure(int reason) throws RemoteException {
+                        throw new RemoteException("Crash");
+                    }
+
+                    @Override
+                    public IBinder asBinder() {
+                        return null;
+                    }
+                });
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+        // No crash.
+    }
+
+    @Test
+    public void selectBackupTransportAsync_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME, null);
+        verify(mBackupManagerServiceMock).selectBackupTransportAsync(TRANSPORT_COMPONENT_NAME,
+                null);
+    }
+
+    @Test
+    public void getConfigurationIntent_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.getConfigurationIntent(TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getConfigurationIntent_forwarded() throws RemoteException {
+        Intent configurationIntentStub = new Intent();
+        when(mBackupManagerServiceMock.getConfigurationIntent(TRANSPORT_NAME)).thenReturn(
+                configurationIntentStub);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(configurationIntentStub, mTrampoline.getConfigurationIntent(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getConfigurationIntent(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDestinationString_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDestinationString(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDestinationString_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getDestinationString(TRANSPORT_NAME)).thenReturn(
+                DESTINATION_STRING);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(DESTINATION_STRING, mTrampoline.getDestinationString(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDestinationString(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDataManagementIntent_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDataManagementIntent(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDataManagementIntent_forwarded() throws RemoteException {
+        Intent dataManagementIntent = new Intent();
+        when(mBackupManagerServiceMock.getDataManagementIntent(TRANSPORT_NAME)).thenReturn(
+                dataManagementIntent);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(dataManagementIntent, mTrampoline.getDataManagementIntent(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDataManagementIntent(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void getDataManagementLabel_calledBeforeInitialize_ignored() throws RemoteException {
+        assertNull(mTrampoline.getDataManagementLabel(TRANSPORT_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getDataManagementLabel_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getDataManagementLabel(TRANSPORT_NAME)).thenReturn(
+                DATA_MANAGEMENT_LABEL);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(DATA_MANAGEMENT_LABEL, mTrampoline.getDataManagementLabel(TRANSPORT_NAME));
+        verify(mBackupManagerServiceMock).getDataManagementLabel(TRANSPORT_NAME);
+    }
+
+    @Test
+    public void beginRestoreSession_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void beginRestoreSession_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+        verify(mBackupManagerServiceMock).beginRestoreSession(PACKAGE_NAME, TRANSPORT_NAME);
+    }
+
+    @Test
+    public void opComplete_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.opComplete(1, 2);
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void opComplete_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.opComplete(1, 2);
+        verify(mBackupManagerServiceMock).opComplete(1, 2);
+    }
+
+    @Test
+    public void getAvailableRestoreToken_calledBeforeInitialize_ignored() throws RemoteException {
+        assertEquals(0, mTrampoline.getAvailableRestoreToken(PACKAGE_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void getAvailableRestoreToken_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.getAvailableRestoreToken(PACKAGE_NAME)).thenReturn(123L);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(123, mTrampoline.getAvailableRestoreToken(PACKAGE_NAME));
+        verify(mBackupManagerServiceMock).getAvailableRestoreToken(PACKAGE_NAME);
+    }
+
+    @Test
+    public void isAppEligibleForBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        assertFalse(mTrampoline.isAppEligibleForBackup(PACKAGE_NAME));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void isAppEligibleForBackup_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.isAppEligibleForBackup(PACKAGE_NAME)).thenReturn(true);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.isAppEligibleForBackup(PACKAGE_NAME));
+        verify(mBackupManagerServiceMock).isAppEligibleForBackup(PACKAGE_NAME);
+    }
+
+    @Test
+    public void requestBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        assertEquals(BackupManager.ERROR_BACKUP_NOT_ALLOWED, mTrampoline.requestBackup(
+                PACKAGE_NAMES, mBackupObserverMock, mBackupManagerMonitorMock, 123));
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void requestBackup_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123)).thenReturn(456);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123));
+        verify(mBackupManagerServiceMock).requestBackup(PACKAGE_NAMES, mBackupObserverMock,
+                mBackupManagerMonitorMock, 123);
+    }
+
+    @Test
+    public void cancelBackups_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.cancelBackups();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void cancelBackups_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.cancelBackups();
+        verify(mBackupManagerServiceMock).cancelBackups();
+    }
+
+    @Test
+    public void beginFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.beginFullBackup(new FullBackupJob());
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void beginFullBackup_forwarded() throws RemoteException {
+        FullBackupJob fullBackupJob = new FullBackupJob();
+        when(mBackupManagerServiceMock.beginFullBackup(fullBackupJob)).thenReturn(true);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        assertTrue(mTrampoline.beginFullBackup(fullBackupJob));
+        verify(mBackupManagerServiceMock).beginFullBackup(fullBackupJob);
+    }
+
+    @Test
+    public void endFullBackup_calledBeforeInitialize_ignored() throws RemoteException {
+        mTrampoline.endFullBackup();
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void endFullBackup_forwarded() throws RemoteException {
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+        mTrampoline.endFullBackup();
+        verify(mBackupManagerServiceMock).endFullBackup();
+    }
+
+    @Test
+    public void dump_callerDoesNotHavePermission_ignored() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_DENIED);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);
+
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dump_calledBeforeInitialize_ignored() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);
+
+        verifyNoMoreInteractions(mBackupManagerServiceMock);
+    }
+
+    @Test
+    public void dump_callerHasPermission_forwarded() throws RemoteException {
+        when(mContextMock.checkCallingOrSelfPermission(
+                android.Manifest.permission.DUMP)).thenReturn(
+                PackageManager.PERMISSION_GRANTED);
+
+        mTrampoline.initialize(UserHandle.USER_SYSTEM);
+
+        mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, null);
+
+        verify(mBackupManagerServiceMock).dump(mFileDescriptorStub, mPrintWriterMock, null);
+    }
+
+    private static class TrampolineTestable extends Trampoline {
+        static boolean sBackupDisabled = false;
+        static boolean sRefactoredServiceEnabled = false;
+        static File sSuppressFile = null;
+        static int sCallingUid = -1;
+        static BackupManagerService sBackupManagerServiceMock = null;
+        static RefactoredBackupManagerService sRefactoredBackupManagerServiceMock = null;
+        private int mCreateServiceCallsCount = 0;
+
+        TrampolineTestable(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createService() {
+            mCreateServiceCallsCount++;
+            return super.createService();
+        }
+
+        @Override
+        public boolean isBackupDisabled() {
+            return sBackupDisabled;
+        }
+
+        @Override
+        public File getSuppressFile() {
+            return sSuppressFile;
+        }
+
+        @Override
+        protected int binderGetCallingUid() {
+            return sCallingUid;
+        }
+
+        @Override
+        protected boolean isRefactoredServiceEnabled() {
+            return sRefactoredServiceEnabled;
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createRefactoredBackupManagerService() {
+            return sRefactoredBackupManagerServiceMock;
+        }
+
+        @Override
+        protected BackupManagerServiceInterface createBackupManagerService() {
+            return sBackupManagerServiceMock;
+        }
+
+        int getCreateServiceCallsCount() {
+            return mCreateServiceCallsCount;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
new file mode 100644
index 0000000..05f4c13
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.backup.restore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class PerformAdbRestoreTaskTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void parseBackupFileAndReturnTarStream_backupNotEncrypted_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordProvided_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordNotProvided_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndIncorrectPassword_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "1234");
+
+        assertThat(tarInputStream).isNull();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
new file mode 100644
index 0000000..45b107d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
@@ -0,0 +1,1008 @@
+package com.android.server.backup.testutils;
+
+import android.app.PackageInstallObserver;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ChangedPackages;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+
+import java.util.List;
+
+/**
+ * Stub for PackageManager to use in tests.
+ */
+public class PackageManagerStub extends PackageManager {
+    public static PackageInfo sPackageInfo;
+
+    @Override
+    public PackageInfo getPackageInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        if (sPackageInfo == null) {
+            throw new NameNotFoundException();
+        }
+
+        return sPackageInfo;
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public Intent getLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName) throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName, int flags)
+            throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int getPackageUid(String packageName, int flags)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return false;
+    }
+
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getActivityInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ServiceInfo getServiceInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo getProviderInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public int checkPermission(String permName, String pkgName) {
+        return 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
+        return false;
+    }
+
+    @Override
+    public String getPermissionControllerPackageName() {
+        return null;
+    }
+
+    @Override
+    public boolean addPermission(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public boolean addPermissionAsync(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public void removePermission(String name) {
+
+    }
+
+    @Override
+    public void grantRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public void revokeRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
+            int flagValues, UserHandle user) {
+
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        return false;
+    }
+
+    @Override
+    public int checkSignatures(String pkg1, String pkg2) {
+        return 0;
+    }
+
+    @Override
+    public int checkSignatures(int uid1, int uid2) {
+        return 0;
+    }
+
+    @Override
+    public String[] getPackagesForUid(int uid) {
+        return new String[0];
+    }
+
+    @Override
+    public String getNameForUid(int uid) {
+        return null;
+    }
+
+    @Override
+    public int getUidForSharedUser(String sharedUserName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplications(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<InstantAppInfo> getInstantApps() {
+        return null;
+    }
+
+    @Override
+    public Drawable getInstantAppIcon(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isInstantApp() {
+        return false;
+    }
+
+    @Override
+    public boolean isInstantApp(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxBytes() {
+        return 0;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxSize() {
+        return 0;
+    }
+
+    @Override
+    public byte[] getInstantAppCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public void clearInstantAppCookie() {
+
+    }
+
+    @Override
+    public void updateInstantAppCookie(byte[] cookie) {
+
+    }
+
+    @Override
+    public boolean setInstantAppCookie(byte[] cookie) {
+        return false;
+    }
+
+    @Override
+    public String[] getSystemSharedLibraryNames() {
+        return new String[0];
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibraries(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public String getServicesSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public String getSharedSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public ChangedPackages getChangedPackages(int sequenceNumber) {
+        return null;
+    }
+
+    @Override
+    public FeatureInfo[] getSystemAvailableFeatures() {
+        return new FeatureInfo[0];
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name) {
+        return false;
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
+        return false;
+    }
+
+    @Override
+    public ResolveInfo resolveActivity(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
+            Intent[] specifics,
+            Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveService(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProvider(String name, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
+        return null;
+    }
+
+    @Override
+    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
+        return null;
+    }
+
+    @Override
+    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getDefaultActivityIcon() {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
+            Rect badgeLocation, int badgeDensity) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getApplicationLabel(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForActivity(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(ApplicationInfo app)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(String appPackageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public int installExistingPackage(String packageName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackage(String packageName, int installReason)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public void verifyPendingInstall(int id, int verificationCode) {
+
+    }
+
+    @Override
+    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+            long millisecondsToDelay) {
+
+    }
+
+    @Override
+    public void verifyIntentFilter(int verificationId, int verificationCode,
+            List<String> failedDomains) {
+
+    }
+
+    @Override
+    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
+        return 0;
+    }
+
+    @Override
+    public boolean updateIntentVerificationStatusAsUser(String packageName, int status,
+            int userId) {
+        return false;
+    }
+
+    @Override
+    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
+        return null;
+    }
+
+    @Override
+    public List<IntentFilter> getAllIntentFilters(String packageName) {
+        return null;
+    }
+
+    @Override
+    public String getDefaultBrowserPackageNameAsUser(int userId) {
+        return null;
+    }
+
+    @Override
+    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+
+    }
+
+    @Override
+    public void setUpdateAvailable(String packageName, boolean updateAvaialble) {
+
+    }
+
+    @Override
+    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
+
+    }
+
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
+            int flags,
+            int userId) {
+
+    }
+
+    @Override
+    public String getInstallerPackageName(String packageName) {
+        return null;
+    }
+
+    @Override
+    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
+
+    }
+
+    @Override
+    public void getPackageSizeInfoAsUser(String packageName, int userId,
+            IPackageStatsObserver observer) {
+
+    }
+
+    @Override
+    public void addPackageToPreferred(String packageName) {
+
+    }
+
+    @Override
+    public void removePackageFromPreferred(String packageName) {
+
+    }
+
+    @Override
+    public List<PackageInfo> getPreferredPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void clearPackagePreferredActivities(String packageName) {
+
+    }
+
+    @Override
+    public int getPreferredActivities(List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
+        return 0;
+    }
+
+    @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        return null;
+    }
+
+    @Override
+    public void setComponentEnabledSetting(ComponentName componentName, int newState,
+            int flags) {
+
+    }
+
+    @Override
+    public int getComponentEnabledSetting(ComponentName componentName) {
+        return 0;
+    }
+
+    @Override
+    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+
+    }
+
+    @Override
+    public int getApplicationEnabledSetting(String packageName) {
+        return 0;
+    }
+
+    @Override
+    public void flushPackageRestrictionsAsUser(int userId) {
+
+    }
+
+    @Override
+    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean getApplicationHiddenSettingAsUser(String packageName,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean isSafeMode() {
+        return false;
+    }
+
+    @Override
+    public void addOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public void removeOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public KeySet getKeySetByAlias(String packageName, String alias) {
+        return null;
+    }
+
+    @Override
+    public KeySet getSigningKeySet(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isSignedBy(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public boolean isSignedByExactly(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
+        return new String[0];
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setApplicationCategoryHint(String packageName, int categoryHint) {
+
+    }
+
+    @Override
+    public int getMoveStatus(int moveId) {
+        return 0;
+    }
+
+    @Override
+    public void registerMoveCallback(MoveCallback callback, Handler handler) {
+
+    }
+
+    @Override
+    public void unregisterMoveCallback(MoveCallback callback) {
+
+    }
+
+    @Override
+    public int movePackage(String packageName, VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public int movePrimaryStorage(VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPrimaryStorageCurrentVolume() {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
+        return null;
+    }
+
+    @Override
+    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
+        return null;
+    }
+
+    @Override
+    public boolean isUpgrade() {
+        return false;
+    }
+
+    @Override
+    public PackageInstaller getPackageInstaller() {
+        return null;
+    }
+
+    @Override
+    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
+            int targetUserId,
+            int flags) {
+
+    }
+
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+
+    }
+
+    @Override
+    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public boolean isPackageAvailable(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstallReason(String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public boolean canRequestPackageInstalls() {
+        return false;
+    }
+
+    @Override
+    public ComponentName getInstantAppResolverSettingsComponent() {
+        return null;
+    }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return null;
+    }
+
+    @Override
+    public String getInstantAppAndroidId(String packageName, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public void registerDexModule(String dexModulePath,
+            DexModuleRegisterCallback callback) {
+
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
new file mode 100644
index 0000000..650681e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -0,0 +1,460 @@
+/*
+ * 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.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.backup.RefactoredBackupManagerService;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppBackupUtilsTest {
+    private static final String CUSTOM_BACKUP_AGENT_NAME = "custom.backup.agent";
+    private static final String TEST_PACKAGE_NAME = "test_package";
+
+    private final Random mRandom = new Random(1000000009);
+
+    @Test
+    public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags = 0;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = null;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_sharedStorageBackupPackage_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemAppWithCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = null;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgent_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsStopped_returnsTrue() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
+
+        boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
+
+        assertThat(isStopped).isTrue();
+    }
+
+    @Test
+    public void appIsStopped_returnsFalse() throws Exception {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags = ~ApplicationInfo.FLAG_STOPPED;
+
+        boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
+
+        assertThat(isStopped).isFalse();
+    }
+
+    @Test
+    public void appGetsFullBackup_noCustomBackupAgent_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = null;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appGetsFullBackup_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_noCustomBackupAgent_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = null;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIsKeyValueOnly_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+
+        boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], null);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_systemApplication_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_allowsUnsignedApps_bothSignaturesNull_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_allowsUnsignedApps_bothSignaturesEmpty_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_allowsUnsignedApps_storedSignatureNullTargetSignatureEmpty_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_allowsUnsignedApps_storedSignatureEmptyTargetSignatureNull_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+    signaturesMatch_disallowsAppsUnsignedOnOnlyOneDevice_storedSignatureIsNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{generateRandomSignature()};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void
+    signaturesMatch_disallowsAppsUnsignedOnOnlyOneDevice_targetSignatureIsNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[]{generateRandomSignature()},
+                packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_signaturesMatch_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        Signature signature3Copy = new Signature(signature3.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+        assertThat(signature3Copy).isEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature3Copy, signature1Copy, signature2Copy}, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature2Copy, signature1Copy}, packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1Copy, signature2Copy};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1, signature2, signature3}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_emptyStoredSignatures_returnsTrue() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_emptyTargetSignatures_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1, signature2, signature3}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception {
+        Signature signature1 = generateRandomSignature();
+        Signature signature2 = generateRandomSignature();
+        Signature signature3 = generateRandomSignature();
+        Signature signature4 = generateRandomSignature();
+        assertThat(signature1).isNotEqualTo(signature2);
+        assertThat(signature2).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature3);
+        assertThat(signature1).isNotEqualTo(signature4);
+        assertThat(signature2).isNotEqualTo(signature4);
+        assertThat(signature3).isNotEqualTo(signature4);
+
+        Signature signature1Copy = new Signature(signature1.toByteArray());
+        Signature signature2Copy = new Signature(signature2.toByteArray());
+        assertThat(signature1Copy).isEqualTo(signature1);
+        assertThat(signature2Copy).isEqualTo(signature2);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signatures = new Signature[]{signature1, signature2, signature3};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = AppBackupUtils.signaturesMatch(
+                new Signature[]{signature1Copy, signature2Copy, signature4}, packageInfo);
+
+        assertThat(result).isFalse();
+    }
+
+    private Signature generateRandomSignature() {
+        byte[] signatureBytes = new byte[256];
+        mRandom.nextBytes(signatureBytes);
+        return new Signature(signatureBytes);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
new file mode 100644
index 0000000..87c587a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.content.pm.PackageInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupManagerMonitorUtilsTest {
+    @Mock private IBackupManagerMonitor mMonitorMock;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void monitorEvent_monitorIsNull_returnsNull() throws Exception {
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(null, 0, null, 0,
+                null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void monitorEvent_monitorOnEventThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mMonitorMock).onEvent(any(Bundle.class));
+
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 0, null,
+                0, null);
+
+        verify(mMonitorMock).onEvent(any(Bundle.class));
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void monitorEvent_packageAndExtrasAreNull_fillsBundleCorrectly() throws Exception {
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 1, null,
+                2, null);
+
+        assertThat(result).isEqualTo(mMonitorMock);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mMonitorMock).onEvent(bundleCaptor.capture());
+        Bundle eventBundle = bundleCaptor.getValue();
+        assertThat(eventBundle.size()).isEqualTo(2);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
+    }
+
+    @Test
+    public void monitorEvent_packageAndExtrasAreNotNull_fillsBundleCorrectly() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test.package";
+        packageInfo.versionCode = 3;
+        Bundle extras = new Bundle();
+        extras.putInt("key1", 4);
+        extras.putString("key2", "value2");
+
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 1,
+                packageInfo, 2, extras);
+
+        assertThat(result).isEqualTo(mMonitorMock);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mMonitorMock).onEvent(bundleCaptor.capture());
+        Bundle eventBundle = bundleCaptor.getValue();
+        assertThat(eventBundle.size()).isEqualTo(6);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
+        assertThat(eventBundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME)).isEqualTo("test.package");
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_PACKAGE_VERSION)).isEqualTo(3);
+        assertThat(eventBundle.getInt("key1")).isEqualTo(4);
+        assertThat(eventBundle.getString("key2")).isEqualTo("value2");
+    }
+
+    @Test
+    public void putMonitoringExtraString_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", "value");
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getString("key")).isEqualTo("value");
+    }
+
+    @Test
+    public void putMonitoringExtraString_bundleDoesNotExist_fillsBundleCorrectly()
+            throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", "value");
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getString("key")).isEqualTo("value");
+    }
+
+
+    @Test
+    public void putMonitoringExtraLong_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", 123);
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getLong("key")).isEqualTo(123);
+    }
+
+    @Test
+    public void putMonitoringExtraLong_bundleDoesNotExist_fillsBundleCorrectly() throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", 123);
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getLong("key")).isEqualTo(123);
+    }
+
+    @Test
+    public void putMonitoringExtraBoolean_bundleExists_fillsBundleCorrectly() throws Exception {
+        Bundle bundle = new Bundle();
+
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(bundle, "key", true);
+
+        assertThat(result).isEqualTo(bundle);
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getBoolean("key")).isTrue();
+    }
+
+    @Test
+    public void putMonitoringExtraBoolean_bundleDoesNotExist_fillsBundleCorrectly()
+            throws Exception {
+        Bundle result = BackupManagerMonitorUtils.putMonitoringExtra(null, "key", true);
+
+        assertThat(result).isNotNull();
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.getBoolean("key")).isTrue();
+    }
+
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java
new file mode 100644
index 0000000..ebe6133
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupObserverUtilsTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.backup.utils;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.BackupProgress;
+import android.app.backup.IBackupObserver;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupObserverUtilsTest {
+    private static final String PACKAGE_NAME = "some.package";
+
+    @Mock
+    private IBackupObserver mBackupObserverMock;
+    private final BackupProgress mBackupProgress = new BackupProgress(0, 0);
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void sendBackupOnUpdate_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupOnUpdate(null, PACKAGE_NAME, mBackupProgress);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupOnUpdate_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupOnUpdate(mBackupObserverMock, PACKAGE_NAME, mBackupProgress);
+
+        verify(mBackupObserverMock).onUpdate(PACKAGE_NAME, mBackupProgress);
+    }
+
+    @Test
+    public void sendBackupOnUpdate_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onUpdate(PACKAGE_NAME,
+                mBackupProgress);
+
+        BackupObserverUtils.sendBackupOnUpdate(mBackupObserverMock, PACKAGE_NAME, mBackupProgress);
+
+        verify(mBackupObserverMock).onUpdate(PACKAGE_NAME, mBackupProgress);
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupOnPackageResult(null, PACKAGE_NAME, 1);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupOnPackageResult(mBackupObserverMock, PACKAGE_NAME, 1);
+
+        verify(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+    }
+
+    @Test
+    public void sendBackupOnPackageResult_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+
+        BackupObserverUtils.sendBackupOnPackageResult(mBackupObserverMock, PACKAGE_NAME, 1);
+
+        verify(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+    }
+
+    @Test
+    public void sendBackupFinished_observerIsNull_doesNotThrow() throws Exception {
+        BackupObserverUtils.sendBackupFinished(null, 1);
+
+        // Should not throw.
+    }
+
+    @Test
+    public void sendBackupFinished_callsObserver() throws Exception {
+        BackupObserverUtils.sendBackupFinished(mBackupObserverMock, 1);
+
+        verify(mBackupObserverMock).backupFinished(1);
+    }
+
+    @Test
+    public void sendBackupFinished_handlesRemoteException() throws Exception {
+        doThrow(new RemoteException()).when(mBackupObserverMock).onResult(PACKAGE_NAME, 1);
+
+        BackupObserverUtils.sendBackupFinished(mBackupObserverMock, 1);
+
+        verify(mBackupObserverMock).backupFinished(1);
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java
new file mode 100644
index 0000000..2f56598
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupRestoreObserverUtilsTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IFullBackupRestoreObserver;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullBackupRestoreObserverUtilsTest {
+    private static final String PACKAGE_NAME = "some.package";
+    @Mock
+    private IFullBackupRestoreObserver mFullBackupRestoreObserverMock;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void sendStartRestore_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendStartRestore_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onStartRestore();
+    }
+
+    @Test
+    public void sendStartRestore_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onStartRestore();
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendStartRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onStartRestore();
+    }
+
+    @Test
+    public void sendOnRestorePackage_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                null, PACKAGE_NAME);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendOnRestorePackage_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                mFullBackupRestoreObserverMock, PACKAGE_NAME);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onRestorePackage(PACKAGE_NAME);
+    }
+
+    @Test
+    public void sendOnRestorePackage_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onRestorePackage(
+                PACKAGE_NAME);
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendOnRestorePackage(
+                mFullBackupRestoreObserverMock, PACKAGE_NAME);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onRestorePackage(PACKAGE_NAME);
+    }
+
+    @Test
+    public void sendEndRestore_observerIsNull_returnsNull() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(null);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void sendEndRestore_callsObserver() throws Exception {
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isEqualTo(mFullBackupRestoreObserverMock);
+        verify(mFullBackupRestoreObserverMock).onEndRestore();
+    }
+
+    @Test
+    public void sendEndRestore_observerThrows_returnsNull() throws Exception {
+        doThrow(new RemoteException()).when(mFullBackupRestoreObserverMock).onEndRestore();
+
+        IFullBackupRestoreObserver result = FullBackupRestoreObserverUtils.sendEndRestore(
+                mFullBackupRestoreObserverMock);
+
+        assertThat(result).isNull();
+        verify(mFullBackupRestoreObserverMock).onEndRestore();
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
new file mode 100644
index 0000000..4e3de64
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Random;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullBackupUtilsTest {
+    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock private OutputStream mOutputStreamMock;
+    private File mTemporaryFile;
+    private ByteArrayOutputStream mByteArrayOutputStream;
+    private ParcelFileDescriptor mTemporaryFileDescriptor;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mTemporaryFile = File.createTempFile("backup-data", ".txt");
+        mByteArrayOutputStream = new ByteArrayOutputStream();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTemporaryFileDescriptor != null) {
+            mTemporaryFileDescriptor.close();
+        }
+        if (mTemporaryFile != null) {
+            mTemporaryFile.delete();
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_inPipeIsNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(null, mOutputStreamMock);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_outNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mParcelFileDescriptorMock, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_emptyInput_throwsEOFException() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_incompleteChunkSizeInput_throwsEOFException()
+            throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeByte(100);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_validEmptyInput_doesNotWriteAnything() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor, mOutputStreamMock);
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_notEnoughData_throwsEOFException() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length + 1);
+        outputStream.write(data);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mByteArrayOutputStream);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneSmallChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneLargeChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(128000);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoSmallChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(200);
+        int chunk1Length = 97;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoLargeChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(256000);
+        int chunk1Length = 127313;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    private static byte[] createFakeDataArray(int length) {
+        byte[] data = new byte[length];
+        new Random(3742).nextBytes(data);
+        return data;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
new file mode 100644
index 0000000..6b25d12
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -0,0 +1,533 @@
+/*
+ * 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.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Bundle;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.RefactoredBackupManagerService;
+import com.android.server.backup.restore.PerformAdbRestoreTask;
+import com.android.server.backup.restore.RestorePolicy;
+import com.android.server.backup.testutils.PackageManagerStub;
+
+import com.google.common.hash.Hashing;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TarBackupReaderTest {
+    private static final String TELEPHONY_PACKAGE_NAME = "com.android.providers.telephony";
+    private static final String TELEPHONY_PACKAGE_SIGNATURE_SHA256 =
+            "301aa3cb081134501c45f1422abc66c24224fd5ded5fdc8f17e697176fd866aa";
+    private static final int TELEPHONY_PACKAGE_VERSION = 25;
+    private static final String TEST_PACKAGE_NAME = "com.android.backup.testing";
+    private static final Signature FAKE_SIGNATURE_1 = new Signature("1234");
+    private static final Signature FAKE_SIGNATURE_2 = new Signature("5678");
+
+    @Mock private BytesReadListener mBytesReadListenerMock;
+    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+
+    private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void readTarHeaders_backupEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readTarHeaders_backupNotEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readTarHeaders_backupNotEncrypted_correctlyReadsPaxHeader() throws Exception {
+        // Files with long names (>100 chars) will force backup to add PAX header.
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_file_with_long_name);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        // Read manifest file.
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                fileMetadata);
+        RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+
+        assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
+        assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
+        assertThat(fileMetadata.path).isEqualTo(
+                RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME);
+
+        tarBackupReader.skipTarPadding(fileMetadata.size);
+
+        // Read actual file (PAX header will only exist here).
+        fileMetadata = tarBackupReader.readTarHeaders();
+        signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                fileMetadata);
+        restorePolicy = tarBackupReader.chooseRestorePolicy(
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+
+        assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
+        assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
+        char[] expectedFileNameChars = new char[200];
+        Arrays.fill(expectedFileNameChars, '1');
+        String expectedFileName = new String(expectedFileNameChars);
+        assertThat(fileMetadata.path).isEqualTo(expectedFileName);
+    }
+
+    @Test
+    public void readAppManifest_backupEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void readAppManifest_backupNotEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void chooseRestorePolicy_signaturesIsNull_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, new FileMetadata(), null /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        verifyZeroInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = true;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_packageDoesNotExistAndAllowApksAndDoesNotHaveApk_returnsAcceptIfApkLogsCannotRestore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = false;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock, times(2)).onEvent(bundleCaptor.capture());
+        List<Bundle> eventBundles = bundleCaptor.getAllValues();
+        assertThat(eventBundles).hasSize(2);
+        assertThat(eventBundles.get(0).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+        assertThat(eventBundles.get(1).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void chooseRestorePolicy_doesNotAllowsBackup_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_ALLOW_BACKUP;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithNoAgent_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_SYSTEM_APP_NO_AGENT);
+    }
+
+    @Test
+    public void chooseRestorePolicy_nonSystemAppSignaturesDoNotMatch_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_2};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithBackupAgentAndRestoreAnyVersion_returnsAccept()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_restoreAnyVersion_returnsAccept() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_notRestoreAnyVersionButVersionMatch_returnsAccept()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 1;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 2;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSIONS_MATCH);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+        info.hasApk = true;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        verifyNoMoreInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
index 07280bc..62b0ca8 100644
--- a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
@@ -21,16 +21,22 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.content.ContentService.ObserverCall;
 import com.android.server.content.ContentService.ObserverNode;
 
+/**
+ * bit FrameworksServicesTests:com.android.server.content.ObserverNodeTest
+ */
+@SmallTest
 public class ObserverNodeTest extends AndroidTestCase {
     static class TestObserver  extends ContentObserver {
         public TestObserver() {
-            super(new Handler());
+            super(new Handler(Looper.getMainLooper()));
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
index be6861c..d093e79 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java
@@ -1,9 +1,32 @@
+/*
+ * 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.content;
 
 import android.os.Bundle;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import junit.framework.TestCase;
 
+/**
+ * Tests for SyncManager.
+ *
+ * bit FrameworksServicesTests:com.android.server.content.SyncManagerTest
+ */
+@SmallTest
 public class SyncManagerTest extends TestCase {
 
     final String KEY_1 = "key_1";
@@ -61,4 +84,42 @@
         assertFalse("Extras considered equal when they are different.",
                 SyncManager.syncExtrasEquals(b1, b2, false /* don't care about system extras */));
     }
+
+    public void testFormatDurationHMS() {
+        checkFormatDurationHMS("0s", 0, 0, 0, 0);
+        checkFormatDurationHMS("1s", 0, 0, 0, 1);
+        checkFormatDurationHMS("9s", 0, 0, 0, 9);
+        checkFormatDurationHMS("10s", 0, 0, 0, 10);
+        checkFormatDurationHMS("59s", 0, 0, 0, 59);
+        checkFormatDurationHMS("1m00s", 0, 0, 1, 0);
+        checkFormatDurationHMS("1m01s", 0, 0, 1, 1);
+        checkFormatDurationHMS("1m09s", 0, 0, 1, 9);
+        checkFormatDurationHMS("1m10s", 0, 0, 1, 10);
+        checkFormatDurationHMS("1m59s", 0, 0, 1, 59);
+        checkFormatDurationHMS("1h00m00s", 0, 1, 0, 0);
+        checkFormatDurationHMS("1h00m01s", 0, 1, 0, 1);
+        checkFormatDurationHMS("1h01m01s", 0, 1, 1, 1);
+        checkFormatDurationHMS("1h09m10s", 0, 1, 9, 10);
+        checkFormatDurationHMS("1h10m59s", 0, 1, 10, 59);
+        checkFormatDurationHMS("1h59m00s", 0, 1, 59, 0);
+
+        checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0);
+        checkFormatDurationHMS("1d00h00m00s", 1, 0, 0, 0);
+        checkFormatDurationHMS("1d01h00m00s", 1, 1, 0, 0);
+        checkFormatDurationHMS("1d09h00m00s", 1, 9, 0, 0);
+        checkFormatDurationHMS("1d10h00m00s", 1, 10, 0, 0);
+        checkFormatDurationHMS("1d23h00m00s", 1, 23, 0, 0);
+        checkFormatDurationHMS("123d01h00m00s", 123, 1, 0, 0);
+
+        final StringBuilder sb = new StringBuilder();
+        assertEquals("-1m01s", SyncManager.formatDurationHMS(sb, -61000L).toString());
+    }
+
+    private void checkFormatDurationHMS(String expected,
+            int d, int h, int m, int s) {
+        final long time = (d * 24 * 3600) + (h * 3600) + (m * 60) + s;
+
+        final StringBuilder sb = new StringBuilder();
+        assertEquals(expected, SyncManager.formatDurationHMS(sb, time * 1000).toString());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
index e45b92a..deaa34c 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -17,24 +17,17 @@
 package com.android.server.content;
 
 import android.accounts.Account;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 /**
- * You can run those tests with:
+ * Test for SyncOperation.
  *
- * adb shell am instrument
- * -e debug false
- * -w
- * -e class android.content.SyncOperationTest com.android.frameworks.coretests/android.test.InstrumentationTestRunner
+ * bit FrameworksServicesTests:com.android.server.content.SyncOperationTest
  */
-
+@SmallTest
 public class SyncOperationTest extends AndroidTestCase {
 
     Account mDummy;
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
index 91c0de6..85de1f1 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
-import android.content.PeriodicSync;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
@@ -33,14 +32,18 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.server.content.SyncStorageEngine.EndPoint;
-
 import com.android.internal.os.AtomicFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.util.List;
 
+/**
+ * Test for SyncStorageEngine.
+ *
+ * bit FrameworksServicesTests:com.android.server.content.SyncStorageEngineTest
+ *
+ * TODO Broken.  Fix it.  b/62485315
+ */
 public class SyncStorageEngineTest extends AndroidTestCase {
 
     protected Account account1;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
index 3819914..175fdd8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
@@ -16,6 +16,7 @@
 package com.android.server.devicepolicy;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Test for {@link DevicePolicyConstants}.
@@ -29,6 +30,7 @@
 
  -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
  */
+@SmallTest
 public class DevicePolicyConstantsTest extends AndroidTestCase {
     private static final String TAG = "DevicePolicyConstantsTest";
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index be1d07b..c5fb0bd 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -47,14 +47,14 @@
 
         mContext = getContext();
 
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(true);
     }
 
     public void testMigration() throws Exception {
-        final File user10dir = mMockContext.addUser(10, 0);
-        final File user11dir = mMockContext.addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
-        mMockContext.addUser(12, 0);
+        final File user10dir = getServices().addUser(10, 0);
+        final File user11dir = getServices().addUser(11, UserInfo.FLAG_MANAGED_PROFILE);
+        getServices().addUser(12, 0);
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
@@ -62,12 +62,12 @@
 
         // Create the legacy owners & policies file.
         DpmTestUtils.writeToFile(
-                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
+                (new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_owner.xml"));
 
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_policies.xml"));
 
@@ -81,12 +81,12 @@
                         "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_11.xml"));
 
         // Set up UserManager
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_ADD_USER,
                 UserManager.DISALLOW_RECORD_AUDIO));
 
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(10))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_REMOVE_USER,
                 UserManager.DISALLOW_ADD_USER,
@@ -95,7 +95,7 @@
                 UserManager.DISALLOW_WALLPAPER,
                 UserManager.DISALLOW_RECORD_AUDIO));
 
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(11))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_REMOVE_USER,
                 UserManager.DISALLOW_ADD_USER,
@@ -113,7 +113,7 @@
             newBaseRestrictions.put(userId, bundle);
 
             return null;
-        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
+        }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
                 anyInt(), any(Bundle.class));
 
         // Initialize DPM/DPMS and let it migrate the persisted information.
@@ -125,7 +125,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -200,17 +200,17 @@
 
         // Create the legacy owners & policies file.
         DpmTestUtils.writeToFile(
-                (new File(mContext.dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
+                (new File(getServices().dataDir, OwnersTestable.LEGACY_FILE)).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest2/legacy_device_owner.xml"));
 
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest2/legacy_device_policies.xml"));
 
         // Set up UserManager
-        when(mMockContext.userManagerInternal.getBaseUserRestrictions(
+        when(getServices().userManagerInternal.getBaseUserRestrictions(
                 eq(UserHandle.USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
                 UserManager.DISALLOW_ADD_USER,
                 UserManager.DISALLOW_RECORD_AUDIO,
@@ -226,7 +226,7 @@
             newBaseRestrictions.put(userId, bundle);
 
             return null;
-        }).when(mContext.userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
+        }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
                 anyInt(), any(Bundle.class));
 
         // Initialize DPM/DPMS and let it migrate the persisted information.
@@ -238,7 +238,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
@@ -273,18 +273,18 @@
     // Test setting default restrictions for managed profile.
     public void testMigration3_managedProfileOwner() throws Exception {
         // Create a managed profile user.
-        final File user10dir = mMockContext.addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
+        final File user10dir = getServices().addUser(10, UserInfo.FLAG_MANAGED_PROFILE);
         // Profile owner package for managed profile user.
         setUpPackageManagerForAdmin(admin1, UserHandle.getUid(10, 123));
         // Set up fake UserManager to make it look like a managed profile.
-        when(mMockContext.userManager.isManagedProfile(eq(10))).thenReturn(true);
+        when(getServices().userManager.isManagedProfile(eq(10))).thenReturn(true);
         // Set up fake Settings to make it look like INSTALL_NON_MARKET_APPS was reversed.
-        when(mMockContext.settings.settingsSecureGetIntForUser(
+        when(getServices().settings.settingsSecureGetIntForUser(
                 eq(Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED),
                 eq(0), eq(10))).thenReturn(1);
         // Write policy and owners files.
         DpmTestUtils.writeToFile(
-                (new File(mContext.systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
+                (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
                 DpmTestUtils.readAsset(mRealTestContext,
                         "DevicePolicyManagerServiceMigrationTest3/system_device_policies.xml"));
         DpmTestUtils.writeToFile(
@@ -304,7 +304,7 @@
         try {
             LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+            dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
             dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
             dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index b870d94..5471715 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -61,11 +61,12 @@
         private final File mDeviceOwnerFile;
         private final File mUsersDataDir;
 
-        public OwnersTestable(DpmMockContext context) {
-            super(context.userManager, context.userManagerInternal, context.packageManagerInternal);
-            mLegacyFile = new File(context.dataDir, LEGACY_FILE);
-            mDeviceOwnerFile = new File(context.dataDir, DEVICE_OWNER_FILE);
-            mUsersDataDir = new File(context.dataDir, "users");
+        public OwnersTestable(MockSystemServices services) {
+            super(services.userManager, services.userManagerInternal,
+                    services.packageManagerInternal);
+            mLegacyFile = new File(services.dataDir, LEGACY_FILE);
+            mDeviceOwnerFile = new File(services.dataDir, DEVICE_OWNER_FILE);
+            mUsersDataDir = new File(services.dataDir, "users");
         }
 
         @Override
@@ -88,8 +89,8 @@
     public final DpmMockContext context;
     private final MockInjector mMockInjector;
 
-    public DevicePolicyManagerServiceTestable(DpmMockContext context, File dataDir) {
-        this(new MockInjector(context, dataDir));
+    public DevicePolicyManagerServiceTestable(MockSystemServices services, DpmMockContext context) {
+        this(new MockInjector(services, context));
     }
 
     private DevicePolicyManagerServiceTestable(MockInjector injector) {
@@ -100,15 +101,13 @@
 
 
     public void notifyChangeToContentObserver(Uri uri, int userHandle) {
-        ContentObserver co = mMockInjector.mContentObservers
-                .get(new Pair<Uri, Integer>(uri, userHandle));
+        ContentObserver co = mMockInjector.mContentObservers.get(new Pair<>(uri, userHandle));
         if (co != null) {
             co.onChange(false, uri, userHandle); // notify synchronously
         }
 
         // Notify USER_ALL observer too.
-        co = mMockInjector.mContentObservers
-                .get(new Pair<Uri, Integer>(uri, UserHandle.USER_ALL));
+        co = mMockInjector.mContentObservers.get(new Pair<>(uri, UserHandle.USER_ALL));
         if (co != null) {
             co.onChange(false, uri, userHandle); // notify synchronously
         }
@@ -118,76 +117,75 @@
     private static class MockInjector extends Injector {
 
         public final DpmMockContext context;
-
-        public final File dataDir;
+        private final MockSystemServices services;
 
         // Key is a pair of uri and userId
         private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>();
 
-        private MockInjector(DpmMockContext context, File dataDir) {
+        private MockInjector(MockSystemServices services, DpmMockContext context) {
             super(context);
+            this.services = services;
             this.context = context;
-            this.dataDir = dataDir;
         }
 
         @Override
         Owners newOwners() {
-            return new OwnersTestable(context);
+            return new OwnersTestable(services);
         }
 
         @Override
         UserManager getUserManager() {
-            return context.userManager;
+            return services.userManager;
         }
 
         @Override
         UserManagerInternal getUserManagerInternal() {
-            return context.userManagerInternal;
+            return services.userManagerInternal;
         }
 
         @Override
         PackageManagerInternal getPackageManagerInternal() {
-            return context.packageManagerInternal;
+            return services.packageManagerInternal;
         }
 
         @Override
         PowerManagerInternal getPowerManagerInternal() {
-            return context.powerManagerInternal;
+            return services.powerManagerInternal;
         }
 
         @Override
         NotificationManager getNotificationManager() {
-            return context.notificationManager;
+            return services.notificationManager;
         }
 
         @Override
         IIpConnectivityMetrics getIIpConnectivityMetrics() {
-            return context.iipConnectivityMetrics;
+            return services.iipConnectivityMetrics;
         }
 
         @Override
         IWindowManager getIWindowManager() {
-            return context.iwindowManager;
+            return services.iwindowManager;
         }
 
         @Override
         IActivityManager getIActivityManager() {
-            return context.iactivityManager;
+            return services.iactivityManager;
         }
 
         @Override
         IPackageManager getIPackageManager() {
-            return context.ipackageManager;
+            return services.ipackageManager;
         }
 
         @Override
         IBackupManager getIBackupManager() {
-            return context.ibackupManager;
+            return services.ibackupManager;
         }
 
         @Override
         IAudioService getIAudioService() {
-            return context.iaudioService;
+            return services.iaudioService;
         }
 
         @Override
@@ -197,32 +195,32 @@
 
         @Override
         LockPatternUtils newLockPatternUtils() {
-            return context.lockPatternUtils;
+            return services.lockPatternUtils;
         }
 
         @Override
         boolean storageManagerIsFileBasedEncryptionEnabled() {
-            return context.storageManager.isFileBasedEncryptionEnabled();
+            return services.storageManager.isFileBasedEncryptionEnabled();
         }
 
         @Override
         boolean storageManagerIsNonDefaultBlockEncrypted() {
-            return context.storageManager.isNonDefaultBlockEncrypted();
+            return services.storageManager.isNonDefaultBlockEncrypted();
         }
 
         @Override
         boolean storageManagerIsEncrypted() {
-            return context.storageManager.isEncrypted();
+            return services.storageManager.isEncrypted();
         }
 
         @Override
         boolean storageManagerIsEncryptable() {
-            return context.storageManager.isEncryptable();
+            return services.storageManager.isEncryptable();
         }
 
         @Override
         String getDevicePolicyFilePathForSystemUser() {
-            return context.systemUserDataDir.getAbsolutePath() + "/";
+            return services.systemUserDataDir.getAbsolutePath() + "/";
         }
 
         @Override
@@ -257,53 +255,53 @@
 
         @Override
         File environmentGetUserSystemDirectory(int userId) {
-            return context.environment.getUserSystemDirectory(userId);
+            return services.environment.getUserSystemDirectory(userId);
         }
 
         @Override
         void powerManagerGoToSleep(long time, int reason, int flags) {
-            context.powerManager.goToSleep(time, reason, flags);
+            services.powerManager.goToSleep(time, reason, flags);
         }
 
         @Override
         void powerManagerReboot(String reason) {
-            context.powerManager.reboot(reason);
+            services.powerManager.reboot(reason);
         }
 
         @Override
-        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force)
-                throws IOException {
-            context.recoverySystem.rebootWipeUserData(shutdown, reason, force);
+        void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+            services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc);
         }
 
         @Override
         boolean systemPropertiesGetBoolean(String key, boolean def) {
-            return context.systemProperties.getBoolean(key, def);
+            return services.systemProperties.getBoolean(key, def);
         }
 
         @Override
         long systemPropertiesGetLong(String key, long def) {
-            return context.systemProperties.getLong(key, def);
+            return services.systemProperties.getLong(key, def);
         }
 
         @Override
         String systemPropertiesGet(String key, String def) {
-            return context.systemProperties.get(key, def);
+            return services.systemProperties.get(key, def);
         }
 
         @Override
         String systemPropertiesGet(String key) {
-            return context.systemProperties.get(key);
+            return services.systemProperties.get(key);
         }
 
         @Override
         void systemPropertiesSet(String key, String value) {
-            context.systemProperties.set(key, value);
+            services.systemProperties.set(key, value);
         }
 
         @Override
         boolean userManagerIsSplitSystemUser() {
-            return context.userManagerForMock.isSplitSystemUser();
+            return services.userManagerForMock.isSplitSystemUser();
         }
 
         @Override
@@ -320,87 +318,87 @@
 
         @Override
         int settingsSecureGetIntForUser(String name, int def, int userHandle) {
-            return context.settings.settingsSecureGetIntForUser(name, def, userHandle);
+            return services.settings.settingsSecureGetIntForUser(name, def, userHandle);
         }
 
         @Override
         String settingsSecureGetStringForUser(String name, int userHandle) {
-            return context.settings.settingsSecureGetStringForUser(name, userHandle);
+            return services.settings.settingsSecureGetStringForUser(name, userHandle);
         }
 
         @Override
         void settingsSecurePutIntForUser(String name, int value, int userHandle) {
-            context.settings.settingsSecurePutIntForUser(name, value, userHandle);
+            services.settings.settingsSecurePutIntForUser(name, value, userHandle);
         }
 
         @Override
         void settingsSecurePutStringForUser(String name, String value, int userHandle) {
-            context.settings.settingsSecurePutStringForUser(name, value, userHandle);
+            services.settings.settingsSecurePutStringForUser(name, value, userHandle);
         }
 
         @Override
         void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
-            context.settings.settingsGlobalPutStringForUser(name, value, userHandle);
+            services.settings.settingsGlobalPutStringForUser(name, value, userHandle);
         }
 
         @Override
         void settingsSecurePutInt(String name, int value) {
-            context.settings.settingsSecurePutInt(name, value);
+            services.settings.settingsSecurePutInt(name, value);
         }
 
         @Override
         void settingsGlobalPutInt(String name, int value) {
-            context.settings.settingsGlobalPutInt(name, value);
+            services.settings.settingsGlobalPutInt(name, value);
         }
 
         @Override
         void settingsSecurePutString(String name, String value) {
-            context.settings.settingsSecurePutString(name, value);
+            services.settings.settingsSecurePutString(name, value);
         }
 
         @Override
         void settingsGlobalPutString(String name, String value) {
-            context.settings.settingsGlobalPutString(name, value);
+            services.settings.settingsGlobalPutString(name, value);
         }
 
         @Override
         int settingsGlobalGetInt(String name, int def) {
-            return context.settings.settingsGlobalGetInt(name, def);
+            return services.settings.settingsGlobalGetInt(name, def);
         }
 
         @Override
         String settingsGlobalGetString(String name) {
-            return context.settings.settingsGlobalGetString(name);
+            return services.settings.settingsGlobalGetString(name);
         }
 
         @Override
         void securityLogSetLoggingEnabledProperty(boolean enabled) {
-            context.settings.securityLogSetLoggingEnabledProperty(enabled);
+            services.settings.securityLogSetLoggingEnabledProperty(enabled);
         }
 
         @Override
         boolean securityLogGetLoggingEnabledProperty() {
-            return context.settings.securityLogGetLoggingEnabledProperty();
+            return services.settings.securityLogGetLoggingEnabledProperty();
         }
 
         @Override
         boolean securityLogIsLoggingEnabled() {
-            return context.settings.securityLogIsLoggingEnabled();
+            return services.settings.securityLogIsLoggingEnabled();
         }
 
         @Override
         TelephonyManager getTelephonyManager() {
-            return context.telephonyManager;
+            return services.telephonyManager;
         }
 
         @Override
         boolean isBuildDebuggable() {
-            return context.buildMock.isDebuggable;
+            return services.buildMock.isDebuggable;
         }
 
         @Override
         KeyChain.KeyChainConnection keyChainBindAsUser(UserHandle user) {
-            return context.keyChainConnection;
+            return services.keyChainConnection;
         }
     }
 }
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 c2b0ea5..23330f1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -15,41 +15,61 @@
  */
 package com.android.server.devicepolicy;
 
+import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
+import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
+import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
 
+import static com.android.server.testutis.TestUtils.assertExpectException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+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;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
+
 import android.Manifest.permission;
 import android.app.Activity;
 import android.app.Notification;
-import android.app.NotificationManager;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.PasswordMetrics;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.StringParceledListSlice;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.net.IIpConnectivityMetrics;
-import android.net.Uri;
 import android.content.pm.UserInfo;
+import android.graphics.Color;
+import android.net.Uri;
 import android.net.wifi.WifiInfo;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.UserManagerInternal;
 import android.provider.Settings;
-import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.telephony.TelephonyManager;
 import android.test.MoreAsserts;
@@ -77,30 +97,6 @@
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
-import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-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;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
 /**
  * Tests for DevicePolicyManager( and DevicePolicyManagerService).
  * You can run them via:
@@ -120,8 +116,15 @@
     private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
             permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
             permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
+    public static final String NOT_DEVICE_OWNER_MSG = "does not own the device";
+    public static final String ONGOING_CALL_MSG = "ongoing call on the device";
 
+    // TODO replace all instances of this with explicit {@link #mServiceContext}.
+    @Deprecated
     private DpmMockContext mContext;
+
+    private DpmMockContext mServiceContext;
+    private DpmMockContext mAdmin1Context;
     public DevicePolicyManager dpm;
     public DevicePolicyManagerServiceTestable dpms;
 
@@ -158,11 +161,13 @@
         super.setUp();
 
         mContext = getContext();
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        mServiceContext = mContext;
+        mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(true);
 
         // By default, pretend all users are running and unlocked.
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
 
         initializeDpms();
 
@@ -171,6 +176,11 @@
         setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
         setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
 
+        mAdmin1Context = new DpmMockContext(getServices(), mRealTestContext);
+        mAdmin1Context.packageName = admin1.getPackageName();
+        mAdmin1Context.applicationInfo = new ApplicationInfo();
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
+
         setUpUserManager();
     }
 
@@ -183,18 +193,15 @@
     private void initializeDpms() {
         // Need clearCallingIdentity() to pass permission checks.
         final long ident = mContext.binder.clearCallingIdentity();
-        try {
-            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
 
-            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+        dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
+        dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
+        dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
 
-            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
-            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
+        dpm = new DevicePolicyManagerTestable(mContext, dpms);
 
-            dpm = new DevicePolicyManagerTestable(mContext, dpms);
-        } finally {
-            mContext.binder.restoreCallingIdentity(ident);
-        }
+        mContext.binder.restoreCallingIdentity(ident);
     }
 
     private void setUpUserManager() {
@@ -213,7 +220,7 @@
 
                 return null;
             }
-        }).when(mContext.userManager).setApplicationRestrictions(
+        }).when(getServices().userManager).setApplicationRestrictions(
                 anyString(), nullable(Bundle.class), any(UserHandle.class));
 
         // UM.getApplicationRestrictions() will read from appRestrictions.
@@ -225,33 +232,36 @@
 
                 return appRestrictions.get(Pair.create(pkg, user));
             }
-        }).when(mContext.userManager).getApplicationRestrictions(
+        }).when(getServices().userManager).getApplicationRestrictions(
                 anyString(), any(UserHandle.class));
 
         // Add the first secondary user.
-        mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
+        getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
     }
 
     private void setAsProfileOwner(ComponentName admin) {
-        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
-        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        final long ident = mServiceContext.binder.clearCallingIdentity();
 
-        // PO needs to be an DA.
-        dpm.setActiveAdmin(admin, /* replace =*/ false);
+        mServiceContext.binder.callingUid =
+                UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
+        runAsCaller(mServiceContext, dpms, dpm -> {
+            // PO needs to be a DA.
+            dpm.setActiveAdmin(admin, /*replace=*/ false);
+            // Fire!
+            assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+            // Check
+            assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+        });
 
-        // Fire!
-        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
-
-        // Check
-        assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+        mServiceContext.binder.restoreCallingIdentity(ident);
     }
 
     public void testHasNoFeature() throws Exception {
-        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+        when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(false);
 
         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
-        new DevicePolicyManagerServiceTestable(mContext, dataDir);
+        new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
         // If the device has no DPMS feature, it shouldn't register the local service.
         assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
@@ -264,19 +274,14 @@
         // 1. Failure cases.
 
         // Caller doesn't have MANAGE_DEVICE_ADMINS.
-        try {
-            dpm.setActiveAdmin(admin1, false);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, false));
 
         // Caller has MANAGE_DEVICE_ADMINS, but for different user.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
-        try {
-            dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1));
     }
 
     /**
@@ -307,7 +312,7 @@
                         DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
 
-        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
                 eq(admin1.getPackageName()),
                 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
                 eq(PackageManager.DONT_KILL_APP),
@@ -335,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);
 
@@ -346,7 +351,7 @@
 
         // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
         // again.  (times(1) because it was previously called for admin1)
-        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
+        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
                 eq(admin1.getPackageName()),
                 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
                 eq(PackageManager.DONT_KILL_APP),
@@ -354,11 +359,8 @@
                 anyString());
 
         // 4. Add the same admin1 again without replace, which should throw.
-        try {
-            dpm.setActiveAdmin(admin1, /* replace =*/ false);
-            fail("Didn't throw");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, /* replace =*/ false));
 
         // 5. Add the same admin1 again with replace, which should succeed.
         dpm.setActiveAdmin(admin1, /* replace =*/ true);
@@ -385,7 +387,7 @@
         final int ANOTHER_USER_ID = 100;
         final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
 
-        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
+        getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user.
 
         // Set up pacakge manager for the other user.
         setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
@@ -420,11 +422,8 @@
         assertTrue(dpm.isAdminActive(admin1));
 
         // Add the same admin1 again without replace, which should throw.
-        try {
-            dpm.setActiveAdmin(admin1, /* replace =*/ false);
-            fail("Didn't throw");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setActiveAdmin(admin1, /* replace =*/ false));
     }
 
     /**
@@ -436,12 +435,9 @@
         // 1. Make sure the caller has proper permissions.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
-        try {
-            dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
-            fail();
-        } catch (IllegalArgumentException expected) {
-            assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
-        }
+        assertExpectException(IllegalArgumentException.class,
+                /* messageRegex= */ permission.BIND_DEVICE_ADMIN,
+                () -> dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false));
         assertFalse(dpm.isAdminActive(adminNoPerm));
 
         // Change the target API level to MNC.  Now it can be set as DA.
@@ -470,11 +466,8 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // Directly call the DPMS method with a different userid, which should fail.
-        try {
-            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
 
         // Try to remove active admin with a different caller userid should fail too, without
         // having MANAGE_DEVICE_ADMINS.
@@ -483,11 +476,8 @@
         // Change the caller, and call into DPMS directly with a different user-id.
 
         mContext.binder.callingUid = 1234567;
-        try {
-            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
     }
 
     /**
@@ -508,20 +498,16 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // 1. User not unlocked.
-        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+        when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(false);
-        try {
-            dpm.removeActiveAdmin(admin1);
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.removeActiveAdmin(admin1));
 
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // 2. User unlocked.
-        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+        when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(true);
 
         dpm.removeActiveAdmin(admin1);
@@ -656,7 +642,7 @@
         // Setup device owner.
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         mContext.packageName = admin1.getPackageName();
-        doReturn(true).when(mContext.lockPatternUtils)
+        doReturn(true).when(getServices().lockPatternUtils)
                 .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID);
         setupDeviceOwner();
 
@@ -687,13 +673,9 @@
         // Try to set a profile owner on the same user, which should fail.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
-        try {
-            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
-            fail("IllegalStateException not thrown");
-        } catch (IllegalStateException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("already has a device owner"));
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "already has a device owner",
+                () -> dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM));
 
         // DO admin can't be deactivated.
         dpm.removeActiveAdmin(admin1);
@@ -739,11 +721,11 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         // TODO We should check if the caller has called clearCallerIdentity().
-        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
+        verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
                 eq(UserHandle.USER_SYSTEM), eq(false));
 
         verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
@@ -850,26 +832,14 @@
             assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
         }
 
-        try {
-            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerComponentOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerUserId();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerNameOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerComponentOnAnyUser);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerUserId);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerNameOnAnyUser);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         // Still no MANAGE_USERS.
@@ -877,26 +847,14 @@
         assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
         assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
 
-        try {
-            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerComponentOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerUserId();
-            fail();
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getDeviceOwnerNameOnAnyUser();
-            fail();
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerComponentOnAnyUser);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerUserId);
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                dpm::getDeviceOwnerNameOnAnyUser);
 
         // Restore.
         mContext.binder.callingUid = origCallingUser;
@@ -916,13 +874,9 @@
         // Call from a process on the system user.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
-        try {
-            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
-            fail("Didn't throw IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("Invalid component"));
-        }
+        assertExpectException(IllegalArgumentException.class,
+                /* messageRegex= */ "Invalid component",
+                () -> dpm.setDeviceOwner(new ComponentName("a.b.c", ".def")));
     }
 
     public void testSetDeviceOwner_failures() throws Exception {
@@ -948,48 +902,43 @@
         assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        when(mContext.userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+        when(getServices().userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
 
         assertTrue(dpm.isAdminActive(admin1));
         assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
 
         // Set up other mocks.
-        when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle());
+        when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle());
 
         // Now call clear.
-        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
-                eq(admin1.getPackageName()),
-                anyInt());
+        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager).
+                getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
 
         // But first pretend the user is locked.  Then it should fail.
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
-        try {
-            dpm.clearDeviceOwnerApp(admin1.getPackageName());
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(false);
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
-        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
-        reset(mContext.userManagerInternal);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
+        reset(getServices().userManagerInternal);
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
 
         // Now DO shouldn't be set.
         assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
 
-        verify(mContext.userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
+        verify(getServices().userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 eq(false),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
 
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 eq(null),
                 eq(true), eq(CAMERA_NOT_DISABLED));
@@ -1023,7 +972,7 @@
         assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
 
         // Verify internal calls.
-        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
         assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
@@ -1032,15 +981,12 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Now call clear.
-        doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser(
+        doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManager).getPackageUidAsUser(
                 eq(admin1.getPackageName()),
                 anyInt());
-        try {
-            dpm.clearDeviceOwnerApp(admin1.getPackageName());
-            fail("Didn't throw");
-        } catch (SecurityException e) {
-            assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage());
-        }
+        assertExpectException(SecurityException.class,
+                /* messageRegex =*/ "clearDeviceOwner can only be called by the device owner",
+                () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
         // DO shouldn't be removed.
         assertTrue(dpm.isDeviceManaged());
@@ -1055,14 +1001,14 @@
 
         // Try setting DO on the same user, which should fail.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
-        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
-        try {
-            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
-            fail("IllegalStateException not thrown");
-        } catch (IllegalStateException expected) {
-            assertTrue("Message was: " + expected.getMessage(),
-                    expected.getMessage().contains("already has a profile owner"));
-        }
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        runAsCaller(mServiceContext, dpms, dpm -> {
+            dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
+            assertExpectException(IllegalStateException.class,
+                    /* messageRegex= */ "already has a profile owner",
+                    () -> dpm.setDeviceOwner(admin2, "owner-name",
+                            DpmMockContext.CALLER_USER_HANDLE));
+        });
     }
 
     public void testClearProfileOwner() throws Exception {
@@ -1074,18 +1020,14 @@
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
         // First try when the user is locked, which should fail.
-        when(mContext.userManager.isUserUnlocked(anyInt()))
+        when(getServices().userManager.isUserUnlocked(anyInt()))
                 .thenReturn(false);
-        try {
-            dpm.clearProfileOwner(admin1);
-            fail("Didn't throw IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "User must be running and unlocked", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "User must be running and unlocked",
+                () -> dpm.clearProfileOwner(admin1));
+
         // Clear, really.
-        when(mContext.userManager.isUserUnlocked(anyInt()))
-                .thenReturn(true);
+        when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
         dpm.clearProfileOwner(admin1);
 
         // Check
@@ -1109,7 +1051,7 @@
         final int ANOTHER_USER_ID = 100;
         final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456);
 
-        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
+        getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user.
 
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1118,7 +1060,7 @@
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
 
         // Make sure the admin packge is installed to each user.
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
@@ -1140,7 +1082,7 @@
         dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
 
         // Set DO on the first non-system user.
-        mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
+        getServices().setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
         assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
 
         assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
@@ -1159,7 +1101,7 @@
      * finds the right component from a package name upon migration.
      */
     public void testDeviceOwnerMigration() throws Exception {
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         checkDeviceOwnerWithMultipleDeviceAdmins();
 
         // Overwrite the device owner setting and clears the clas name.
@@ -1172,7 +1114,7 @@
         assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
 
         // Then create a new DPMS to have it load the settings from files.
-        when(mContext.userManager.getUserRestrictions(any(UserHandle.class)))
+        when(getServices().userManager.getUserRestrictions(any(UserHandle.class)))
                 .thenReturn(new Bundle());
         initializeDpms();
 
@@ -1226,8 +1168,7 @@
      */
     private int setupPackageInPackageManager(final String packageName, final int appId)
             throws Exception {
-        return setupPackageInPackageManager(
-                packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
+        return setupPackageInPackageManager(packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
                 ApplicationInfo.FLAG_HAS_CODE);
     }
 
@@ -1240,31 +1181,29 @@
      * @param flags flags to set in the ApplicationInfo for this package
      * @return the UID of the package as known by the mock package manager
      */
-    private int setupPackageInPackageManager(
-            final String packageName, int userId, final int appId, int flags)
-            throws Exception {
-        // Make the PackageManager return the package instead of throwing a NameNotFoundException
+    private int setupPackageInPackageManager(final String packageName, int userId, final int appId,
+            int flags) throws Exception {
+        final int uid = UserHandle.getUid(userId, appId);
+        // Make the PackageManager return the package instead of throwing NameNotFoundException
         final PackageInfo pi = new PackageInfo();
         pi.applicationInfo = new ApplicationInfo();
         pi.applicationInfo.flags = flags;
-        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
+        doReturn(pi).when(getServices().ipackageManager).getPackageInfo(
                 eq(packageName),
                 anyInt(),
                 eq(userId));
-        doReturn(pi.applicationInfo).when(mContext.ipackageManager).getApplicationInfo(
+        doReturn(pi.applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
                 eq(packageName),
                 anyInt(),
                 eq(userId));
-
         // Setup application UID with the PackageManager
-        final int uid = UserHandle.getUid(userId, appId);
-        doReturn(uid).when(mContext.packageManager).getPackageUidAsUser(
+        doReturn(uid).when(getServices().packageManager).getPackageUidAsUser(
                 eq(packageName),
                 eq(userId));
         // Associate packageName to uid
-        doReturn(packageName).when(mContext.ipackageManager).getNameForUid(eq(uid));
+        doReturn(packageName).when(getServices().ipackageManager).getNameForUid(eq(uid));
         doReturn(new String[]{packageName})
-            .when(mContext.ipackageManager).getPackagesForUid(eq(uid));
+                .when(getServices().ipackageManager).getPackagesForUid(eq(uid));
         return uid;
     }
 
@@ -1275,7 +1214,7 @@
         mContext.applicationInfo = new ApplicationInfo();
         mContext.callerPermissions.add(permission.MANAGE_USERS);
         mContext.packageName = "com.android.frameworks.servicestests";
-        mContext.addPackageContext(user, mContext);
+        getServices().addPackageContext(user, mContext);
         when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
         StringParceledListSlice oneCert = asSlice(new String[] {"1"});
@@ -1285,20 +1224,20 @@
         doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2));
 
         // Given that we have exactly one certificate installed,
-        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
+        when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
         // when that certificate is approved,
         dpms.approveCaCert(oneCert.getList().get(0), userId, true);
         // a notification should not be shown.
-        verify(mContext.notificationManager, timeout(1000))
+        verify(getServices().notificationManager, timeout(1000))
                 .cancelAsUser(anyString(), anyInt(), eq(user));
 
         // Given that we have four certificates installed,
-        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
+        when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
         // when two of them are approved (one of them approved twice hence no action),
         dpms.approveCaCert(fourCerts.getList().get(0), userId, true);
         dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
         // a notification should be shown saying that there are two certificates left to approve.
-        verify(mContext.notificationManager, timeout(1000))
+        verify(getServices().notificationManager, timeout(1000))
                 .notifyAsUser(anyString(), anyInt(), argThat(
                         new BaseMatcher<Notification>() {
                             @Override
@@ -1355,12 +1294,8 @@
         mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
         mContext.packageName = RESTRICTIONS_DELEGATE;
 
-        // DPMS throws a SecurityException
-        try {
-            dpm.installCaCert(null, null);
-            fail("Didn't throw SecurityException on unauthorized access");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.installCaCert(null, null));
 
         // On calling install certificate APIs from an authorized process
         mContext.binder.callingUid = CERT_DELEGATE_UID;
@@ -1382,11 +1317,8 @@
         // DPMS does not allow access to ex-delegate
         mContext.binder.callingUid = CERT_DELEGATE_UID;
         mContext.packageName = CERT_DELEGATE;
-        try {
-            dpm.installCaCert(null, null);
-            fail("Didn't throw SecurityException on unauthorized access");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.installCaCert(null, null));
 
         // But still allows access to other existing delegates
         mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
@@ -1403,6 +1335,8 @@
 
         final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
         final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
+        final String nonDelegateExceptionMessageRegex =
+                "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.";
         final int appRestrictionsManagerAppId = 20987;
         final int appRestrictionsManagerUid = setupPackageInPackageManager(
                 appRestrictionsManagerPackage, appRestrictionsManagerAppId);
@@ -1412,24 +1346,10 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        Bundle rest = new Bundle();
+        final Bundle rest = new Bundle();
         rest.putString("KEY_STRING", "Foo1");
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", rest);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
-        try {
-            dpm.getApplicationRestrictions(null, "pkg1");
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", rest));
 
         // Check via the profile owner that no restrictions were set.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -1437,14 +1357,10 @@
         assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
 
         // Check the API does not allow setting a non-existent package
-        try {
-            dpm.setApplicationRestrictionsManagingPackage(admin1,
-                    nonExistAppRestrictionsManagerPackage);
-            fail("Non-existent app set as app restriction manager.");
-        } catch (PackageManager.NameNotFoundException expected) {
-            MoreAsserts.assertContainsRegex(
-                    nonExistAppRestrictionsManagerPackage, expected.getMessage());
-        }
+        assertExpectException(PackageManager.NameNotFoundException.class,
+                /* messageRegex= */ nonExistAppRestrictionsManagerPackage,
+                () -> dpm.setApplicationRestrictionsManagingPackage(
+                        admin1, nonExistAppRestrictionsManagerPackage));
 
         // Let appRestrictionsManagerPackage manage app restrictions
         dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
@@ -1464,14 +1380,8 @@
         mContext.binder.callingUid = UserHandle.getUid(
                 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", rest);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", rest));
 
         // The DPM is still able to manage app restrictions, even if it allowed another app to do it
         // too.
@@ -1487,14 +1397,8 @@
         mContext.binder.callingUid = appRestrictionsManagerUid;
         mContext.packageName = appRestrictionsManagerPackage;
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
-        try {
-            dpm.setApplicationRestrictions(null, "pkg1", null);
-            fail("Didn't throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex(
-                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
-                    expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
+                () -> dpm.setApplicationRestrictions(null, "pkg1", null));
     }
 
     public void testSetUserRestriction_asDo() throws Exception {
@@ -1517,7 +1421,7 @@
                 UserHandle.USER_SYSTEM));
 
         // Check that the user restrictions that are enabled by default are set. Then unset them.
-        String[] defaultRestrictions = UserRestrictionsUtils
+        final String[] defaultRestrictions = UserRestrictionsUtils
                 .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(defaultRestrictions),
@@ -1527,35 +1431,35 @@
                 DpmTestUtils.newRestrictions(defaultRestrictions),
                 dpm.getUserRestrictions(admin1)
         );
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
         );
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         for (String restriction : defaultRestrictions) {
             dpm.clearUserRestriction(admin1, restriction);
         }
 
         assertNoDeviceOwnerRestrictions();
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1569,11 +1473,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
@@ -1585,71 +1489,71 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         assertNoDeviceOwnerRestrictions();
 
         // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when
         // DO sets them, the scope is global.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // More tests.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 // DISALLOW_CAMERA will be applied to both local and global.
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_DISABLED_GLOBALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // Set up another DA and let it disable camera.  Now DISALLOW_CAMERA will only be applied
         // locally.
         dpm.setCameraDisabled(admin1, false);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM);
         dpm.setCameraDisabled(admin2, true);
 
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
                 eq(true), eq(CAMERA_DISABLED_LOCALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         // TODO Make sure restrictions are written to the file.
     }
 
@@ -1663,19 +1567,19 @@
         );
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
                         UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1694,11 +1598,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1715,11 +1619,11 @@
         );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(),
@@ -1734,22 +1638,22 @@
         // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
         // though when DO sets them they'll be applied globally.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(false), eq(CAMERA_NOT_DISABLED));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
                 eq(false), eq(CAMERA_DISABLED_LOCALLY));
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         // TODO Make sure restrictions are written to the file.
     }
@@ -1785,13 +1689,13 @@
                 DpmTestUtils.newRestrictions(defaultRestrictions),
                 dpm.getUserRestrictions(admin1)
         );
-        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
         );
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
 
         for (String restriction : defaultRestrictions) {
             dpm.clearUserRestriction(admin1, restriction);
@@ -1800,7 +1704,7 @@
         assertNoDeviceOwnerRestrictions();
 
         // Initialize DPMS again and check that the user restriction wasn't enabled again.
-        reset(mContext.userManagerInternal);
+        reset(getServices().userManagerInternal);
         initializeDpms();
         assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
         assertNotNull(dpms.getDeviceOwnerAdminLocked());
@@ -1815,7 +1719,7 @@
         UserRestrictionsUtils
                 .getDefaultEnabledForDeviceOwner().add(newDefaultEnabledRestriction);
         try {
-            reset(mContext.userManagerInternal);
+            reset(getServices().userManagerInternal);
             initializeDpms();
             assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
             assertNotNull(dpms.getDeviceOwnerAdminLocked());
@@ -1828,13 +1732,13 @@
                 DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
                 dpm.getUserRestrictions(admin1)
             );
-            verify(mContext.userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
+            verify(getServices().userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
                 eq(true) /* isDeviceOwner */,
                 eq(CAMERA_NOT_DISABLED)
             );
-            reset(mContext.userManagerInternal);
+            reset(getServices().userManagerInternal);
 
             // Remove the restriction.
             dpm.clearUserRestriction(admin1, newDefaultEnabledRestriction);
@@ -1873,33 +1777,21 @@
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
 
         // Test 1. Caller doesn't have DO or DA.
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("No active admin", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ "No active admin",
+                () -> dpm.getWifiMacAddress(admin1));
 
         // DO needs to be an DA.
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         assertTrue(dpm.isAdminActive(admin1));
 
         // Test 2. Caller has DA, but not DO.
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.getWifiMacAddress(admin1));
 
         // Test 3. Caller has PO, but not DO.
         assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
-        try {
-            dpm.getWifiMacAddress(admin1);
-            fail();
-        } catch (SecurityException e) {
-            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.getWifiMacAddress(admin1));
 
         // Remove PO.
         dpm.clearProfileOwner(admin1);
@@ -1911,13 +1803,13 @@
         assertNull(dpm.getWifiMacAddress(admin1));
 
         // 4-2.  Returns WifiInfo, but with the default MAC.
-        when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
+        when(getServices().wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
         assertNull(dpm.getWifiMacAddress(admin1));
 
         // 4-3. With a real MAC address.
         final WifiInfo wi = new WifiInfo();
         wi.setMacAddress("11:22:33:44:55:66");
-        when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
+        when(getServices().wifiManager.getConnectionInfo()).thenReturn(wi);
         assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
     }
 
@@ -1934,21 +1826,13 @@
         // Set admin1 as DA.
         dpm.setActiveAdmin(admin1, false);
         assertTrue(dpm.isAdminActive(admin1));
-        try {
-            dpm.reboot(admin1);
-            fail("DA calls DPM.reboot(), did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set admin1 as PO.
         assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
-        try {
-            dpm.reboot(admin1);
-            fail("PO calls DPM.reboot(), did not throw expected SecurityException");
-        } catch (SecurityException expected) {
-            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG,
+                () -> dpm.reboot(admin1));
 
         // Remove PO and add DO.
         dpm.clearProfileOwner(admin1);
@@ -1957,27 +1841,19 @@
 
         // admin1 is DO.
         // Set current call state of device to ringing.
-        when(mContext.telephonyManager.getCallState())
+        when(getServices().telephonyManager.getCallState())
                 .thenReturn(TelephonyManager.CALL_STATE_RINGING);
-        try {
-            dpm.reboot(admin1);
-            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set current call state of device to dialing/active.
-        when(mContext.telephonyManager.getCallState())
+        when(getServices().telephonyManager.getCallState())
                 .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
-        try {
-            dpm.reboot(admin1);
-            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
-        } catch (IllegalStateException expected) {
-            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
-        }
+        assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG,
+                () -> dpm.reboot(admin1));
 
         // Set current call state of device to idle.
-        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
+        when(getServices().telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
         dpm.reboot(admin1);
     }
 
@@ -2001,31 +1877,20 @@
 
         // Only system can call the per user versions.
         {
-            try {
-                dpm.getShortSupportMessageForUser(admin1,
-                        DpmMockContext.CALLER_USER_HANDLE);
-                fail("Only system should be able to call getXXXForUser versions");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
-            }
-            try {
-                dpm.getLongSupportMessageForUser(admin1,
-                        DpmMockContext.CALLER_USER_HANDLE);
-                fail("Only system should be able to call getXXXForUser versions");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
-            }
+            assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
+                    () -> dpm.getShortSupportMessageForUser(admin1,
+                            DpmMockContext.CALLER_USER_HANDLE));
+            assertExpectException(SecurityException.class, /* messageRegex= */ "message for user",
+                    () -> dpm.getLongSupportMessageForUser(admin1,
+                        DpmMockContext.CALLER_USER_HANDLE));
         }
 
         // Can't set message for admin in another uid.
         {
             mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1;
-            try {
-                dpm.setShortSupportMessage(admin1, "Some text");
-                fail("Admins should only be able to change their own support text.");
-            } catch (SecurityException expected) {
-                MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage());
-            }
+            assertExpectException(SecurityException.class,
+                    /* messageRegex= */ "is not owned by uid",
+                    () -> dpm.setShortSupportMessage(admin1, "Some text"));
             mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         }
 
@@ -2086,7 +1951,7 @@
         assertNull(intent);
 
         // Existing permission that is not set by device/profile owner returns null
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
@@ -2094,7 +1959,7 @@
         assertNull(intent);
 
         // Permission that is set by device owner returns correct intent
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2103,8 +1968,7 @@
         assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
         assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
                 intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
-        assertEquals(admin1,
-                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
+        assertEquals(admin1, intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
         assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
                 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
 
@@ -2240,24 +2104,17 @@
 
     public void testSetUserProvisioningState_unprivileged() throws Exception {
         setupProfileOwner();
-        try {
-            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DpmMockContext.CALLER_USER_HANDLE);
-            fail("Expected SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DpmMockContext.CALLER_USER_HANDLE));
     }
 
     public void testSetUserProvisioningState_noManagement() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
-        try {
-            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DpmMockContext.CALLER_USER_HANDLE);
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "change provisioning state unless a .* owner is set",
+                () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DpmMockContext.CALLER_USER_HANDLE));
         assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
     }
 
@@ -2323,15 +2180,11 @@
         setupProfileOwner();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
 
-        try {
-            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
-                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
-                    DevicePolicyManager.STATE_USER_UNMANAGED);
-            fail("Expected IllegalStateException");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "Cannot move to user provisioning state",
+                () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                        DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                        DevicePolicyManager.STATE_USER_UNMANAGED));
     }
 
     public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
@@ -2339,15 +2192,11 @@
         setupProfileOwner();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
 
-        try {
-            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
-                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
-                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
-            fail("Expected IllegalStateException");
-        } catch (IllegalStateException e) {
-            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
-                    e.getMessage());
-        }
+        assertExpectException(IllegalStateException.class,
+                /* messageRegex= */ "Cannot move to user provisioning state",
+                () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                        DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
+                        DevicePolicyManager.STATE_USER_SETUP_COMPLETE));
     }
 
     private void exerciseUserProvisioningTransitions(int userId, int... states) {
@@ -2384,52 +2233,52 @@
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 0);
         verifyScreenTimeoutCall(null, false);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 1);
         verifyScreenTimeoutCall(1, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
         verifyScreenTimeoutCall(null, false);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 5);
         verifyScreenTimeoutCall(5, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 4);
         verifyScreenTimeoutCall(4, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 0);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE);
         verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1);
         verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
         verifyScreenTimeoutCall(10, true);
-        reset(mMockContext.powerManagerInternal);
-        reset(mMockContext.settings);
+        reset(getServices().powerManagerInternal);
+        reset(getServices().settings);
 
         // There's no restriction; shold be set to MAX.
         dpm.setMaximumTimeToLock(admin2, 0);
@@ -2449,25 +2298,20 @@
 
         // verify that the minimum timeout cannot be modified on user builds (system property is
         // not being read)
-        mContext.buildMock.isDebuggable = false;
+        getServices().buildMock.isDebuggable = false;
 
         dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
         assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
         assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
 
-        verify(mContext.systemProperties, never()).getLong(anyString(), anyLong());
+        verify(getServices().systemProperties, never()).getLong(anyString(), anyLong());
 
         // restore to the debuggable build state
-        mContext.buildMock.isDebuggable = true;
+        getServices().buildMock.isDebuggable = true;
 
         // Always return the default (second arg) when getting system property for long type
-        when(mContext.systemProperties.getLong(anyString(), anyLong())).thenAnswer(
-                new Answer<Long>() {
-                    @Override
-                    public Long answer(InvocationOnMock invocation) throws Throwable {
-                        return (Long) invocation.getArguments()[1];
-                    }
-                }
+        when(getServices().systemProperties.getLong(anyString(), anyLong())).thenAnswer(
+                invocation -> invocation.getArguments()[1]
         );
 
         // reset to default (0 means the admin is not participating, so default should be returned)
@@ -2515,20 +2359,17 @@
                 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
 
         // negative value
-        try {
-            dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE);
-            fail("Didn't throw IllegalArgumentException");
-        } catch (IllegalArgumentException iae) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE));
     }
 
     private void verifyScreenTimeoutCall(Integer expectedTimeout,
             boolean shouldStayOnWhilePluggedInBeCleared) {
         if (expectedTimeout == null) {
-            verify(mMockContext.powerManagerInternal, times(0))
+            verify(getServices().powerManagerInternal, times(0))
                     .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt());
         } else {
-            verify(mMockContext.powerManagerInternal, times(1))
+            verify(getServices().powerManagerInternal, times(1))
                     .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout));
         }
         // TODO Verify calls to settingsGlobalPutInt.  Tried but somehow mockito threw
@@ -2536,13 +2377,13 @@
     }
 
     private void setup_DeviceAdminFeatureOff() throws Exception {
-        when(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
+        when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
                 .thenReturn(false);
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(false);
         initializeDpms();
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2575,11 +2416,11 @@
     }
 
     private void setup_ManagedProfileFeatureOff() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(false);
         initializeDpms();
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2597,7 +2438,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
 
         // Test again when split user is on
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
@@ -2619,7 +2460,7 @@
                 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
 
         // Test again when split user is on
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
                 DevicePolicyManager.CODE_OK);
         assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
@@ -2632,10 +2473,10 @@
     }
 
     private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2670,10 +2511,10 @@
     }
 
     private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -2691,9 +2532,9 @@
         final int MANAGED_PROFILE_USER_ID = 18;
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308);
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
                 true)).thenReturn(true);
     }
 
@@ -2755,11 +2596,11 @@
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // The DO should be allowed to initiate provisioning if it set the restriction itself, but
         // other packages should be forbidden.
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2781,11 +2622,11 @@
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // The DO should not be allowed to initiate provisioning if the restriction is set by
         // another entity.
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -2823,11 +2664,11 @@
         setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
         mContext.packageName = admin1.getPackageName();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.SYSTEM)))
                 .thenReturn(true);
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.SYSTEM)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -2847,10 +2688,10 @@
     }
 
     private void setup_splitUser_firstBoot_systemUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
 
@@ -2886,10 +2727,10 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -2926,10 +2767,10 @@
     }
 
     private void setup_splitUser_firstBoot_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -2963,10 +2804,10 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3005,10 +2846,10 @@
     private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
         setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
 
@@ -3035,10 +2876,10 @@
     private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3066,16 +2907,16 @@
     private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
                 .thenReturn(true);
-        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
-        when(mContext.userManager.hasUserRestriction(
+        when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
                 eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))))
                 .thenReturn(true);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 false /* we can't remove a managed profile */)).thenReturn(false);
-        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+        when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
                 true)).thenReturn(true);
         setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
 
@@ -3100,32 +2941,23 @@
 
     public void testCheckProvisioningPreCondition_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
-        try {
-            dpm.checkProvisioningPreCondition(
-                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package");
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.checkProvisioningPreCondition(
+                        DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package"));
     }
 
     public void testForceUpdateUserSetupComplete_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
-        try {
-            dpm.forceUpdateUserSetupComplete();
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.forceUpdateUserSetupComplete());
     }
 
     public void testForceUpdateUserSetupComplete_systemUser() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // GIVEN calling from user 20
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
-        try {
-            dpm.forceUpdateUserSetupComplete();
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.forceUpdateUserSetupComplete());
     }
 
     public void testForceUpdateUserSetupComplete_userbuild() {
@@ -3143,7 +2975,7 @@
         dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
 
         // GIVEN it's user build
-        mContext.buildMock.isDebuggable = false;
+        getServices().buildMock.isDebuggable = false;
 
         assertTrue(dpms.hasUserSetupCompleted());
 
@@ -3168,7 +3000,7 @@
         dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
 
         // GIVEN it's userdebug build
-        mContext.buildMock.isDebuggable = true;
+        getServices().buildMock.isDebuggable = true;
 
         assertTrue(dpms.hasUserSetupCompleted());
 
@@ -3179,12 +3011,13 @@
     }
 
     private void clearDeviceOwner() throws Exception {
-        final long ident = mContext.binder.clearCallingIdentity();
-        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager)
+        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager)
                 .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
-        dpm.clearDeviceOwnerApp(admin1.getPackageName());
-        mContext.binder.restoreCallingIdentity(ident);
+
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        runAsCaller(mAdmin1Context, dpms, dpm -> {
+            dpm.clearDeviceOwnerApp(admin1.getPackageName());
+        });
     }
 
     public void testGetLastSecurityLogRetrievalTime() throws Exception {
@@ -3193,7 +3026,7 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
         when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
                 .thenReturn(true);
 
@@ -3202,9 +3035,9 @@
 
         // Enabling logging should not change the timestamp.
         dpm.setSecurityLoggingEnabled(admin1, true);
-        verify(mContext.settings)
+        verify(getServices().settings)
                 .securityLogSetLoggingEnabledProperty(true);
-        when(mContext.settings.securityLogGetLoggingEnabledProperty())
+        when(getServices().settings.securityLogGetLoggingEnabledProperty())
                 .thenReturn(true);
         assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
 
@@ -3268,7 +3101,7 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
 
         // No bug reports were requested so far.
         assertEquals(-1, dpm.getLastBugReportRequestTime());
@@ -3316,8 +3149,8 @@
 
         // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
         // feature is disabled because there are non-affiliated secondary users.
-        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
-        when(mContext.iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
+        getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE);
+        when(getServices().iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
                 .thenReturn(true);
 
         // No logs were retrieved so far.
@@ -3388,7 +3221,7 @@
 
         // Add a secondary user, it should never talk with.
         final int ANOTHER_USER_ID = 36;
-        mContext.addUser(ANOTHER_USER_ID, 0);
+        getServices().addUser(ANOTHER_USER_ID, 0);
 
         // Since the managed profile is not affiliated, they should not be allowed to talk to each
         // other.
@@ -3469,7 +3302,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         // Lock task packages are updated when loading user data.
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0]));
 
         // Set up a managed profile managed by different package (package name shouldn't matter)
@@ -3478,7 +3311,7 @@
         final ComponentName adminDifferentPackage =
                 new ComponentName("another.package", "whatever.class");
         addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
 
         // The DO can still set lock task packages
@@ -3488,22 +3321,16 @@
         MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1));
         assertTrue(dpm.isLockTaskPermitted("doPackage1"));
         assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages));
 
         // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         final String[] poPackages = {"poPackage1", "poPackage2"};
-        try {
-            dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
-            fail("Didn't throw expected security exception.");
-        } catch (SecurityException expected) {
-        }
-        try {
-            dpm.getLockTaskPackages(adminDifferentPackage);
-            fail("Didn't throw expected security exception.");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.setLockTaskPackages(adminDifferentPackage, poPackages));
+        assertExpectException(SecurityException.class, /* messageRegex =*/ null,
+                () -> dpm.getLockTaskPackages(adminDifferentPackage));
         assertFalse(dpm.isLockTaskPermitted("doPackage1"));
 
         // Setting same affiliation ids
@@ -3519,14 +3346,14 @@
         MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage));
         assertTrue(dpm.isLockTaskPermitted("poPackage1"));
         assertFalse(dpm.isLockTaskPermitted("doPackage2"));
-        verify(mContext.iactivityManager)
+        verify(getServices().iactivityManager)
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages));
 
         // Unaffiliate the profile, lock task mode no longer available on the profile.
         dpm.setAffiliationIds(adminDifferentPackage, Collections.emptySet());
         assertFalse(dpm.isLockTaskPermitted("poPackage1"));
         // Lock task packages cleared when loading user data and when the user becomes unaffiliated.
-        verify(mContext.iactivityManager, times(2))
+        verify(getServices().iactivityManager, times(2))
                 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3590,11 +3417,11 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
         dpm.wipeData(0);
-        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
+        verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(
                 MANAGED_PROFILE_USER_ID);
     }
 
@@ -3604,48 +3431,56 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        try {
-            // The PO is not allowed to remove the profile if the user restriction was set on the
-            // profile by the system
-            dpm.wipeData(0);
-            fail("SecurityException not thrown");
-        } catch (SecurityException expected) {
-        }
+        // The PO is not allowed to remove the profile if the user restriction was set on the
+        // profile by the system
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.wipeData(0));
     }
 
     public void testWipeDataDeviceOwner() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
 
         dpm.wipeData(0);
-        verify(mContext.recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
+    }
+
+    public void testWipeEuiccDataEnabled() throws Exception {
+        setDeviceOwner();
+        when(getServices().userManager.getUserRestrictionSource(
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserHandle.SYSTEM))
+            .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+
+        dpm.wipeData(WIPE_EUICC);
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(true));
     }
 
     public void testWipeDataDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
-        try {
-            // The DO is not allowed to wipe the device if the user restriction was set
-            // by the system
-            dpm.wipeData(0);
-            fail("SecurityException not thrown");
-        } catch (SecurityException expected) {
-        }
+        // The DO is not allowed to wipe the device if the user restriction was set
+        // by the system
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.wipeData(0));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception {
@@ -3654,10 +3489,10 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
@@ -3675,9 +3510,9 @@
 
         // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because
         // both the user restriction and the policy were set by the PO.
-        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
+        verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(
                 MANAGED_PROFILE_USER_ID);
-        verifyZeroInteractions(mContext.recoverySystem);
+        verifyZeroInteractions(getServices().recoverySystem);
     }
 
     public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()
@@ -3687,10 +3522,10 @@
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
 
         // Even if the caller is the managed profile, the current user is the user 0
-        when(mContext.iactivityManager.getCurrentUser())
+        when(getServices().iactivityManager.getCurrentUser())
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                 UserHandle.of(MANAGED_PROFILE_USER_ID)))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -3708,14 +3543,14 @@
 
         // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is
         // not wiped.
-        verify(mContext.userManagerInternal, never())
+        verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
-        verifyZeroInteractions(mContext.recoverySystem);
+        verifyZeroInteractions(getServices().recoverySystem);
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
@@ -3730,13 +3565,14 @@
 
         // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
         // user restriction and the policy were set by the DO.
-        verify(mContext.recoverySystem).rebootWipeUserData(
-                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
+        verify(getServices().recoverySystem).rebootWipeUserData(
+                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true),
+                /*wipeEuicc=*/ eq(false));
     }
 
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
-        when(mContext.userManager.getUserRestrictionSource(
+        when(getServices().userManager.getUserRestrictionSource(
                 UserManager.DISALLOW_FACTORY_RESET,
                 UserHandle.SYSTEM))
                 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
@@ -3750,8 +3586,8 @@
         dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
 
         // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped.
-        verifyZeroInteractions(mContext.recoverySystem);
-        verify(mContext.userManagerInternal, never())
+        verifyZeroInteractions(getServices().recoverySystem);
+        verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
     }
 
@@ -3760,18 +3596,18 @@
         final String app1 = "com.example.app1";
         final String app2 = "com.example.app2";
 
-        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
+        when(getServices().ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
-        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager)
+        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(getServices().packageManager)
                 .getPermissionFlags(permission, app1, UserHandle.SYSTEM);
-        when(mContext.packageManager.getPermissionFlags(permission, app1,
+        when(getServices().packageManager.getPermissionFlags(permission, app1,
                 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
                 .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
-        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
+        when(getServices().ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
                 .thenReturn(PackageManager.PERMISSION_DENIED);
-        doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2,
+        doReturn(0).when(getServices().packageManager).getPermissionFlags(permission, app2,
                 UserHandle.SYSTEM);
-        when(mContext.packageManager.getPermissionFlags(permission, app2,
+        when(getServices().packageManager.getPermissionFlags(permission, app2,
                 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);
 
         // System can retrieve permission grant state.
@@ -3785,11 +3621,8 @@
         // A regular app cannot retrieve permission grant state.
         mContext.binder.callingUid = setupPackageInPackageManager(app1, 1);
         mContext.packageName = app1;
-        try {
-            dpm.getPermissionGrantState(null, app1, permission);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException expected) {
-        }
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpm.getPermissionGrantState(null, app1, permission));
 
         // Profile owner can retrieve permission grant state.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -3805,37 +3638,113 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         // test token validation
-        try {
-            dpm.setResetPasswordToken(admin1, new byte[31]);
-            fail("should not have accepted tokens too short");
-        } catch (IllegalArgumentException expected) {
-        }
+        assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
+                () -> dpm.setResetPasswordToken(admin1, new byte[31]));
+
         // test adding a token
         final byte[] token = new byte[32];
         final long handle = 123456;
         final String password = "password";
-        when(mContext.lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
             .thenReturn(handle);
         assertTrue(dpm.setResetPasswordToken(admin1, token));
 
         // test password activation
-        when(mContext.lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
             .thenReturn(true);
         assertTrue(dpm.isResetPasswordTokenActive(admin1));
 
         // test reset password with token
-        when(mContext.lockPatternUtils.setLockCredentialWithToken(eq(password),
+        when(getServices().lockPatternUtils.setLockCredentialWithToken(eq(password),
                 eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), eq(handle), eq(token),
                 eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(true);
         assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));
 
         // test removing a token
-        when(mContext.lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(true);
         assertTrue(dpm.clearResetPasswordToken(admin1));
     }
 
+    public void testIsActivePasswordSufficient() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        mContext.packageName = admin1.getPackageName();
+        setupDeviceOwner();
+
+        dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
+        dpm.setPasswordMinimumLength(admin1, 8);
+        dpm.setPasswordMinimumLetters(admin1, 6);
+        dpm.setPasswordMinimumLowerCase(admin1, 3);
+        dpm.setPasswordMinimumUpperCase(admin1, 1);
+        dpm.setPasswordMinimumNonLetter(admin1, 1);
+        dpm.setPasswordMinimumNumeric(admin1, 1);
+        dpm.setPasswordMinimumSymbols(admin1, 0);
+
+        PasswordMetrics passwordMetricsNoSymbols = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
+                8, 2,
+                6, 1,
+                0, 1);
+
+        setActivePasswordState(passwordMetricsNoSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        initializeDpms();
+        reset(mContext.spiedContext);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        // This call simulates the user entering the password for the first time after a reboot.
+        // This causes password metrics to be reloaded into memory.  Until this happens,
+        // dpm.isActivePasswordSufficient() will continue to return its last checkpointed value,
+        // even if the DPC changes password requirements so that the password no longer meets the
+        // requirements.  This is a known limitation of the current implementation of
+        // isActivePasswordSufficient() - see b/34218769.
+        setActivePasswordState(passwordMetricsNoSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+
+        dpm.setPasswordMinimumSymbols(admin1, 1);
+        // This assertion would fail if we had not called setActivePasswordState() again after
+        // initializeDpms() - see previous comment.
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        initializeDpms();
+        reset(mContext.spiedContext);
+        assertFalse(dpm.isActivePasswordSufficient());
+
+        PasswordMetrics passwordMetricsWithSymbols = new PasswordMetrics(
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
+                7, 2,
+                5, 1,
+                1, 2);
+
+        setActivePasswordState(passwordMetricsWithSymbols);
+        assertTrue(dpm.isActivePasswordSufficient());
+    }
+
+    private void setActivePasswordState(PasswordMetrics passwordMetrics)
+            throws Exception {
+        final int userHandle = UserHandle.getUserId(mContext.binder.callingUid);
+        final long ident = mContext.binder.clearCallingIdentity();
+
+        dpm.setActivePasswordState(passwordMetrics, userHandle);
+        dpm.reportPasswordChanged(userHandle);
+
+        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
+        intent.setComponent(admin1);
+        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(mContext.binder.callingUid));
+
+        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
+                MockUtils.checkIntent(intent),
+                MockUtils.checkUserHandle(userHandle));
+
+        // CertificateMonitor.updateInstalledCertificates is called on the background thread,
+        // let it finish with system uid, otherwise it will throw and crash.
+        flushTasks();
+
+        mContext.binder.restoreCallingIdentity(ident);
+    }
+
     public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception {
         final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
         final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
@@ -3857,12 +3766,12 @@
 
         // Device owner changes IME for first user.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
                 .thenReturn("ime1");
         dpm.setSecureSetting(admin1, currentIme, "ime2");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
                 UserHandle.USER_SYSTEM);
-        reset(mContext.settings);
+        reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
         assertTrue(dpm.isCurrentInputMethodSetByOwner());
@@ -3885,10 +3794,10 @@
 
         // Device owner changes IME for first user again.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
                 .thenReturn("ime2");
         dpm.setSecureSetting(admin1, currentIme, "ime3");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
                 UserHandle.USER_SYSTEM);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
@@ -3936,12 +3845,12 @@
 
         // Profile owner changes IME for second user.
         mContext.binder.callingUid = profileOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
                 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1");
         dpm.setSecureSetting(admin1, currentIme, "ime2");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
                 DpmMockContext.CALLER_USER_HANDLE);
-        reset(mContext.settings);
+        reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
         assertFalse(dpm.isCurrentInputMethodSetByOwner());
@@ -3964,10 +3873,10 @@
 
         // Profile owner changes IME for second user again.
         mContext.binder.callingUid = profileOwnerUid;
-        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
                 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2");
         dpm.setSecureSetting(admin1, currentIme, "ime3");
-        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
+        verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
                 DpmMockContext.CALLER_USER_HANDLE);
         dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
@@ -4026,7 +3935,7 @@
         // Attempt to set to empty list (which means no listener is whitelisted)
         mContext.binder.callingUid = adminUid;
         assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4049,12 +3958,10 @@
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
                 admin1, Collections.singletonList(permittedListener)));
 
-        try {
-            dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID);
-            fail("isNotificationListenerServicePermitted should throw if not called from System");
-        } catch (SecurityException expected) {
-        }
+        // isNotificationListenerServicePermitted should throw if not called from System.
+        assertExpectException(SecurityException.class, /* messageRegex= */ null,
+                () -> dpms.isNotificationListenerServicePermitted(
+                        permittedListener, MANAGED_PROFILE_USER_ID));
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         assertTrue(dpms.isNotificationListenerServicePermitted(
@@ -4103,7 +4010,7 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
                 admin1, Collections.singletonList(permittedListener)));
-        List<String> permittedListeners =
+        final List<String> permittedListeners =
                 dpms.getPermittedCrossProfileNotificationListeners(admin1);
         assertEquals(1, permittedListeners.size());
         assertEquals(permittedListener, permittedListeners.get(0));
@@ -4120,7 +4027,7 @@
         // Setting an empty whitelist - only system listeners allowed
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4184,7 +4091,7 @@
         // all allowed in primary profile
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.<String>emptyList()));
+                admin1, Collections.emptyList()));
         assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -4199,39 +4106,38 @@
     }
 
     public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setDeviceOwner();
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = admin1.getPackageName();
-        caller.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-
-        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
+        verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context);
     }
 
     public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
         setAsProfileOwner(admin1);
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = admin1.getPackageName();
-        caller.binder.callingUid = DpmMockContext.CALLER_UID;
-
-        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
-        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, caller);
+        verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context);
+        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, mAdmin1Context);
     }
 
     public void testGetOwnerInstalledCaCertsForDelegate() throws Exception {
-        mContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.packageName = mRealTestContext.getPackageName();
+        mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
         setAsProfileOwner(admin1);
 
-        final String delegate = "com.example.delegate";
-        final int delegateUid = setupPackageInPackageManager(delegate, 20988);
-        dpm.setCertInstallerPackage(admin1, delegate);
+        final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext);
+        caller.packageName = "com.example.delegate";
+        caller.binder.callingUid = setupPackageInPackageManager(caller.packageName,
+                DpmMockContext.CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE);
 
-        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
-        caller.packageName = delegate;
-        caller.binder.callingUid = delegateUid;
+        // Make caller a delegated cert installer.
+        runAsCaller(mAdmin1Context, dpms,
+                dpm -> dpm.setCertInstallerPackage(admin1, caller.packageName));
 
         verifyCanGetOwnerInstalledCaCerts(null, caller);
         verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller);
@@ -4243,13 +4149,9 @@
         final byte[] caCert = TEST_CA.getBytes();
 
         // device admin (used for posting the tls notification)
-        final DpmMockContext admin1Context;
+        DpmMockContext admin1Context = mAdmin1Context;
         if (admin1.getPackageName().equals(callerContext.getPackageName())) {
             admin1Context = callerContext;
-        } else {
-            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
-            admin1Context.packageName = admin1.getPackageName();
-            admin1Context.applicationInfo = new ApplicationInfo();
         }
         when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
@@ -4260,21 +4162,21 @@
         // system_server
         final DpmMockContext serviceContext = mContext;
         serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        serviceContext.addPackageContext(callerUser, admin1Context);
-        serviceContext.addPackageContext(callerUser, callerContext);
+        getServices().addPackageContext(callerUser, admin1Context);
+        getServices().addPackageContext(callerUser, callerContext);
 
         // Install a CA cert.
         runAsCaller(callerContext, dpms, (dpm) -> {
-            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
+            when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                         .thenReturn(alias);
             assertTrue(dpm.installCaCert(caller, caCert));
-            when(mContext.keyChainConnection.getService().getUserCaAliases())
+            when(getServices().keyChainConnection.getService().getUserCaAliases())
                     .thenReturn(asSlice(new String[] {alias}));
-
         });
 
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         final List<String> ownerInstalledCaCerts = new ArrayList<>();
@@ -4282,26 +4184,26 @@
         // Device Owner / Profile Owner can find out which CA certs were installed by itself.
         runAsCaller(admin1Context, dpms, (dpm) -> {
             final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
-            assertEquals(Arrays.asList(alias), installedCaCerts);
+            assertEquals(Collections.singletonList(alias), installedCaCerts);
             ownerInstalledCaCerts.addAll(installedCaCerts);
         });
 
         // Restarting the DPMS should not lose information.
         initializeDpms();
-        runAsCaller(admin1Context, dpms, (dpm) -> {
-            assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
-        });
+        runAsCaller(admin1Context, dpms, (dpm) ->
+                assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser)));
 
         // System can find out which CA certs were installed by the Device Owner / Profile Owner.
         runAsCaller(serviceContext, dpms, (dpm) -> {
             assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
 
             // Remove the CA cert.
-            reset(mContext.keyChainConnection.getService());
+            reset(getServices().keyChainConnection.getService());
         });
 
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         // Verify that the CA cert is no longer reported as installed by the Device Owner / Profile
@@ -4317,13 +4219,9 @@
         final byte[] caCert = TEST_CA.getBytes();
 
         // device admin (used for posting the tls notification)
-        final DpmMockContext admin1Context;
+        DpmMockContext admin1Context = mAdmin1Context;
         if (admin1.getPackageName().equals(callerContext.getPackageName())) {
             admin1Context = callerContext;
-        } else {
-            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
-            admin1Context.packageName = admin1.getPackageName();
-            admin1Context.applicationInfo = new ApplicationInfo();
         }
         when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
@@ -4334,27 +4232,26 @@
         // system_server
         final DpmMockContext serviceContext = mContext;
         serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        serviceContext.addPackageContext(callerUser, admin1Context);
-        serviceContext.addPackageContext(callerUser, callerContext);
+        getServices().addPackageContext(callerUser, admin1Context);
+        getServices().addPackageContext(callerUser, callerContext);
 
         // Install a CA cert as caller
         runAsCaller(callerContext, dpms, (dpm) -> {
-            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
+            when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                     .thenReturn(alias);
             assertTrue(dpm.installCaCert(callerName, caCert));
         });
 
         // Fake the CA cert as having been installed
-        when(serviceContext.keyChainConnection.getService().getUserCaAliases())
+        when(getServices().keyChainConnection.getService().getUserCaAliases())
                 .thenReturn(asSlice(new String[] {alias}));
-        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
+        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+                callerUser.getIdentifier());
         flushTasks();
 
         // Removing the Profile Owner should clear the information on which CA certs were installed
-        runAsCaller(admin1Context, dpms, (dpm) -> {
-            dpm.clearProfileOwner(admin1);
-        });
+        runAsCaller(admin1Context, dpms, dpm -> dpm.clearProfileOwner(admin1));
 
         runAsCaller(serviceContext, dpms, (dpm) -> {
             final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
@@ -4364,7 +4261,7 @@
     }
 
     private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
-        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
+        when(getServices().settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
                 userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
         dpms.notifyChangeToContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle);
@@ -4377,8 +4274,8 @@
 
     private void assertProvisioningAllowed(String action, boolean expected, String packageName,
             int uid) {
-        String previousPackageName = mContext.packageName;
-        int previousUid = mMockContext.binder.callingUid;
+        final String previousPackageName = mContext.packageName;
+        final int previousUid = mMockContext.binder.callingUid;
 
         // Call assertProvisioningAllowed with the packageName / uid passed as arguments.
         mContext.packageName = packageName;
@@ -4411,7 +4308,7 @@
     private void addManagedProfile(
             ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception {
         final int userId = UserHandle.getUserId(adminUid);
-        mContext.addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
+        getServices().addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
         mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
         setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin);
         dpm.setActiveAdmin(admin, false, userId);
@@ -4432,6 +4329,6 @@
 
         // We can't let exceptions happen on the background thread. Throw them here if they happen
         // so they still cause the test to fail despite being suppressed.
-        mContext.rethrowBackgroundBroadcastExceptions();
+        getServices().rethrowBackgroundBroadcastExceptions();
     }
 }
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 87106ec..9702118 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -16,61 +16,28 @@
 
 package com.android.server.devicepolicy;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlarmManager;
-import android.app.IActivityManager;
-import android.app.NotificationManager;
-import android.app.backup.IBackupManager;
+import static org.mockito.Mockito.mock;
+
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
-import android.media.IAudioService;
-import android.net.IIpConnectivityMetrics;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.PowerManager.WakeLock;
-import android.os.PowerManagerInternal;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.security.KeyChain;
-import android.telephony.TelephonyManager;
-import android.test.mock.MockContentResolver;
 import android.test.mock.MockContext;
 import android.util.ArrayMap;
-import android.util.Pair;
-import android.view.IWindowManager;
-
-import com.android.internal.widget.LockPatternUtils;
 
 import org.junit.Assert;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
 /**
  * Context used throughout DPMS tests.
@@ -107,9 +74,10 @@
     public static final int SYSTEM_PID = 11111;
 
     public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name";
-
     public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434);
 
+    private final MockSystemServices mMockSystemServices;
+
     public static class MockBinder {
         public int callingUid = CALLER_UID;
         public int callingPid = CALLER_PID;
@@ -144,130 +112,7 @@
         }
     }
 
-    public static class EnvironmentForMock {
-        public File getUserSystemDirectory(int userId) {
-            return null;
-        }
-    }
-
-    public static class BuildMock {
-        public boolean isDebuggable = true;
-    }
-
-    public static class PowerManagerForMock {
-        public WakeLock newWakeLock(int levelAndFlags, String tag) {
-            return null;
-        }
-
-        public void goToSleep(long time, int reason, int flags) {
-        }
-
-        public void reboot(String reason) {
-        }
-    }
-
-    public static class RecoverySystemForMock {
-        public void rebootWipeUserData(
-                boolean shutdown, String reason, boolean force) throws IOException {
-        }
-    }
-
-    public static class SystemPropertiesForMock {
-        public boolean getBoolean(String key, boolean def) {
-            return false;
-        }
-
-        public long getLong(String key, long def) {
-            return 0;
-        }
-
-        public String get(String key, String def) {
-            return null;
-        }
-
-        public String get(String key) {
-            return null;
-        }
-
-        public void set(String key, String value) {
-        }
-    }
-
-    public static class UserManagerForMock {
-        public boolean isSplitSystemUser() {
-            return false;
-        }
-    }
-
-    public static class SettingsForMock {
-        public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
-            return 0;
-        }
-
-        public String settingsSecureGetStringForUser(String name, int userHandle) {
-            return null;
-        }
-
-        public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
-        }
-
-        public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
-        }
-
-        public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
-        }
-
-        public void settingsSecurePutInt(String name, int value) {
-        }
-
-        public void settingsGlobalPutInt(String name, int value) {
-        }
-
-        public void settingsSecurePutString(String name, String value) {
-        }
-
-        public void settingsGlobalPutString(String name, String value) {
-        }
-
-        public int settingsGlobalGetInt(String name, int value) {
-            return 0;
-        }
-
-        public String settingsGlobalGetString(String name) {
-            return "";
-        }
-
-        public void securityLogSetLoggingEnabledProperty(boolean enabled) {
-        }
-
-        public boolean securityLogGetLoggingEnabledProperty() {
-            return false;
-        }
-
-        public boolean securityLogIsLoggingEnabled() {
-            return false;
-        }
-    }
-
-    public static class StorageManagerForMock {
-        public boolean isFileBasedEncryptionEnabled() {
-            return false;
-        }
-
-        public boolean isNonDefaultBlockEncrypted() {
-            return false;
-        }
-
-        public boolean isEncrypted() {
-            return false;
-        }
-
-        public boolean isEncryptable() {
-            return false;
-        }
-    }
-
-    public final Context realTestContext;
+    private final Context realTestContext;
 
     /**
      * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
@@ -276,39 +121,8 @@
      */
     public final Context spiedContext;
 
-    public final File dataDir;
-    public final File systemUserDataDir;
-
     public final MockBinder binder;
-    public final EnvironmentForMock environment;
     public final Resources resources;
-    public final SystemPropertiesForMock systemProperties;
-    public final UserManager userManager;
-    public final UserManagerInternal userManagerInternal;
-    public final PackageManagerInternal packageManagerInternal;
-    public final UserManagerForMock userManagerForMock;
-    public final PowerManagerForMock powerManager;
-    public final PowerManagerInternal powerManagerInternal;
-    public final RecoverySystemForMock recoverySystem;
-    public final NotificationManager notificationManager;
-    public final IIpConnectivityMetrics iipConnectivityMetrics;
-    public final IWindowManager iwindowManager;
-    public final IActivityManager iactivityManager;
-    public final IPackageManager ipackageManager;
-    public final IBackupManager ibackupManager;
-    public final IAudioService iaudioService;
-    public final LockPatternUtils lockPatternUtils;
-    public final StorageManagerForMock storageManager;
-    public final WifiManager wifiManager;
-    public final SettingsForMock settings;
-    public final MockContentResolver contentResolver;
-    public final TelephonyManager telephonyManager;
-    public final AccountManager accountManager;
-    public final AlarmManager alarmManager;
-    public final KeyChain.KeyChainConnection keyChainConnection;
-
-    /** Note this is a partial mock, not a real mock. */
-    public final PackageManager packageManager;
 
     /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */
     @Deprecated
@@ -317,246 +131,17 @@
     /** Less confusing alias for {@link #callerPermissions}. */
     public final List<String> permissions = callerPermissions;
 
-    private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
-
-    public final BuildMock buildMock = new BuildMock();
-
-    /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
-    public final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
-
     public String packageName = null;
 
     public ApplicationInfo applicationInfo = null;
 
-    // We have to keep track of broadcast receivers registered for a given intent ourselves as the
-    // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
-    // not work.
-    private class BroadcastReceiverRegistration {
-        public final BroadcastReceiver receiver;
-        public final IntentFilter filter;
-        public final Handler scheduler;
-
-        // Exceptions thrown in a background thread kill the whole test. Save them instead.
-        public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
-
-        public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
-                Handler scheduler) {
-            this.receiver = receiver;
-            this.filter = filter;
-            this.scheduler = scheduler;
-        }
-
-        public void sendBroadcastIfApplicable(int userId, Intent intent) {
-            final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
-                    0 /* resultCode */, null /* resultData */, null /* resultExtras */,
-                    0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
-                    0 /* flags */);
-            if (filter.match(null, intent, false, "DpmMockContext") > 0) {
-                final Runnable send = () -> {
-                    receiver.setPendingResult(result);
-                    receiver.onReceive(DpmMockContext.this, intent);
-                };
-                if (scheduler != null) {
-                    scheduler.post(() -> {
-                        try {
-                            send.run();
-                        } catch (Exception e) {
-                            backgroundException.compareAndSet(null, e);
-                        }
-                    });
-                } else {
-                    send.run();
-                }
-            }
-        }
-    }
-    private List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
-
-    public DpmMockContext(Context realTestContext, String name) {
-        this(realTestContext, new File(realTestContext.getCacheDir(), name));
-    }
-
-    public DpmMockContext(Context context, File dataDir) {
+    public DpmMockContext(MockSystemServices mockSystemServices, Context context) {
+        mMockSystemServices = mockSystemServices;
         realTestContext = context;
 
-        this.dataDir = dataDir;
-        DpmTestUtils.clearDir(dataDir);
-
         binder = new MockBinder();
-        environment = mock(EnvironmentForMock.class);
         resources = mock(Resources.class);
-        systemProperties = mock(SystemPropertiesForMock.class);
-        userManager = mock(UserManager.class);
-        userManagerInternal = mock(UserManagerInternal.class);
-        userManagerForMock = mock(UserManagerForMock.class);
-        packageManagerInternal = mock(PackageManagerInternal.class);
-        powerManager = mock(PowerManagerForMock.class);
-        powerManagerInternal = mock(PowerManagerInternal.class);
-        recoverySystem = mock(RecoverySystemForMock.class);
-        notificationManager = mock(NotificationManager.class);
-        iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
-        iwindowManager = mock(IWindowManager.class);
-        iactivityManager = mock(IActivityManager.class);
-        ipackageManager = mock(IPackageManager.class);
-        ibackupManager = mock(IBackupManager.class);
-        iaudioService = mock(IAudioService.class);
-        lockPatternUtils = mock(LockPatternUtils.class);
-        storageManager = mock(StorageManagerForMock.class);
-        wifiManager = mock(WifiManager.class);
-        settings = mock(SettingsForMock.class);
-        telephonyManager = mock(TelephonyManager.class);
-        accountManager = mock(AccountManager.class);
-        alarmManager = mock(AlarmManager.class);
-        keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
-
-        // Package manager is huge, so we use a partial mock instead.
-        packageManager = spy(context.getPackageManager());
-
         spiedContext = mock(Context.class);
-
-        contentResolver = new MockContentResolver();
-
-        // Add the system user with a fake profile group already set up (this can happen in the real
-        // world if a managed profile is added and then removed).
-        systemUserDataDir =
-                addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
-
-        // System user is always running.
-        setUserRunning(UserHandle.USER_SYSTEM, true);
-    }
-
-    public File addUser(int userId, int flags) {
-        return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
-    }
-
-    public File addUser(int userId, int flags, int profileGroupId) {
-        // Set up (default) UserInfo for CALLER_USER_HANDLE.
-        final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
-        uh.profileGroupId = profileGroupId;
-        when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
-
-        mUserInfos.add(uh);
-        when(userManager.getUsers()).thenReturn(mUserInfos);
-        when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
-        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
-        when(userManager.getUserInfo(anyInt())).thenAnswer(
-                new Answer<UserInfo>() {
-                    @Override
-                    public UserInfo answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        return getUserInfo(userId);
-                    }
-                }
-        );
-        when(userManager.getProfiles(anyInt())).thenAnswer(
-                new Answer<List<UserInfo>>() {
-                    @Override
-                    public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        return getProfiles(userId);
-                    }
-                }
-        );
-        when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
-                new Answer<int[]>() {
-                    @Override
-                    public int[] answer(InvocationOnMock invocation) throws Throwable {
-                        final int userId = (int) invocation.getArguments()[0];
-                        List<UserInfo> profiles = getProfiles(userId);
-                        return profiles.stream()
-                                .mapToInt(profile -> profile.id)
-                                .toArray();
-                    }
-                }
-        );
-        when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
-
-        // Create a data directory.
-        final File dir = new File(dataDir, "users/" + userId);
-        DpmTestUtils.clearDir(dir);
-
-        when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
-        return dir;
-    }
-
-    public void removeUser(int userId) {
-        for (int i = 0; i < mUserInfos.size(); i++) {
-            if (mUserInfos.get(i).id == userId) {
-                mUserInfos.remove(i);
-                break;
-            }
-        }
-        when(userManager.getUserInfo(eq(userId))).thenReturn(null);
-
-        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
-    }
-
-    private UserInfo getUserInfo(int userId) {
-        for (UserInfo ui : mUserInfos) {
-            if (ui.id == userId) {
-                return ui;
-            }
-        }
-        return null;
-    }
-
-    private List<UserInfo> getProfiles(int userId) {
-        final ArrayList<UserInfo> ret = new ArrayList<UserInfo>();
-        UserInfo parent = null;
-        for (UserInfo ui : mUserInfos) {
-            if (ui.id == userId) {
-                parent = ui;
-                break;
-            }
-        }
-        if (parent == null) {
-            return ret;
-        }
-        for (UserInfo ui : mUserInfos) {
-            if (ui == parent
-                    || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
-                    && ui.profileGroupId == parent.profileGroupId) {
-                ret.add(ui);
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Add multiple users at once.  They'll all have flag 0.
-     */
-    public void addUsers(int... userIds) {
-        for (int userId : userIds) {
-            addUser(userId, 0);
-        }
-    }
-
-    public void setUserRunning(int userId, boolean isRunning) {
-        when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
-                .thenReturn(isRunning);
-    }
-
-    public void injectBroadcast(final Intent intent) {
-        final int userId = UserHandle.getUserId(binder.getCallingUid());
-        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
-            receiver.sendBroadcastIfApplicable(userId, intent);
-        }
-    }
-
-    public void rethrowBackgroundBroadcastExceptions() throws Exception {
-        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
-            final Exception e = receiver.backgroundException.getAndSet(null);
-            if (e != null) {
-                throw e;
-            }
-        }
-    }
-
-    public void addPackageContext(UserHandle user, Context context) {
-        if (context.getPackageName() == null) {
-            throw new NullPointerException("getPackageName() == null");
-        }
-        userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
     }
 
     @Override
@@ -589,15 +174,15 @@
     public Object getSystemService(String name) {
         switch (name) {
             case Context.ALARM_SERVICE:
-                return alarmManager;
+                return mMockSystemServices.alarmManager;
             case Context.USER_SERVICE:
-                return userManager;
+                return mMockSystemServices.userManager;
             case Context.POWER_SERVICE:
-                return powerManager;
+                return mMockSystemServices.powerManager;
             case Context.WIFI_SERVICE:
-                return wifiManager;
+                return mMockSystemServices.wifiManager;
             case Context.ACCOUNT_SERVICE:
-                return accountManager;
+                return mMockSystemServices.accountManager;
         }
         throw new UnsupportedOperationException();
     }
@@ -609,22 +194,25 @@
 
     @Override
     public PackageManager getPackageManager() {
-        return packageManager;
+        return mMockSystemServices.packageManager;
+    }
+
+    public UserManagerInternal getUserManagerInternal() {
+        return mMockSystemServices.userManagerInternal;
     }
 
     @Override
     public void enforceCallingOrSelfPermission(String permission, String message) {
-        if (binder.getCallingUid() == SYSTEM_UID) {
+        if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
             return; // Assume system has all permissions.
         }
-
         List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
         if (permissions == null) {
             // TODO: delete the following line. to do this without breaking any tests, first it's
             //       necessary to remove all tests that set it directly.
             permissions = callerPermissions;
-//            throw new UnsupportedOperationException(
-//                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
+            //            throw new UnsupportedOperationException(
+            //                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
         }
         if (!permissions.contains(permission)) {
             throw new SecurityException("Caller doesn't have " + permission + " : " + message);
@@ -773,44 +361,40 @@
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, null));
+        mMockSystemServices.registerReceiver(receiver, filter, null);
         return spiedContext.registerReceiver(receiver, filter);
     }
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
             String broadcastPermission, Handler scheduler) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
         return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
     }
 
     @Override
     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
             IntentFilter filter, String broadcastPermission, Handler scheduler) {
-        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+        mMockSystemServices.registerReceiver(receiver, filter, scheduler);
         return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
                 scheduler);
     }
 
     @Override
     public void unregisterReceiver(BroadcastReceiver receiver) {
-        mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
+        mMockSystemServices.unregisterReceiver(receiver);
         spiedContext.unregisterReceiver(receiver);
     }
 
     @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws PackageManager.NameNotFoundException {
-        final Pair<UserHandle, String> key = new Pair<>(user, packageName);
-        if (userPackageContexts.containsKey(key)) {
-            return userPackageContexts.get(key);
-        }
-        throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
+        return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
     }
 
     @Override
     public ContentResolver getContentResolver() {
-        return contentResolver;
+        return mMockSystemServices.contentResolver;
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index 5d68edd..e0ea573 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -16,6 +16,10 @@
 
 package com.android.server.devicepolicy;
 
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -28,20 +32,14 @@
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
 
-import java.io.File;
 import java.util.List;
 
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-
 public abstract class DpmTestBase extends AndroidTestCase {
     public static final String TAG = "DpmTest";
 
     protected Context mRealTestContext;
     protected DpmMockContext mMockContext;
-
-    public File dataDir;
+    private MockSystemServices mServices;
 
     public ComponentName admin1;
     public ComponentName admin2;
@@ -55,8 +53,8 @@
 
         mRealTestContext = super.getContext();
 
-        mMockContext = new DpmMockContext(
-                mRealTestContext, new File(mRealTestContext.getCacheDir(), "test-data"));
+        mServices = new MockSystemServices(mRealTestContext, "test-data");
+        mMockContext = new DpmMockContext(mServices, mRealTestContext);
 
         admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
         admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
@@ -71,12 +69,16 @@
         return mMockContext;
     }
 
+    public MockSystemServices getServices() {
+        return mServices;
+    }
+
     protected interface DpmRunnable {
-        public void run(DevicePolicyManager dpm) throws Exception;
+        void run(DevicePolicyManager dpm) throws Exception;
     }
 
     /**
-     * Simulate an RPC from {@param caller} to the service context ({@link #mContext}).
+     * Simulate an RPC from {@param caller} to the service context ({@link #mMockContext}).
      *
      * The caller sees its own context. The server also sees its own separate context, with the
      * appropriate calling UID and calling permissions fields already set up.
@@ -85,12 +87,15 @@
             DpmRunnable action) {
         final DpmMockContext serviceContext = mMockContext;
 
+        // Save calling UID and PID before clearing identity so we don't run into aliasing issues.
+        final int callingUid = caller.binder.callingUid;
+        final int callingPid = caller.binder.callingPid;
+
         final long origId = serviceContext.binder.clearCallingIdentity();
         try {
-            serviceContext.binder.callingUid = caller.binder.callingUid;
-            serviceContext.binder.callingPid = caller.binder.callingPid;
-            serviceContext.binder.callingPermissions.put(caller.binder.callingUid,
-                    caller.permissions);
+            serviceContext.binder.callingUid = callingUid;
+            serviceContext.binder.callingPid = callingPid;
+            serviceContext.binder.callingPermissions.put(callingUid, caller.permissions);
             action.run(new DevicePolicyManagerTestable(caller, dpms));
         } catch (Exception e) {
             throw new AssertionError(e);
@@ -99,7 +104,7 @@
         }
     }
 
-    protected void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
+    private void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
             throws Exception {
         final PackageInfo pi = DpmTestUtils.cloneParcelable(
                 mRealTestContext.getPackageManager().getPackageInfo(
@@ -110,12 +115,12 @@
             pi.applicationInfo = ai;
         }
 
-        doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
+        doReturn(pi).when(mServices.ipackageManager).getPackageInfo(
                 eq(packageName),
                 eq(0),
                 eq(userId));
 
-        doReturn(ai.uid).when(mMockContext.packageManager).getPackageUidAsUser(
+        doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(
                 eq(packageName),
                 eq(userId));
     }
@@ -151,7 +156,7 @@
      * @param copyFromAdmin package information for {@code admin} will be built based on this
      *    component's information.
      */
-    protected void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
+    private void setUpPackageManagerForFakeAdmin(ComponentName admin, int packageUid,
             Integer enabledSetting, Integer appTargetSdk, ComponentName copyFromAdmin)
             throws Exception {
 
@@ -171,7 +176,7 @@
         ai.packageName = admin.getPackageName();
         ai.name = admin.getClassName();
 
-        doReturn(ai).when(mMockContext.ipackageManager).getApplicationInfo(
+        doReturn(ai).when(mServices.ipackageManager).getApplicationInfo(
                 eq(admin.getPackageName()),
                 anyInt(),
                 eq(UserHandle.getUserId(packageUid)));
@@ -198,12 +203,12 @@
 
         // Note we don't set up queryBroadcastReceivers.  We don't use it in DPMS.
 
-        doReturn(aci).when(mMockContext.ipackageManager).getReceiverInfo(
+        doReturn(aci).when(mServices.ipackageManager).getReceiverInfo(
                 eq(admin),
                 anyInt(),
                 eq(UserHandle.getUserId(packageUid)));
 
-        doReturn(new String[] {admin.getPackageName()}).when(mMockContext.ipackageManager)
+        doReturn(new String[] {admin.getPackageName()}).when(mServices.ipackageManager)
             .getPackagesForUid(eq(packageUid));
         // Set up getPackageInfo().
         markPackageAsInstalled(admin.getPackageName(), ai, UserHandle.getUserId(packageUid));
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
new file mode 100644
index 0000000..99f54ba
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -0,0 +1,462 @@
+/*
+ * 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.devicepolicy;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlarmManager;
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.app.backup.IBackupManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserInfo;
+import android.media.IAudioService;
+import android.net.IIpConnectivityMetrics;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.provider.Settings;
+import android.security.KeyChain;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentResolver;
+import android.util.ArrayMap;
+import android.util.Pair;
+import android.view.IWindowManager;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * System services mocks and some other data that are shared by all contexts during the test.
+ */
+public class MockSystemServices {
+    public final File systemUserDataDir;
+    public final EnvironmentForMock environment;
+    public final SystemPropertiesForMock systemProperties;
+    public final UserManager userManager;
+    public final UserManagerInternal userManagerInternal;
+    public final PackageManagerInternal packageManagerInternal;
+    public final UserManagerForMock userManagerForMock;
+    public final PowerManagerForMock powerManager;
+    public final PowerManagerInternal powerManagerInternal;
+    public final RecoverySystemForMock recoverySystem;
+    public final NotificationManager notificationManager;
+    public final IIpConnectivityMetrics iipConnectivityMetrics;
+    public final IWindowManager iwindowManager;
+    public final IActivityManager iactivityManager;
+    public final IPackageManager ipackageManager;
+    public final IBackupManager ibackupManager;
+    public final IAudioService iaudioService;
+    public final LockPatternUtils lockPatternUtils;
+    public final StorageManagerForMock storageManager;
+    public final WifiManager wifiManager;
+    public final SettingsForMock settings;
+    public final MockContentResolver contentResolver;
+    public final TelephonyManager telephonyManager;
+    public final AccountManager accountManager;
+    public final AlarmManager alarmManager;
+    public final KeyChain.KeyChainConnection keyChainConnection;
+    /** Note this is a partial mock, not a real mock. */
+    public final PackageManager packageManager;
+    public final BuildMock buildMock = new BuildMock();
+    public final File dataDir;
+
+    public MockSystemServices(Context realContext, String name) {
+        dataDir = new File(realContext.getCacheDir(), name);
+        DpmTestUtils.clearDir(dataDir);
+
+        environment = mock(EnvironmentForMock.class);
+        systemProperties = mock(SystemPropertiesForMock.class);
+        userManager = mock(UserManager.class);
+        userManagerInternal = mock(UserManagerInternal.class);
+        userManagerForMock = mock(UserManagerForMock.class);
+        packageManagerInternal = mock(PackageManagerInternal.class);
+        powerManager = mock(PowerManagerForMock.class);
+        powerManagerInternal = mock(PowerManagerInternal.class);
+        recoverySystem = mock(RecoverySystemForMock.class);
+        notificationManager = mock(NotificationManager.class);
+        iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
+        iwindowManager = mock(IWindowManager.class);
+        iactivityManager = mock(IActivityManager.class);
+        ipackageManager = mock(IPackageManager.class);
+        ibackupManager = mock(IBackupManager.class);
+        iaudioService = mock(IAudioService.class);
+        lockPatternUtils = mock(LockPatternUtils.class);
+        storageManager = mock(StorageManagerForMock.class);
+        wifiManager = mock(WifiManager.class);
+        settings = mock(SettingsForMock.class);
+        telephonyManager = mock(TelephonyManager.class);
+        accountManager = mock(AccountManager.class);
+        alarmManager = mock(AlarmManager.class);
+        keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
+
+        // Package manager is huge, so we use a partial mock instead.
+        packageManager = spy(realContext.getPackageManager());
+
+        contentResolver = new MockContentResolver();
+        contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+
+        // Add the system user with a fake profile group already set up (this can happen in the real
+        // world if a managed profile is added and then removed).
+        systemUserDataDir =
+                addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
+
+        // System user is always running.
+        setUserRunning(UserHandle.USER_SYSTEM, true);
+    }
+
+    /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
+    private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
+
+    private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
+
+    private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
+
+    public void registerReceiver(
+            BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) {
+        mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
+    }
+
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
+    }
+
+    public File addUser(int userId, int flags) {
+        return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
+    }
+
+    public File addUser(int userId, int flags, int profileGroupId) {
+        // Set up (default) UserInfo for CALLER_USER_HANDLE.
+        final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
+        uh.profileGroupId = profileGroupId;
+        when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
+
+        mUserInfos.add(uh);
+        when(userManager.getUsers()).thenReturn(mUserInfos);
+        when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
+        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
+        when(userManager.getUserInfo(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId1 = (int) invocation.getArguments()[0];
+                    return getUserInfo(userId1);
+                }
+        );
+        when(userManager.getProfiles(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId12 = (int) invocation.getArguments()[0];
+                    return getProfiles(userId12);
+                }
+        );
+        when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
+                invocation -> {
+                    final int userId13 = (int) invocation.getArguments()[0];
+                    List<UserInfo> profiles = getProfiles(userId13);
+                    return profiles.stream()
+                            .mapToInt(profile -> profile.id)
+                            .toArray();
+                }
+        );
+        when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
+
+        // Create a data directory.
+        final File dir = new File(dataDir, "users/" + userId);
+        DpmTestUtils.clearDir(dir);
+
+        when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
+        return dir;
+    }
+
+    public void removeUser(int userId) {
+        for (int i = 0; i < mUserInfos.size(); i++) {
+            if (mUserInfos.get(i).id == userId) {
+                mUserInfos.remove(i);
+                break;
+            }
+        }
+        when(userManager.getUserInfo(eq(userId))).thenReturn(null);
+
+        when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
+    }
+
+    private UserInfo getUserInfo(int userId) {
+        for (final UserInfo ui : mUserInfos) {
+            if (ui.id == userId) {
+                return ui;
+            }
+        }
+        return null;
+    }
+
+    private List<UserInfo> getProfiles(int userId) {
+        final ArrayList<UserInfo> ret = new ArrayList<>();
+        UserInfo parent = null;
+        for (final UserInfo ui : mUserInfos) {
+            if (ui.id == userId) {
+                parent = ui;
+                break;
+            }
+        }
+        if (parent == null) {
+            return ret;
+        }
+        for (final UserInfo ui : mUserInfos) {
+            if (ui == parent
+                    || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
+                    && ui.profileGroupId == parent.profileGroupId) {
+                ret.add(ui);
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Add multiple users at once.  They'll all have flag 0.
+     */
+    public void addUsers(int... userIds) {
+        for (final int userId : userIds) {
+            addUser(userId, 0);
+        }
+    }
+
+    public void setUserRunning(int userId, boolean isRunning) {
+        when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
+                .thenReturn(isRunning);
+    }
+
+    public void injectBroadcast(Context context, final Intent intent, int userId) {
+        //final int userId = UserHandle.getUserId(binder.getCallingUid());
+        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
+            receiver.sendBroadcastIfApplicable(context, userId, intent);
+        }
+    }
+
+    public void rethrowBackgroundBroadcastExceptions() throws Exception {
+        for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
+            final Exception e = receiver.backgroundException.getAndSet(null);
+            if (e != null) {
+                throw e;
+            }
+        }
+    }
+
+    public void addPackageContext(UserHandle user, Context context) {
+        if (context.getPackageName() == null) {
+            throw new NullPointerException("getPackageName() == null");
+        }
+        userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
+    }
+
+    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+            throws PackageManager.NameNotFoundException {
+        final Pair<UserHandle, String> key = new Pair<>(user, packageName);
+        if (userPackageContexts.containsKey(key)) {
+            return userPackageContexts.get(key);
+        }
+        throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
+    }
+
+
+    public static class EnvironmentForMock {
+        public File getUserSystemDirectory(int userId) {
+            return null;
+        }
+    }
+
+    public static class BuildMock {
+        public boolean isDebuggable = true;
+    }
+
+    public static class PowerManagerForMock {
+        public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) {
+            return null;
+        }
+
+        public void goToSleep(long time, int reason, int flags) {
+        }
+
+        public void reboot(String reason) {
+        }
+    }
+
+    public static class RecoverySystemForMock {
+        public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
+                boolean wipeEuicc) throws IOException {
+        }
+    }
+
+    public static class SystemPropertiesForMock {
+        public boolean getBoolean(String key, boolean def) {
+            return false;
+        }
+
+        public long getLong(String key, long def) {
+            return 0;
+        }
+
+        public String get(String key, String def) {
+            return null;
+        }
+
+        public String get(String key) {
+            return null;
+        }
+
+        public void set(String key, String value) {
+        }
+    }
+
+    public static class UserManagerForMock {
+        public boolean isSplitSystemUser() {
+            return false;
+        }
+    }
+
+    public static class SettingsForMock {
+        public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
+            return 0;
+        }
+
+        public String settingsSecureGetStringForUser(String name, int userHandle) {
+            return null;
+        }
+
+        public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
+        }
+
+        public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
+        }
+
+        public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
+        }
+
+        public void settingsSecurePutInt(String name, int value) {
+        }
+
+        public void settingsGlobalPutInt(String name, int value) {
+        }
+
+        public void settingsSecurePutString(String name, String value) {
+        }
+
+        public void settingsGlobalPutString(String name, String value) {
+        }
+
+        public int settingsGlobalGetInt(String name, int value) {
+            return 0;
+        }
+
+        public String settingsGlobalGetString(String name) {
+            return "";
+        }
+
+        public void securityLogSetLoggingEnabledProperty(boolean enabled) {
+        }
+
+        public boolean securityLogGetLoggingEnabledProperty() {
+            return false;
+        }
+
+        public boolean securityLogIsLoggingEnabled() {
+            return false;
+        }
+    }
+
+    public static class StorageManagerForMock {
+        public boolean isFileBasedEncryptionEnabled() {
+            return false;
+        }
+
+        public boolean isNonDefaultBlockEncrypted() {
+            return false;
+        }
+
+        public boolean isEncrypted() {
+            return false;
+        }
+
+        public boolean isEncryptable() {
+            return false;
+        }
+    }
+
+    // We have to keep track of broadcast receivers registered for a given intent ourselves as the
+    // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
+    // not work.
+    private static class BroadcastReceiverRegistration {
+        public final BroadcastReceiver receiver;
+        public final IntentFilter filter;
+        public final Handler scheduler;
+
+        // Exceptions thrown in a background thread kill the whole test. Save them instead.
+        public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
+
+        public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
+                Handler scheduler) {
+            this.receiver = receiver;
+            this.filter = filter;
+            this.scheduler = scheduler;
+        }
+
+        public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) {
+            final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
+                    0 /* resultCode */, null /* resultData */, null /* resultExtras */,
+                    0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
+                    0 /* flags */);
+            if (filter.match(null, intent, false, "DpmMockContext") > 0) {
+                final Runnable send = () -> {
+                    receiver.setPendingResult(result);
+                    receiver.onReceive(context, intent);
+                };
+                if (scheduler != null) {
+                    scheduler.post(() -> {
+                        try {
+                            send.run();
+                        } catch (Exception e) {
+                            backgroundException.compareAndSet(null, e);
+                        }
+                    });
+                } else {
+                    send.run();
+                }
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index 423c4d5..85835f7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -20,6 +20,7 @@
 
 import android.content.ComponentName;
 import android.os.UserHandle;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Tests for the DeviceOwner object that saves & loads device and policy owner information.
@@ -32,13 +33,14 @@
 
  (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  */
+@SmallTest
 public class OwnersTest extends DpmTestBase {
     public void testUpgrade01() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test01/input.xml"));
@@ -70,7 +72,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -87,11 +89,11 @@
     }
 
     public void testUpgrade02() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test02/input.xml"));
@@ -125,7 +127,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -145,11 +147,11 @@
     }
 
     public void testUpgrade03() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test03/input.xml"));
@@ -191,7 +193,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -223,11 +225,11 @@
      * and {@link  Owners#setProfileOwnerUserRestrictionsMigrated(int)}.
      */
     public void testUpgrade04() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test04/input.xml"));
@@ -273,7 +275,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -306,7 +308,7 @@
         }
 
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -319,7 +321,7 @@
         }
 
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
@@ -333,11 +335,11 @@
     }
 
     public void testUpgrade05() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test05/input.xml"));
@@ -370,7 +372,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -389,11 +391,11 @@
     }
 
     public void testUpgrade06() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
         // First, migrate.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
 
             DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
                     DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test06/input.xml"));
@@ -425,7 +427,7 @@
 
         // Then re-read and check.
         {
-            final OwnersTestable owners = new OwnersTestable(getContext());
+            final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -444,9 +446,9 @@
     }
 
     public void testRemoveExistingFiles() throws Exception {
-        getContext().addUsers(10, 11, 20, 21);
+        getServices().addUsers(10, 11, 20, 21);
 
-        final OwnersTestable owners = new OwnersTestable(getContext());
+        final OwnersTestable owners = new OwnersTestable(getServices());
 
         // First, migrate to create new-style config files.
         DpmTestUtils.writeToFile(owners.getLegacyConfigFileWithTestOverride(),
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index c399a5d..61df22e 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -29,8 +29,11 @@
 import android.view.WindowManagerInternal;
 
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.display.DisplayDeviceInfo;
 import com.android.server.display.DisplayManagerService.SyncRoot;
 import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
+import com.android.server.lights.LightsManager;
 
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -44,35 +47,51 @@
 
 @SmallTest
 public class DisplayManagerServiceTest extends AndroidTestCase {
-    private Handler mHandler;
-    private DisplayManagerService mDisplayManager;
+    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
+    private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
+
+    private final DisplayManagerService.Injector mShortMockedInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler, DisplayAdapter.Listener listener) {
+                    return mMockVirtualDisplayAdapter;
+                }
+
+                @Override
+                long getDefaultDisplayDelayTimeout() {
+                    return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                }
+            };
+    private final DisplayManagerService.Injector mBasicInjector =
+            new DisplayManagerService.Injector() {
+                @Override
+                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                        Context context, Handler handler,
+                        DisplayAdapter.Listener displayAdapterListener) {
+                    return new VirtualDisplayAdapter(syncRoot, context, handler,
+                            displayAdapterListener,
+                            (String name, boolean secure) -> mMockDisplayToken);
+                }
+            };
+
     @Mock InputManagerInternal mMockInputManagerInternal;
     @Mock IVirtualDisplayCallback.Stub mMockAppToken;
     @Mock WindowManagerInternal mMockWindowManagerInternal;
+    @Mock LightsManager mMockLightsManager;
     @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
     @Mock IBinder mMockDisplayToken;
 
     @Override
     protected void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mDisplayManager = new DisplayManagerService(mContext,
-        new DisplayManagerService.Injector() {
-            @Override
-            VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
-                    Handler handler, DisplayAdapter.Listener displayAdapterListener) {
-                return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
-                        (String name, boolean secure) -> mMockDisplayToken);
-            }
-        });
-        mHandler = mDisplayManager.getDisplayHandler();
 
         LocalServices.removeServiceForTest(InputManagerInternal.class);
         LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal);
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
-
-        mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */);
-        mDisplayManager.windowManagerAndInputReady();
+        LocalServices.removeServiceForTest(LightsManager.class);
+        LocalServices.addService(LightsManager.class, mMockLightsManager);
         super.setUp();
     }
 
@@ -82,8 +101,14 @@
     }
 
     public void testCreateVirtualDisplay_sentToInputManager() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
+        displayManager.windowManagerAndInputReady();
+
         // This is effectively the DisplayManager service published to ServiceManager.
-        DisplayManagerService.BinderService bs = mDisplayManager.new BinderService();
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
 
         String uniqueId = "uniqueId --- Test";
         String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":";
@@ -98,10 +123,10 @@
                 "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
                 uniqueId);
 
-        mDisplayManager.performTraversalInTransactionFromWindowManagerInternal();
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
 
         // flush the handler
-        mHandler.runWithScissors(() -> {}, 0 /* now */);
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
 
         ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor =
                 ArgumentCaptor.forClass(List.class);
@@ -115,4 +140,97 @@
         assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
         assertEquals(displayId, dv.displayId);
     }
+
+    public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+
+        // This is effectively the DisplayManager service published to ServiceManager.
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+        String uniqueId = "uniqueId --- Rotates With Content Test";
+        int width = 600;
+        int height = 800;
+        int dpi = 320;
+        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
+                null /* projection */, "com.android.frameworks.servicestests",
+                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
+                uniqueId);
+
+        displayManager.performTraversalInTransactionFromWindowManagerInternal();
+
+        // flush the handler
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+
+        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+        assertNotNull(ddi);
+        assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+    }
+
+    /**
+     * Tests that the virtual display is created along-side the default display.
+     */
+    public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the default display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        Handler handler = displayManager.getDisplayHandler();
+        handler.runWithScissors(() -> {}, 0 /* now */);
+
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " default display");
+    }
+
+    /**
+     * Tests that we get a Runtime exception when we cannot initialize the virtual display.
+     */
+    public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
+        DisplayManagerService displayManager = new DisplayManagerService(mContext,
+                new DisplayManagerService.Injector() {
+                    @Override
+                    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
+                            Context context, Handler handler, DisplayAdapter.Listener listener) {
+                        return null;  // return null for the adapter.  This should cause a failure.
+                    }
+
+                    @Override
+                    long getDefaultDisplayDelayTimeout() {
+                        return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
+                    }
+                });
+        try {
+            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        } catch (RuntimeException e) {
+            return;
+        }
+        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
+                + " virtual display adapter");
+    }
+
+    private void registerDefaultDisplays(DisplayManagerService displayManager) {
+        Handler handler = displayManager.getDisplayHandler();
+        // Would prefer to call displayManager.onStart() directly here but it performs binderService
+        // registration which triggers security exceptions when running from a test.
+        handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
+        // flush the handler
+        handler.runWithScissors(() -> {}, 0 /* now */);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 33e1a16..689c8f7 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -206,7 +206,8 @@
                 invalidLateRuntimeElapsedMillis - TWO_HOURS;  // Early is (late - period).
         final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage",
                 0 /* sourceUserId */, "someTag",
-                invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis);
+                invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis,
+                0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */);
 
         mTaskStoreUnderTest.add(js);
         Thread.sleep(IO_WAIT);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
new file mode 100644
index 0000000..84cca0e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.pm.UserInfo;
+import android.os.FileUtils;
+import android.os.IProgressListener;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.security.KeyStore;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+
+public class BaseLockSettingsServiceTests extends AndroidTestCase {
+    protected static final int PRIMARY_USER_ID = 0;
+    protected static final int MANAGED_PROFILE_USER_ID = 12;
+    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
+    protected static final int SECONDARY_USER_ID = 20;
+
+    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED);
+
+    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
+
+    LockSettingsService mService;
+
+    MockLockSettingsContext mContext;
+    LockSettingsStorageTestable mStorage;
+
+    LockPatternUtils mLockPatternUtils;
+    MockGateKeeperService mGateKeeperService;
+    NotificationManager mNotificationManager;
+    UserManager mUserManager;
+    MockStorageManager mStorageManager;
+    IActivityManager mActivityManager;
+    DevicePolicyManager mDevicePolicyManager;
+    KeyStore mKeyStore;
+    MockSyntheticPasswordManager mSpManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mLockPatternUtils = mock(LockPatternUtils.class);
+        mGateKeeperService = new MockGateKeeperService();
+        mNotificationManager = mock(NotificationManager.class);
+        mUserManager = mock(UserManager.class);
+        mStorageManager = new MockStorageManager();
+        mActivityManager = mock(IActivityManager.class);
+        mDevicePolicyManager = mock(DevicePolicyManager.class);
+
+        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
+                mDevicePolicyManager, mock(StorageManager.class));
+        mStorage = new LockSettingsStorageTestable(mContext,
+                new File(getContext().getFilesDir(), "locksettings"));
+        File storageDir = mStorage.mStorageDir;
+        if (storageDir.exists()) {
+            FileUtils.deleteContents(storageDir);
+        } else {
+            storageDir.mkdirs();
+        }
+
+        mSpManager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService, mUserManager);
+        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
+                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager,
+                mSpManager);
+        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
+        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
+        installChildProfile(MANAGED_PROFILE_USER_ID);
+        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
+        when(mUserManager.getUsers(anyBoolean())).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
+
+        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
+                new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
+                        (IProgressListener) args[3]);
+                return true;
+            }
+        });
+
+        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"));
+    }
+
+    private UserInfo installChildProfile(int profileId) {
+        final UserInfo userInfo = new UserInfo(
+            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
+        mPrimaryUserProfiles.add(userInfo);
+        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
+        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
+        return userInfo;
+    }
+
+    private UserInfo installAndTurnOffChildProfile(int profileId) {
+        final UserInfo userInfo = installChildProfile(profileId);
+        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
+        return userInfo;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+        File db = getContext().getDatabasePath("locksettings.db");
+        assertTrue(!db.exists() || db.delete());
+
+        File storageDir = mStorage.mStorageDir;
+        assertTrue(FileUtils.deleteContents(storageDir));
+    }
+
+    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
+        assertTrue(Arrays.equals(expected, actual));
+    }
+
+    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
+        assertFalse(Arrays.equals(expected, actual));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
new file mode 100644
index 0000000..3a4aa2d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -0,0 +1,140 @@
+/*
+ * 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.locksettings;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.IActivityManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.storage.IStorageManager;
+import android.security.KeyStore;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.FileNotFoundException;
+
+public class LockSettingsServiceTestable extends LockSettingsService {
+
+    private static class MockInjector extends LockSettingsService.Injector {
+
+        private LockSettingsStorage mLockSettingsStorage;
+        private KeyStore mKeyStore;
+        private IActivityManager mActivityManager;
+        private LockPatternUtils mLockPatternUtils;
+        private IStorageManager mStorageManager;
+        private SyntheticPasswordManager mSpManager;
+
+        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
+                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
+                IStorageManager storageManager, SyntheticPasswordManager spManager) {
+            super(context);
+            mLockSettingsStorage = storage;
+            mKeyStore = keyStore;
+            mActivityManager = activityManager;
+            mLockPatternUtils = lockPatternUtils;
+            mStorageManager = storageManager;
+            mSpManager = spManager;
+        }
+
+        @Override
+        public Handler getHandler() {
+            return mock(Handler.class);
+        }
+
+        @Override
+        public LockSettingsStorage getStorage() {
+            return mLockSettingsStorage;
+        }
+
+        @Override
+        public LockSettingsStrongAuth getStrongAuth() {
+            return mock(LockSettingsStrongAuth.class);
+        }
+
+        @Override
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return mock(SynchronizedStrongAuthTracker.class);
+        }
+
+        @Override
+        public IActivityManager getActivityManager() {
+            return mActivityManager;
+        }
+
+        @Override
+        public LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        public KeyStore getKeyStore() {
+            return mKeyStore;
+        }
+
+        @Override
+        public IStorageManager getStorageManager() {
+            return mStorageManager;
+        }
+
+        @Override
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return mSpManager;
+        }
+
+        @Override
+        public int binderGetCallingUid() {
+            return Process.SYSTEM_UID;
+        }
+
+
+    }
+
+    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
+            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
+            IStorageManager storageManager, IActivityManager mActivityManager,
+            SyntheticPasswordManager spManager) {
+        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
+                storageManager, spManager));
+        mGateKeeperService = gatekeeper;
+    }
+
+    @Override
+    protected void tieProfileLockToParent(int userId, String password) {
+        mStorage.writeChildProfileLock(userId, password.getBytes());
+    }
+
+    @Override
+    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException,
+            KeyPermanentlyInvalidatedException {
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        try {
+            if (mGateKeeperService.getSecureUserId(userId) == 0) {
+                throw new KeyPermanentlyInvalidatedException();
+            }
+        } catch (RemoteException e) {
+            // shouldn't happen.
+        }
+        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
new file mode 100644
index 0000000..cb32492
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+
+import android.os.RemoteException;
+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;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
+ */
+public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCreatePasswordPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD,
+                PASSWORD_QUALITY_ALPHABETIC);
+    }
+
+    public void testCreatePatternPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN,
+                PASSWORD_QUALITY_SOMETHING);
+    }
+
+    public void testChangePasswordPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
+                "asdfghjk", CREDENTIAL_TYPE_PASSWORD, PASSWORD_QUALITY_ALPHABETIC);
+    }
+
+    public void testChangePatternPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
+                "1596321", CREDENTIAL_TYPE_PATTERN, PASSWORD_QUALITY_SOMETHING);
+    }
+
+    public void testChangePasswordFailPrimaryUser() throws RemoteException {
+        final long sid = 1234;
+        final String FAILED_MESSAGE = "Failed to enroll password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
+
+        try {
+            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
+                    PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+            fail("Did not fail when enrolling using incorrect credential");
+        } 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);
+    }
+
+    public void testClearPasswordPrimaryUser() throws RemoteException {
+        final String PASSWORD = "password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertFalse(mService.havePassword(PRIMARY_USER_ID));
+        assertFalse(mService.havePattern(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testManagedProfileUnifiedChallenge() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
+        mService.setLockCredential(UnifiedPassword, 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);
+        final long turnedOffProfileSid =
+                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+        assertTrue(turnedOffProfileSid != 0);
+        assertTrue(turnedOffProfileSid != primarySid);
+        assertTrue(turnedOffProfileSid != profileSid);
+
+        // clear auth token and wait for verify challenge from primary user to re-generate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
+        // verify credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+
+        // Verify that we have a new auth token for the profile
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
+        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
+
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        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);
+        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);
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallenge() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
+        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // clear auth token and make sure verify challenge from primary user does not regenerate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        // verify primary credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+
+        // verify profile credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Change primary credential and make sure we don't affect profile
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                primaryPassword, PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+    }
+
+    private void testCreateCredential(int userId, String credential, int type, int quality)
+            throws RemoteException {
+        mService.setLockCredential(credential, type, null, quality, userId);
+        assertVerifyCredentials(userId, credential, type, -1);
+    }
+
+    private void testChangeCredentials(int userId, String newCredential, int newType,
+            String oldCredential, int oldType, int quality) throws RemoteException {
+        final long sid = 1234;
+        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
+        mService.setLockCredential(newCredential, newType, oldCredential, quality, userId);
+        assertVerifyCredentials(userId, newCredential, newType, sid);
+    }
+
+    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
+            throws RemoteException{
+        final long challenge = 54321;
+        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
+                userId);
+
+        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
+        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
+        final int incorrectType;
+        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            assertTrue(mService.havePassword(userId));
+            assertFalse(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
+            assertFalse(mService.havePassword(userId));
+            assertTrue(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        } else {
+            assertFalse(mService.havePassword(userId));
+            assertFalse(mService.havePassword(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        }
+        // check for bad type
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
+                incorrectType, challenge, userId).getResponseCode());
+        // check for bad credential
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
+                type, challenge, userId).getResponseCode());
+    }
+
+    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
+        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
+        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/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
new file mode 100644
index 0000000..424c08c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import static junit.framework.Assert.*;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static java.io.FileDescriptor.*;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+
+/**
+ * Test class for {@link LockSettingsShellCommand}.
+ *
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsShellCommandTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class LockSettingsShellCommandTest {
+
+    private LockSettingsShellCommand mCommand;
+
+    private @Mock LockPatternUtils mLockPatternUtils;
+    private int mUserId;
+    private final Binder mBinder = new Binder();
+    private final ShellCallback mShellCallback = new ShellCallback();
+    private final ResultReceiver mResultReceiver = new ResultReceiver(
+            new Handler(Looper.getMainLooper()));
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mUserId = ActivityManager.getCurrentUser();
+        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
+    }
+
+    @Test
+    public void testWrongPassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
+        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
+                new String[] { "set-pin", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testChangePin() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pin", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-password", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePattern() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pattern", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
+    }
+
+    @Test
+    public void testClear() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "clear", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).clearLock("1234", mUserId);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
new file mode 100644
index 0000000..4bdd1c5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -0,0 +1,66 @@
+/*
+ * 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.locksettings;
+
+import android.content.Context;
+
+import java.io.File;
+
+public class LockSettingsStorageTestable extends LockSettingsStorage {
+
+    public File mStorageDir;
+
+    public LockSettingsStorageTestable(Context context, File storageDir) {
+        super(context);
+        mStorageDir = storageDir;
+    }
+
+    @Override
+    String getLockPatternFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPatternFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getLockPasswordFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPasswordFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getChildProfileLockFile(int userId) {
+        return makeDirs(mStorageDir,
+                super.getChildProfileLockFile(userId)).getAbsolutePath();
+    }
+
+    @Override
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
+                userId).getAbsolutePath());
+    }
+
+    private File makeDirs(File baseDir, String filePath) {
+        File path = new File(filePath);
+        if (path.getParent() == null) {
+            return new File(baseDir, filePath);
+        } else {
+            File mappedDir = new File(baseDir, path.getParent());
+            mappedDir.mkdirs();
+            return new File(mappedDir, path.getName());
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
new file mode 100644
index 0000000..a0578c9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -0,0 +1,453 @@
+/*
+ * 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.android.server.locksettings;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.UserInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.FileUtils;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsStorageTests
+ */
+public class LockSettingsStorageTests extends AndroidTestCase {
+    private static final int SOME_USER_ID = 1034;
+    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
+    private final byte[] PASSWORD_1 = "password1".getBytes();
+    private final byte[] PATTERN_0 = "123654".getBytes();
+    private final byte[] PATTERN_1 = "147852369".getBytes();
+
+    public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 33};
+
+    LockSettingsStorage mStorage;
+    File mStorageDir;
+
+    private File mDb;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
+        mDb = getContext().getDatabasePath("locksettings.db");
+
+        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
+        assertTrue(FileUtils.deleteContents(mStorageDir));
+        assertTrue(!mDb.exists() || mDb.delete());
+
+        final UserManager mockUserManager = mock(UserManager.class);
+        // User 2 is a profile of user 1.
+        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
+        // User 3 is a profile of user 0.
+        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
+
+        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
+                mock(NotificationManager.class), mock(DevicePolicyManager.class),
+                mock(StorageManager.class));
+        mStorage = new LockSettingsStorageTestable(context,
+                new File(getContext().getFilesDir(), "locksettings"));
+        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                    @Override
+                    public void initialize(SQLiteDatabase db) {
+                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
+                    }
+                });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+    }
+
+    public void testKeyValue_InitializeWorked() {
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+        mStorage.clearCache();
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+    }
+
+    public void testKeyValue_WriteThenRead() {
+        mStorage.writeKeyValue("key", "value", 0);
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+        mStorage.clearCache();
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+    }
+
+    public void testKeyValue_DefaultValue() {
+        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
+        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
+    }
+
+    public void testKeyValue_Concurrency() {
+        final Object monitor = new Object();
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    synchronized (monitor) {
+                        try {
+                            monitor.wait();
+                        } catch (InterruptedException e) {
+                            return;
+                        }
+                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        mStorage.writeKeyValue("key", "initalValue", 0);
+        synchronized (monitor) {
+            monitor.notifyAll();
+        }
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+        mStorage.clearCache();
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+    }
+
+    public void testKeyValue_CacheStarvedWriter() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        latch.await();
+                    } catch (InterruptedException e) {
+                        return;
+                    }
+                    if (threadId == 50) {
+                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
+                    } else {
+                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        latch.countDown();
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        String cached = mStorage.readKeyValue("key", "default", 0);
+        mStorage.clearCache();
+        String storage = mStorage.readKeyValue("key", "default", 0);
+        assertEquals("Cached value didn't match stored value", storage, cached);
+    }
+
+    public void testRemoveUser() {
+        mStorage.writeKeyValue("key", "value", 0);
+        writePasswordBytes(PASSWORD_0, 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.writeKeyValue("key", "value", 1);
+        writePasswordBytes(PASSWORD_1, 1);
+        writePatternBytes(PATTERN_1, 1);
+
+        mStorage.removeUser(0);
+
+        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
+        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
+        assertPatternBytes(PATTERN_1, 1);
+    }
+
+    public void testCredential_Default() {
+        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
+    }
+
+    public void testPassword_Write() {
+        writePasswordBytes(PASSWORD_0, 0);
+
+        assertPasswordBytes(PASSWORD_0, 0);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 0);
+    }
+
+    public void testPassword_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 1);
+        writePasswordBytes(PASSWORD_1, 2);
+
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+    }
+
+    public void testLockType_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 10);
+        writePatternBytes(PATTERN_0, 20);
+
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+        mStorage.clearCache();
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+    }
+
+    public void testPassword_WriteParentWritesProfile() {
+        writePasswordBytes(PASSWORD_0, 2);
+        writePasswordBytes(PASSWORD_1, 1);
+
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+    }
+
+    public void testProfileLock_ReadWriteChildProfileLock() {
+        assertFalse(mStorage.hasChildProfileLock(20));
+        mStorage.writeChildProfileLock(20, PASSWORD_0);
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+        mStorage.clearCache();
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+    }
+
+    public void testPattern_Write() {
+        writePatternBytes(PATTERN_0, 0);
+
+        assertPatternBytes(PATTERN_0, 0);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testPattern_WriteProfileWritesParent() {
+        writePatternBytes(PATTERN_0, 1);
+        writePatternBytes(PATTERN_1, 2);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPattern_WriteParentWritesProfile() {
+        writePatternBytes(PATTERN_1, 2);
+        writePatternBytes(PATTERN_0, 1);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPrefetch() {
+        mStorage.writeKeyValue("key", "toBeFetched", 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.clearCache();
+        mStorage.prefetchUser(0);
+
+        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testFileLocation_Owner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
+        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
+        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
+        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
+    }
+
+    public void testFileLocation_SecondaryUser() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
+        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
+    }
+
+    public void testFileLocation_ProfileToSecondary() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
+        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
+    }
+
+    public void testFileLocation_ProfileToOwner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
+        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
+    }
+
+    public void testSyntheticPasswordState() {
+        final byte[] data = {1,2,3,4};
+        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
+        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
+
+        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
+        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+    }
+
+    public void testPersistentData_serializeUnserialize() {
+        byte[] serialized = PersistentData.toBytes(PersistentData.TYPE_GATEKEEPER, SOME_USER_ID,
+                DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, PAYLOAD);
+        PersistentData deserialized = PersistentData.fromBytes(serialized);
+
+        assertEquals(PersistentData.TYPE_GATEKEEPER, deserialized.type);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, deserialized.qualityForUi);
+        assertArrayEquals(PAYLOAD, deserialized.payload);
+    }
+
+    public void testPersistentData_unserializeNull() {
+        PersistentData deserialized = PersistentData.fromBytes(null);
+        assertSame(PersistentData.NONE, deserialized);
+    }
+
+    public void testPersistentData_unserializeEmptyArray() {
+        PersistentData deserialized = PersistentData.fromBytes(new byte[0]);
+        assertSame(PersistentData.NONE, deserialized);
+    }
+
+    public void testPersistentData_unserialize_version1() {
+        // This test ensures that we can read serialized VERSION_1 PersistentData even if we change
+        // the wire format in the future.
+        byte[] serializedVersion1 = new byte[] {
+                1, /* PersistentData.VERSION_1 */
+                2, /* PersistentData.TYPE_SP */
+                0x00, 0x00, 0x04, 0x0A,  /* SOME_USER_ID */
+                0x00, 0x03, 0x00, 0x00,  /* PASSWORD_NUMERIC_COMPLEX */
+                1, 2, -1, -2, 33, /* PAYLOAD */
+        };
+        PersistentData deserialized = PersistentData.fromBytes(serializedVersion1);
+        assertEquals(PersistentData.TYPE_SP, deserialized.type);
+        assertEquals(SOME_USER_ID, deserialized.userId);
+        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
+                deserialized.qualityForUi);
+        assertArrayEquals(PAYLOAD, deserialized.payload);
+
+        // Make sure the constants we use on the wire do not change.
+        assertEquals(0, PersistentData.TYPE_NONE);
+        assertEquals(1, PersistentData.TYPE_GATEKEEPER);
+        assertEquals(2, PersistentData.TYPE_SP);
+        assertEquals(3, PersistentData.TYPE_SP_WEAVER);
+    }
+
+    public void testCredentialHash_serializeUnserialize() {
+        byte[] serialized = CredentialHash.create(
+                PAYLOAD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD).toBytes();
+        CredentialHash deserialized = CredentialHash.fromBytes(serialized);
+
+        assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
+        assertArrayEquals(PAYLOAD, deserialized.hash);
+        assertFalse(deserialized.isBaseZeroPattern);
+    }
+
+    public void testCredentialHash_unserialize_versionGatekeeper() {
+        // This test ensures that we can read serialized VERSION_GATEKEEPER CredentialHashes
+        // even if we change the wire format in the future.
+        byte[] serialized = new byte[] {
+                1, /* VERSION_GATEKEEPER */
+                2, /* CREDENTIAL_TYPE_PASSWORD */
+                0, 0, 0, 5, /* hash length */
+                1, 2, -1, -2, 33, /* hash */
+        };
+        CredentialHash deserialized = CredentialHash.fromBytes(serialized);
+
+        assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
+        assertArrayEquals(PAYLOAD, deserialized.hash);
+        assertFalse(deserialized.isBaseZeroPattern);
+
+        // Make sure the constants we use on the wire do not change.
+        assertEquals(-1, LockPatternUtils.CREDENTIAL_TYPE_NONE);
+        assertEquals(1, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
+        assertEquals(2, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+    }
+
+    private static void assertArrayEquals(byte[] expected, byte[] actual) {
+        if (!Arrays.equals(expected, actual)) {
+            fail("expected:<" + Arrays.toString(expected) +
+                    "> but was:<" + Arrays.toString(actual) + ">");
+        }
+    }
+
+    private void writePasswordBytes(byte[] password, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+    }
+
+    private void writePatternBytes(byte[] pattern, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+    }
+
+    private void assertPasswordBytes(byte[] password, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
+        assertArrayEquals(password, cred.hash);
+    }
+
+    private void assertPatternBytes(byte[] pattern, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
+        assertArrayEquals(pattern, cred.hash);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
new file mode 100644
index 0000000..b89c1d1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
@@ -0,0 +1,198 @@
+/*
+ * 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.locksettings;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+public class MockGateKeeperService implements IGateKeeperService {
+    static class VerifyHandle {
+        public byte[] password;
+        public long sid;
+
+        public VerifyHandle(byte[] password, long sid) {
+            this.password = password;
+            this.sid = sid;
+        }
+
+        public VerifyHandle(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            sid = buffer.getLong();
+            password = new byte[buffer.remaining()];
+            buffer.get(password);
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
+            buffer.put((byte)0);
+            buffer.putLong(sid);
+            buffer.put(password);
+            return buffer.array();
+        }
+    }
+
+    static class AuthToken {
+        public long challenge;
+        public long sid;
+
+        public AuthToken(long challenge, long sid) {
+            this.challenge = challenge;
+            this.sid = sid;
+        }
+
+        public AuthToken(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            challenge = buffer.getLong();
+            sid = buffer.getLong();
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
+            buffer.put((byte)0);
+            buffer.putLong(challenge);
+            buffer.putLong(sid);
+            return buffer.array();
+        }
+    }
+
+    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
+    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
+
+    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
+
+    @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)) {
+                // Trusted enroll
+                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
+                refreshSid(uid, handle.sid, false);
+                handleMap.put(uid, newHandle.toBytes());
+                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+            } else {
+                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);
+        }
+    }
+
+    @Override
+    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
+            byte[] providedPassword) throws android.os.RemoteException {
+        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
+    }
+
+    @Override
+    public GateKeeperResponse verifyChallenge(int uid, long challenge,
+            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
+
+        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
+        if (Arrays.equals(handle.password, providedPassword)) {
+            byte[] knownHandle = handleMap.get(uid);
+            if (knownHandle != null) {
+                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
+                    throw new AssertionFailedError("Got correct but obsolete handle");
+                }
+            }
+            refreshSid(uid, handle.sid, false);
+            AuthToken token = new AuthToken(challenge, handle.sid);
+            refreshAuthToken(uid, token);
+            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
+        } else {
+            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
+        }
+    }
+
+    private void refreshAuthToken(int uid, AuthToken token) {
+        authTokenMap.put(uid, token);
+    }
+
+    public AuthToken getAuthToken(int uid) {
+        return authTokenMap.get(uid);
+    }
+
+    public AuthToken getAuthTokenForSid(long sid) {
+        for(AuthToken token : authTokenMap.values()) {
+            if (token.sid == sid) {
+                return token;
+            }
+        }
+        return null;
+    }
+
+    public void clearAuthToken(int uid) {
+        authTokenMap.remove(uid);
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearSecureUserId(int userId) throws RemoteException {
+        sidMap.remove(userId);
+    }
+
+    @Override
+    public void reportDeviceSetupComplete() throws RemoteException {
+    }
+
+    @Override
+    public long getSecureUserId(int userId) throws RemoteException {
+        if (sidMap.containsKey(userId)) {
+            return sidMap.get(userId);
+        } else {
+            return 0L;
+        }
+    }
+
+    private void refreshSid(int uid, long sid, boolean force) {
+        if (!sidMap.containsKey(uid) || force) {
+            sidMap.put(uid, sid);
+        } else{
+            if (sidMap.get(uid) != sid) {
+                throw new AssertionFailedError("Inconsistent SID");
+            }
+        }
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
new file mode 100644
index 0000000..8da33a8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -0,0 +1,63 @@
+/*
+ * 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.locksettings;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+public class MockLockSettingsContext extends ContextWrapper {
+
+    private UserManager mUserManager;
+    private NotificationManager mNotificationManager;
+    private DevicePolicyManager mDevicePolicyManager;
+    private StorageManager mStorageManager;
+
+    public MockLockSettingsContext(Context base, UserManager userManager,
+            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
+            StorageManager storageManager) {
+        super(base);
+        mUserManager = userManager;
+        mNotificationManager = notificationManager;
+        mDevicePolicyManager = devicePolicyManager;
+        mStorageManager = storageManager;
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        if (USER_SERVICE.equals(name)) {
+            return mUserManager;
+        } else if (NOTIFICATION_SERVICE.equals(name)) {
+            return mNotificationManager;
+        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
+            return mDevicePolicyManager;
+        } else if (STORAGE_SERVICE.equals(name)) {
+            return mStorageManager;
+        } else {
+            throw new RuntimeException("System service not mocked: " + name);
+        }
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        // Skip permission checks for unit tests.
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
new file mode 100644
index 0000000..40e114b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
@@ -0,0 +1,507 @@
+/*
+ * 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.locksettings;
+
+import android.content.pm.IPackageMoveObserver;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.storage.DiskInfo;
+import android.os.storage.IObbActionListener;
+import android.os.storage.IStorageEventListener;
+import android.os.storage.IStorageManager;
+import android.os.storage.IStorageShutdownObserver;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.util.ArrayMap;
+import android.util.Pair;
+
+import com.android.internal.os.AppFuseMount;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockStorageManager implements IStorageManager {
+
+    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
+    private boolean mIgnoreBadUnlock;
+
+    @Override
+    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        getUserAuth(userId).add(new Pair<>(token, secret));
+    }
+
+    @Override
+    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
+        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
+        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
+        auths.clear();
+        auths.add(latest);
+    }
+
+    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
+        if (!mAuth.containsKey(userId)) {
+            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
+            auths.add(new Pair(null, null));
+            mAuth.put(userId,  auths);
+        }
+        return mAuth.get(userId);
+    }
+
+    public byte[] getUserUnlockToken(int userId) {
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (auths.size() != 1) {
+            throw new AssertionFailedError("More than one secret exists");
+        }
+        return auths.get(0).second;
+    }
+
+    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
+            throws RemoteException {
+        listener.onStarted(userId, null);
+        listener.onFinished(userId, null);
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (secret != null) {
+            if (auths.size() > 1) {
+                throw new AssertionFailedError("More than one secret exists");
+            }
+            Pair<byte[], byte[]> auth = auths.get(0);
+            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
+                throw new AssertionFailedError("Invalid secret to unlock user");
+            }
+        } else {
+            if (auths != null && auths.size() > 0) {
+                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
+            }
+        }
+    }
+
+    public void setIgnoreBadUnlock(boolean ignore) {
+        mIgnoreBadUnlock = ignore;
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void registerListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageConnected() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageEnabled() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public int formatVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int[] getStorageUsers(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getVolumeState(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
+            boolean external) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int finalizeSecureContainer(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int destroySecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSecureContainerMounted(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerPath(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSecureContainerList() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void finishMediaUpdate() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
+            int nonce) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isObbMounted(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getMountedObbPath(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isExternalStorageEmulated() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int decryptStorage(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int encryptStorage(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int changeEncryptionPassword(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getEncryptionState() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int verifyEncryptionPassword(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int fixPermissionsSecureContainer(String id, int gid, String filename)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mkdirs(String callingPkg, String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPasswordType() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public void setField(String field, String contents) throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public String getField(String field) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long lastMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void runMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void waitForAsecScan() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DiskInfo[] getDisks() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void format(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPublic(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPrivate(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionMixed(String diskId, int ratio) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetVolume(String fsUuid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetAllVolumes() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPrimaryStorageUuid() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long benchmark(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDebugFlags(int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void lockUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserStorage(String volumeUuid, int userId, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isConvertibleToFBE() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void fstrim(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getAllocatableBytes(String path, int flags, String callingPackage) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void allocateBytes(String path, long bytes, int flags, String callingPackage) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void secdiscard(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
new file mode 100644
index 0000000..d7468c2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
+
+    private MockGateKeeperService mGateKeeper;
+    private IWeaver mWeaverService;
+
+    public MockSyntheticPasswordManager(LockSettingsStorage storage,
+            MockGateKeeperService gatekeeper, UserManager userManager) {
+        super(storage, userManager);
+        mGateKeeper = gatekeeper;
+    }
+
+    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
+
+    @Override
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
+            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
+        buffer.put(blob, 0, blob.length);
+        buffer.flip();
+        int len;
+        len = buffer.getInt();
+        byte[] data = new byte[len];
+        buffer.get(data);
+        len = buffer.getInt();
+        byte[] appId = new byte[len];
+        buffer.get(appId);
+        long sid = buffer.getLong();
+        if (!Arrays.equals(appId, applicationId)) {
+            throw new AssertionFailedError("Invalid application id");
+        }
+        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
+            throw new AssertionFailedError("No valid auth token");
+        }
+        return data;
+    }
+
+    @Override
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
+                + applicationId.length + Long.BYTES);
+        buffer.putInt(data.length);
+        buffer.put(data);
+        buffer.putInt(applicationId.length);
+        buffer.put(applicationId);
+        buffer.putLong(sid);
+        byte[] result = buffer.array();
+        mBlobs.put(blobKeyName, result);
+        return result;
+    }
+
+    @Override
+    protected void destroySPBlobKey(String keyAlias) {
+    }
+
+    @Override
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return new MockGateKeeperService.VerifyHandle(handle).sid;
+    }
+
+    @Override
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        try {
+            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
+            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+            return f.generateSecret(spec).getEncoded();
+        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    protected IWeaver getWeaverService() throws RemoteException {
+        return mWeaverService;
+    }
+
+    public void enableWeaver() {
+        mWeaverService = new MockWeaverService();
+        initWeaverService();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
new file mode 100644
index 0000000..34831cd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
@@ -0,0 +1,108 @@
+package com.android.server.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.hidl.base.V1_0.DebugInfo;
+import android.os.IHwBinder;
+import android.os.IHwBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.Pair;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockWeaverService implements IWeaver {
+
+    private static final int MAX_SLOTS = 8;
+    private static final int KEY_LENGTH = 256 / 8;
+    private static final int VALUE_LENGTH = 256 / 8;
+
+    private Pair<ArrayList<Byte>, ArrayList<Byte>>[] slots = new Pair[MAX_SLOTS];
+    @Override
+    public void getConfig(getConfigCallback cb) throws RemoteException {
+        WeaverConfig config = new WeaverConfig();
+        config.keySize = KEY_LENGTH;
+        config.valueSize = VALUE_LENGTH;
+        config.slots = MAX_SLOTS;
+        cb.onValues(WeaverStatus.OK, config);
+    }
+
+    @Override
+    public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
+            throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+        slots[slotId] = Pair.create((ArrayList<Byte>) key.clone(), (ArrayList<Byte>) value.clone());
+        return WeaverStatus.OK;
+    }
+
+    @Override
+    public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+
+        WeaverReadResponse response = new WeaverReadResponse();
+        if (key.equals(slots[slotId].first)) {
+            response.value.addAll(slots[slotId].second);
+            cb.onValues(WeaverStatus.OK, response);
+        } else {
+            cb.onValues(WeaverStatus.FAILED, response);
+        }
+    }
+
+    @Override
+    public IHwBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<String> interfaceChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String interfaceDescriptor() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setHALInstrumentation() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean linkToDeath(DeathRecipient recipient, long cookie) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void ping() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DebugInfo getDebugInfo() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void notifySyspropsChanged() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean unlinkToDeath(DeathRecipient recipient) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<byte[]> getHashChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
new file mode 100644
index 0000000..ba4ff33
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -0,0 +1,421 @@
+/*
+ * 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.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+
+import android.app.admin.DevicePolicyManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
+
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
+ */
+public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
+
+    public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 55};
+    public static final byte[] PAYLOAD2 = new byte[] {2, 3, -2, -3, 44, 1};
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testPasswordBasedSyntheticPassword() throws RemoteException {
+        final int USER_ID = 10;
+        final String PASSWORD = "user-password";
+        final String BADPASSWORD = "bad-password";
+        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage,
+                mGateKeeperService, mUserManager);
+        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
+                null, USER_ID);
+        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, PASSWORD_QUALITY_ALPHABETIC,
+                USER_ID);
+
+        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
+        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
+
+        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
+        assertNull(result.authToken);
+    }
+
+    private void disableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+    }
+
+    private void enableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private boolean hasSyntheticPassword(int userId) throws RemoteException {
+        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
+    }
+
+    public void testPasswordMigration() throws RemoteException {
+        final String PASSWORD = "testPasswordMigration-password";
+
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        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);
+        // Performs migration
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+
+        // SP-based verification
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
+        enableSyntheticPassword(userId);
+        int quality = password != null ? PASSWORD_QUALITY_ALPHABETIC
+                : PASSWORD_QUALITY_UNSPECIFIED;
+        int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
+                : LockPatternUtils.CREDENTIAL_TYPE_NONE;
+        mService.setLockCredential(password, type, null, quality, userId);
+    }
+
+    public void testSyntheticPasswordChangeCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
+        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
+                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+    public void testSyntheticPasswordClearCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, PASSWORD,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // Untrusted change password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // Verify the password
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+
+    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, 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);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
+        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testTokenBasedResetPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedClearPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, handle,
+                TOKEN.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String NEWPASSWORD = "password";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD,
+                PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+
+        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                handle, TOKEN.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        final String PASSWORD = "password";
+        // Set up pre-SP user password
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+        enableSyntheticPassword(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        // Token not activated immediately since user password exists
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        // Activate token (password gets migrated to SP at the same time)
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                        PRIMARY_USER_ID).getResponseCode());
+        // Verify token is activated
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+    }
+
+    public void testPasswordData_serializeDeserialize() {
+        PasswordData data = new PasswordData();
+        data.scryptN = 11;
+        data.scryptR = 22;
+        data.scryptP = 33;
+        data.passwordType = CREDENTIAL_TYPE_PASSWORD;
+        data.salt = PAYLOAD;
+        data.passwordHandle = PAYLOAD2;
+
+        PasswordData deserialized = PasswordData.fromBytes(data.toBytes());
+
+        assertEquals(11, deserialized.scryptN);
+        assertEquals(22, deserialized.scryptR);
+        assertEquals(33, deserialized.scryptP);
+        assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
+        assertArrayEquals(PAYLOAD, deserialized.salt);
+        assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+    }
+
+    public void testPasswordData_deserialize() {
+        // Test that we can deserialize existing PasswordData and don't inadvertently change the
+        // wire format.
+        byte[] serialized = new byte[] {
+                0, 0, 0, 2, /* CREDENTIAL_TYPE_PASSWORD */
+                11, /* scryptN */
+                22, /* scryptR */
+                33, /* scryptP */
+                0, 0, 0, 5, /* salt.length */
+                1, 2, -1, -2, 55, /* salt */
+                0, 0, 0, 6, /* passwordHandle.length */
+                2, 3, -2, -3, 44, 1, /* passwordHandle */
+        };
+        PasswordData deserialized = PasswordData.fromBytes(serialized);
+
+        assertEquals(11, deserialized.scryptN);
+        assertEquals(22, deserialized.scryptR);
+        assertEquals(33, deserialized.scryptP);
+        assertEquals(CREDENTIAL_TYPE_PASSWORD, deserialized.passwordType);
+        assertArrayEquals(PAYLOAD, deserialized.salt);
+        assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+    }
+
+    // b/34600579
+    //TODO: add non-migration work profile case, and unify/un-unify transition.
+    //TODO: test token after user resets password
+    //TODO: test token based reset after unified work challenge
+    //TODO: test clear password after unified work challenge
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
new file mode 100644
index 0000000..5e56704
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
@@ -0,0 +1,11 @@
+package com.android.server.locksettings;
+
+public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mSpManager.enableWeaver();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index f1d5927..3c64582 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1266,16 +1266,16 @@
         if (force || !ENABLE_DUMP) return;
 
         Log.v(TAG, "Dumping ShortcutService: " + message);
-        for (String line : dumpsys(null).split("\n")) {
+        for (String line : dumpsys("-u").split("\n")) {
             Log.v(TAG, line);
         }
     }
 
     protected String dumpCheckin() {
-        return dumpsys(new String[]{"--checkin"});
+        return dumpsys("--checkin");
     }
 
-    private String dumpsys(String[] args) {
+    protected String dumpsys(String... args) {
         final ArrayList<String> origPermissions = new ArrayList<>(mCallerPermissions);
         mCallerPermissions.add(android.Manifest.permission.DUMP);
         try {
@@ -2139,4 +2139,15 @@
         mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(getCallingPackage(), getCallingUserId()));
     }
+
+    protected void assertFileNotExists(String path) {
+        final File f = new File(mInjectedFilePathRoot, path);
+        assertFalse("File shouldn't exist: " + f.getAbsolutePath(), f.exists());
+    }
+
+    protected void assertFileExistsWithContent(String path) {
+        final File f = new File(mInjectedFilePathRoot, path);
+        assertTrue("File should exist: " + f.getAbsolutePath(), f.exists());
+        assertTrue("File should be larger than 0b: " + f.getAbsolutePath(), f.length() > 0);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index f4944f9..951f226 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4732,8 +4732,23 @@
      * - Bitmaps
      */
     public void testBackupAndRestore() {
+
+        assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
+        assertFileNotExists("user-0/shortcut_dump/restore-2.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-3.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-4.txt");
+        assertFileNotExists("user-0/shortcut_dump/restore-5-finish.txt");
+
         prepareForBackupTest();
 
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-0-start.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-1-payload.xml");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-2.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-3.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-4.txt");
+        assertFileExistsWithContent("user-0/shortcut_dump/restore-5-finish.txt");
+
         checkBackupAndRestore_success();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
index 25f9100..da641b9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.array;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertContains;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertSuccess;
@@ -40,7 +41,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Unit test for "cmd shortcut"
+ * Unit test for "cmd shortcut" and "dumpsys shortcut".
  *
  * Launcher related commands are tested in
  */
@@ -336,4 +337,29 @@
                     .areAllNotPinned();
         });
     }
+
+    public void testDumpsysArgs() {
+        checkDumpsysArgs(null, true, false, false);
+        checkDumpsysArgs(array("-u"), true, true, false);
+        checkDumpsysArgs(array("--uid"), true, true, false);
+
+        checkDumpsysArgs(array("-f"), true, false, true);
+        checkDumpsysArgs(array("--files"), true, false, true);
+
+        checkDumpsysArgs(array("-a"), true, true, true);
+        checkDumpsysArgs(array("--all"), true, true, true);
+
+        checkDumpsysArgs(array("-a", "-n"), false, true, true);
+        checkDumpsysArgs(array("-a", "--no-main"), false, true, true);
+    }
+
+    private void checkDumpsysArgs(String[] args, boolean expectMain, boolean expectUid,
+            boolean expectDumpFiles) {
+        String dump = dumpsys(args);
+
+        assertEquals(expectMain, dump.contains("Icon format: PNG"));
+        assertEquals(expectUid, dump.contains("SHORTCUT MANAGER UID STATES"));
+        assertEquals(expectDumpFiles, dump.contains("SHORTCUT MANAGER FILES"));
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 1964cad..b656d5e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -53,8 +53,7 @@
 
     // Packages which are used during tests.
     private static final String[] PACKAGES = new String[] {
-            "com.android.egg",
-            "com.android.retaildemo"
+            "com.android.egg"
     };
 
     private final Object mUserRemoveLock = new Object();
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
deleted file mode 100644
index 6706969..0000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ /dev/null
@@ -1,156 +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.server.retaildemo;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.IPackageInstallObserver2;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.FileUtils;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentResolver;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PreloadAppsInstallerTest {
-    private static final int TEST_DEMO_USER = 111;
-
-    private Context mContext;
-    private @Mock IPackageManager mIpm;
-    private MockContentResolver mContentResolver;
-    private File mPreloadsAppsDirectory;
-    private String[] mPreloadedApps =
-            new String[] {"test1.apk.preload", "test2.apk.preload", "test3.apk.preload"};
-    private ArrayList<String> mPreloadedAppPaths = new ArrayList<>();
-
-    private PreloadAppsInstaller mInstaller;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
-        mContentResolver = new MockContentResolver(mContext);
-        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        initializePreloadedApps();
-        Settings.Secure.putStringForUser(mContentResolver,
-                Settings.Secure.DEMO_USER_SETUP_COMPLETE, "0", TEST_DEMO_USER);
-
-        mInstaller = new PreloadAppsInstaller(mContext, mIpm, mPreloadsAppsDirectory);
-    }
-
-    private void initializePreloadedApps() throws Exception {
-        mPreloadsAppsDirectory = new File(InstrumentationRegistry.getContext().getFilesDir(),
-                 "test_preload_apps_dir");
-        mPreloadsAppsDirectory.mkdir();
-        for (String name : mPreloadedApps) {
-            final File f = new File(mPreloadsAppsDirectory, name);
-            f.createNewFile();
-            mPreloadedAppPaths.add(f.getPath());
-        }
-    }
-
-    @After
-    public void tearDown() {
-        if (mPreloadsAppsDirectory != null) {
-            FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory);
-        }
-    }
-
-    @Test
-    public void testInstallApps() throws Exception {
-        mInstaller.installApps(TEST_DEMO_USER);
-        for (String path : mPreloadedAppPaths) {
-            ArgumentCaptor<IPackageInstallObserver2> observer =
-                    ArgumentCaptor.forClass(IPackageInstallObserver2.class);
-            verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
-                    anyString(), eq(TEST_DEMO_USER));
-            observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
-                    null, null);
-            // Verify that we try to install the package in system user.
-            verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        }
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-
-    @Test
-    public void testInstallApps_noPreloads() throws Exception {
-        // Delete all files in preloaded apps directory - no preloaded apps
-        FileUtils.deleteContents(mPreloadsAppsDirectory);
-        mInstaller.installApps(TEST_DEMO_USER);
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-
-    @Test
-    public void testInstallApps_installationFails() throws Exception {
-        mInstaller.installApps(TEST_DEMO_USER);
-        for (int i = 0; i < mPreloadedAppPaths.size(); ++i) {
-            ArgumentCaptor<IPackageInstallObserver2> observer =
-                    ArgumentCaptor.forClass(IPackageInstallObserver2.class);
-            final String path = mPreloadedAppPaths.get(i);
-            verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
-                    anyString(), eq(TEST_DEMO_USER));
-            if (i == 0) {
-                observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_FAILED_DEXOPT,
-                        null, null);
-                continue;
-            }
-            observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
-                    null, null);
-            // Verify that we try to install the package in system user.
-            verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
-                    0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
-        }
-        assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
-                "1",
-                Settings.Secure.getStringForUser(mContentResolver,
-                        Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
deleted file mode 100644
index 2e13d29..0000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ /dev/null
@@ -1,476 +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.server.retaildemo;
-
-import static com.android.server.retaildemo.RetailDemoModeService.SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.Manifest;
-import android.app.ActivityManagerInternal;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.RetailDemoModeServiceInternal;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.util.ArrayMap;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.SystemService;
-import com.android.server.retaildemo.RetailDemoModeService.Injector;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.compat.ArgumentMatcher;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RetailDemoModeServiceTest {
-    private static final int TEST_DEMO_USER = 111;
-    private static final long SETUP_COMPLETE_TIMEOUT_MS = 2000; // 2 sec
-    private static final String TEST_CAMERA_PKG = "test.cameraapp";
-    private static final String TEST_PRELOADS_DIR_NAME = "test_preloads";
-
-    private Context mContext;
-    private @Mock UserManager mUm;
-    private @Mock PackageManager mPm;
-    private @Mock IPackageManager mIpm;
-    private @Mock NotificationManager mNm;
-    private @Mock ActivityManagerInternal mAmi;
-    private @Mock AudioManager mAudioManager;
-    private @Mock WifiManager mWifiManager;
-    private @Mock LockPatternUtils mLockPatternUtils;
-    private @Mock JobScheduler mJobScheduler;
-    private MockPreloadAppsInstaller mPreloadAppsInstaller;
-    private MockContentResolver mContentResolver;
-    private MockContactsProvider mContactsProvider;
-    private Configuration mConfiguration;
-    private File mTestPreloadsDir;
-    private CountDownLatch mLatch;
-
-    private RetailDemoModeService mService;
-    private TestInjector mInjector;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
-        when(mContext.getSystemServiceName(eq(JobScheduler.class))).thenReturn(
-                Context.JOB_SCHEDULER_SERVICE);
-        when(mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).thenReturn(mJobScheduler);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
-        mContentResolver = new MockContentResolver(mContext);
-        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        mContactsProvider = new MockContactsProvider(mContext);
-        mContentResolver.addProvider(CallLog.AUTHORITY, mContactsProvider);
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        mPreloadAppsInstaller = new MockPreloadAppsInstaller(mContext);
-        mConfiguration = new Configuration();
-        mTestPreloadsDir = new File(InstrumentationRegistry.getContext().getFilesDir(),
-                TEST_PRELOADS_DIR_NAME);
-
-        Settings.Global.putString(mContentResolver, Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, "");
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 1);
-
-        // Initialize RetailDemoModeService
-        mInjector = new TestInjector();
-        mService = new RetailDemoModeService(mInjector);
-        mService.onStart();
-    }
-
-    @After
-    public void tearDown() {
-        if (mTestPreloadsDir != null) {
-            FileUtils.deleteContentsAndDir(mTestPreloadsDir);
-        }
-    }
-
-    @Test
-    public void testDemoUserSetup() throws Exception {
-        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-
-        mLatch = new CountDownLatch(1);
-        final UserInfo userInfo = new UserInfo();
-        userInfo.id = TEST_DEMO_USER;
-        when(mUm.createUser(anyString(), anyInt())).thenReturn(userInfo);
-
-        setCameraPackage(TEST_CAMERA_PKG);
-        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
-        assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
-                "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
-        final ArgumentCaptor<IntentFilter> intentFilter =
-                ArgumentCaptor.forClass(IntentFilter.class);
-        verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
-        assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
-                intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
-
-        // Wait for the setup to complete.
-        mLatch.await(SETUP_COMPLETE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        ArgumentCaptor<Integer> flags = ArgumentCaptor.forClass(Integer.class);
-        verify(mUm).createUser(anyString(), flags.capture());
-        assertTrue("FLAG_DEMO not set during user creation",
-                (flags.getValue() & UserInfo.FLAG_DEMO) != 0);
-        assertTrue("FLAG_EPHEMERAL not set during user creation",
-                (flags.getValue() & UserInfo.FLAG_EPHEMERAL) != 0);
-        // Verify if necessary restrictions are being set.
-        final UserHandle user = UserHandle.of(TEST_DEMO_USER);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
-        // Verify if necessary settings are updated.
-        assertEquals("SKIP_FIRST_USE_HINTS setting is not set for demo user",
-                Settings.Secure.getIntForUser(mContentResolver,
-                        Settings.Secure.SKIP_FIRST_USE_HINTS, TEST_DEMO_USER),
-                1);
-        assertEquals("PACKAGE_VERIFIER_ENABLE settings should be set to 0 for demo user",
-                Settings.Global.getInt(mContentResolver,
-                        Settings.Global.PACKAGE_VERIFIER_ENABLE),
-                0);
-        // Verify if camera is granted location permission.
-        verify(mPm).grantRuntimePermission(TEST_CAMERA_PKG,
-                Manifest.permission.ACCESS_FINE_LOCATION, user);
-        // Verify call logs are cleared.
-        assertTrue("Call logs should be deleted", mContactsProvider.isCallLogDeleted());
-    }
-
-    @Test
-    public void testSettingsObserver_disableDemoMode() throws Exception {
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        when(mUm.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM))
-                .thenReturn(false);
-        Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
-        // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
-        observer.onChange(false, deviceDemoModeUri);
-        final ArgumentCaptor<BroadcastReceiver> receiver =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
-
-        Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
-        new File(mTestPreloadsDir, "dir1").mkdirs();
-        new File(mTestPreloadsDir, "file1").createNewFile();
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 0);
-        observer.onChange(false, deviceDemoModeUri);
-        verify(mContext).unregisterReceiver(receiver.getValue());
-        verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, false, UserHandle.SYSTEM);
-        assertEquals("Package verifier enable value has not been reset", 1,
-                Settings.Global.getInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE));
-        Thread.sleep(20); // Wait for the deletion to complete.
-        // verify that the preloaded directory is emptied.
-        assertEquals("Preloads directory is not emptied",
-                0, mTestPreloadsDir.list().length);
-        // Verify that the expiration job was scheduled
-        verify(mJobScheduler).schedule(any(JobInfo.class));
-    }
-
-    @Test
-    public void testSettingsObserver_enableDemoMode() throws Exception {
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
-        // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
-        observer.onChange(false, deviceDemoModeUri);
-        assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
-                "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
-        final ArgumentCaptor<IntentFilter> intentFilter =
-                ArgumentCaptor.forClass(IntentFilter.class);
-        verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
-        assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
-                intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
-    }
-
-    @Test
-    public void testSwitchToDemoUser() {
-        // To make the RetailDemoModeService update it's internal state.
-        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-        final RetailDemoModeService.SettingsObserver observer =
-                mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
-        observer.onChange(false, Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE));
-
-        final UserInfo userInfo = new UserInfo(TEST_DEMO_USER, "demo_user",
-                UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
-        when(mUm.getUserInfo(TEST_DEMO_USER)).thenReturn(userInfo);
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
-        final int minVolume = -111;
-        for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
-            when(mAudioManager.getStreamMinVolume(stream)).thenReturn(minVolume);
-        }
-
-        mService.onSwitchUser(TEST_DEMO_USER);
-        verify(mAmi).updatePersistentConfigurationForUser(mConfiguration, TEST_DEMO_USER);
-        for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
-            verify(mAudioManager).setStreamVolume(stream, minVolume, 0);
-        }
-        verify(mLockPatternUtils).setLockScreenDisabled(true, TEST_DEMO_USER);
-        verify(mWifiManager).setWifiEnabled(true);
-    }
-
-    private void setCameraPackage(String pkgName) {
-        final ResolveInfo ri = new ResolveInfo();
-        final ActivityInfo ai = new ActivityInfo();
-        ai.packageName = pkgName;
-        ri.activityInfo = ai;
-        when(mPm.resolveActivityAsUser(
-                argThat(new IntentMatcher(MediaStore.ACTION_IMAGE_CAPTURE)),
-                anyInt(),
-                eq(TEST_DEMO_USER))).thenReturn(ri);
-    }
-
-    private class IntentMatcher extends ArgumentMatcher<Intent> {
-        private final Intent mIntent;
-
-        IntentMatcher(String action) {
-            mIntent = new Intent(action);
-        }
-
-        @Override
-        public boolean matchesObject(Object argument) {
-            if (argument instanceof Intent) {
-                return ((Intent) argument).filterEquals(mIntent);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "Expected: " + mIntent;
-        }
-    }
-
-    private class MockContactsProvider extends MockContentProvider {
-        private boolean mCallLogDeleted;
-
-        MockContactsProvider(Context context) {
-            super(context);
-        }
-
-        @Override
-        public int delete(Uri uri, String selection, String[] selectionArgs) {
-            if (CallLog.Calls.CONTENT_URI.equals(uri)) {
-                mCallLogDeleted = true;
-            }
-            return 0;
-        }
-
-        public boolean isCallLogDeleted() {
-            return mCallLogDeleted;
-        }
-    }
-
-    private class MockPreloadAppsInstaller extends PreloadAppsInstaller {
-        MockPreloadAppsInstaller(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void installApps(int userId) {
-        }
-    }
-
-    private class TestInjector extends Injector {
-        private ArrayMap<String, String> mSystemProperties = new ArrayMap<>();
-
-        TestInjector() {
-            super(mContext);
-        }
-
-        @Override
-        Context getContext() {
-            return mContext;
-        }
-
-        @Override
-        UserManager getUserManager() {
-            return mUm;
-        }
-
-        @Override
-        WifiManager getWifiManager() {
-            return mWifiManager;
-        }
-
-        @Override
-        void switchUser(int userId) {
-            if (mLatch != null) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        AudioManager getAudioManager() {
-            return mAudioManager;
-        }
-
-        @Override
-        NotificationManager getNotificationManager() {
-            return mNm;
-        }
-
-        @Override
-        ActivityManagerInternal getActivityManagerInternal() {
-            return mAmi;
-        }
-
-        @Override
-        PackageManager getPackageManager() {
-            return mPm;
-        }
-
-        @Override
-        IPackageManager getIPackageManager() {
-            return mIpm;
-        }
-
-        @Override
-        ContentResolver getContentResolver() {
-            return mContentResolver;
-        }
-
-        @Override
-        PreloadAppsInstaller getPreloadAppsInstaller() {
-            return mPreloadAppsInstaller;
-        }
-
-        @Override
-        void systemPropertiesSet(String key, String value) {
-            mSystemProperties.put(key, value);
-        }
-
-        @Override
-        void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
-        }
-
-        @Override
-        void initializeWakeLock() {
-        }
-
-        @Override
-        void destroyWakeLock() {
-        }
-
-        @Override
-        boolean isWakeLockHeld() {
-            return false;
-        }
-
-        @Override
-        void acquireWakeLock() {
-        }
-
-        @Override
-        void releaseWakeLock() {
-        }
-
-        @Override
-        void logSessionDuration(int duration) {
-        }
-
-        @Override
-        void logSessionCount(int count) {
-        }
-
-        @Override
-        Configuration getSystemUsersConfiguration() {
-            return mConfiguration;
-        }
-
-        @Override
-        LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        Notification createResetNotification() {
-            return null;
-        }
-
-        @Override
-        File getDataPreloadsDirectory() {
-            return mTestPreloadsDir;
-        }
-
-        @Override
-        File getDataPreloadsFileCacheDirectory() {
-            return new File(mTestPreloadsDir, "file_cache");
-        }
-
-        @Override
-        void publishLocalService(RetailDemoModeService service,
-                RetailDemoModeServiceInternal localService) {
-        }
-
-        String systemPropertiesGet(String key) {
-            return mSystemProperties.get(key);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java b/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
index d2a4484..8828988 100644
--- a/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/testutis/TestUtils.java
@@ -23,12 +23,14 @@
     private TestUtils() {
     }
 
+    public interface ExceptionRunnable {
+        void run() throws Exception;
+    }
+
     public static void assertExpectException(Class<? extends Throwable> expectedExceptionType,
-            String expectedExceptionMessageRegex, Runnable r) {
+            String expectedExceptionMessageRegex, ExceptionRunnable r) {
         try {
             r.run();
-            Assert.fail("Expected exception type " + expectedExceptionType.getName()
-                    + " was not thrown");
         } catch (Throwable e) {
             Assert.assertTrue(
                     "Expected exception type was " + expectedExceptionType.getName()
@@ -37,6 +39,9 @@
             if (expectedExceptionMessageRegex != null) {
                 MoreAsserts.assertContainsRegex(expectedExceptionMessageRegex, e.getMessage());
             }
+            return; // Pass.
         }
+        Assert.fail("Expected exception type " + expectedExceptionType.getName()
+                + " was not thrown");
     }
 }
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..432cfc7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import android.app.ActivityManager;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.view.DisplayInfo;
@@ -27,6 +28,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;
 
 /**
@@ -48,6 +50,20 @@
     }
 
     /**
+     * Ensures that appBounds causes {@link android.content.pm.ActivityInfo.CONFIG_APP_BOUNDS} diff.
+     */
+    @Test
+    public void testAppBoundsConfigurationDiff() {
+        final Configuration config = new Configuration();
+        final Configuration config2 = new Configuration();
+        config.appBounds = new Rect(0, 1, 1, 0);
+        config2.appBounds = new Rect(1, 2, 2, 1);
+
+        assertEquals(ActivityInfo.CONFIG_SCREEN_SIZE, config.diff(config2));
+        assertEquals(0, config.diffPublicOnly(config2));
+    }
+
+    /**
      * Ensures the configuration app bounds at the root level match the app dimensions.
      */
     @Test
@@ -121,7 +137,6 @@
                 mParentBounds);
     }
 
-
     private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
         final StackWindowController stackController = stackId != null ?
@@ -140,4 +155,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/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 36083bf..b09601e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -185,6 +185,11 @@
         assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
         // Can specify orientation if the current orientation candidate is orientation behind.
         assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation(SCREEN_ORIENTATION_BEHIND));
+
+        token.sendingToBottom = false;
+        token.setIsOnTop(true);
+        // Allow for token to provide orientation hidden if on top and not being sent to bottom.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 856e940..91eb55b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -31,10 +31,13 @@
 import org.junit.runner.RunWith;
 
 import android.content.res.Configuration;
+import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
 import android.util.SparseIntArray;
+import android.view.MotionEvent;
 
 import java.util.Arrays;
 import java.util.LinkedList;
@@ -237,6 +240,52 @@
         assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
     }
 
+    /**
+     * Tests tapping on a stack in different display results in window gaining focus.
+     */
+    @Test
+    public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
+        DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
+        // Create a second display
+        final DisplayContent dc1 = createNewDisplay();
+
+        // Add stack with activity.
+        final TaskStack stack0 = createTaskStackOnDisplay(dc0);
+        final Task task0 = createTaskInStack(stack0, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token =
+                new WindowTestUtils.TestAppWindowToken(dc0);
+        task0.addChild(token, 0);
+        dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc0.mTapDetector);
+        final TaskStack stack1 = createTaskStackOnDisplay(dc1);
+        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token1 =
+                new WindowTestUtils.TestAppWindowToken(dc0);
+        task1.addChild(token1, 0);
+        dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc1.mTapDetector);
+
+        // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
+        DisplayMetrics dm0 = dc0.getDisplayMetrics();
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
+
+        // Check focus is on primary display.
+        assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
+
+        // Tap on secondary display
+        DisplayMetrics dm1 = dc1.getDisplayMetrics();
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
+
+        // Check focus is on secondary.
+        assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+    }
+
     @Test
     @Ignore
     public void testFocusedWindowMultipleDisplays() throws Exception {
@@ -355,4 +404,18 @@
         }
         assertTrue(actualWindows.isEmpty());
     }
+
+    private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
+        final long downTime = SystemClock.uptimeMillis();
+        final long eventTime = SystemClock.uptimeMillis() + 100;
+        final int metaState = 0;
+
+        return MotionEvent.obtain(
+                downTime,
+                eventTime,
+                isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
+                x,
+                y,
+                metaState);
+    }
 }
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..95adc9c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -17,6 +17,11 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -38,6 +43,7 @@
 import android.os.RemoteException;
 import android.view.Display;
 import android.view.IWindowManager;
+import android.view.InputChannel;
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
@@ -90,7 +96,14 @@
                 }).when(am).notifyKeyguardFlagsChanged(any());
             }
 
-            sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false,
+            InputManagerService ims = mock(InputManagerService.class);
+            // InputChannel is final and can't be mocked.
+            InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
+            if (input != null && input.length > 1) {
+                doReturn(input[1]).when(ims).monitorInput(anyString());
+            }
+
+            sWm = WindowManagerService.main(context, ims, true, false,
                     false, new TestWindowManagerPolicy());
         }
         return sWm;
@@ -381,6 +394,11 @@
     }
 
     @Override
+    public boolean okToAnimate() {
+        return true;
+    }
+
+    @Override
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
 
     }
@@ -609,6 +627,11 @@
     }
 
     @Override
+    public int getNavBarPosition() {
+        return NAV_BAR_BOTTOM;
+    }
+
+    @Override
     public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
             Rect outInsets) {
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 8fe4116..6e253e7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -363,6 +363,50 @@
                 Math.min(pf.height(), displayInfo.logicalHeight));
     }
 
+    @Test
+    public void testLayoutLetterboxedWindow() {
+        // First verify task behavior in multi-window mode.
+        final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+
+        final int taskLeft = logicalWidth / 5;
+        final int taskTop = logicalHeight / 5;
+        final int taskRight = logicalWidth / 4 * 3;
+        final int taskBottom = logicalHeight / 4 * 3;
+        final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
+        TaskWithBounds task = new TaskWithBounds(taskBounds);
+        task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
+        task.mFullscreenForTest = false;
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                pf /* contentFrame */, pf /* visibleFrame */, pf /* decorFrame */,
+                pf /* stableFrame */, null /* outsetFrame */);
+        // For non fullscreen tasks the containing frame is based off the
+        // task bounds not the parent frame.
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+
+        // Now simulate switch to fullscreen for letterboxed app.
+        final int xInset = logicalWidth / 10;
+        final int yInset = logicalWidth / 10;
+        final Rect cf = new Rect(xInset, yInset, logicalWidth - xInset, logicalHeight - yInset);
+        w.mAppToken.onOverrideConfigurationChanged(w.mAppToken.getOverrideConfiguration(), cf);
+        pf.set(0, 0, logicalWidth, logicalHeight);
+        task.mFullscreenForTest = true;
+
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                cf /* contentFrame */, cf /* visibleFrame */, pf /* decorFrame */,
+                cf /* stableFrame */, null /* outsetFrame */);
+        assertEquals(cf, w.mFrame);
+        assertEquals(cf, w.getContentFrameLw());
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+    }
+
     private WindowStateWithTask createWindow(Task task, int width, int height) {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.width = width;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index c809c32..67db5f4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -218,8 +218,7 @@
         root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         root.mTurnOnScreen = false;
 
-        root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
-                wasVisible /*wasVisible*/);
+        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
         assertTrue(root.mTurnOnScreen);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index b83532c..7ff1110 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -89,6 +89,7 @@
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
     public static class TestAppWindowToken extends AppWindowToken {
+        boolean mOnTop = false;
 
         TestAppWindowToken(DisplayContent dc) {
             super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */,
@@ -125,6 +126,15 @@
         int positionInParent() {
             return getParent().mChildren.indexOf(this);
         }
+
+        void setIsOnTop(boolean onTop) {
+            mOnTop = onTop;
+        }
+
+        @Override
+        boolean isOnTop() {
+            return mOnTop;
+        }
     }
 
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 922f08d..926a606 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -339,6 +339,10 @@
         return ret;
     }
 
+    public static <T> T[] array(T... array) {
+        return array;
+    }
+
     public static <T> List<T> list(T... array) {
         return Arrays.asList(array);
     }
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 562443f..9f4fb85 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -197,7 +197,7 @@
             // logic should be kept in sync with getAllocatableBytes().
             if (isQuotaSupported(volumeUuid, callingPackage)) {
                 final long cacheTotal = getCacheBytes(volumeUuid, callingPackage);
-                final long cacheReserved = mStorage.getStorageCacheBytes(path);
+                final long cacheReserved = mStorage.getStorageCacheBytes(path, 0);
                 final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
 
                 return path.getUsableSpace() + cacheClearable;
diff --git a/services/usb/Android.mk b/services/usb/Android.mk
index 57bf57d..55bfccf 100644
--- a/services/usb/Android.mk
+++ b/services/usb/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_JAVA_LIBRARIES := services.core \
 android.hidl.manager-V1.0-java
 
-LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb-V1.0-java
+LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb-V1.0-java \
+android.hardware.usb-V1.1-java
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 03d8241..68c1d5f 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -65,6 +65,9 @@
     private final HashMap<UsbDevice,UsbAudioDevice>
         mAudioDevices = new HashMap<UsbDevice,UsbAudioDevice>();
 
+    private boolean mIsInputHeadset; // as reported by UsbDescriptorParser
+    private boolean mIsOutputHeadset; // as reported by UsbDescriptorParser
+
     private final HashMap<UsbDevice,UsbMidiDevice>
         mMidiDevices = new HashMap<UsbDevice,UsbMidiDevice>();
 
@@ -184,24 +187,34 @@
         try {
             // Playback Device
             if (audioDevice.mHasPlayback) {
-                int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_OUT_USB_ACCESSORY :
-                        AudioSystem.DEVICE_OUT_USB_DEVICE);
+                int device;
+                if (mIsOutputHeadset) {
+                    device = AudioSystem.DEVICE_OUT_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_OUT_USB_ACCESSORY
+                        : AudioSystem.DEVICE_OUT_USB_DEVICE);
+                }
                 if (DEBUG) {
                     Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) +
-                            " addr:" + address + " name:" + audioDevice.mDeviceName);
+                            " addr:" + address + " name:" + audioDevice.getDeviceName());
                 }
                 mAudioService.setWiredDeviceConnectionState(
-                        device, state, address, audioDevice.mDeviceName, TAG);
+                        device, state, address, audioDevice.getDeviceName(), TAG);
             }
 
             // Capture Device
             if (audioDevice.mHasCapture) {
-               int device = (audioDevice == mAccessoryAudioDevice ?
-                        AudioSystem.DEVICE_IN_USB_ACCESSORY :
-                        AudioSystem.DEVICE_IN_USB_DEVICE);
+                int device;
+                if (mIsInputHeadset) {
+                    device = AudioSystem.DEVICE_IN_USB_HEADSET;
+                } else {
+                    device = (audioDevice == mAccessoryAudioDevice
+                        ? AudioSystem.DEVICE_IN_USB_ACCESSORY
+                        : AudioSystem.DEVICE_IN_USB_DEVICE);
+                }
                 mAudioService.setWiredDeviceConnectionState(
-                        device, state, address, audioDevice.mDeviceName, TAG);
+                        device, state, address, audioDevice.getDeviceName(), TAG);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState");
@@ -329,10 +342,9 @@
         UsbAudioDevice audioDevice =
                 new UsbAudioDevice(card, device, hasPlayback, hasCapture, deviceClass);
         AlsaCardsParser.AlsaCardRecord cardRecord = mCardsParser.getCardRecordFor(card);
-        audioDevice.mDeviceName = cardRecord.mCardName;
-        audioDevice.mDeviceDescription = cardRecord.mCardDescription;
+        audioDevice.setDeviceNameAndDescription(cardRecord.mCardName, cardRecord.mCardDescription);
 
-        notifyDeviceState(audioDevice, true);
+        notifyDeviceState(audioDevice, true /*enabled*/);
 
         return audioDevice;
     }
@@ -344,12 +356,16 @@
         return selectAudioCard(mCardsParser.getDefaultCard());
     }
 
-    /* package */ void usbDeviceAdded(UsbDevice usbDevice) {
-       if (DEBUG) {
-          Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() +
-                  " nm:" + usbDevice.getProductName());
+    /* package */ void usbDeviceAdded(UsbDevice usbDevice,
+            boolean isInputHeadset, boolean isOutputHeadset) {
+        if (DEBUG) {
+            Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName()
+                    + " nm:" + usbDevice.getProductName());
         }
 
+        mIsInputHeadset = isInputHeadset;
+        mIsOutputHeadset = isOutputHeadset;
+
         // Is there an audio interface in there?
         boolean isAudioDevice = false;
 
@@ -442,7 +458,7 @@
         Slog.i(TAG, "USB Audio Device Removed: " + audioDevice);
         if (audioDevice != null) {
             if (audioDevice.mHasPlayback || audioDevice.mHasCapture) {
-                notifyDeviceState(audioDevice, false);
+                notifyDeviceState(audioDevice, false /*enabled*/);
 
                 // if there any external devices left, select one of them
                 selectDefaultDevice();
@@ -461,9 +477,9 @@
         if (enabled) {
             mAccessoryAudioDevice = new UsbAudioDevice(card, device, true, false,
                     UsbAudioDevice.kAudioDeviceClass_External);
-            notifyDeviceState(mAccessoryAudioDevice, true);
+            notifyDeviceState(mAccessoryAudioDevice, true /*enabled*/);
         } else if (mAccessoryAudioDevice != null) {
-            notifyDeviceState(mAccessoryAudioDevice, false);
+            notifyDeviceState(mAccessoryAudioDevice, false /*enabled*/);
             mAccessoryAudioDevice = null;
         }
     }
@@ -508,6 +524,7 @@
     //
     // Logging
     //
+    // called by UsbService.dump
     public void dump(IndentingPrintWriter pw) {
         pw.println("USB Audio Devices:");
         for (UsbDevice device : mAudioDevices.keySet()) {
diff --git a/services/usb/java/com/android/server/usb/UsbAudioDevice.java b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
index 70d1fc6..4b17dfe 100644
--- a/services/usb/java/com/android/server/usb/UsbAudioDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
@@ -36,8 +36,8 @@
     // This member is a combination of the above bit-flags
     public final int mDeviceClass;
 
-    public String mDeviceName = "";
-    public String mDeviceDescription = "";
+    private String mDeviceName = "";
+    private String mDeviceDescription = "";
 
     public UsbAudioDevice(int card, int device,
             boolean hasPlayback, boolean hasCapture, int deviceClass) {
@@ -59,8 +59,19 @@
         return sb.toString();
     }
 
-    public String toShortString() {
+    // called by logDevices
+    String toShortString() {
         return "[card:" + mCard + " device:" + mDevice + " " + mDeviceName + "]";
     }
+
+    String getDeviceName() {
+        return mDeviceName;
+    }
+
+    void setDeviceNameAndDescription(String deviceName, String deviceDescription) {
+        mDeviceName = deviceName;
+        mDeviceDescription = deviceDescription;
+    }
+
 }
 
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index ca74688..2219863 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -30,6 +30,10 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbConfiguration;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
@@ -61,6 +65,8 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Scanner;
@@ -125,9 +131,11 @@
     private static final int MSG_BOOT_COMPLETED = 4;
     private static final int MSG_USER_SWITCHED = 5;
     private static final int MSG_UPDATE_USER_RESTRICTIONS = 6;
-    private static final int MSG_UPDATE_HOST_STATE = 7;
+    private static final int MSG_UPDATE_PORT_STATE = 7;
     private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8;
     private static final int MSG_UPDATE_CHARGING_STATE = 9;
+    private static final int MSG_UPDATE_HOST_STATE = 10;
+    private static final int MSG_LOCALE_CHANGED = 11;
 
     private static final int AUDIO_MODE_SOURCE = 1;
 
@@ -168,6 +176,22 @@
     private final UsbSettingsManager mSettingsManager;
     private Intent mBroadcastedIntent;
     private boolean mPendingBootBroadcast;
+    private static Set<Integer> sBlackListedInterfaces;
+
+    static {
+        sBlackListedInterfaces = new HashSet<Integer>();
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_COMM);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HID);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_PRINTER);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_MASS_STORAGE);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_HUB);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CDC_DATA);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CSCID);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_CONTENT_SEC);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_VIDEO);
+        sBlackListedInterfaces.add(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
+    };
 
     private class AdbSettingsObserver extends ContentObserver {
         public AdbSettingsObserver() {
@@ -201,7 +225,7 @@
         }
     };
 
-    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mPortReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
@@ -219,6 +243,26 @@
         }
     };
 
+    private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE))
+                    .getDeviceList().entrySet().iterator();
+            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true);
+            } else {
+                mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false);
+            }
+        }
+    };
+
+    private final BroadcastReceiver mLanguageChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mHandler.sendEmptyMessage(MSG_LOCALE_CHANGED);
+        }
+    };
+
     public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
         mContext = context;
@@ -243,10 +287,18 @@
         if (secureAdbEnabled && !dataEncrypted) {
             mDebuggingManager = new UsbDebuggingManager(context);
         }
-        mContext.registerReceiver(mHostReceiver,
+        mContext.registerReceiver(mPortReceiver,
                 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
         mContext.registerReceiver(mChargingReceiver,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+        IntentFilter filter =
+                new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+        mContext.registerReceiver(mHostReceiver, filter);
+
+        mContext.registerReceiver(mLanguageChangedReceiver,
+                new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
     }
 
     private UsbProfileGroupSettingsManager getCurrentSettings() {
@@ -371,6 +423,8 @@
         private boolean mSinkPower;
         private boolean mConfigured;
         private boolean mUsbDataUnlocked;
+        private boolean mAudioAccessoryConnected;
+        private boolean mAudioAccessorySupported;
         private String mCurrentFunctions;
         private boolean mCurrentFunctionsApplied;
         private UsbAccessory mCurrentAccessory;
@@ -379,6 +433,8 @@
         private int mCurrentUser = UserHandle.USER_NULL;
         private boolean mUsbCharging;
         private String mCurrentOemFunctions;
+        private boolean mHideUsbNotification;
+        private boolean mSupportsAllCombinations;
 
         public UsbHandler(Looper looper) {
             super(looper);
@@ -481,21 +537,16 @@
         }
 
         public void updateHostState(UsbPort port, UsbPortStatus status) {
-            boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
-            boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
-            boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
-
             if (DEBUG) {
                 Slog.i(TAG, "updateHostState " + port + " status=" + status);
             }
 
             SomeArgs args = SomeArgs.obtain();
-            args.argi1 = hostConnected ? 1 : 0;
-            args.argi2 = sourcePower ? 1 : 0;
-            args.argi3 = sinkPower ? 1 : 0;
+            args.arg1 = port;
+            args.arg2 = status;
 
-            removeMessages(MSG_UPDATE_HOST_STATE);
-            Message msg = obtainMessage(MSG_UPDATE_HOST_STATE, args);
+            removeMessages(MSG_UPDATE_PORT_STATE);
+            Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args);
             // debounce rapid transitions of connect/disconnect on type-c ports
             sendMessageDelayed(msg, UPDATE_DELAY);
         }
@@ -540,7 +591,7 @@
                 }
 
                 setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
-                updateAdbNotification();
+                updateAdbNotification(false);
             }
 
             if (mDebuggingManager != null) {
@@ -560,7 +611,7 @@
 
             if (usbDataUnlocked != mUsbDataUnlocked) {
                 mUsbDataUnlocked = usbDataUnlocked;
-                updateUsbNotification();
+                updateUsbNotification(false);
                 forceRestart = true;
             }
 
@@ -642,8 +693,9 @@
                 // Set the new USB configuration.
                 setUsbConfig(oemFunctions);
 
-                if (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
-                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP)) {
+                if (mBootCompleted
+                        && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
+                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {
                     // Start up dependent services.
                     updateUsbStateBroadcastIfNeeded(true);
                 }
@@ -765,7 +817,7 @@
             }
 
             // send broadcast intent only if the USB state has changed
-            if (!isUsbStateChanged(intent)) {
+            if (!isUsbStateChanged(intent) && !configChanged) {
                 if (DEBUG) {
                     Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
                 }
@@ -840,8 +892,8 @@
                     mConnected = (msg.arg1 == 1);
                     mConfigured = (msg.arg2 == 1);
 
-                    updateUsbNotification();
-                    updateAdbNotification();
+                    updateUsbNotification(false);
+                    updateAdbNotification(false);
                     if (mBootCompleted) {
                         updateUsbStateBroadcastIfNeeded(false);
                     }
@@ -859,14 +911,31 @@
                         mPendingBootBroadcast = true;
                     }
                     break;
-                case MSG_UPDATE_HOST_STATE:
+                case MSG_UPDATE_PORT_STATE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     boolean prevHostConnected = mHostConnected;
-                    mHostConnected = (args.argi1 == 1);
-                    mSourcePower = (args.argi2 == 1);
-                    mSinkPower = (args.argi3 == 1);
+                    UsbPort port = (UsbPort) args.arg1;
+                    UsbPortStatus status = (UsbPortStatus) args.arg2;
+                    mHostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
+                    mSourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
+                    mSinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
+                    mAudioAccessoryConnected =
+                            (status.getCurrentMode() == UsbPort.MODE_AUDIO_ACCESSORY);
+                    mAudioAccessorySupported = port.isModeSupported(UsbPort.MODE_AUDIO_ACCESSORY);
+                    // Ideally we want to see if PR_SWAP and DR_SWAP is supported.
+                    // But, this should be suffice, since, all four combinations are only supported
+                    // when PR_SWAP and DR_SWAP are supported.
+                    mSupportsAllCombinations = status.isRoleCombinationSupported(
+                            UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE,
+                            UsbPort.DATA_ROLE_DEVICE)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST);
+
                     args.recycle();
-                    updateUsbNotification();
+                    updateUsbNotification(false);
                     if (mBootCompleted) {
                         if (mHostConnected || prevHostConnected) {
                             updateUsbStateBroadcastIfNeeded(false);
@@ -877,7 +946,39 @@
                     break;
                 case MSG_UPDATE_CHARGING_STATE:
                     mUsbCharging = (msg.arg1 == 1);
-                    updateUsbNotification();
+                    updateUsbNotification(false);
+                    break;
+                case MSG_UPDATE_HOST_STATE:
+                    Iterator devices = (Iterator) msg.obj;
+                    boolean connected = (msg.arg1 == 1);
+
+                    if (DEBUG) {
+                        Slog.i(TAG, "HOST_STATE connected:" + connected);
+                    }
+
+                    mHideUsbNotification = false;
+                    while (devices.hasNext()) {
+                        Map.Entry pair = (Map.Entry) devices.next();
+                        if (DEBUG) {
+                            Slog.i(TAG, pair.getKey() + " = " + pair.getValue());
+                        }
+                        UsbDevice device = (UsbDevice) pair.getValue();
+                        int configurationCount = device.getConfigurationCount() - 1;
+                        while (configurationCount >= 0) {
+                            UsbConfiguration config = device.getConfiguration(configurationCount);
+                            configurationCount--;
+                            int interfaceCount = config.getInterfaceCount() - 1;
+                            while (interfaceCount >= 0) {
+                                UsbInterface intrface = config.getInterface(interfaceCount);
+                                interfaceCount--;
+                                if (sBlackListedInterfaces.contains(intrface.getInterfaceClass())) {
+                                    mHideUsbNotification = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    updateUsbNotification(false);
                     break;
                 case MSG_ENABLE_ADB:
                     setAdbEnabled(msg.arg1 == 1);
@@ -895,10 +996,14 @@
                             mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
                     break;
                 case MSG_SYSTEM_READY:
-                    updateUsbNotification();
-                    updateAdbNotification();
+                    updateUsbNotification(false);
+                    updateAdbNotification(false);
                     updateUsbFunctions();
                     break;
+                case MSG_LOCALE_CHANGED:
+                    updateAdbNotification(true);
+                    updateUsbNotification(true);
+                    break;
                 case MSG_BOOT_COMPLETED:
                     mBootCompleted = true;
                     if (mPendingBootBroadcast) {
@@ -949,15 +1054,31 @@
             return mCurrentAccessory;
         }
 
-        private void updateUsbNotification() {
+        private void updateUsbNotification(boolean force) {
             if (mNotificationManager == null || !mUseUsbNotification
                     || ("0".equals(SystemProperties.get("persist.charging.notify")))) {
                 return;
             }
+
+            // Dont show the notification when connected to a USB peripheral
+            // and the link does not support PR_SWAP and DR_SWAP
+            if (mHideUsbNotification && !mSupportsAllCombinations) {
+                if (mUsbNotificationId != 0) {
+                    mNotificationManager.cancelAsUser(null, mUsbNotificationId,
+                            UserHandle.ALL);
+                    mUsbNotificationId = 0;
+                    Slog.d(TAG, "Clear notification");
+                }
+                return;
+            }
+
             int id = 0;
             int titleRes = 0;
             Resources r = mContext.getResources();
-            if (mConnected) {
+            if (mAudioAccessoryConnected && !mAudioAccessorySupported) {
+                titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title;
+                id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED;
+            } else if (mConnected) {
                 if (!mUsbDataUnlocked) {
                     if (mSourcePower) {
                         titleRes = com.android.internal.R.string.usb_supplying_notification_title;
@@ -996,26 +1117,51 @@
                 titleRes = com.android.internal.R.string.usb_charging_notification_title;
                 id = SystemMessage.NOTE_USB_CHARGING;
             }
-            if (id != mUsbNotificationId) {
+            if (id != mUsbNotificationId || force) {
                 // clear notification if title needs changing
                 if (mUsbNotificationId != 0) {
                     mNotificationManager.cancelAsUser(null, mUsbNotificationId,
                             UserHandle.ALL);
+                    Slog.d(TAG, "Clear notification");
                     mUsbNotificationId = 0;
                 }
                 if (id != 0) {
-                    CharSequence message = r.getText(
-                            com.android.internal.R.string.usb_notification_message);
+                    CharSequence message;
                     CharSequence title = r.getText(titleRes);
+                    PendingIntent pi;
+                    String channel;
 
-                    Intent intent = Intent.makeRestartActivityTask(
-                            new ComponentName("com.android.settings",
-                                    "com.android.settings.deviceinfo.UsbModeChooserActivity"));
-                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
-                            intent, 0, null, UserHandle.CURRENT);
+                    if (titleRes
+                            != com.android.internal.R.string
+                            .usb_unsupported_audio_accessory_title) {
+                        Intent intent = Intent.makeRestartActivityTask(
+                                new ComponentName("com.android.settings",
+                                        "com.android.settings.deviceinfo.UsbModeChooserActivity"));
+                        pi = PendingIntent.getActivityAsUser(mContext, 0,
+                                intent, 0, null, UserHandle.CURRENT);
+                        channel = SystemNotificationChannels.USB;
+                        message = r.getText(
+                                com.android.internal.R.string.usb_notification_message);
+                    } else {
+                        final Intent intent = new Intent();
+                        intent.setClassName("com.android.settings",
+                                "com.android.settings.HelpTrampoline");
+                        intent.putExtra(Intent.EXTRA_TEXT,
+                                "help_url_audio_accessory_not_supported");
 
-                    Notification notification =
-                            new Notification.Builder(mContext, SystemNotificationChannels.USB)
+                        if (mContext.getPackageManager().resolveActivity(intent, 0) != null) {
+                            pi = PendingIntent.getActivity(mContext, 0, intent, 0);
+                        } else {
+                            pi = null;
+                        }
+
+                        channel = SystemNotificationChannels.ALERTS;
+                        message = r.getText(
+                                com.android.internal.R.string
+                                        .usb_unsupported_audio_accessory_message);
+                    }
+
+                    Notification.Builder builder = new Notification.Builder(mContext, channel)
                                     .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                                     .setWhen(0)
                                     .setOngoing(true)
@@ -1027,22 +1173,37 @@
                                     .setContentTitle(title)
                                     .setContentText(message)
                                     .setContentIntent(pi)
-                                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                                    .build();
+                                    .setVisibility(Notification.VISIBILITY_PUBLIC);
+
+                    if (titleRes
+                            == com.android.internal.R.string
+                            .usb_unsupported_audio_accessory_title) {
+                        builder.setStyle(new Notification.BigTextStyle()
+                                .bigText(message));
+                    }
+                    Notification notification = builder.build();
+
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
+                    Slog.d(TAG, "push notification:" + title);
                     mUsbNotificationId = id;
                 }
             }
         }
 
-        private void updateAdbNotification() {
+        private void updateAdbNotification(boolean force) {
             if (mNotificationManager == null) return;
             final int id = SystemMessage.NOTE_ADB_ACTIVE;
             final int titleRes = com.android.internal.R.string.adb_active_notification_title;
+
             if (mAdbEnabled && mConnected) {
                 if ("0".equals(SystemProperties.get("persist.adb.notify"))) return;
 
+                if (force && mAdbNotificationShown) {
+                    mAdbNotificationShown = false;
+                    mNotificationManager.cancelAsUser(null, id, UserHandle.ALL);
+                }
+
                 if (!mAdbNotificationShown) {
                     Resources r = mContext.getResources();
                     CharSequence title = r.getText(titleRes);
@@ -1085,10 +1246,13 @@
         private String getDefaultFunctions() {
             String func = SystemProperties.get(getPersistProp(true),
                     UsbManager.USB_FUNCTION_NONE);
-            if (UsbManager.USB_FUNCTION_NONE.equals(func)) {
-                func = UsbManager.USB_FUNCTION_MTP;
+            // if ADB is enabled, reset functions to ADB
+            // else enable MTP as usual.
+            if (UsbManager.containsFunction(func, UsbManager.USB_FUNCTION_ADB)) {
+                return UsbManager.USB_FUNCTION_ADB;
+            } else {
+                return UsbManager.USB_FUNCTION_MTP;
             }
-            return func;
         }
 
         public void dump(IndentingPrintWriter pw) {
@@ -1104,6 +1268,9 @@
             pw.println("  mSourcePower: " + mSourcePower);
             pw.println("  mSinkPower: " + mSinkPower);
             pw.println("  mUsbCharging: " + mUsbCharging);
+            pw.println("  mHideUsbNotification: " + mHideUsbNotification);
+            pw.println("  mAudioAccessoryConnected: " + mAudioAccessoryConnected);
+
             try {
                 pw.println("  Kernel state: "
                         + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());
@@ -1211,8 +1378,7 @@
                         newFunction = UsbManager.addFunction(overrideFunctions.second,
                                 UsbManager.USB_FUNCTION_ADB);
                     } else {
-                        newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE,
-                                UsbManager.USB_FUNCTION_ADB);
+                        newFunction = overrideFunctions.second;
                     }
                     Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: "
                             + UsbDeviceManager.getPersistProp(false));
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index af78c05..3279fa6 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.usb;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,6 +31,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.descriptors.UsbDescriptorParser;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -259,7 +259,18 @@
                     getCurrentUserSettings().deviceAttachedForFixedHandler(mNewDevice,
                             usbDeviceConnectionHandler);
                 }
-                mUsbAlsaManager.usbDeviceAdded(mNewDevice);
+                // deviceName is something like: "/dev/bus/usb/001/001"
+                UsbDescriptorParser parser = new UsbDescriptorParser();
+                boolean isInputHeadset = false;
+                boolean isOutputHeadset = false;
+                if (parser.parseDevice(mNewDevice.getDeviceName())) {
+                    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/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 2729795..7e2496c 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -22,11 +22,12 @@
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
 import android.hardware.usb.V1_0.IUsb;
-import android.hardware.usb.V1_0.IUsbCallback;
 import android.hardware.usb.V1_0.PortRole;
 import android.hardware.usb.V1_0.PortRoleType;
 import android.hardware.usb.V1_0.PortStatus;
 import android.hardware.usb.V1_0.Status;
+import android.hardware.usb.V1_1.IUsbCallback;
+import android.hardware.usb.V1_1.PortStatus_1_1;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.Bundle;
@@ -454,6 +455,39 @@
             return;
         }
 
+
+        public void notifyPortStatusChange_1_1(ArrayList<PortStatus_1_1> currentPortStatus,
+                int retval) {
+            if (!portManager.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
+
+            for (PortStatus_1_1 current : currentPortStatus) {
+                RawPortInfo temp = new RawPortInfo(current.status.portName,
+                        current.supportedModes, current.currentMode,
+                        current.status.canChangeMode, current.status.currentPowerRole,
+                        current.status.canChangePowerRole,
+                        current.status.currentDataRole, current.status.canChangeDataRole);
+                newPortInfo.add(temp);
+                logAndPrint(Log.INFO, pw, "ClientCallback: " + current.status.portName);
+            }
+
+            Message message = portManager.mHandler.obtainMessage();
+            Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
+            message.what = MSG_UPDATE_PORTS;
+            message.setData(bundle);
+            portManager.mHandler.sendMessage(message);
+            return;
+        }
+
         public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
             if (retval == Status.SUCCESS) {
                 logAndPrint(Log.INFO, pw, portName + " role switch successful");
@@ -568,7 +602,7 @@
             IndentingPrintWriter pw) {
         // Only allow mode switch capability for dual role ports.
         // Validate that the current mode matches the supported modes we expect.
-        if (supportedModes != UsbPort.MODE_DUAL) {
+        if ((supportedModes & UsbPort.MODE_DUAL) != UsbPort.MODE_DUAL) {
             canChangeMode = false;
             if (currentMode != 0 && currentMode != supportedModes) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent current mode from USB "
diff --git a/services/usb/java/com/android/server/usb/descriptors/ByteStream.java b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
new file mode 100644
index 0000000..d678931
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/ByteStream.java
@@ -0,0 +1,189 @@
+/*
+ * 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.usb.descriptors;
+
+import android.annotation.NonNull;
+
+/**
+ * @hide
+ * A stream interface wrapping a byte array. Very much like a java.io.ByteArrayInputStream
+ * but with the capability to "back up" in situations where the parser discovers that a
+ * UsbDescriptor has overrun its length.
+ */
+public class ByteStream {
+    private static final String TAG = "ByteStream";
+
+    /** The byte array being wrapped */
+    @NonNull
+    private final byte[] mBytes; // this is never null.
+
+    /**
+     * The index into the byte array to be read next.
+     * This value is altered by reading data out of the stream
+     * (using either the getByte() or unpack*() methods), or alternatively
+     * by explicitly offseting the stream position with either
+     * advance() or reverse().
+     */
+    private int mIndex;
+
+    /*
+     * This member used with resetReadCount() & getReadCount() can be used to determine how many
+     * bytes a UsbDescriptor subclass ACTUALLY reads (as opposed to what its length field says).
+     * using this info, the parser can mark a descriptor as valid or invalid and correct the stream
+     * position with advance() & reverse() to keep from "getting lost" in the descriptor stream.
+     */
+    private int mReadCount;
+
+    /**
+     * Create a ByteStream object wrapping the specified byte array.
+     *
+     * @param bytes The byte array containing the raw descriptor information retrieved from
+     *              the USB device.
+     * @throws IllegalArgumentException
+     */
+    public ByteStream(@NonNull byte[] bytes) {
+        if (bytes == null) {
+            throw new IllegalArgumentException();
+        }
+        mBytes = bytes;
+    }
+
+    /**
+     * Resets the running count of bytes read so that later we can see how much more has been read.
+     */
+    public void resetReadCount() {
+        mReadCount = 0;
+    }
+
+    /**
+     * Retrieves the running count of bytes read from the stream.
+     */
+    public int getReadCount() {
+        return mReadCount;
+    }
+
+    /**
+     * @return The value of the next byte in the stream without advancing the stream.
+     * Does not affect the running count as the byte hasn't been "consumed".
+     * @throws IndexOutOfBoundsException
+     */
+    public byte peekByte() {
+        if (available() > 0) {
+            return mBytes[mIndex + 1];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return the next byte from the stream and advances the stream and the read count. Note
+     * that this is a signed byte (as is the case of byte in Java). The user may need to understand
+     * from context if it should be interpreted as an unsigned value.
+     * @throws IndexOutOfBoundsException
+     */
+    public byte getByte() {
+        if (available() > 0) {
+            mReadCount++;
+            return mBytes[mIndex++];
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 2 bytes in *little endian format* from the stream and composes a 16-bit integer.
+     * As we are storing the 2-byte value in a 4-byte integer, the upper 2 bytes are always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 16-bit integer (packed into the lower 2 bytes of an int) encoded by the
+     * next 2 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbWord() {
+        if (available() >= 2) {
+            int b0 = getByte();
+            int b1 = getByte();
+            return ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reads 3 bytes in *little endian format* from the stream and composes a 24-bit integer.
+     * As we are storing the 3-byte value in a 4-byte integer, the upper byte is always
+     * 0, essentially making the returned value *unsigned*.
+     * @return The 24-bit integer (packed into the lower 3 bytes of an int) encoded by the
+     * next 3 bytes in the stream.
+     * @throws IndexOutOfBoundsException
+     */
+    public int unpackUsbTriple() {
+        if (available() >= 3) {
+            int b0 = getByte();
+            int b1 = getByte();
+            int b2 = getByte();
+            return ((b2 << 16) & 0x00FF0000) | ((b1 << 8) & 0x0000FF00) | (b0 & 0x000000FF);
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Advances the logical position in the stream. Affects the running count also.
+     * @param numBytes The number of bytes to advance.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void advance(int numBytes) {
+        if (numBytes < 0) {
+            // Positive offsets only
+            throw new IllegalArgumentException();
+        }
+        // do arithmetic and comparison in long to ovoid potention integer overflow
+        long longNewIndex = (long) mIndex + (long) numBytes;
+        if (longNewIndex < (long) mBytes.length) {
+            mReadCount += numBytes;
+            mIndex += numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Reverse the logical position in the stream. Affects the running count also.
+     * @param numBytes The (positive) number of bytes to reverse.
+     * @throws IndexOutOfBoundsException
+     * @throws IllegalArgumentException
+     */
+    public void reverse(int numBytes) {
+        if (numBytes < 0) {
+            // Positive (reverse) offsets only
+            throw new IllegalArgumentException();
+        }
+        if (mIndex >= numBytes) {
+            mReadCount -= numBytes;
+            mIndex -= numBytes;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * @return The number of bytes available to be read in the stream.
+     */
+    public int available() {
+        return mBytes.length - mIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
new file mode 100644
index 0000000..96fcc6a
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioControlEndpoint.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Audio Control Endpoint.
+ * audio10.pdf section 4.4.2.1
+ */
+public class UsbACAudioControlEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioControlEndpoint";
+
+    private byte mAddress;  // 2:1 The address of the endpoint on the USB device.
+                            // D7: Direction. 1 = IN endpoint
+                            // D6..4: Reserved, reset to zero
+                            // D3..0: The endpoint number.
+    private byte mAttribs;  // 3:1 (see ATTRIBSMASK_* below
+    private int mMaxPacketSize; // 4:2 Maximum packet size this endpoint is capable of sending
+                                // or receiving when this configuration is selected.
+    private byte mInterval; // 6:1
+
+    static final byte ADDRESSMASK_DIRECTION = (byte) 0x80;
+    static final byte ADDRESSMASK_ENDPOINT  = 0x0F;
+
+    static final byte ATTRIBSMASK_SYNC  = 0x0C;
+    static final byte ATTRIBMASK_TRANS  = 0x03;
+
+    public UsbACAudioControlEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getAddress() {
+        return mAddress;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public int getMaxPacketSize() {
+        return mMaxPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mAddress = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
new file mode 100644
index 0000000..d387883
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACAudioStreamEndpoint.java
@@ -0,0 +1,39 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Streaming Endpoint
+ * see audio10.pdf section 3.7.2
+ */
+public class UsbACAudioStreamEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACAudioStreamEndpoint";
+
+    //TODO data fields...
+    public UsbACAudioStreamEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        //TODO Read fields
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
new file mode 100644
index 0000000..223496ab
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACEndpoint.java
@@ -0,0 +1,71 @@
+/*
+ * 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.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Endpoint
+ * see audio10.pdf section 4.4.1.2
+ */
+abstract class UsbACEndpoint extends UsbDescriptor {
+    private static final String TAG = "ACEndpoint";
+
+    protected final byte mSubclass; // from the mSubclass member of the "enclosing"
+                                    // Interface Descriptor, not the stream.
+    protected byte mSubtype;        // 2:1 HEADER descriptor subtype
+
+    UsbACEndpoint(int length, byte type, byte subclass) {
+        super(length, type);
+        mSubclass = subclass;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSubtype = stream.getByte();
+
+        return mLength;
+    }
+
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser,
+            int length, byte type) {
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return new UsbACAudioControlEndpoint(length, type, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return new UsbACAudioStreamEndpoint(length, type, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return new UsbACMidiEndpoint(length, type, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Endpoint id:0x" + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
new file mode 100644
index 0000000..739fe55
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACFeatureUnit.java
@@ -0,0 +1,76 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Feature Unit Interface
+ * see audio10.pdf section 3.5.5
+ */
+public class UsbACFeatureUnit extends UsbACInterface {
+    private static final String TAG = "ACFeatureUnit";
+
+    // audio10.pdf section 4.3.2.5
+    public static final int CONTROL_MASK_MUTE =    0x0001;
+    public static final int CONTROL_MASK_VOL =     0x0002;
+    public static final int CONTROL_MASK_BASS =    0x0004;
+    public static final int CONTROL_MASK_MID =     0x0008;
+    public static final int CONTROL_MASK_TREB =    0x0010;
+    public static final int CONTROL_MASK_EQ =      0x0020;
+    public static final int CONTROL_MASK_AGC =     0x0040;
+    public static final int CONTROL_MASK_DELAY =   0x0080;
+    public static final int CONTROL_MASK_BOOST =   0x0100; // BASS boost
+    public static final int CONTROL_MASK_LOUD =    0x0200; // LOUDNESS
+
+    private int mNumChannels;
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit
+    private byte mSourceID; // 4:1 ID of the Unit or Terminal to which this Feature Unit
+                            // is connected.
+    private byte mControlSize;  // 5:1 Size in bytes of an element of the mControls array: n
+    private int[] mControls;    // 6:? bitmask (see above) of supported controls in a given
+                                // logical channel
+    private byte mUnitName;     // ?:1 Index of a string descriptor, describing this Feature Unit.
+
+    public UsbACFeatureUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public int getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getControlSize() {
+        return mControlSize;
+    }
+
+    public int[] getControls() {
+        return mControls;
+    }
+
+    public byte getUnitName() {
+        return mUnitName;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
new file mode 100644
index 0000000..e31438c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACHeader.java
@@ -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.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Interface Header.
+ * see audio10.pdf section 4.3.2
+ */
+public class UsbACHeader extends UsbACInterface {
+    private static final String TAG = "ACHeader";
+
+    private int mADCRelease;    // 3:2 Audio Device Class Specification Release (BCD).
+    private int mTotalLength;   // 5:2 Total number of bytes returned for the class-specific
+                                // AudioControl interface descriptor. Includes the combined length
+                                // of this descriptor header and all Unit and Terminal descriptors.
+    private byte mNumInterfaces = 0; // 7:1 The number of AudioStreaming and MIDIStreaming
+                                     // interfaces in the Audio Interface Collection to which this
+                                     // AudioControl interface belongs: n
+    private byte[] mInterfaceNums = null;   // 8:n List of Audio/MIDI streaming interface
+                                            // numbers associate with this endpoint
+    private byte mControls;                 // Vers 2.0 thing
+
+    public UsbACHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public int getADCRelease() {
+        return mADCRelease;
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte[] getInterfaceNums() {
+        return mInterfaceNums;
+    }
+
+    public byte getControls() {
+        return mControls;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mADCRelease = stream.unpackUsbWord();
+
+        mTotalLength = stream.unpackUsbWord();
+        if (mADCRelease >= 0x200) {
+            mControls = stream.getByte();
+        } else {
+            mNumInterfaces = stream.getByte();
+            mInterfaceNums = new byte[mNumInterfaces];
+            for (int index = 0; index < mNumInterfaces; index++) {
+                mInterfaceNums[index] = stream.getByte();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
new file mode 100644
index 0000000..653a7de
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInputTerminal.java
@@ -0,0 +1,64 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Input Terminal interface.
+ * see audio10.pdf section 4.3.2.1
+ */
+public class UsbACInputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACInputTerminal";
+
+    private byte mNrChannels;       // 7:1 1 Channel (0x01)
+                                    // Number of logical output channels in the
+                                    // Terminal’s output audio channel cluster
+    private int mChannelConfig;     // 8:2 Mono (0x0000)
+    private byte mChannelNames;     // 10:1 Unused (0x00)
+    private byte mTerminal;         // 11:1 Unused (0x00)
+
+    public UsbACInputTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getNrChannels() {
+        return mNrChannels;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChannelNames() {
+        return mChannelNames;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNrChannels = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChannelNames = stream.getByte();
+        mTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
new file mode 100644
index 0000000..0ab7fcc
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACInterface.java
@@ -0,0 +1,190 @@
+/*
+ * 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.usb.descriptors;
+
+import android.util.Log;
+
+/**
+ * @hide
+ * An audio class-specific Interface.
+ * see audio10.pdf section 4.3.2
+ */
+public abstract class UsbACInterface extends UsbDescriptor {
+    private static final String TAG = "ACInterface";
+
+    // Audio Control Subtypes
+    public static final byte ACI_UNDEFINED = 0;
+    public static final byte ACI_HEADER = 1;
+    public static final byte ACI_INPUT_TERMINAL = 2;
+    public static final byte ACI_OUTPUT_TERMINAL = 3;
+    public static final byte ACI_MIXER_UNIT = 4;
+    public static final byte ACI_SELECTOR_UNIT = 5;
+    public static final byte ACI_FEATURE_UNIT = 6;
+    public static final byte ACI_PROCESSING_UNIT = 7;
+    public static final byte ACI_EXTENSION_UNIT = 8;
+
+    // Audio Streaming Subtypes
+    public static final byte ASI_UNDEFINED = 0;
+    public static final byte ASI_GENERAL = 1;
+    public static final byte ASI_FORMAT_TYPE = 2;
+    public static final byte ASI_FORMAT_SPECIFIC = 3;
+
+    // MIDI Streaming Subtypes
+    public static final byte MSI_UNDEFINED = 0;
+    public static final byte MSI_HEADER = 1;
+    public static final byte MSI_IN_JACK = 2;
+    public static final byte MSI_OUT_JACK = 3;
+    public static final byte MSI_ELEMENT = 4;
+
+    // Sample format IDs (encodings)
+    // FORMAT_I
+    public static final int FORMAT_I_UNDEFINED     = 0x0000;
+    public static final int FORMAT_I_PCM           = 0x0001;
+    public static final int FORMAT_I_PCM8          = 0x0002;
+    public static final int FORMAT_I_IEEE_FLOAT    = 0x0003;
+    public static final int FORMAT_I_ALAW          = 0x0004;
+    public static final int FORMAT_I_MULAW         = 0x0005;
+    // FORMAT_II
+    public static final int FORMAT_II_UNDEFINED    = 0x1000;
+    public static final int FORMAT_II_MPEG         = 0x1001;
+    public static final int FORMAT_II_AC3          = 0x1002;
+    // FORMAT_III
+    public static final int FORMAT_III_UNDEFINED              = 0x2000;
+    public static final int FORMAT_III_IEC1937AC3             = 0x2001;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer1   = 0x2002;
+    public static final int FORMAT_III_IEC1937_MPEG1_Layer2   = 0x2003;
+    public static final int FORMAT_III_IEC1937_MPEG2_EXT      = 0x2004;
+    public static final int FORMAT_III_IEC1937_MPEG2_Layer1LS = 0x2005;
+
+    protected final byte mSubtype;  // 2:1 HEADER descriptor subtype
+    protected final byte mSubclass; // from the mSubclass member of the
+                                    // "enclosing" Interface Descriptor
+
+    public UsbACInterface(int length, byte type, byte subtype, byte subclass) {
+        super(length, type);
+        mSubtype = subtype;
+        mSubclass = subclass;
+    }
+
+    public byte getSubtype() {
+        return mSubtype;
+    }
+
+    public byte getSubclass() {
+        return mSubclass;
+    }
+
+    private static UsbDescriptor allocAudioControlDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ACI_HEADER:
+                return new UsbACHeader(length, type, subtype, subClass);
+
+            case ACI_INPUT_TERMINAL:
+                return new UsbACInputTerminal(length, type, subtype, subClass);
+
+            case ACI_OUTPUT_TERMINAL:
+                return new UsbACOutputTerminal(length, type, subtype, subClass);
+
+            case ACI_SELECTOR_UNIT:
+                return new UsbACSelectorUnit(length, type, subtype, subClass);
+
+            case ACI_FEATURE_UNIT:
+                return new UsbACFeatureUnit(length, type, subtype, subClass);
+
+            case ACI_MIXER_UNIT:
+                return new UsbACMixerUnit(length, type, subtype, subClass);
+
+            case ACI_PROCESSING_UNIT:
+            case ACI_EXTENSION_UNIT:
+            case ACI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocAudioStreamingDescriptor(ByteStream stream,
+            int length, byte type, byte subtype, byte subClass) {
+        switch (subtype) {
+            case ASI_GENERAL:
+                return new UsbASGeneral(length, type, subtype, subClass);
+
+            case ASI_FORMAT_TYPE:
+                return UsbASFormat.allocDescriptor(stream, length, type, subtype, subClass);
+
+            case ASI_FORMAT_SPECIFIC:
+            case ASI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown Audio Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    private static UsbDescriptor allocMidiStreamingDescriptor(int length, byte type,
+            byte subtype, byte subClass) {
+        switch (subtype) {
+            case MSI_HEADER:
+                return new UsbMSMidiHeader(length, type, subtype, subClass);
+
+            case MSI_IN_JACK:
+                return new UsbMSMidiInputJack(length, type, subtype, subClass);
+
+            case MSI_OUT_JACK:
+                return new UsbMSMidiOutputJack(length, type, subtype, subClass);
+
+            case MSI_ELEMENT:
+                // break;
+                // Fall through until we implement that descriptor
+
+            case MSI_UNDEFINED:
+                // break; Fall through until we implement this descriptor
+            default:
+                Log.w(TAG, "Unknown MIDI Streaming Interface subtype:0x"
+                        + Integer.toHexString(subtype));
+                return null;
+        }
+    }
+
+    /**
+     * Allocates an audio class interface subtype based on subtype and subclass.
+     */
+    public static UsbDescriptor allocDescriptor(UsbDescriptorParser parser, ByteStream stream,
+            int length, byte type) {
+        byte subtype = stream.getByte();
+        UsbInterfaceDescriptor interfaceDesc = parser.getCurInterface();
+        byte subClass = interfaceDesc.getUsbSubclass();
+        switch (subClass) {
+            case AUDIO_AUDIOCONTROL:
+                return allocAudioControlDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_AUDIOSTREAMING:
+                return allocAudioStreamingDescriptor(stream, length, type, subtype, subClass);
+
+            case AUDIO_MIDISTREAMING:
+                return allocMidiStreamingDescriptor(length, type, subtype, subClass);
+
+            default:
+                Log.w(TAG, "Unknown Audio Class Interface Subclass: 0x"
+                        + Integer.toHexString(subClass));
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
new file mode 100644
index 0000000..9c07242
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMidiEndpoint.java
@@ -0,0 +1,52 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Endpoint.
+ * see midi10.pdf section 6.2.2
+ */
+public class UsbACMidiEndpoint extends UsbACEndpoint {
+    private static final String TAG = "ACMidiEndpoint";
+
+    private byte mNumJacks;
+    private byte[] mJackIds;
+
+    public UsbACMidiEndpoint(int length, byte type, byte subclass) {
+        super(length, type, subclass);
+    }
+
+    public byte getNumJacks() {
+        return mNumJacks;
+    }
+
+    public byte[] getJackIds() {
+        return mJackIds;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mNumJacks = stream.getByte();
+        mJackIds = new byte[mNumJacks];
+        for (int jack = 0; jack < mNumJacks; jack++) {
+            mJackIds[jack] = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
new file mode 100644
index 0000000..552b5ae
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACMixerUnit.java
@@ -0,0 +1,100 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Mixer Interface.
+ * see audio10.pdf section 4.3.2.3
+ */
+public class UsbACMixerUnit extends UsbACInterface {
+    private static final String TAG = "ACMixerUnit";
+
+    private byte mUnitID;       // 3:1
+    private byte mNumInputs;    // 4:1 Number of Input Pins of this Unit.
+    private byte[] mInputIDs;   // 5...:1 ID of the Unit or Terminal to which the Input Pins
+                                // are connected.
+    private byte mNumOutputs;   // The number of output channels
+    private int mChannelConfig; // Spacial location of output channels
+    private byte mChanNameID;   // First channel name string descriptor ID
+    private byte[] mControls;   // bitmasks of which controls are present for each channel
+    private byte mNameID;       // string descriptor ID of mixer name
+
+    public UsbACMixerUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumInputs() {
+        return mNumInputs;
+    }
+
+    public byte[] getInputIDs() {
+        return mInputIDs;
+    }
+
+    public byte getNumOutputs() {
+        return mNumOutputs;
+    }
+
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    public byte getChanNameID() {
+        return mChanNameID;
+    }
+
+    public byte[] getControls() {
+        return mControls;
+    }
+
+    public byte getNameID() {
+        return mNameID;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumInputs = stream.getByte();
+        mInputIDs = new byte[mNumInputs];
+        for (int input = 0; input < mNumInputs; input++) {
+            mInputIDs[input] = stream.getByte();
+        }
+        mNumOutputs = stream.getByte();
+        mChannelConfig = stream.unpackUsbWord();
+        mChanNameID = stream.getByte();
+
+        int controlArraySize;
+        int totalChannels = mNumInputs * mNumOutputs;
+        if (totalChannels % 8 == 0) {
+            controlArraySize = totalChannels / 8;
+        } else {
+            controlArraySize = totalChannels / 8 + 1;
+        }
+        mControls = new byte[controlArraySize];
+        for (int index = 0; index < controlArraySize; index++) {
+            mControls[index] = stream.getByte();
+        }
+
+        mNameID = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
new file mode 100644
index 0000000..f957e3d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACOutputTerminal.java
@@ -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.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Output Terminal Interface.
+ * see audio10.pdf section 4.3.2.2
+ */
+public class UsbACOutputTerminal extends UsbACTerminal {
+    private static final String TAG = "ACOutputTerminal";
+
+    private byte mSourceID;         // 7:1 From Input Terminal. (0x01)
+    private byte mTerminal;         // 8:1 Unused.
+
+    public UsbACOutputTerminal(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getSourceID() {
+        return mSourceID;
+    }
+
+    public byte getTerminal() {
+        return mTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        super.parseRawDescriptors(stream);
+
+        mSourceID = stream.getByte();
+        mTerminal = stream.getByte();
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
new file mode 100644
index 0000000..b1f60bd
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACSelectorUnit.java
@@ -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.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Selector Unit Interface.
+ * see audio10.pdf section 4.3.2.4
+ */
+public class UsbACSelectorUnit extends UsbACInterface {
+    private static final String TAG = "ACSelectorUnit";
+
+    private byte mUnitID;   // 3:1 Constant uniquely identifying the Unit within the audio function.
+                            // This value is used in all requests to address this Unit.
+    private byte mNumPins;  // 4:1 Number of input pins in this unit
+    private byte[] mSourceIDs;  // 5+mNumPins:1 ID of the Unit or Terminal to which the first
+                                // Input Pin of this Selector Unit is connected.
+    private byte mNameIndex;    // Index of a string descriptor, describing the Selector Unit.
+
+    public UsbACSelectorUnit(int length, byte type, byte subtype, byte subClass) {
+        super(length, type, subtype, subClass);
+    }
+
+    public byte getUnitID() {
+        return mUnitID;
+    }
+
+    public byte getNumPins() {
+        return mNumPins;
+    }
+
+    public byte[] getSourceIDs() {
+        return mSourceIDs;
+    }
+
+    public byte getNameIndex() {
+        return mNameIndex;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mUnitID = stream.getByte();
+        mNumPins = stream.getByte();
+        mSourceIDs = new byte[mNumPins];
+        for (int index = 0; index < mNumPins; index++) {
+            mSourceIDs[index] = stream.getByte();
+        }
+        mNameIndex = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
new file mode 100644
index 0000000..ea80208
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java
@@ -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.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ */
+public abstract class UsbACTerminal extends UsbACInterface {
+    // Note that these fields are the same for both the
+    // audio class-specific Output Terminal Interface.(audio10.pdf section 4.3.2.2)
+    // and audio class-specific Input Terminal interface.(audio10.pdf section 4.3.2.1)
+    // so we may as well unify the parsing here.
+    protected byte mTerminalID;       // 3:1 ID of this Output Terminal. (0x02)
+    protected int mTerminalType;      // 4:2 USB Streaming. (0x0101)
+    protected byte mAssocTerminal;    // 6:1 Unused (0x00)
+
+    public UsbACTerminal(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalID() {
+        return mTerminalID;
+    }
+
+    public int getTerminalType() {
+        return mTerminalType;
+    }
+
+    public byte getAssocTerminal() {
+        return mAssocTerminal;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalID = stream.getByte();
+        mTerminalType = stream.unpackUsbWord();
+        mAssocTerminal = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
new file mode 100644
index 0000000..d7c84c6
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormat.java
@@ -0,0 +1,64 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format Interface.
+ *   Subclasses: UsbACFormatI and UsbACFormatII.
+ * see audio10.pdf section 4.5.3 & & Frmts10.pdf
+ */
+public abstract class UsbASFormat extends UsbACInterface {
+    private static final String TAG = "ASFormat";
+
+    private final byte mFormatType;   // 3:1 FORMAT_TYPE_*
+
+    public static final byte FORMAT_TYPE_I = 1;
+    public static final byte FORMAT_TYPE_II = 2;
+
+    public UsbASFormat(int length, byte type, byte subtype, byte formatType, byte mSubclass) {
+        super(length, type, subtype, mSubclass);
+        mFormatType = formatType;
+    }
+
+    public byte getFormatType() {
+        return mFormatType;
+    }
+
+    /**
+     * Allocates the audio-class format subtype associated with the format type read from the
+     * stream.
+     */
+    public static UsbDescriptor allocDescriptor(ByteStream stream, int length, byte type,
+            byte subtype, byte subclass) {
+
+        byte formatType = stream.getByte();
+        //TODO
+        // There is an issue parsing format descriptors on (some) USB 2.0 pro-audio interfaces
+        // Since we don't need this info for headset detection, just skip these descriptors
+        // for now to avoid the (low) possibility of an IndexOutOfBounds exception.
+        switch (formatType) {
+//            case FORMAT_TYPE_I:
+//                return new UsbASFormatI(length, type, subtype, formatType, subclass);
+//
+//            case FORMAT_TYPE_II:
+//                return new UsbASFormatII(length, type, subtype, formatType, subclass);
+
+            default:
+                return null;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
new file mode 100644
index 0000000..347a6cf
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatI.java
@@ -0,0 +1,77 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format I interface.
+ * see Frmts10.pdf section 2.2
+ */
+public class UsbASFormatI extends UsbASFormat {
+    private static final String TAG = "ASFormatI";
+
+    private byte mNumChannels;      // 4:1
+    private byte mSubframeSize;     // 5:1 frame size in bytes
+    private byte mBitResolution;    // 6:1 sample size in bits
+    private byte mSampleFreqType;   // 7:1
+    private int[] mSampleRates;     // if mSamFreqType == 0, there will be 2 values: the
+                                    // min & max rates otherwise mSamFreqType rates.
+                                    // All 3-byte values. All rates in Hz
+
+    public UsbASFormatI(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public byte getNumChannels() {
+        return mNumChannels;
+    }
+
+    public byte getSubframeSize() {
+        return mSubframeSize;
+    }
+
+    public byte getBitResolution() {
+        return mBitResolution;
+    }
+
+    public byte getSampleFreqType() {
+        return mSampleFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mNumChannels = stream.getByte();
+        mSubframeSize = stream.getByte();
+        mBitResolution = stream.getByte();
+        mSampleFreqType = stream.getByte();
+        if (mSampleFreqType == 0) {
+            mSampleRates = new int[2];
+            mSampleRates[0] = stream.unpackUsbTriple();
+            mSampleRates[1] = stream.unpackUsbTriple();
+        } else {
+            mSampleRates = new int[mSampleFreqType];
+            for (int index = 0; index < mSampleFreqType; index++) {
+                mSampleRates[index] = stream.unpackUsbTriple();
+            }
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
new file mode 100644
index 0000000..abdc621
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASFormatII.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Format II interface.
+ * see Frmts10.pdf section 2.3
+ */
+public class UsbASFormatII extends UsbASFormat {
+    private static final String TAG = "ASFormatII";
+
+    private int mMaxBitRate; // 4:2 Indicates the maximum number of bits per second this
+                            // interface can handle. Expressed in kbits/s.
+    private int mSamplesPerFrame;   // 6:2 Indicates the number of PCM audio samples contained
+                                    // in one encoded audio frame.
+    private byte mSamFreqType;  // Indicates how the sampling frequency can be programmed:
+                                // 0: Continuous sampling frequency
+                                // 1..255: The number of discrete sampling frequencies supported
+                                // by the isochronous data endpoint of the AudioStreaming
+                                // interface (ns)
+    private int[] mSampleRates; // if mSamFreqType == 0, there will be 2 values:
+                                // the min & max rates. otherwise mSamFreqType rates.
+                                // All 3-byte values. All rates in Hz
+
+    public UsbASFormatII(int length, byte type, byte subtype, byte formatType, byte subclass) {
+        super(length, type, subtype, formatType, subclass);
+    }
+
+    public int getMaxBitRate() {
+        return mMaxBitRate;
+    }
+
+    public int getSamplesPerFrame() {
+        return mSamplesPerFrame;
+    }
+
+    public byte getSamFreqType() {
+        return mSamFreqType;
+    }
+
+    public int[] getSampleRates() {
+        return mSampleRates;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mMaxBitRate = stream.unpackUsbWord();
+        mSamplesPerFrame = stream.unpackUsbWord();
+        mSamFreqType = stream.getByte();
+        int numFreqs = mSamFreqType == 0 ? 2 : mSamFreqType;
+        mSampleRates = new int[numFreqs];
+        for (int index = 0; index < numFreqs; index++) {
+            mSampleRates[index] = stream.unpackUsbTriple();
+        }
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java
new file mode 100644
index 0000000..c4f42d3
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbASGeneral.java
@@ -0,0 +1,58 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific General interface.
+ * see audio10.pdf section 4.5.2
+ */
+public class UsbASGeneral extends UsbACInterface {
+    private static final String TAG = "ACGeneral";
+
+    // audio10.pdf - section 4.5.2
+    private byte mTerminalLink; // 3:1 The Terminal ID of the Terminal to which the endpoint
+                                // of this interface is connected.
+    private byte mDelay;        // 4:1 Delay introduced by the data path (see Section 3.4,
+                                // “Inter Channel Synchronization”). Expressed in number of frames.
+    private int mFormatTag;     // 5:2 The Audio Data Format that has to be used to communicate
+                                // with this interface.
+
+    public UsbASGeneral(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    public byte getTerminalLink() {
+        return mTerminalLink;
+    }
+
+    public byte getDelay() {
+        return mDelay;
+    }
+
+    public int getFormatTag() {
+        return mFormatTag;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTerminalLink = stream.getByte();
+        mDelay = stream.getByte();
+        mFormatTag = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
new file mode 100644
index 0000000..185cee2
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbBinaryParser.java
@@ -0,0 +1,72 @@
+/*
+ * 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.usb.descriptors;
+
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+import com.android.server.usb.descriptors.report.UsbStrings;
+
+/**
+ * @hide
+ * A class that just walks the descriptors and does a hex dump of the contained values.
+ * Usefull as a debugging tool.
+ */
+public class UsbBinaryParser {
+    private static final String TAG = "UsbBinaryParser";
+    private static final boolean LOGGING = false;
+
+    private void dumpDescriptor(ByteStream stream, int length, byte type, StringBuilder builder) {
+
+        // Log
+        if (LOGGING) {
+            Log.i(TAG, "l:" + length + " t:" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type));
+            StringBuilder sb = new StringBuilder();
+            for (int index = 2; index < length; index++) {
+                sb.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            Log.i(TAG, sb.toString());
+        } else {
+            // Screen Dump
+            builder.append("<p>");
+            builder.append("<b> l:" + length
+                    + " t:0x" + Integer.toHexString(type) + " "
+                    + UsbStrings.getDescriptorName(type) + "</b><br>");
+            for (int index = 2; index < length; index++) {
+                builder.append("0x" + Integer.toHexString(stream.getByte() & 0xFF) + " ");
+            }
+            builder.append("</p>");
+        }
+    }
+
+    /**
+     * Walk through descriptor stream and generate an HTML text report of the contents.
+     * TODO: This should be done in the model of UsbDescriptorsParser/Reporter model.
+     */
+    public void parseDescriptors(UsbDeviceConnection connection, byte[] descriptors,
+                                 StringBuilder builder) {
+
+        builder.append("<tt>");
+        ByteStream stream = new ByteStream(descriptors);
+        while (stream.available() > 0) {
+            int length = (int) stream.getByte() & 0x000000FF;
+            byte type = stream.getByte();
+            dumpDescriptor(stream, length, type, builder);
+        }
+        builder.append("</tt>");
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
new file mode 100644
index 0000000..8ae6d0f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbConfigDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * An USB Config Descriptor.
+ * see usb11.pdf section 9.6.2
+ */
+public class UsbConfigDescriptor extends UsbDescriptor {
+    private static final String TAG = "Config";
+
+    private int mTotalLength;   // 2:2 Total length in bytes of data returned
+    private byte mNumInterfaces; // 4:1 Number of Interfaces
+    private byte mConfigValue;  // 5:1 Value to use as an argument to select this configuration
+    private byte mConfigIndex;  // 6:1 Index of String Descriptor describing this configuration
+    private byte mAttribs;      // 7:1 D7 Reserved, set to 1. (USB 1.0 Bus Powered)
+                                //     D6 Self Powered
+                                //     D5 Remote Wakeup
+                                //     D4..0 Reserved, set to 0.
+    private byte mMaxPower;     // 8:1 Maximum Power Consumption in 2mA units
+
+    UsbConfigDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getTotalLength() {
+        return mTotalLength;
+    }
+
+    public byte getNumInterfaces() {
+        return mNumInterfaces;
+    }
+
+    public byte getConfigValue() {
+        return mConfigValue;
+    }
+
+    public byte getConfigIndex() {
+        return mConfigIndex;
+    }
+
+    public byte getAttribs() {
+        return mAttribs;
+    }
+
+    public byte getMaxPower() {
+        return mMaxPower;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mTotalLength = stream.unpackUsbWord();
+        mNumInterfaces = stream.getByte();
+        mConfigValue = stream.getByte();
+        mConfigIndex = stream.getByte();
+        mAttribs = stream.getByte();
+        mMaxPower = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
new file mode 100644
index 0000000..63b2d7f
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java
@@ -0,0 +1,223 @@
+/*
+ * 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.usb.descriptors;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+/*
+ * Some notes about UsbDescriptor and its subclasses.
+ *
+ * It is assumed that the user of the UsbDescriptorParser knows what they are doing
+ * so NO PROTECTION is implemented against "improper" use. Such uses are specifically:
+ * allocating a UsbDescriptor (subclass) object outside of the context of parsing/reading
+ * a rawdescriptor stream and perhaps accessing fields which have not been inialized (by
+ * parsing/reading or course).
+ */
+
+/**
+ * @hide
+ * Common superclass for all USB Descriptors.
+ */
+public abstract class UsbDescriptor {
+    private static final String TAG = "Descriptor";
+
+    protected final int mLength;    // 0:1 bLength Number Size of the Descriptor in Bytes (18 bytes)
+                                    // we store this as an int because Java bytes are SIGNED.
+    protected final byte mType;     // 1:1 bDescriptorType Constant Device Descriptor (0x01)
+
+    private byte[] mRawData;
+
+    private static final int SIZE_STRINGBUFFER = 256;
+    private static byte[] sStringBuffer = new byte[SIZE_STRINGBUFFER];
+
+    // Status
+    public static final int STATUS_UNPARSED         = 0;
+    public static final int STATUS_PARSED_OK        = 1;
+    public static final int STATUS_PARSED_UNDERRUN  = 2;
+    public static final int STATUS_PARSED_OVERRUN   = 3;
+    private int mStatus = STATUS_UNPARSED;
+
+    private static String[] sStatusStrings = {
+            "UNPARSED", "PARSED - OK", "PARSED - UNDERRUN", "PARSED - OVERRUN"};
+
+    // Descriptor Type IDs
+    public static final byte DESCRIPTORTYPE_DEVICE = 0x01;            // 1
+    public static final byte DESCRIPTORTYPE_CONFIG = 0x02;            // 2
+    public static final byte DESCRIPTORTYPE_STRING = 0x03;            // 3
+    public static final byte DESCRIPTORTYPE_INTERFACE = 0x04;         // 4
+    public static final byte DESCRIPTORTYPE_ENDPOINT = 0x05;          // 5
+    public static final byte DESCRIPTORTYPE_INTERFACEASSOC = 0x0B;    // 11
+    public static final byte DESCRIPTORTYPE_BOS = 0x0F;               // 15
+    public static final byte DESCRIPTORTYPE_CAPABILITY = 0x10;        // 16
+
+    public static final byte DESCRIPTORTYPE_HID = 0x21;                // 33
+    public static final byte DESCRIPTORTYPE_REPORT = 0x22;             // 34
+    public static final byte DESCRIPTORTYPE_PHYSICAL = 0x23;           // 35
+    public static final byte DESCRIPTORTYPE_AUDIO_INTERFACE = 0x24;    // 36
+    public static final byte DESCRIPTORTYPE_AUDIO_ENDPOINT = 0x25;     // 37
+    public static final byte DESCRIPTORTYPE_HUB = 0x29;                // 41
+    public static final byte DESCRIPTORTYPE_SUPERSPEED_HUB = 0x2A;     // 42
+    public static final byte DESCRIPTORTYPE_ENDPOINT_COMPANION = 0x30; // 48
+
+    // Class IDs
+    public static final byte CLASSID_DEVICE  =      0x00;
+    public static final byte CLASSID_AUDIO =        0x01;
+    public static final byte CLASSID_COM =          0x02;
+    public static final byte CLASSID_HID =          0x03;
+    // public static final byte CLASSID_??? =       0x04;
+    public static final byte CLASSID_PHYSICAL =     0x05;
+    public static final byte CLASSID_IMAGE =        0x06;
+    public static final byte CLASSID_PRINTER =      0x07;
+    public static final byte CLASSID_STORAGE =      0x08;
+    public static final byte CLASSID_HUB =          0x09;
+    public static final byte CLASSID_CDC_CONTROL =  0x0A;
+    public static final byte CLASSID_SMART_CARD =   0x0B;
+    //public static final byte CLASSID_??? =        0x0C;
+    public static final byte CLASSID_SECURITY =     0x0D;
+    public static final byte CLASSID_VIDEO =        0x0E;
+    public static final byte CLASSID_HEALTHCARE =   0x0F;
+    public static final byte CLASSID_AUDIOVIDEO =   0x10;
+    public static final byte CLASSID_BILLBOARD =    0x11;
+    public static final byte CLASSID_TYPECBRIDGE =  0x12;
+    public static final byte CLASSID_DIAGNOSTIC =   (byte) 0xDC;
+    public static final byte CLASSID_WIRELESS =     (byte) 0xE0;
+    public static final byte CLASSID_MISC =         (byte) 0xEF;
+    public static final byte CLASSID_APPSPECIFIC =  (byte) 0xFE;
+    public static final byte CLASSID_VENDSPECIFIC = (byte) 0xFF;
+
+    // Audio Subclass codes
+    public static final byte AUDIO_SUBCLASS_UNDEFINED   = 0x00;
+    public static final byte AUDIO_AUDIOCONTROL         = 0x01;
+    public static final byte AUDIO_AUDIOSTREAMING       = 0x02;
+    public static final byte AUDIO_MIDISTREAMING        = 0x03;
+
+    // Request IDs
+    public static final int REQUEST_GET_STATUS         = 0x00;
+    public static final int REQUEST_CLEAR_FEATURE      = 0x01;
+    public static final int REQUEST_SET_FEATURE        = 0x03;
+    public static final int REQUEST_GET_ADDRESS        = 0x05;
+    public static final int REQUEST_GET_DESCRIPTOR     = 0x06;
+    public static final int REQUEST_SET_DESCRIPTOR     = 0x07;
+    public static final int REQUEST_GET_CONFIGURATION  = 0x08;
+    public static final int REQUEST_SET_CONFIGURATION  = 0x09;
+
+    /**
+     * @throws IllegalArgumentException
+     */
+    UsbDescriptor(int length, byte type) {
+        // a descriptor has at least a length byte and type byte
+        // one could imagine an empty one otherwise
+        if (length < 2) {
+            // huh?
+            throw new IllegalArgumentException();
+        }
+
+        mLength = length;
+        mType = type;
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    public byte getType() {
+        return mType;
+    }
+
+    public int getStatus() {
+        return mStatus;
+    }
+
+    public void setStatus(int status) {
+        mStatus = status;
+    }
+
+    public String getStatusString() {
+        return sStatusStrings[mStatus];
+    }
+
+    public byte[] getRawData() {
+        return mRawData;
+    }
+
+    /**
+     * Called by the parser for any necessary cleanup.
+     */
+    public void postParse(ByteStream stream) {
+        // Status
+        int bytesRead = stream.getReadCount();
+        if (bytesRead < mLength) {
+            // Too cold...
+            stream.advance(mLength - bytesRead);
+            mStatus = STATUS_PARSED_UNDERRUN;
+            Log.w(TAG, "UNDERRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " < l:" + mLength);
+        } else if (bytesRead > mLength) {
+            // Too hot...
+            stream.reverse(bytesRead - mLength);
+            mStatus = STATUS_PARSED_OVERRUN;
+            Log.w(TAG, "OVERRRUN t:0x" + Integer.toHexString(mType)
+                    + " r:" + bytesRead + " > l:" + mLength);
+        } else {
+            // Just right!
+            mStatus = STATUS_PARSED_OK;
+        }
+    }
+
+    /**
+     * Reads data fields from specified raw-data stream.
+     */
+    public int parseRawDescriptors(ByteStream stream) {
+        int numRead = stream.getReadCount();
+        int dataLen = mLength - numRead;
+        if (dataLen > 0) {
+            mRawData = new byte[dataLen];
+            for (int index = 0; index < dataLen; index++) {
+                mRawData[index] = stream.getByte();
+            }
+        }
+        return mLength;
+    }
+
+    /**
+     * Gets a string for the specified index from the USB Device's string descriptors.
+     */
+    public static String getUsbDescriptorString(UsbDeviceConnection connection, byte strIndex) {
+        String usbStr = "";
+        if (strIndex != 0) {
+            try {
+                int rdo = connection.controlTransfer(
+                        UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD,
+                        REQUEST_GET_DESCRIPTOR,
+                        (DESCRIPTORTYPE_STRING << 8) | strIndex,
+                        0,
+                        sStringBuffer,
+                        0xFF,
+                        0);
+                if (rdo >= 0) {
+                    usbStr = new String(sStringBuffer, 2, rdo - 2, "UTF-16LE");
+                } else {
+                    usbStr = "?";
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Can not communicate with USB device", e);
+            }
+        }
+        return usbStr;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
new file mode 100644
index 0000000..d4a0ac4
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -0,0 +1,387 @@
+/*
+ * 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.usb.descriptors;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ * Class for parsing a binary stream of USB Descriptors.
+ */
+public class UsbDescriptorParser {
+    private static final String TAG = "DescriptorParser";
+
+    // Descriptor Objects
+    private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>();
+
+    private UsbDeviceDescriptor mDeviceDescriptor;
+    private UsbInterfaceDescriptor mCurInterfaceDescriptor;
+
+    public UsbDescriptorParser() {}
+
+    /**
+     * The probability (as returned by getHeadsetProbability() at which we conclude
+     * the peripheral is a headset.
+     */
+    private static final float IN_HEADSET_TRIGGER = 0.75f;
+    private static final float OUT_HEADSET_TRIGGER = 0.75f;
+
+    private UsbDescriptor allocDescriptor(ByteStream stream) {
+        stream.resetReadCount();
+
+        int length = (int) stream.getByte() & 0x000000FF;
+        byte type = stream.getByte();
+
+        UsbDescriptor descriptor = null;
+        switch (type) {
+            /*
+             * Standard
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_DEVICE:
+                descriptor = mDeviceDescriptor = new UsbDeviceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_CONFIG:
+                descriptor = new UsbConfigDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACE:
+                descriptor = mCurInterfaceDescriptor = new UsbInterfaceDescriptor(length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_ENDPOINT:
+                descriptor = new UsbEndpointDescriptor(length, type);
+                break;
+
+            /*
+             * HID
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_HID:
+                descriptor = new UsbHIDDescriptor(length, type);
+                break;
+
+            /*
+             * Other
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC:
+                descriptor = new UsbInterfaceAssoc(length, type);
+                break;
+
+            /*
+             * Audio Class Specific
+             */
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
+                descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+                break;
+
+            case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
+                descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+                break;
+
+            default:
+                break;
+        }
+
+        if (descriptor == null) {
+            // Unknown Descriptor
+            Log.i(TAG, "Unknown Descriptor len:" + length + " type:0x"
+                    + Integer.toHexString(type));
+            descriptor = new UsbUnknown(length, type);
+        }
+
+        return descriptor;
+    }
+
+    public UsbDeviceDescriptor getDeviceDescriptor() {
+        return mDeviceDescriptor;
+    }
+
+    public UsbInterfaceDescriptor getCurInterface() {
+        return mCurInterfaceDescriptor;
+    }
+
+    /**
+     * @hide
+     */
+    public void parseDescriptors(byte[] descriptors) {
+        mDescriptors.clear();
+
+        ByteStream stream = new ByteStream(descriptors);
+        while (stream.available() > 0) {
+            UsbDescriptor descriptor = null;
+            try {
+                descriptor = allocDescriptor(stream);
+            } catch (Exception ex) {
+                Log.e(TAG, "Exception allocating USB descriptor.", ex);
+            }
+
+            if (descriptor != null) {
+                // Parse
+                try {
+                    descriptor.parseRawDescriptors(stream);
+
+                    // Its OK to add the invalid descriptor as the postParse()
+                    // routine will mark it as invalid.
+                    mDescriptors.add(descriptor);
+
+                    // Clean up
+                    descriptor.postParse(stream);
+                } catch (Exception ex) {
+                    Log.e(TAG, "Exception parsing USB descriptors.", ex);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean parseDevice(String deviceAddr) {
+        byte[] rawDescriptors = getRawDescriptors(deviceAddr);
+        if (rawDescriptors != null) {
+            parseDescriptors(rawDescriptors);
+            return true;
+        }
+        return false;
+    }
+
+    private native byte[] getRawDescriptors(String deviceAddr);
+
+    public int getParsingSpec() {
+        return mDeviceDescriptor != null ? mDeviceDescriptor.getSpec() : 0;
+    }
+
+    public ArrayList<UsbDescriptor> getDescriptors() {
+        return mDescriptors;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getDescriptors(byte type) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == type) {
+                list.add(descriptor);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getInterfaceDescriptorsForClass(byte usbClass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            // ensure that this isn't an unrecognized DESCRIPTORTYPE_INTERFACE
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_INTERFACE) {
+                if (descriptor instanceof UsbInterfaceDescriptor) {
+                    UsbInterfaceDescriptor intrDesc = (UsbInterfaceDescriptor) descriptor;
+                    if (intrDesc.getUsbClass() == usbClass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<UsbDescriptor> getACInterfaceDescriptors(byte subtype, byte subclass) {
+        ArrayList<UsbDescriptor> list = new ArrayList<UsbDescriptor>();
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor.getType() == UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE) {
+                // ensure that this isn't an unrecognized DESCRIPTORTYPE_AUDIO_INTERFACE
+                if (descriptor instanceof UsbACInterface) {
+                    UsbACInterface acDescriptor = (UsbACInterface) descriptor;
+                    if (acDescriptor.getSubtype() == subtype
+                            && acDescriptor.getSubclass() == subclass) {
+                        list.add(descriptor);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognized Audio Interface l:" + descriptor.getLength()
+                            + " t:0x" + Integer.toHexString(descriptor.getType()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasHIDDescriptor() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID);
+        return !descriptors.isEmpty();
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasMIDIInterface() {
+        ArrayList<UsbDescriptor> descriptors =
+                getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_AUDIO);
+        for (UsbDescriptor descriptor : descriptors) {
+            // enusure that this isn't an unrecognized interface descriptor
+            if (descriptor instanceof UsbInterfaceDescriptor) {
+                UsbInterfaceDescriptor interfaceDescr = (UsbInterfaceDescriptor) descriptor;
+                if (interfaceDescr.getUsbSubclass() == UsbDescriptor.AUDIO_MIDISTREAMING) {
+                    return true;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Class Interface l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public float getInputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a microphone
+        boolean hasMic = false;
+        acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL,
+                UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACInputTerminal) {
+                UsbACInputTerminal inDescr = (UsbACInputTerminal) descriptor;
+                if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED
+                        || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) {
+                    hasMic = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Input terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasMic && hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasMic && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getInputHeadsetProbability() reports a probability of a USB Input peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isInputHeadset() {
+        return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER;
+    }
+
+    /**
+     * @hide
+     */
+    public float getOutputHeadsetProbability() {
+        if (hasMIDIInterface()) {
+            return 0.0f;
+        }
+
+        float probability = 0.0f;
+        ArrayList<UsbDescriptor> acDescriptors;
+
+        // Look for a "speaker"
+        boolean hasSpeaker = false;
+        acDescriptors =
+                getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbACInterface.AUDIO_AUDIOCONTROL);
+        for (UsbDescriptor descriptor : acDescriptors) {
+            if (descriptor instanceof UsbACOutputTerminal) {
+                UsbACOutputTerminal outDescr = (UsbACOutputTerminal) descriptor;
+                if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_OUT_SPEAKER
+                        || outDescr.getTerminalType()
+                            == UsbTerminalTypes.TERMINAL_OUT_HEADPHONES
+                        || outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET) {
+                    hasSpeaker = true;
+                    break;
+                }
+            } else {
+                Log.w(TAG, "Undefined Audio Output terminal l:" + descriptor.getLength()
+                        + " t:0x" + Integer.toHexString(descriptor.getType()));
+            }
+        }
+
+        if (hasSpeaker) {
+            probability += 0.75f;
+        }
+
+        if (hasSpeaker && hasHIDDescriptor()) {
+            probability += 0.25f;
+        }
+
+        return probability;
+    }
+
+    /**
+     * getOutputHeadsetProbability() reports a probability of a USB Output peripheral being a
+     * headset. The probability range is between 0.0f (definitely NOT a headset) and
+     * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient
+     * to count on the peripheral being a headset.
+     */
+    public boolean isOutputHeadset() {
+        return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER;
+    }
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
new file mode 100644
index 0000000..90848ca
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -0,0 +1,109 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Device Descriptor.
+ * see usb11.pdf section 9.6.1
+ */
+/* public */ public class UsbDeviceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Device";
+
+    private int mSpec;          // 2:2 bcdUSB 2 BCD USB Specification Number - BCD
+    private byte mDevClass;     // 4:1 class code
+    private byte mDevSubClass;  // 5:1 subclass code
+    private byte mProtocol;     // 6:1 protocol
+    private byte mPacketSize;   // 7:1 Maximum Packet Size for Zero Endpoint.
+                                // Valid Sizes are 8, 16, 32, 64
+    private int mVendorID;      // 8:2 vendor ID
+    private int mProductID;     // 10:2 product ID
+    private int mDeviceRelease; // 12:2 Device Release number - BCD
+    private byte mMfgIndex;     // 14:1 Index of Manufacturer String Descriptor
+    private byte mProductIndex; // 15:1 Index of Product String Descriptor
+    private byte mSerialNum;    // 16:1 Index of Serial Number String Descriptor
+    private byte mNumConfigs;   // 17:1 Number of Possible Configurations
+
+    UsbDeviceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getSpec() {
+        return mSpec;
+    }
+
+    public byte getDevClass() {
+        return mDevClass;
+    }
+
+    public byte getDevSubClass() {
+        return mDevSubClass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getPacketSize() {
+        return mPacketSize;
+    }
+
+    public int getVendorID() {
+        return mVendorID;
+    }
+
+    public int getProductID() {
+        return mProductID;
+    }
+
+    public int getDeviceRelease() {
+        return mDeviceRelease;
+    }
+
+    public byte getMfgIndex() {
+        return mMfgIndex;
+    }
+
+    public byte getProductIndex() {
+        return mProductIndex;
+    }
+
+    public byte getSerialNum() {
+        return mSerialNum;
+    }
+
+    public byte getNumConfigs() {
+        return mNumConfigs;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mSpec = stream.unpackUsbWord();
+        mDevClass = stream.getByte();
+        mDevSubClass = stream.getByte();
+        mProtocol = stream.getByte();
+        mPacketSize = stream.getByte();
+        mVendorID = stream.unpackUsbWord();
+        mProductID = stream.unpackUsbWord();
+        mDeviceRelease = stream.unpackUsbWord();
+        mMfgIndex = stream.getByte();
+        mProductIndex = stream.getByte();
+        mSerialNum = stream.getByte();
+        mNumConfigs = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
new file mode 100644
index 0000000..def6700
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbEndpointDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A Usb Endpoint Descriptor.
+ * see usb11.pdf section 9.6.4
+ */
+public class UsbEndpointDescriptor extends UsbDescriptor {
+    private static final String TAG = "EndPoint";
+
+    public static final byte MASK_ENDPOINT_ADDRESS     = 0b0001111;
+    public static final byte MASK_ENDPOINT_DIRECTION   = (byte) 0b10000000;
+    public static final byte DIRECTION_OUTPUT          = 0x00;
+    public static final byte DIRECTION_INPUT           = (byte) 0x80;
+
+    public static final byte MASK_ATTRIBS_TRANSTYPE = 0b00000011;
+    public static final byte TRANSTYPE_CONTROL     = 0x00;
+    public static final byte TRANSTYPE_ISO         = 0x01;
+    public static final byte TRANSTYPE_BULK        = 0x02;
+    public static final byte TRANSTYPE_INTERRUPT   = 0x03;
+
+    public static final byte MASK_ATTRIBS_SYNCTYPE  = 0b00001100;
+    public static final byte SYNCTYPE_NONE          = 0b00000000;
+    public static final byte SYNCTYPE_ASYNC         = 0b00000100;
+    public static final byte SYNCTYPE_ADAPTSYNC     = 0b00001000;
+    public static final byte SYNCTYPE_RESERVED      = 0b00001100;
+
+    public static final byte MASK_ATTRIBS_USEAGE    = 0b00110000;
+    public static final byte USEAGE_DATA            = 0b00000000;
+    public static final byte USEAGE_FEEDBACK        = 0b00010000;
+    public static final byte USEAGE_EXPLICIT        = 0b00100000;
+    public static final byte USEAGE_RESERVED        = 0b00110000;
+
+    private byte mEndpointAddress;  // 2:1 Endpoint Address
+                                    // Bits 0..3b Endpoint Number.
+                                    // Bits 4..6b Reserved. Set to Zero
+                                    // Bits 7 Direction 0 = Out, 1 = In
+                                    // (Ignored for Control Endpoints)
+    private byte mAttributes;   // 3:1 Various flags
+                                // Bits 0..1 Transfer Type:
+                                //     00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
+                                // Bits 2..7 are reserved. If Isochronous endpoint,
+                                // Bits 3..2 = Synchronisation Type (Iso Mode)
+                                //  00 = No Synchonisation
+                                //  01 = Asynchronous
+                                //  10 = Adaptive
+                                //  11 = Synchronous
+                                // Bits 5..4 = Usage Type (Iso Mode)
+                                //  00: Data Endpoint
+                                //  01:Feedback Endpoint 10
+                                //  Explicit Feedback Data Endpoint
+                                //  11: Reserved
+    private int mPacketSize;    // 4:2 Maximum Packet Size this endpoint is capable of
+                                // sending or receiving
+    private byte mInterval;     // 6:1 Interval for polling endpoint data transfers. Value in
+                                // frame counts.
+                                // Ignored for Bulk & Control Endpoints. Isochronous must equal
+                                // 1 and field may range from 1 to 255 for interrupt endpoints.
+    private byte mRefresh;
+    private byte mSyncAddress;
+
+    public UsbEndpointDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getEndpointAddress() {
+        return mEndpointAddress;
+    }
+
+    public byte getAttributes() {
+        return mAttributes;
+    }
+
+    public int getPacketSize() {
+        return mPacketSize;
+    }
+
+    public byte getInterval() {
+        return mInterval;
+    }
+
+    public byte getRefresh() {
+        return mRefresh;
+    }
+
+    public byte getSyncAddress() {
+        return mSyncAddress;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mEndpointAddress = stream.getByte();
+        mAttributes = stream.getByte();
+        mPacketSize = stream.unpackUsbWord();
+        mInterval = stream.getByte();
+        if (mLength == 9) {
+            mRefresh = stream.getByte();
+            mSyncAddress = stream.getByte();
+        }
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
new file mode 100644
index 0000000..56c07ec
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbHIDDescriptor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB HID (Human Interface Descriptor).
+ * see HID1_11.pdf - 6.2.1
+ */
+public class UsbHIDDescriptor extends UsbDescriptor {
+    private static final String TAG = "HID";
+
+    private int mRelease;           // 2:2 the HID Class Specification release.
+    private byte mCountryCode;      // 4:1 country code of the localized hardware.
+    private byte mNumDescriptors;   // number of descriptors (always at least one
+                                    // i.e. Report descriptor.)
+    private byte mDescriptorType;   // 6:1 type of class descriptor.
+                                    // See Section 7.1.2: Set_Descriptor
+                                    // Request for a table of class descriptor constants.
+    private int mDescriptorLen;     // 7:2 Numeric expression that is the total size of
+                                    // the Report descriptor.
+
+    public UsbHIDDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    public int getRelease() {
+        return mRelease;
+    }
+
+    public byte getCountryCode() {
+        return mCountryCode;
+    }
+
+    public byte getNumDescriptors() {
+        return mNumDescriptors;
+    }
+
+    public byte getDescriptorType() {
+        return mDescriptorType;
+    }
+
+    public int getDescriptorLen() {
+        return mDescriptorLen;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mRelease = stream.unpackUsbWord();
+        mCountryCode = stream.getByte();
+        mNumDescriptors = stream.getByte();
+        mDescriptorType = stream.getByte();
+        mDescriptorLen = stream.unpackUsbWord();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
new file mode 100644
index 0000000..4b18a01
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceAssoc.java
@@ -0,0 +1,73 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A USB Interface Association Descriptor.
+ * found this one here: http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf
+ * also: https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx
+ */
+public class UsbInterfaceAssoc extends UsbDescriptor {
+    private static final String TAG = "InterfaceAssoc";
+
+    private byte mFirstInterface;
+    private byte mInterfaceCount;
+    private byte mFunctionClass;
+    private byte mFunctionSubClass;
+    private byte mFunctionProtocol;
+    private byte mFunction;
+
+    public UsbInterfaceAssoc(int length, byte type) {
+        super(length, type);
+    }
+
+    public byte getFirstInterface() {
+        return mFirstInterface;
+    }
+
+    public byte getInterfaceCount() {
+        return mInterfaceCount;
+    }
+
+    public byte getFunctionClass() {
+        return mFunctionClass;
+    }
+
+    public byte getFunctionSubClass() {
+        return mFunctionSubClass;
+    }
+
+    public byte getFunctionProtocol() {
+        return mFunctionProtocol;
+    }
+
+    public byte getFunction() {
+        return mFunction;
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mFirstInterface = stream.getByte();
+        mInterfaceCount = stream.getByte();
+        mFunctionClass = stream.getByte();
+        mFunctionSubClass = stream.getByte();
+        mFunctionProtocol = stream.getByte();
+        mFunction = stream.getByte();
+
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
new file mode 100644
index 0000000..21b5e0c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbInterfaceDescriptor.java
@@ -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.
+ */
+package com.android.server.usb.descriptors;
+
+/**
+ * @hide
+ * A common super-class for all USB Interface Descritor subtypes.
+ * see usb11.pdf section 9.6.3
+ */
+public class UsbInterfaceDescriptor extends UsbDescriptor {
+    private static final String TAG = "Interface";
+
+    protected byte mInterfaceNumber;  // 2:1 Number of Interface
+    protected byte mAlternateSetting; // 3:1 Value used to select alternative setting
+    protected byte mNumEndpoints;     // 4:1 Number of Endpoints used for this interface
+    protected byte mUsbClass;         // 5:1 Class Code
+    protected byte mUsbSubclass;      // 6:1 Subclass Code
+    protected byte mProtocol;         // 7:1 Protocol Code
+    protected byte mDescrIndex;       // 8:1 Index of String Descriptor Describing this interface
+
+    UsbInterfaceDescriptor(int length, byte type) {
+        super(length, type);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        mInterfaceNumber = stream.getByte();
+        mAlternateSetting = stream.getByte();
+        mNumEndpoints = stream.getByte();
+        mUsbClass = stream.getByte();
+        mUsbSubclass = stream.getByte();
+        mProtocol = stream.getByte();
+        mDescrIndex = stream.getByte();
+
+        return mLength;
+    }
+
+    public byte getInterfaceNumber() {
+        return mInterfaceNumber;
+    }
+
+    public byte getAlternateSetting() {
+        return mAlternateSetting;
+    }
+
+    public byte getNumEndpoints() {
+        return mNumEndpoints;
+    }
+
+    public byte getUsbClass() {
+        return mUsbClass;
+    }
+
+    public byte getUsbSubclass() {
+        return mUsbSubclass;
+    }
+
+    public byte getProtocol() {
+        return mProtocol;
+    }
+
+    public byte getDescrIndex() {
+        return mDescrIndex;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.java
new file mode 100644
index 0000000..4452b23
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiHeader.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.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Streaming Interface.
+ * see midi10.pdf section 6.1.2.1
+ */
+public class UsbMSMidiHeader extends UsbACInterface {
+    private static final String TAG = "MSMidiHeader";
+
+    public UsbMSMidiHeader(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.java
new file mode 100644
index 0000000..2d33ba7
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiInputJack.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.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Input Jack Interface.
+ * see midi10.pdf section B.4.3
+ */
+public class UsbMSMidiInputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiInputJack";
+
+    UsbMSMidiInputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.java
new file mode 100644
index 0000000..bd2dc11
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbMSMidiOutputJack.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.server.usb.descriptors;
+
+/**
+ * @hide
+ * An audio class-specific Midi Output Jack Interface.
+ * see midi10.pdf section B.4.4
+ */
+public class UsbMSMidiOutputJack extends UsbACInterface {
+    private static final String TAG = "MSMidiOutputJack";
+
+    public UsbMSMidiOutputJack(int length, byte type, byte subtype, byte subclass) {
+        super(length, type, subtype, subclass);
+    }
+
+    @Override
+    public int parseRawDescriptors(ByteStream stream) {
+        // TODO - read data memebers
+        stream.advance(mLength - stream.getReadCount());
+        return mLength;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
new file mode 100644
index 0000000..b521462
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
@@ -0,0 +1,93 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A class for decoding information in Terminal Descriptors.
+ * see termt10.pdf
+ */
+public class UsbTerminalTypes {
+    private static final String TAG = "TerminalTypes";
+
+    // USB
+    public static final int TERMINAL_USB_STREAMING   = 0x0101;
+
+    // Inputs
+    public static final int TERMINAL_IN_UNDEFINED    = 0x0200;
+    public static final int TERMINAL_IN_MIC          = 0x0201;
+    public static final int TERMINAL_IN_DESKTOP_MIC  = 0x0202;
+    public static final int TERMINAL_IN_PERSONAL_MIC = 0x0203;
+    public static final int TERMINAL_IN_OMNI_MIC     = 0x0204;
+    public static final int TERMINAL_IN_MIC_ARRAY    = 0x0205;
+    public static final int TERMINAL_IN_PROC_MIC_ARRAY = 0x0206;
+
+    // Outputs
+    public static final int TERMINAL_OUT_UNDEFINED       = 0x0300;
+    public static final int TERMINAL_OUT_SPEAKER         = 0x0301;
+    public static final int TERMINAL_OUT_HEADPHONES      = 0x0302;
+    public static final int TERMINAL_OUT_HEADMOUNTED     = 0x0303;
+    public static final int TERMINAL_OUT_DESKTOPSPEAKER  = 0x0304;
+    public static final int TERMINAL_OUT_ROOMSPEAKER     = 0x0305;
+    public static final int TERMINAL_OUT_COMSPEAKER      = 0x0306;
+    public static final int TERMINAL_OUT_LFSPEAKER       = 0x0307;
+
+    // Bi-directional
+    public static final int TERMINAL_BIDIR_UNDEFINED    = 0x0400;
+    public static final int TERMINAL_BIDIR_HANDSET      = 0x0401;
+    public static final int TERMINAL_BIDIR_HEADSET      = 0x0402;
+    public static final int TERMINAL_BIDIR_SKRPHONE     = 0x0403;
+    public static final int TERMINAL_BIDIR_SKRPHONE_SUPRESS = 0x0404;
+    public static final int TERMINAL_BIDIR_SKRPHONE_CANCEL = 0x0405;
+
+    // Telephony
+    public static final int TERMINAL_TELE_UNDEFINED     = 0x0500;
+    public static final int TERMINAL_TELE_PHONELINE     = 0x0501;
+    public static final int TERMINAL_TELE_PHONE         = 0x0502;
+    public static final int TERMINAL_TELE_DOWNLINEPHONE = 0x0503;
+
+    // External
+    public static final int TERMINAL_EXTERN_UNDEFINED   = 0x0600;
+    public static final int TERMINAL_EXTERN_ANALOG      = 0x0601;
+    public static final int TERMINAL_EXTERN_DIGITAL     = 0x0602;
+    public static final int TERMINAL_EXTERN_LINE        = 0x0603;
+    public static final int TERMINAL_EXTERN_LEGACY      = 0x0604;
+    public static final int TERMINAL_EXTERN_SPIDF       = 0x0605;
+    public static final int TERMINAL_EXTERN_1394DA      = 0x0606;
+    public static final int TERMINAL_EXTERN_1394DV      = 0x0607;
+
+    public static final int TERMINAL_EMBED_UNDEFINED    = 0x0700;
+    public static final int TERMINAL_EMBED_CALNOISE     = 0x0701;
+    public static final int TERMINAL_EMBED_EQNOISE      = 0x0702;
+    public static final int TERMINAL_EMBED_CDPLAYER     = 0x0703;
+    public static final int TERMINAL_EMBED_DAT          = 0x0704;
+    public static final int TERMINAL_EMBED_DCC          = 0x0705;
+    public static final int TERMINAL_EMBED_MINIDISK     = 0x0706;
+    public static final int TERMINAL_EMBED_ANALOGTAPE   = 0x0707;
+    public static final int TERMINAL_EMBED_PHONOGRAPH   = 0x0708;
+    public static final int TERMINAL_EMBED_VCRAUDIO     = 0x0709;
+    public static final int TERMINAL_EMBED_VIDDISKAUDIO = 0x070A;
+    public static final int TERMINAL_EMBED_DVDAUDIO     = 0x070B;
+    public static final int TERMINAL_EMBED_TVAUDIO      = 0x070C;
+    public static final int TERMINAL_EMBED_SATELLITEAUDIO = 0x070D;
+    public static final int TERMINAL_EMBED_CABLEAUDIO   = 0x070E;
+    public static final int TERMINAL_EMBED_DSSAUDIO     = 0x070F;
+    public static final int TERMINAL_EMBED_RADIOAUDIO   = 0x0710;
+    public static final int TERMINAL_EMBED_RADIOTRANSMITTER = 0x0711;
+    public static final int TERMINAL_EMBED_MULTITRACK   = 0x0712;
+    public static final int TERMINAL_EMBED_SYNTHESIZER  = 0x0713;
+
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
new file mode 100644
index 0000000..a6fe8bb
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbUnknown.java
@@ -0,0 +1,28 @@
+/*
+ * 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.usb.descriptors;
+
+/**
+ * @hide
+ * A holder for any unrecognized descriptor encountered in the descriptor stream.
+ */
+public class UsbUnknown extends UsbDescriptor {
+    static final String TAG = "Unknown";
+
+    public UsbUnknown(int length, byte type) {
+        super(length, type);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
new file mode 100644
index 0000000..c98789d
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/HTMLReporter.java
@@ -0,0 +1,572 @@
+/*
+ * 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.usb.descriptors.report;
+
+import android.hardware.usb.UsbDeviceConnection;
+
+import com.android.server.usb.descriptors.UsbACAudioControlEndpoint;
+import com.android.server.usb.descriptors.UsbACAudioStreamEndpoint;
+import com.android.server.usb.descriptors.UsbACFeatureUnit;
+import com.android.server.usb.descriptors.UsbACHeader;
+import com.android.server.usb.descriptors.UsbACInputTerminal;
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbACMidiEndpoint;
+import com.android.server.usb.descriptors.UsbACMixerUnit;
+import com.android.server.usb.descriptors.UsbACOutputTerminal;
+import com.android.server.usb.descriptors.UsbACSelectorUnit;
+import com.android.server.usb.descriptors.UsbACTerminal;
+import com.android.server.usb.descriptors.UsbASFormat;
+import com.android.server.usb.descriptors.UsbASFormatI;
+import com.android.server.usb.descriptors.UsbASFormatII;
+import com.android.server.usb.descriptors.UsbASGeneral;
+import com.android.server.usb.descriptors.UsbConfigDescriptor;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbDeviceDescriptor;
+import com.android.server.usb.descriptors.UsbEndpointDescriptor;
+import com.android.server.usb.descriptors.UsbHIDDescriptor;
+import com.android.server.usb.descriptors.UsbInterfaceAssoc;
+import com.android.server.usb.descriptors.UsbInterfaceDescriptor;
+import com.android.server.usb.descriptors.UsbMSMidiHeader;
+import com.android.server.usb.descriptors.UsbMSMidiInputJack;
+import com.android.server.usb.descriptors.UsbMSMidiOutputJack;
+import com.android.server.usb.descriptors.UsbUnknown;
+
+/**
+ * Implements the Reporter inteface to provide HTML reporting for UsbDescriptor subclasses.
+ */
+public class HTMLReporter implements Reporter {
+    private final StringBuilder mStringBuilder;
+    private final UsbDeviceConnection mConnection;
+
+    public HTMLReporter(StringBuilder stringBuilder, UsbDeviceConnection connection) {
+        mStringBuilder = stringBuilder;
+        mConnection = connection;
+    }
+
+    /*
+     * HTML Helpers
+     */
+    private void writeHeader(int level, String text) {
+        mStringBuilder
+                .append("<h").append(level).append('>')
+                .append(text)
+                .append("</h").append(level).append('>');
+    }
+
+    private void openParagraph() {
+        mStringBuilder.append("<p>");
+    }
+
+    private void closeParagraph() {
+        mStringBuilder.append("</p>");
+    }
+
+    private void writeParagraph(String text) {
+        openParagraph();
+        mStringBuilder.append(text);
+        closeParagraph();
+    }
+
+    private void openList() {
+        mStringBuilder.append("<ul>");
+    }
+
+    private void closeList() {
+        mStringBuilder.append("</ul>");
+    }
+
+    private void openListItem() {
+        mStringBuilder.append("<li>");
+    }
+
+    private void closeListItem() {
+        mStringBuilder.append("</li>");
+    }
+
+    private void writeListItem(String text) {
+        openListItem();
+        mStringBuilder.append(text);
+        closeListItem();
+    }
+
+    /*
+     * Data Formating Helpers
+     */
+    private static String getHexString(byte value) {
+        return "0x" + Integer.toHexString(((int) value) & 0xFF).toUpperCase();
+    }
+
+    private static String getBCDString(int value) {
+        int major = value >> 8;
+        int minor = (value >> 4) & 0x0F;
+        int subminor = value & 0x0F;
+
+        return "" + major + "." + minor + subminor;
+    }
+
+    private static String getHexString(int value) {
+        int intValue = value & 0xFFFF;
+        return "0x" + Integer.toHexString(intValue).toUpperCase();
+    }
+
+    private void dumpHexArray(byte[] rawData, StringBuilder builder) {
+        if (rawData != null) {
+            // Assume the type and Length and perhaps sub-type have been displayed
+            openParagraph();
+            for (int index = 0; index < rawData.length; index++) {
+                builder.append(getHexString(rawData[index]) + " ");
+            }
+            closeParagraph();
+        }
+    }
+
+    /**
+     * Decode ACTUAL UsbDescriptor sub classes and call type-specific report methods.
+     */
+    @Override
+    public void report(UsbDescriptor descriptor) {
+        if (descriptor instanceof UsbDeviceDescriptor) {
+            tsReport((UsbDeviceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbConfigDescriptor) {
+            tsReport((UsbConfigDescriptor) descriptor);
+        } else if (descriptor instanceof UsbInterfaceDescriptor) {
+            tsReport((UsbInterfaceDescriptor) descriptor);
+        } else if (descriptor instanceof UsbEndpointDescriptor) {
+            tsReport((UsbEndpointDescriptor) descriptor);
+        } else if (descriptor instanceof UsbHIDDescriptor) {
+            tsReport((UsbHIDDescriptor) descriptor);
+        } else if (descriptor instanceof UsbACAudioControlEndpoint) {
+            tsReport((UsbACAudioControlEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACAudioStreamEndpoint) {
+            tsReport((UsbACAudioStreamEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACHeader) {
+            tsReport((UsbACHeader) descriptor);
+        } else if (descriptor instanceof UsbACFeatureUnit) {
+            tsReport((UsbACFeatureUnit) descriptor);
+        } else if (descriptor instanceof UsbACInputTerminal) {
+            tsReport((UsbACInputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACOutputTerminal) {
+            tsReport((UsbACOutputTerminal) descriptor);
+        } else if (descriptor instanceof UsbACMidiEndpoint) {
+            tsReport((UsbACMidiEndpoint) descriptor);
+        } else if (descriptor instanceof UsbACMixerUnit) {
+            tsReport((UsbACMixerUnit) descriptor);
+        } else if (descriptor instanceof UsbACSelectorUnit) {
+            tsReport((UsbACSelectorUnit) descriptor);
+        } else if (descriptor instanceof UsbASFormatI) {
+            tsReport((UsbASFormatI) descriptor);
+        } else if (descriptor instanceof UsbASFormatII) {
+            tsReport((UsbASFormatII) descriptor);
+        } else if (descriptor instanceof UsbASFormat) {
+            tsReport((UsbASFormat) descriptor);
+        } else if (descriptor instanceof UsbASGeneral) {
+            tsReport((UsbASGeneral) descriptor);
+        } else if (descriptor instanceof UsbInterfaceAssoc) {
+            tsReport((UsbInterfaceAssoc) descriptor);
+        } else if (descriptor instanceof UsbMSMidiHeader) {
+            tsReport((UsbMSMidiHeader) descriptor);
+        } else if (descriptor instanceof UsbMSMidiInputJack) {
+            tsReport((UsbMSMidiInputJack) descriptor);
+        } else if (descriptor instanceof UsbMSMidiOutputJack) {
+            tsReport((UsbMSMidiOutputJack) descriptor);
+        } else if (descriptor instanceof UsbUnknown) {
+            tsReport((UsbUnknown) descriptor);
+        } else if (descriptor instanceof UsbACInterface) {
+            tsReport((UsbACInterface) descriptor);
+        } else if (descriptor instanceof UsbDescriptor) {
+            tsReport((UsbDescriptor) descriptor);
+        }
+    }
+
+    //
+    // Type-specific report() implementations
+    //
+    private void tsReport(UsbDescriptor descriptor) {
+        int length = descriptor.getLength();
+        byte type = descriptor.getType();
+        int status = descriptor.getStatus();
+
+        String descTypeStr = UsbStrings.getDescriptorName(type);
+        writeParagraph(descTypeStr + ":" + type + " l:" + length + " s:" + status);
+    }
+
+    private void tsReport(UsbDeviceDescriptor descriptor) {
+        writeHeader(1, "Device len:" + descriptor.getLength());
+        openList();
+
+        int spec = descriptor.getSpec();
+        writeListItem("spec:" + getBCDString(spec));
+
+        byte devClass = descriptor.getDevClass();
+        String classStr = UsbStrings.getClassName(devClass);
+        byte devSubClass = descriptor.getDevSubClass();
+        String subClasStr = UsbStrings.getClassName(devSubClass);
+        writeListItem("class " + devClass + ":" + classStr + " subclass"
+                + devSubClass + ":" + subClasStr);
+        writeListItem("vendorID:" + descriptor.getVendorID()
+                + " prodID:" + descriptor.getProductID()
+                + " prodRel:" + getBCDString(descriptor.getDeviceRelease()));
+
+        byte mfgIndex = descriptor.getMfgIndex();
+        String manufacturer = UsbDescriptor.getUsbDescriptorString(mConnection, mfgIndex);
+        byte productIndex = descriptor.getProductIndex();
+        String product = UsbDescriptor.getUsbDescriptorString(mConnection, productIndex);
+
+        writeListItem("mfg " + mfgIndex + ":" + manufacturer
+                + " prod " + productIndex + ":" + product);
+        closeList();
+    }
+
+    private void tsReport(UsbConfigDescriptor descriptor) {
+        writeHeader(2, "Config #" + descriptor.getConfigValue()
+                + " len:" + descriptor.getLength());
+
+        openList();
+        writeListItem(descriptor.getNumInterfaces() + " interfaces.");
+        writeListItem("attribs:" + getHexString(descriptor.getAttribs()));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceDescriptor descriptor) {
+        byte usbClass = descriptor.getUsbClass();
+        byte usbSubclass = descriptor.getUsbSubclass();
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        String className = UsbStrings.getClassName(usbClass);
+        String subclassName = "";
+        if (usbClass == UsbDescriptor.CLASSID_AUDIO) {
+            subclassName = UsbStrings.getAudioSubclassName(usbSubclass);
+        }
+
+        writeHeader(2, descr + " #" + descriptor.getInterfaceNumber()
+                        + " len:" + descriptor.getLength());
+        String descrStr =
+                UsbDescriptor.getUsbDescriptorString(mConnection, descriptor.getDescrIndex());
+        if (descrStr.length() > 0) {
+            mStringBuilder.append("<br>" + descrStr);
+        }
+        openList();
+        writeListItem("class " + getHexString(usbClass) + ":" + className
+                + " subclass " + getHexString(usbSubclass) + ":" + subclassName);
+        writeListItem(""  + descriptor.getNumEndpoints() + " endpoints");
+        closeList();
+    }
+
+    private void tsReport(UsbEndpointDescriptor descriptor) {
+        writeHeader(3, "Endpoint " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength());
+        openList();
+
+        byte address = descriptor.getEndpointAddress();
+        writeListItem("address:"
+                + getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS)
+                + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION)
+                        == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
+
+        byte attributes = descriptor.getAttributes();
+        openListItem();
+        mStringBuilder.append("attribs:" + getHexString(attributes) + " ");
+        switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) {
+            case UsbEndpointDescriptor.TRANSTYPE_CONTROL:
+                mStringBuilder.append("Control");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_ISO:
+                mStringBuilder.append("Iso");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_BULK:
+                mStringBuilder.append("Bulk");
+                break;
+            case UsbEndpointDescriptor.TRANSTYPE_INTERRUPT:
+                mStringBuilder.append("Interrupt");
+                break;
+        }
+        closeListItem();
+
+        // These flags are only relevant for ISO transfer type
+        if ((attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE)
+                == UsbEndpointDescriptor.TRANSTYPE_ISO) {
+            openListItem();
+            mStringBuilder.append("sync:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_SYNCTYPE) {
+                case UsbEndpointDescriptor.SYNCTYPE_NONE:
+                    mStringBuilder.append("NONE");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ASYNC:
+                    mStringBuilder.append("ASYNC");
+                    break;
+                case UsbEndpointDescriptor.SYNCTYPE_ADAPTSYNC:
+                    mStringBuilder.append("ADAPTIVE ASYNC");
+                    break;
+            }
+            closeListItem();
+
+            openListItem();
+            mStringBuilder.append("useage:");
+            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_USEAGE) {
+                case UsbEndpointDescriptor.USEAGE_DATA:
+                    mStringBuilder.append("DATA");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_FEEDBACK:
+                    mStringBuilder.append("FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_EXPLICIT:
+                    mStringBuilder.append("EXPLICIT FEEDBACK");
+                    break;
+                case UsbEndpointDescriptor.USEAGE_RESERVED:
+                    mStringBuilder.append("RESERVED");
+                    break;
+            }
+            closeListItem();
+        }
+        writeListItem("package size:" + descriptor.getPacketSize());
+        writeListItem("interval:" + descriptor.getInterval());
+        closeList();
+    }
+
+    private void tsReport(UsbHIDDescriptor descriptor) {
+        String descr = UsbStrings.getDescriptorName(descriptor.getType());
+        writeHeader(2, descr + " len:" + descriptor.getLength());
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getRelease()));
+        writeListItem("type:" + getBCDString(descriptor.getDescriptorType()));
+        writeListItem("descriptor.getNumDescriptors()  descriptors len:"
+                + descriptor.getDescriptorLen());
+        closeList();
+    }
+
+    private void tsReport(UsbACAudioControlEndpoint descriptor) {
+        writeHeader(3, "AC Audio Control Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACAudioStreamEndpoint descriptor) {
+        writeHeader(3, "AC Audio Streaming Endpoint:"
+                + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACHeader descriptor) {
+        tsReport((UsbACInterface) descriptor);
+
+        openList();
+        writeListItem("spec:" + getBCDString(descriptor.getADCRelease()));
+        int numInterfaces = descriptor.getNumInterfaces();
+        writeListItem("" + numInterfaces + " interfaces");
+        if (numInterfaces > 0) {
+            openListItem();
+            mStringBuilder.append("[");
+            byte[] interfaceNums = descriptor.getInterfaceNums();
+            if (numInterfaces != 0 && interfaceNums != null) {
+                for (int index = 0; index < numInterfaces; index++) {
+                    mStringBuilder.append("" + interfaceNums[index]);
+                    if (index < numInterfaces - 1) {
+                        mStringBuilder.append(" ");
+                    }
+                }
+            }
+            mStringBuilder.append("]");
+            closeListItem();
+        }
+        writeListItem("controls:" + getHexString(descriptor.getControls()));
+        closeList();
+    }
+
+    private void tsReport(UsbACFeatureUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInterface descriptor) {
+        String subClassName =
+                descriptor.getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL
+                        ? "AC Control"
+                        : "AC Streaming";
+        byte subtype = descriptor.getSubtype();
+        String subTypeStr = UsbStrings.getACControlInterfaceName(subtype);
+        writeHeader(4, subClassName + " - " + getHexString(subtype)
+                + ":" + subTypeStr + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbACTerminal descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbACInputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("" + descriptor.getNrChannels() + " chans. config:"
+                + getHexString(descriptor.getChannelConfig()));
+        closeList();
+    }
+
+    private void tsReport(UsbACOutputTerminal descriptor) {
+        tsReport((UsbACTerminal) descriptor);
+
+        openList();
+        writeListItem("ID:" + getHexString(descriptor.getTerminalID()));
+        int terminalType = descriptor.getTerminalType();
+        writeListItem("Type:<b>" + getHexString(terminalType) + ":"
+                + UsbStrings.getTerminalName(terminalType) + "</b>");
+        writeListItem("AssocTerminal:" + getHexString(descriptor.getAssocTerminal()));
+        writeListItem("Source:" + getHexString(descriptor.getSourceID()));
+        closeList();
+    }
+
+    private void tsReport(UsbACMidiEndpoint descriptor) {
+        writeHeader(3, "AC Midi Endpoint:" + getHexString(descriptor.getType())
+                + " length:" + descriptor.getLength());
+        openList();
+        writeListItem("" + descriptor.getNumJacks() + " jacks.");
+        closeList();
+    }
+
+    private void tsReport(UsbACMixerUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+
+        writeListItem("Unit ID:" + getHexString(descriptor.getUnitID()));
+        byte numInputs = descriptor.getNumInputs();
+        byte[] inputIDs = descriptor.getInputIDs();
+        openListItem();
+        mStringBuilder.append("Num Inputs:" + numInputs + " [");
+        for (int input = 0; input < numInputs; input++) {
+            mStringBuilder.append("" + getHexString(inputIDs[input]));
+            if (input < numInputs - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+
+        writeListItem("Num Outputs:" + descriptor.getNumOutputs());
+        writeListItem("Chan Config:" + getHexString(descriptor.getChannelConfig()));
+
+        byte[] controls = descriptor.getControls();
+        openListItem();
+        mStringBuilder.append("controls:" + controls.length + " [");
+        for (int ctrl = 0; ctrl < controls.length; ctrl++) {
+            mStringBuilder.append("" + controls[ctrl]);
+            if (ctrl < controls.length - 1) {
+                mStringBuilder.append(" ");
+            }
+        }
+        mStringBuilder.append("]");
+        closeListItem();
+        closeList();
+        // byte mChanNameID; // First channel name string descriptor ID
+        // byte mNameID;       // string descriptor ID of mixer name
+    }
+
+    private void tsReport(UsbACSelectorUnit descriptor) {
+        tsReport((UsbACInterface) descriptor);
+    }
+
+    private void tsReport(UsbASFormat descriptor) {
+        writeHeader(4, "AC Streaming Format "
+                + (descriptor.getFormatType() ==  UsbASFormat.FORMAT_TYPE_I  ? "I" : "II")
+                + " - " + getHexString(descriptor.getSubtype()) + ":"
+                + " len:" + descriptor.getLength());
+    }
+
+    private void tsReport(UsbASFormatI descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("chans:" + descriptor.getNumChannels());
+        writeListItem("subframe size:" + descriptor.getSubframeSize());
+        writeListItem("bit resolution:" + descriptor.getBitResolution());
+        byte sampleFreqType = descriptor.getSampleFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+        closeList();
+    }
+
+    private void tsReport(UsbASFormatII descriptor) {
+        tsReport((UsbASFormat) descriptor);
+        openList();
+        writeListItem("max bit rate:" + descriptor.getMaxBitRate());
+        writeListItem("samples per frame:" + descriptor.getMaxBitRate());
+        byte sampleFreqType = descriptor.getSamFreqType();
+        int[] sampleRates = descriptor.getSampleRates();
+        writeListItem("sample freq type:" + sampleFreqType);
+        if (sampleFreqType == 0) {
+            openList();
+            writeListItem("min:" + sampleRates[0]);
+            writeListItem("max:" + sampleRates[1]);
+            closeList();
+        } else {
+            openList();
+            for (int index = 0; index < sampleFreqType; index++) {
+                writeListItem("" + sampleRates[index]);
+            }
+            closeList();
+        }
+
+        closeList();
+    }
+
+    private void tsReport(UsbASGeneral descriptor) {
+        tsReport((UsbACInterface) descriptor);
+        openList();
+        int formatTag = descriptor.getFormatTag();
+        writeListItem("fmt:" + UsbStrings.getAudioFormatName(formatTag) + " - "
+                + getHexString(formatTag));
+        closeList();
+    }
+
+    private void tsReport(UsbInterfaceAssoc descriptor) {
+        tsReport((UsbDescriptor) descriptor);
+    }
+
+    private void tsReport(UsbMSMidiHeader descriptor) {
+        writeHeader(3, "MS Midi Header:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiInputJack descriptor) {
+        writeHeader(3, "MS Midi Input Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbMSMidiOutputJack descriptor) {
+        writeHeader(3, "MS Midi Output Jack:" + getHexString(descriptor.getType())
+                + " subType:" + getHexString(descriptor.getSubclass())
+                + " length:" + descriptor.getSubclass());
+    }
+
+    private void tsReport(UsbUnknown descriptor) {
+        writeParagraph("<i><b>Unknown Descriptor " + getHexString(descriptor.getType())
+                + " len:" + descriptor.getLength() + "</b></i>");
+        dumpHexArray(descriptor.getRawData(), mStringBuilder);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
new file mode 100644
index 0000000..2944c10
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbDescriptor;
+
+/**
+ * Declares the Reporter interface to provide HTML reporting for UsbDescriptor (sub)classes.
+ *
+ * NOTE: It is the responsibility of the implementor of this interface to correctly
+ * interpret/decode the SPECIFIC UsbDescriptor subclass (perhaps with 'instanceof') that is
+ * passed and handle that in the appropriate manner. This appears to be a
+ * not very object-oriented approach, and that is true. This approach DOES however move the
+ * complexity and 'plumbing' of reporting into the Reporter implementation and avoids needing
+ * a (trivial) type-specific call to 'report()' in each UsbDescriptor (sub)class, instead
+ * having just one in the top-level UsbDescriptor class. It also removes the need to add new
+ * type-specific 'report()' methods to be added to Reporter interface whenever a
+ * new UsbDescriptor subclass is defined. This seems like a pretty good trade-off.
+ *
+ * See HTMLReporter.java in this package for an example of type decoding.
+ */
+public interface Reporter {
+    /**
+     * Generate report for this UsbDescriptor descriptor
+     */
+    void report(UsbDescriptor descriptor);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
new file mode 100644
index 0000000..c13111b
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/Reporting.java
@@ -0,0 +1,27 @@
+/*
+ * 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.usb.descriptors.report;
+
+/**
+ * Declares the interface for classes that provide reporting functionality.
+ * (This is the double-indirection aspect of the "Visitor" pattern.
+ */
+public interface Reporting {
+    /**
+     * Declares the report method that UsbDescriptor subclasses call.
+     */
+    void report(Reporter reporter);
+}
diff --git a/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
new file mode 100644
index 0000000..0461150
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/descriptors/report/UsbStrings.java
@@ -0,0 +1,312 @@
+/*
+ * 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.usb.descriptors.report;
+
+import com.android.server.usb.descriptors.UsbACInterface;
+import com.android.server.usb.descriptors.UsbDescriptor;
+import com.android.server.usb.descriptors.UsbTerminalTypes;
+
+import java.util.HashMap;
+
+/**
+ * @hide
+ * A class to provide human-readable strings for various USB constants.
+ */
+public class UsbStrings {
+    private static final String TAG = "UsbStrings";
+
+    private static HashMap<Byte, String> sDescriptorNames;
+    private static HashMap<Byte, String> sACControlInterfaceNames;
+    private static HashMap<Byte, String> sACStreamingInterfaceNames;
+    private static HashMap<Byte, String> sClassNames;
+    private static HashMap<Byte, String> sAudioSubclassNames;
+    private static HashMap<Integer, String> sAudioEncodingNames;
+    private static HashMap<Integer, String> sTerminalNames;
+
+    private static void initDescriptorNames() {
+        sDescriptorNames = new HashMap<Byte, String>();
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_DEVICE, "Device");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CONFIG, "Config");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_STRING, "String");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACE, "Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT, "Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_BOS, "BOS (whatever that means)");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_INTERFACEASSOC,
+                "Interface Association");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_CAPABILITY, "Capability");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HID, "HID");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_REPORT, "Report");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_PHYSICAL, "Physical");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE,
+                "Audio Class Interface");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT, "Audio Class Endpoint");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_HUB, "Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_SUPERSPEED_HUB, "Superspeed Hub");
+        sDescriptorNames.put(UsbDescriptor.DESCRIPTORTYPE_ENDPOINT_COMPANION,
+                "Endpoint Companion");
+    }
+
+    private static void initACControlInterfaceNames() {
+        sACControlInterfaceNames = new HashMap<Byte, String>();
+        sACControlInterfaceNames.put(UsbACInterface.ACI_UNDEFINED, "Undefined");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_HEADER, "Header");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_INPUT_TERMINAL, "Input Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_OUTPUT_TERMINAL, "Output Terminal");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_MIXER_UNIT, "Mixer Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_SELECTOR_UNIT, "Selector Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_FEATURE_UNIT, "Feature Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_PROCESSING_UNIT, "Processing Unit");
+        sACControlInterfaceNames.put(UsbACInterface.ACI_EXTENSION_UNIT, "Extension Unit");
+    }
+
+    private static void initACStreamingInterfaceNames() {
+        sACStreamingInterfaceNames = new HashMap<Byte, String>();
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_UNDEFINED, "Undefined");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_GENERAL, "General");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_TYPE, "Format Type");
+        sACStreamingInterfaceNames.put(UsbACInterface.ASI_FORMAT_SPECIFIC, "Format Specific");
+    }
+
+    private static void initClassNames() {
+        sClassNames = new HashMap<Byte, String>();
+        sClassNames.put(UsbDescriptor.CLASSID_DEVICE, "Device");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIO, "Audio");
+        sClassNames.put(UsbDescriptor.CLASSID_COM, "Communications");
+        sClassNames.put(UsbDescriptor.CLASSID_HID, "HID");
+        sClassNames.put(UsbDescriptor.CLASSID_PHYSICAL, "Physical");
+        sClassNames.put(UsbDescriptor.CLASSID_IMAGE, "Image");
+        sClassNames.put(UsbDescriptor.CLASSID_PRINTER, "Printer");
+        sClassNames.put(UsbDescriptor.CLASSID_STORAGE, "Storage");
+        sClassNames.put(UsbDescriptor.CLASSID_HUB, "Hub");
+        sClassNames.put(UsbDescriptor.CLASSID_CDC_CONTROL, "CDC Control");
+        sClassNames.put(UsbDescriptor.CLASSID_SMART_CARD, "Smart Card");
+        sClassNames.put(UsbDescriptor.CLASSID_SECURITY, "Security");
+        sClassNames.put(UsbDescriptor.CLASSID_VIDEO, "Video");
+        sClassNames.put(UsbDescriptor.CLASSID_HEALTHCARE, "Healthcare");
+        sClassNames.put(UsbDescriptor.CLASSID_AUDIOVIDEO, "Audio/Video");
+        sClassNames.put(UsbDescriptor.CLASSID_BILLBOARD, "Billboard");
+        sClassNames.put(UsbDescriptor.CLASSID_TYPECBRIDGE, "Type C Bridge");
+        sClassNames.put(UsbDescriptor.CLASSID_DIAGNOSTIC, "Diagnostic");
+        sClassNames.put(UsbDescriptor.CLASSID_WIRELESS, "Wireless");
+        sClassNames.put(UsbDescriptor.CLASSID_MISC, "Misc");
+        sClassNames.put(UsbDescriptor.CLASSID_APPSPECIFIC, "Application Specific");
+        sClassNames.put(UsbDescriptor.CLASSID_VENDSPECIFIC, "Vendor Specific");
+    }
+
+    private static void initAudioSubclassNames() {
+        sAudioSubclassNames = new HashMap<Byte, String>();
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_SUBCLASS_UNDEFINED, "Undefinded");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOCONTROL, "Audio Control");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_AUDIOSTREAMING, "Audio Streaming");
+        sAudioSubclassNames.put(UsbDescriptor.AUDIO_MIDISTREAMING, "MIDI Streaming");
+    }
+
+    private static void initAudioEncodingNames() {
+        sAudioEncodingNames = new HashMap<Integer, String>();
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_UNDEFINED, "Format I Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM, "Format I PCM");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_PCM8, "Format I PCM8");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_IEEE_FLOAT, "Format I FLOAT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_ALAW, "Format I ALAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_I_MULAW, "Format I MuLAW");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_UNDEFINED, "FORMAT_II Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_MPEG, "FORMAT_II MPEG");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_II_AC3, "FORMAT_II AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_UNDEFINED, "FORMAT_III Undefined");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937AC3, "FORMAT_III IEC1937 AC3");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer1,
+                "FORMAT_III MPEG1 Layer 1");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG1_Layer2,
+                "FORMAT_III MPEG1 Layer 2");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_EXT,
+                "FORMAT_III MPEG2 EXT");
+        sAudioEncodingNames.put(UsbACInterface.FORMAT_III_IEC1937_MPEG2_Layer1LS,
+                "FORMAT_III MPEG2 Layer1LS");
+    }
+
+    private static void initTerminalNames() {
+        sTerminalNames = new HashMap<Integer, String>();
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_USB_STREAMING, "USB Streaming");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC, "Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_DESKTOP_MIC, "Desktop Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PERSONAL_MIC,
+                "Personal (headset) Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_OMNI_MIC, "Omni Microphone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_MIC_ARRAY, "Microphone Array");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_IN_PROC_MIC_ARRAY,
+                "Proecessing Microphone Array");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_SPEAKER, "Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADPHONES, "Headphones");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_HEADMOUNTED, "Head Mounted Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_DESKTOPSPEAKER, "Desktop Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_ROOMSPEAKER, "Room Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_COMSPEAKER, "Communications Speaker");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_OUT_LFSPEAKER, "Low Frequency Speaker");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HANDSET, "Handset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_HEADSET, "Headset");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE, "Speaker Phone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_SUPRESS,
+                "Speaker Phone (echo supressing)");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL,
+                "Speaker Phone (echo canceling)");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONELINE, "Phone Line");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_PHONE, "Telephone");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_TELE_DOWNLINEPHONE, "Down Line Phone");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_ANALOG, "Analog Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL, "Digital Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LINE, "Line Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_LEGACY, "Legacy Audio Connector");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_SPIDF, "S/PIDF Interface");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DA, "1394 Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EXTERN_1394DV, "1394 Audio/Video");
+
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_UNDEFINED, "Undefined");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CALNOISE, "Calibration Nose");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_EQNOISE, "EQ Noise");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CDPLAYER, "CD Player");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DAT, "DAT");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DCC, "DCC");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MINIDISK, "Mini Disk");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_ANALOGTAPE, "Analog Tap");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_PHONOGRAPH, "Phonograph");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VCRAUDIO, "VCR Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_VIDDISKAUDIO, "Video Disk Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DVDAUDIO, "DVD Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_TVAUDIO, "TV Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SATELLITEAUDIO, "Satellite Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_CABLEAUDIO, "Cable Tuner Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_DSSAUDIO, "DSS Audio");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_RADIOTRANSMITTER, "Radio Transmitter");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_MULTITRACK, "Multitrack Recorder");
+        sTerminalNames.put(UsbTerminalTypes.TERMINAL_EMBED_SYNTHESIZER, "Synthesizer");
+    }
+
+    /**
+     * Retrieves the terminal name for the specified terminal type ID.
+     */
+    public static String getTerminalName(int terminalType) {
+        String name = sTerminalNames.get(terminalType);
+        return name != null
+                ? name
+                : "Unknown Terminal Type 0x" + Integer.toHexString(terminalType);
+    }
+    /**
+     * Initializes string tables.
+     */
+    public static void allocUsbStrings() {
+        initDescriptorNames();
+        initACControlInterfaceNames();
+        initACStreamingInterfaceNames();
+        initClassNames();
+        initAudioSubclassNames();
+        initAudioEncodingNames();
+        initTerminalNames();
+    }
+
+    /**
+     * Initializes string tables.
+     */
+    public static void releaseUsbStrings() {
+        sDescriptorNames = null;
+        sACControlInterfaceNames = null;
+        sACStreamingInterfaceNames = null;
+        sClassNames = null;
+        sAudioSubclassNames = null;
+        sAudioEncodingNames = null;
+        sTerminalNames = null;
+    }
+
+    /**
+     * Retrieves the name for the specified descriptor ID.
+     */
+    public static String getDescriptorName(byte descriptorID) {
+        String name = sDescriptorNames.get(descriptorID);
+        int iDescriptorID = descriptorID & 0xFF;
+        return name != null
+            ? name
+            : "Unknown Descriptor [0x" + Integer.toHexString(iDescriptorID)
+                + ":" + iDescriptorID + "]";
+    }
+
+    /**
+     * Retrieves the audio-class control interface name for the specified audio-class subtype.
+     */
+    public static String getACControlInterfaceName(byte subtype) {
+        String name = sACControlInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown subtype [0x" + Integer.toHexString(iSubType)
+                    + ":" + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the audio-class streaming interface name for the specified audio-class subtype.
+     */
+    public static String getACStreamingInterfaceName(byte subtype) {
+        String name = sACStreamingInterfaceNames.get(subtype);
+        int iSubType = subtype & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Subtype [0x" + Integer.toHexString(iSubType) + ":"
+                    + iSubType + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB class ID.
+     */
+    public static String getClassName(byte classID) {
+        String name = sClassNames.get(classID);
+        int iClassID = classID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Class ID [0x" + Integer.toHexString(iClassID) + ":"
+                    + iClassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio subclass ID.
+     */
+    public static String getAudioSubclassName(byte subClassID) {
+        String name = sAudioSubclassNames.get(subClassID);
+        int iSubclassID = subClassID & 0xFF;
+        return name != null
+                ? name
+                : "Unknown Audio Subclass [0x" + Integer.toHexString(iSubclassID) + ":"
+                    + iSubclassID + "]";
+    }
+
+    /**
+     * Retrieves the name for the specified USB audio format ID.
+     */
+    public static String getAudioFormatName(int formatID) {
+        String name = sAudioEncodingNames.get(formatID);
+        return name != null
+                ? name
+                : "Unknown Format (encoding) ID [0x" + Integer.toHexString(formatID) + ":"
+                    + formatID + "]";
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 520b0e8..f53eb15 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -300,7 +300,11 @@
 
             // Load the model if it is not loaded.
             if (!modelData.isModelLoaded()) {
-                // Load the model
+                // Before we try and load this model, we should first make sure that any other
+                // models that don't have an active recognition/dead callback are unloaded. Since
+                // there is a finite limit on the number of models that the hardware may be able to
+                // have loaded, we want to make sure there's room for our model.
+                stopAndUnloadDeadModelsLocked();
                 int[] handle = new int[] { INVALID_VALUE };
                 int status = mModule.loadSoundModel(soundModel, handle);
                 if (status != SoundTrigger.STATUS_OK) {
@@ -554,6 +558,13 @@
         }
     }
 
+    boolean isRecognitionRequested(UUID modelId) {
+        synchronized (mLock) {
+            ModelData modelData = mModelDataMap.get(modelId);
+            return modelData != null && modelData.isRequested();
+        }
+    }
+
     //---- SoundTrigger.StatusListener methods
     @Override
     public void onRecognition(RecognitionEvent event) {
@@ -901,7 +912,29 @@
         }
     }
 
+    /**
+     * Stops and unloads a sound model, and removes any reference to the model if successful.
+     *
+     * @param modelData The model data to remove.
+     * @param exception Optional exception to print in logcat. May be null.
+     */
     private void forceStopAndUnloadModelLocked(ModelData modelData, Exception exception) {
+      forceStopAndUnloadModelLocked(modelData, exception, null /* modelDataIterator */);
+    }
+
+    /**
+     * Stops and unloads a sound model, and removes any reference to the model if successful.
+     *
+     * @param modelData The model data to remove.
+     * @param exception Optional exception to print in logcat. May be null.
+     * @param modelDataIterator If this function is to be used while iterating over the
+     *        mModelDataMap, you can provide the iterator for the current model data to be used to
+     *        remove the modelData from the map. This avoids generating a
+     *        ConcurrentModificationException, since this function will try and remove the model
+     *        data from the mModelDataMap when it can successfully unload the model.
+     */
+    private void forceStopAndUnloadModelLocked(ModelData modelData, Exception exception,
+            Iterator modelDataIterator) {
         if (exception != null) {
           Slog.e(TAG, "forceStopAndUnloadModel", exception);
         }
@@ -918,7 +951,11 @@
             Slog.d(TAG, "Unloading previously loaded dangling model " + modelData.getHandle());
             if (mModule.unloadSoundModel(modelData.getHandle()) == STATUS_OK) {
                 // Remove the model data from existence.
-                mModelDataMap.remove(modelData.getModelId());
+                if (modelDataIterator != null) {
+                    modelDataIterator.remove();
+                } else {
+                    mModelDataMap.remove(modelData.getModelId());
+                }
                 Iterator it = mKeyphraseUuidMap.entrySet().iterator();
                 while (it.hasNext()) {
                     Map.Entry pair = (Map.Entry) it.next();
@@ -933,6 +970,23 @@
         }
     }
 
+    private void stopAndUnloadDeadModelsLocked() {
+        Iterator it = mModelDataMap.entrySet().iterator();
+        while (it.hasNext()) {
+            ModelData modelData = (ModelData) ((Map.Entry) it.next()).getValue();
+            if (!modelData.isModelLoaded()) {
+                continue;
+            }
+            if (modelData.getCallback() == null
+                    || (modelData.getCallback().asBinder() != null
+                        && !modelData.getCallback().asBinder().pingBinder())) {
+                // No one is listening on this model, so we might as well evict it.
+                Slog.w(TAG, "Removing model " + modelData.getHandle() + " that has no clients");
+                forceStopAndUnloadModelLocked(modelData, null /* exception */, it);
+            }
+        }
+    }
+
     private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
         ModelData modelData = mModelDataMap.get(modelId);
         if (modelData == null) {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 9bca012..51c805d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -16,18 +16,25 @@
 
 package com.android.server.soundtrigger;
 import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK;
 
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.Manifest;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
 import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.ParcelUuid;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Slog;
 
@@ -36,6 +43,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.TreeMap;
 import java.util.UUID;
 
 /**
@@ -52,16 +60,23 @@
     private static final boolean DEBUG = true;
 
     final Context mContext;
+    private Object mLock;
     private final SoundTriggerServiceStub mServiceStub;
     private final LocalSoundTriggerService mLocalSoundTriggerService;
     private SoundTriggerDbHelper mDbHelper;
     private SoundTriggerHelper mSoundTriggerHelper;
+    private final TreeMap<UUID, SoundModel> mLoadedModels;
+    private final TreeMap<UUID, LocalSoundTriggerRecognitionStatusCallback> mIntentCallbacks;
+    private PowerManager.WakeLock mWakelock;
 
     public SoundTriggerService(Context context) {
         super(context);
         mContext = context;
         mServiceStub = new SoundTriggerServiceStub();
         mLocalSoundTriggerService = new LocalSoundTriggerService(context);
+        mLoadedModels = new TreeMap<UUID, SoundModel>();
+        mIntentCallbacks = new TreeMap<UUID, LocalSoundTriggerRecognitionStatusCallback>();
+        mLock = new Object();
     }
 
     @Override
@@ -177,8 +192,357 @@
             mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
             mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
         }
+
+        @Override
+        public int loadGenericSoundModel(GenericSoundModel soundModel) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (soundModel == null || soundModel.uuid == null) {
+                Slog.e(TAG, "Invalid sound model");
+                return STATUS_ERROR;
+            }
+            if (DEBUG) {
+                Slog.i(TAG, "loadGenericSoundModel(): id = " + soundModel.uuid);
+            }
+            synchronized (mLock) {
+                SoundModel oldModel = mLoadedModels.get(soundModel.uuid);
+                // If the model we're loading is actually different than what we had loaded, we
+                // should unload that other model now. We don't care about return codes since we
+                // don't know if the other model is loaded.
+                if (oldModel != null && !oldModel.equals(soundModel)) {
+                    mSoundTriggerHelper.unloadGenericSoundModel(soundModel.uuid);
+                    mIntentCallbacks.remove(soundModel.uuid);
+                }
+                mLoadedModels.put(soundModel.uuid, soundModel);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int loadKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (soundModel == null || soundModel.uuid == null) {
+                Slog.e(TAG, "Invalid sound model");
+                return STATUS_ERROR;
+            }
+            if (soundModel.keyphrases == null || soundModel.keyphrases.length != 1) {
+                Slog.e(TAG, "Only one keyphrase per model is currently supported.");
+                return STATUS_ERROR;
+            }
+            if (DEBUG) {
+                Slog.i(TAG, "loadKeyphraseSoundModel(): id = " + soundModel.uuid);
+            }
+            synchronized (mLock) {
+                SoundModel oldModel = mLoadedModels.get(soundModel.uuid);
+                // If the model we're loading is actually different than what we had loaded, we
+                // should unload that other model now. We don't care about return codes since we
+                // don't know if the other model is loaded.
+                if (oldModel != null && !oldModel.equals(soundModel)) {
+                    mSoundTriggerHelper.unloadKeyphraseSoundModel(soundModel.keyphrases[0].id);
+                    mIntentCallbacks.remove(soundModel.uuid);
+                }
+                mLoadedModels.put(soundModel.uuid, soundModel);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int startRecognitionForIntent(ParcelUuid soundModelId, PendingIntent callbackIntent,
+                SoundTrigger.RecognitionConfig config) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "startRecognition(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                LocalSoundTriggerRecognitionStatusCallback callback = mIntentCallbacks.get(
+                        soundModelId.getUuid());
+                if (callback != null) {
+                    Slog.e(TAG, soundModelId + " is already running");
+                    return STATUS_ERROR;
+                }
+                callback = new LocalSoundTriggerRecognitionStatusCallback(soundModelId.getUuid(),
+                        callbackIntent, config);
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE: {
+                        KeyphraseSoundModel keyphraseSoundModel = (KeyphraseSoundModel) soundModel;
+                        ret = mSoundTriggerHelper.startKeyphraseRecognition(
+                                keyphraseSoundModel.keyphrases[0].id, keyphraseSoundModel, callback,
+                                config);
+                    } break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.startGenericRecognition(soundModel.uuid,
+                                (GenericSoundModel) soundModel, callback, config);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to start model: " + ret);
+                    return ret;
+                }
+                mIntentCallbacks.put(soundModelId.getUuid(), callback);
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int stopRecognitionForIntent(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "stopRecognition(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                LocalSoundTriggerRecognitionStatusCallback callback = mIntentCallbacks.get(
+                        soundModelId.getUuid());
+                if (callback == null) {
+                    Slog.e(TAG, soundModelId + " is not running");
+                    return STATUS_ERROR;
+                }
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE:
+                        ret = mSoundTriggerHelper.stopKeyphraseRecognition(
+                                ((KeyphraseSoundModel)soundModel).keyphrases[0].id, callback);
+                        break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.stopGenericRecognition(soundModel.uuid, callback);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to stop model: " + ret);
+                    return ret;
+                }
+                mIntentCallbacks.remove(soundModelId.getUuid());
+            }
+            return STATUS_OK;
+        }
+
+        @Override
+        public int unloadSoundModel(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return STATUS_ERROR;
+            if (DEBUG) {
+                Slog.i(TAG, "unloadSoundModel(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return STATUS_ERROR;
+                }
+                int ret;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE:
+                        ret = mSoundTriggerHelper.unloadKeyphraseSoundModel(
+                                ((KeyphraseSoundModel)soundModel).keyphrases[0].id);
+                        break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.unloadGenericSoundModel(soundModel.uuid);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        return STATUS_ERROR;
+                }
+                if (ret != STATUS_OK) {
+                    Slog.e(TAG, "Failed to unload model");
+                    return ret;
+                }
+                mLoadedModels.remove(soundModelId.getUuid());
+                return STATUS_OK;
+            }
+        }
+
+        @Override
+        public boolean isRecognitionActive(ParcelUuid parcelUuid) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return false;
+            synchronized (mLock) {
+                LocalSoundTriggerRecognitionStatusCallback callback =
+                        mIntentCallbacks.get(parcelUuid.getUuid());
+                if (callback == null) {
+                    return false;
+                }
+                return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid());
+            }
+        }
     }
 
+    private final class LocalSoundTriggerRecognitionStatusCallback
+            extends IRecognitionStatusCallback.Stub {
+        private UUID mUuid;
+        private PendingIntent mCallbackIntent;
+        private RecognitionConfig mRecognitionConfig;
+
+        public LocalSoundTriggerRecognitionStatusCallback(UUID modelUuid,
+                PendingIntent callbackIntent,
+                RecognitionConfig config) {
+            mUuid = modelUuid;
+            mCallbackIntent = callbackIntent;
+            mRecognitionConfig = config;
+        }
+
+        @Override
+        public boolean pingBinder() {
+            return mCallbackIntent != null;
+        }
+
+        @Override
+        public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.w(TAG, "Keyphrase sound trigger event: " + event);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
+            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                if (!mRecognitionConfig.allowMultipleTriggers) {
+                    removeCallback(/*releaseWakeLock=*/false);
+                }
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.w(TAG, "Generic sound trigger event: " + event);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
+            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                if (!mRecognitionConfig.allowMultipleTriggers) {
+                    removeCallback(/*releaseWakeLock=*/false);
+                }
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onError(int status) {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onError: " + status);
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_ERROR);
+            extras.putExtra(SoundTriggerManager.EXTRA_STATUS, status);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+                // Remove the callback, but wait for the intent to finish before we let go of the
+                // wake lock
+                removeCallback(/*releaseWakeLock=*/false);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onRecognitionPaused() {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onRecognitionPaused");
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        @Override
+        public void onRecognitionResumed() {
+            if (mCallbackIntent == null) {
+                return;
+            }
+            grabWakeLock();
+
+            Slog.i(TAG, "onRecognitionResumed");
+            Intent extras = new Intent();
+            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
+                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED);
+            try {
+                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
+            } catch (PendingIntent.CanceledException e) {
+                removeCallback(/*releaseWakeLock=*/true);
+            }
+        }
+
+        private void removeCallback(boolean releaseWakeLock) {
+            mCallbackIntent = null;
+            synchronized (mLock) {
+                mIntentCallbacks.remove(mUuid);
+                if (releaseWakeLock) {
+                    mWakelock.release();
+                }
+            }
+        }
+    }
+
+    private void grabWakeLock() {
+        synchronized (mLock) {
+            if (mWakelock == null) {
+                PowerManager pm = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE));
+                mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+            }
+            mWakelock.acquire();
+        }
+    }
+
+    private PendingIntent.OnFinished mCallbackCompletedHandler = new PendingIntent.OnFinished() {
+        @Override
+        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+                String resultData, Bundle resultExtras) {
+            // We're only ever invoked when the callback is done, so release the lock.
+            synchronized (mLock) {
+                mWakelock.release();
+            }
+        }
+    };
+
     public final class LocalSoundTriggerService extends SoundTriggerInternal {
         private final Context mContext;
         private SoundTriggerHelper mSoundTriggerHelper;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index b4414d5..e8e0680 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -132,6 +133,86 @@
     public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
             "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
 
+    /**
+     * Call event sent from a {@link Call} via {@link #sendCallEvent(String, Bundle)} to inform
+     * Telecom that the user has requested that the current {@link Call} should be handed over
+     * to another {@link ConnectionService}.
+     * <p>
+     * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to
+     * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to.
+     * @hide
+     */
+    public static final String EVENT_REQUEST_HANDOVER =
+            "android.telecom.event.REQUEST_HANDOVER";
+
+    /**
+     * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Specifies the
+     * {@link PhoneAccountHandle} to which a call should be handed over to.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
+            "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
+
+    /**
+     * Integer extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Specifies the
+     * video state of the call when it is handed over to the new {@link PhoneAccount}.
+     * <p>
+     * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+     * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
+     * {@link VideoProfile#STATE_TX_ENABLED}.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_VIDEO_STATE =
+            "android.telecom.extra.HANDOVER_VIDEO_STATE";
+
+    /**
+     * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event.  Used by the
+     * {@link InCallService} initiating a handover to provide a {@link Bundle} with extra
+     * information to the handover {@link ConnectionService} specified by
+     * {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE}.
+     * <p>
+     * This {@link Bundle} is not interpreted by Telecom, but passed as-is to the
+     * {@link ConnectionService} via the request extras when
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * is called to initate the handover.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
+
+    /**
+     * Call event sent from Telecom to the handover {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
+     * to the {@link ConnectionService} has completed successfully.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_COMPLETE =
+            "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Call event sent from Telecom to the handover destination {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform the handover destination that the
+     * source connection has disconnected.  The {@link Bundle} parameter for the call event will be
+     * {@code null}.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
+            "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
+
+    /**
+     * Call event sent from Telecom to the handover {@link ConnectionService} via
+     * {@link Connection#onCallEvent(String, Bundle)} to inform a {@link Connection} that a handover
+     * to the {@link ConnectionService} has failed.
+     * <p>
+     * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_FAILED =
+            "android.telecom.event.HANDOVER_FAILED";
+
     public static class Details {
 
         /** Call can currently be put on hold or unheld. */
@@ -1009,12 +1090,17 @@
          * @return A string containing text sent by the remote user, or {@code null} if the
          * conversation has been terminated or if there was an error while reading.
          */
-        public String read() throws IOException {
-            int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
-            if (numRead < 0) {
-                return null;
+        public String read() {
+            try {
+                int numRead = mReceiveStream.read(mReadBuffer, 0, READ_BUFFER_SIZE);
+                if (numRead < 0) {
+                    return null;
+                }
+                return new String(mReadBuffer, 0, numRead);
+            } catch (IOException e) {
+                Log.w(this, "Exception encountered when reading from InputStreamReader: %s", e);
             }
-            return new String(mReadBuffer, 0, numRead);
+            return null;
         }
 
         /**
@@ -1022,7 +1108,9 @@
          * be read.
          * @return A string containing text entered by the user, or {@code null} if the user has
          * not entered any new text yet.
+         * @hide
          */
+        @TestApi
         public String readImmediately() throws IOException {
             if (mReceiveStream.ready()) {
                 return read();
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index e79d841..5fcff18 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -456,10 +456,6 @@
      * @param conferenceableConnections The set of connections this connection can conference with.
      */
     public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
-        if (Objects.equals(mConferenceableConnections, conferenceableConnections)) {
-            return;
-        }
-
         clearConferenceableList();
         for (Connection c : conferenceableConnections) {
             // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index d7412a7..8ba934c 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -569,6 +569,24 @@
     public static final String EVENT_CALL_REMOTELY_UNHELD =
             "android.telecom.event.CALL_REMOTELY_UNHELD";
 
+    /**
+     * Connection event used to inform an {@link InCallService} which initiated a call handover via
+     * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has
+     * successfully completed.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_COMPLETE =
+            "android.telecom.event.HANDOVER_COMPLETE";
+
+    /**
+     * Connection event used to inform an {@link InCallService} which initiated a call handover via
+     * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed
+     * to complete.
+     * @hide
+     */
+    public static final String EVENT_HANDOVER_FAILED =
+            "android.telecom.event.HANDOVER_FAILED";
+
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 2faa96b..6f970fa 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -92,6 +92,24 @@
     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     public static final String SERVICE_INTERFACE = "android.telecom.ConnectionService";
 
+    /**
+     * Boolean extra used by Telecom to inform a {@link ConnectionService} that the purpose of it
+     * being asked to create a new outgoing {@link Connection} is to perform a handover of an
+     * ongoing call on the device from another {@link PhoneAccount}/{@link ConnectionService}.  Will
+     * be specified in the {@link ConnectionRequest#getExtras()} passed by Telecom when
+     * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} is called.
+     * <p>
+     * When your {@link ConnectionService} receives this extra, it should communicate the fact that
+     * this is a handover to the other device's matching {@link ConnectionService}.  That
+     * {@link ConnectionService} will continue the handover using
+     * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}, specifying
+     * {@link TelecomManager#EXTRA_IS_HANDOVER}.  Telecom will match the phone numbers of the
+     * handover call on the other device with ongoing calls for {@link ConnectionService}s which
+     * support {@link PhoneAccount#EXTRA_SUPPORTS_HANDOVER_FROM}.
+     * @hide
+     */
+    public static final String EXTRA_IS_HANDOVER = TelecomManager.EXTRA_IS_HANDOVER;
+
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 640c9e1..de20538 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -325,7 +325,8 @@
         return sEventManager;
     }
 
-    private static SessionManager getSessionManager() {
+    @VisibleForTesting
+    public static SessionManager getSessionManager() {
         // Checking for null again outside of synchronization because we only need to synchronize
         // during the lazy loading of the session logger. We don't need to synchronize elsewhere.
         if (sSessionManager == null) {
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 5530cb7..691e7cf 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -76,6 +76,67 @@
     public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING =
             "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
 
+     /**
+     * Indicating flag for phone account whether to use voip audio mode for voip calls
+     * @hide
+     */
+    public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE =
+            "android.telecom.extra.ALWAYS_USE_VOIP_AUDIO_MODE";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
+     * connection (see {@link android.telecom.Call#EVENT_REQUEST_HANDOVER}) to this
+     * {@link PhoneAccount} from a {@link PhoneAccount} specifying
+     * {@link #EXTRA_SUPPORTS_HANDOVER_FROM}.
+     * <p>
+     * A handover request is initiated by the user from the default dialer app to indicate a desire
+     * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
+     * @hide
+     */
+    public static final String EXTRA_SUPPORTS_HANDOVER_TO =
+            "android.telecom.extra.SUPPORTS_HANDOVER_TO";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} supports using a fallback if video calling is
+     * not available. This extra is for device level support, {@link
+     * android.telephony.CarrierConfigManager#KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL} should also
+     * be checked to ensure it is not disabled by individual carrier.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK =
+            "android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK";
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether this {@link PhoneAccount} is capable of supporting a request to handover a
+     * connection from this {@link PhoneAccount} to another {@link PhoneAccount}.
+     * (see {@link android.telecom.Call#EVENT_REQUEST_HANDOVER}) which specifies
+     * {@link #EXTRA_SUPPORTS_HANDOVER_TO}.
+     * <p>
+     * A handover request is initiated by the user from the default dialer app to indicate a desire
+     * to handover a call from one {@link PhoneAccount}/{@link ConnectionService} to another.
+     * @hide
+     */
+    public static final String EXTRA_SUPPORTS_HANDOVER_FROM =
+            "android.telecom.extra.SUPPORTS_HANDOVER_FROM";
+
+
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates whether a Self-Managed {@link PhoneAccount} should log its calls to the call log.
+     * Self-Managed {@link PhoneAccount}s are responsible for their own notifications, so the system
+     * will not create a notification when a missed call is logged.
+     * <p>
+     * By default, Self-Managed {@link PhoneAccount}s do not log their calls to the call log.
+     * Setting this extra to {@code true} provides a means for them to log their calls.
+     * @hide
+     */
+    public static final String EXTRA_LOG_SELF_MANAGED_CALLS =
+            "android.telecom.extra.LOG_SELF_MANAGED_CALLS";
+
     /**
      * Flag indicating that this {@code PhoneAccount} can act as a connection manager for
      * other connections. The {@link ConnectionService} associated with this {@code PhoneAccount}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 57fc9ce..f30d7bd 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.hardware.camera2.CameraManager;
 import android.net.Uri;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -1464,7 +1465,11 @@
         if (mExtras == null) {
             mExtras = new Bundle();
         }
-        mExtras.putAll(extras);
+        try {
+            mExtras.putAll(extras);
+        } catch (BadParcelableException bpe) {
+            Log.w(this, "putExtras: could not unmarshal extras; exception = " + bpe);
+        }
 
         notifyExtrasChanged();
     }
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index fdb1f09..aa2323d 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -349,6 +349,44 @@
             "android.telecom.extra.NEW_OUTGOING_CALL_CANCEL_TIMEOUT";
 
     /**
+     * Boolean extra specified to indicate that the intention of adding a call is to handover an
+     * existing call from the user's device to a different {@link PhoneAccount}.
+     * <p>
+     * Used when calling {@link #addNewIncomingCall(PhoneAccountHandle, Bundle)}
+     * to indicate to Telecom that the purpose of adding a new incoming call is to handover an
+     * existing call from the user's device to a different {@link PhoneAccount}.  This occurs on
+     * the receiving side of a handover.
+     * <p>
+     * Used when Telecom calls
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * to indicate that the purpose of Telecom requesting a new outgoing connection it to request
+     * a handover to this {@link ConnectionService} from an ongoing call on the user's device.  This
+     * occurs on the initiating side of a handover.
+     * <p>
+     * The phone number of the call used by Telecom to determine which call should be handed over.
+     * @hide
+     */
+    public static final String EXTRA_IS_HANDOVER = "android.telecom.extra.IS_HANDOVER";
+
+    /**
+     * Parcelable extra used with {@link #EXTRA_IS_HANDOVER} to indicate the source
+     * {@link PhoneAccountHandle} when initiating a handover which {@link ConnectionService}
+     * the handover is from.
+     * @hide
+     */
+    public static final String EXTRA_HANDOVER_FROM_PHONE_ACCOUNT =
+            "android.telecom.extra.HANDOVER_FROM_PHONE_ACCOUNT";
+
+    /**
+     * Extra key specified in the {@link ConnectionRequest#getExtras()} when Telecom calls
+     * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+     * to inform the {@link ConnectionService} what the initial {@link CallAudioState} of the
+     * {@link Connection} will be.
+     * @hide
+     */
+    public static final String EXTRA_CALL_AUDIO_STATE = "android.telecom.extra.CALL_AUDIO_STATE";
+
+    /**
      * A boolean extra, which when set on the {@link Intent#ACTION_CALL} intent or on the bundle
      * passed into {@link #placeCall(Uri, Bundle)}, indicates that the call should be initiated with
      * an RTT session open. See {@link android.telecom.Call.RttCall} for more information on RTT.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 386a3a3..9e252d2 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1044,6 +1044,26 @@
      */
     public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET =
             "carrier_default_actions_on_reset_string_array";
+
+    /**
+     * Defines carrier-specific actions which act upon
+     * com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+     * used for customization of the default carrier app
+     * Format:
+     * {
+     *     "true : CARRIER_ACTION_IDX_1",
+     *     "false: CARRIER_ACTION_IDX_2"
+     * }
+     * Where {@code true} is a boolean indicates default network available/unavailable
+     * Where {@code CARRIER_ACTION_IDX} is an integer defined in
+     * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
+     * Example:
+     * {@link com.android.carrierdefaultapp.CarrierActionUtils
+     * #CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER enable the app as the default URL handler}
+     * @hide
+     */
+    public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE =
+            "carrier_default_actions_on_default_network_available_string_array";
     /**
      * Defines a list of acceptable redirection url for default carrier app
      * @hides
@@ -1248,6 +1268,15 @@
     public static final String KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO = "video_calls_can_be_hd_audio";
 
     /**
+     * Whether system apps are allowed to use fallback if carrier video call is not available.
+     * Defaults to {@code true}.
+     *
+     * @hide
+     */
+    public static final String KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL =
+            "allow_video_calling_fallback_bool";
+
+    /**
      * Defines operator-specific {@link com.android.ims.ImsReasonInfo} mappings.
      *
      * Format: "ORIGINAL_CODE|MESSAGE|NEW_CODE"
@@ -1516,6 +1545,17 @@
             "imsi_key_expiration_days_time_int";
 
     /**
+     * Key identifying if the CDMA Caller ID presentation and suppression MMI codes
+     * should be converted to 3GPP CLIR codes when a multimode (CDMA+UMTS+LTE) device is roaming
+     * on a 3GPP network. Specifically *67<number> will be converted to #31#<number> and
+     * *82<number> will be converted to *31#<number> before dialing a call when this key is
+     * set TRUE and device is roaming on a 3GPP network.
+     * @hide
+     */
+    public static final String KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL =
+            "convert_cdma_caller_id_mmi_codes_while_roaming_on_3gpp_bool";
+    
+    /**
      * Flag specifying whether IMS registration state menu is shown in Status Info setting,
      * default to false.
      * @hide
@@ -1729,12 +1769,22 @@
         // Default carrier app configurations
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY,
                 new String[]{
-                        "4, 1"
+                        "9, 4, 1"
+                        //9: CARRIER_ACTION_REGISTER_NETWORK_AVAIL
                         //4: CARRIER_ACTION_DISABLE_METERED_APNS
                         //1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
                 });
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET, new String[]{
-                "6" //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+                "6, 8"
+                //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+                //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
+                });
+        sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE,
+                new String[] {
+                        String.valueOf(false) + ": 7",
+                        //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
+                        String.valueOf(true) + ": 8"
+                        //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
                 });
         sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
 
@@ -1753,6 +1803,7 @@
         sDefaults.putBoolean(KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL, true);
         sDefaults.putBoolean(KEY_WIFI_CALLS_CAN_BE_HD_AUDIO, true);
         sDefaults.putBoolean(KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO, true);
+        sDefaults.putBoolean(KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL, true);
 
         sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false);
@@ -1772,10 +1823,12 @@
         sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
         sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
-	sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
-        sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putInt(IMSI_KEY_EXPIRATION_DAYS_TIME_INT, IMSI_ENCRYPTION_DAYS_TIME_DISABLED);
         sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null);
+        sDefaults.putBoolean(KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
+                false);
+        sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
+        sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
     }
 
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index cf2d27e..4e1c15f 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -16,7 +16,10 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -30,6 +33,8 @@
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
 
+import java.util.Arrays;
+
 /**
  * A Parcelable class for Subscription Information.
  */
@@ -110,11 +115,34 @@
     private String mCountryIso;
 
     /**
+     * Whether the subscription is an embedded one.
+     */
+    private boolean mIsEmbedded;
+
+    /**
+     * The access rules for this subscription, if it is embedded and defines any.
+     */
+    @Nullable
+    private UiccAccessRule[] mAccessRules;
+
+    /**
      * @hide
      */
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, int mcc, int mnc, String countryIso) {
+        this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
+                roaming, icon, mcc, mnc, countryIso, false /* isEmbedded */,
+                null /* accessRules */);
+    }
+
+    /**
+     * @hide
+     */
+    public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
+            CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
+            Bitmap icon, int mcc, int mnc, String countryIso, boolean isEmbedded,
+            @Nullable UiccAccessRule[] accessRules) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -128,6 +156,8 @@
         this.mMcc = mcc;
         this.mMnc = mnc;
         this.mCountryIso = countryIso;
+        this.mIsEmbedded = isEmbedded;
+        this.mAccessRules = accessRules;
     }
 
     /**
@@ -284,6 +314,79 @@
         return this.mCountryIso;
     }
 
+    /**
+     * @return whether the subscription is an embedded one.
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public boolean isEmbedded() {
+        return this.mIsEmbedded;
+    }
+
+    /**
+     * Checks whether the app with the given context is authorized to manage this subscription
+     * according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded}
+     * returns true).
+     *
+     * @param context Context of the application to check.
+     * @return whether the app is authorized to manage this subscription per its metadata.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public boolean canManageSubscription(Context context) {
+        return canManageSubscription(context, context.getPackageName());
+    }
+
+    /**
+     * Checks whether the given app is authorized to manage this subscription according to its
+     * metadata. Only supported for embedded subscriptions (if {@link #isEmbedded} returns true).
+     *
+     * @param context Any context.
+     * @param packageName Package name of the app to check.
+     * @return whether the app is authorized to manage this subscription per its metadata.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     */
+    public boolean canManageSubscription(Context context, String packageName) {
+        if (!isEmbedded()) {
+            throw new UnsupportedOperationException("Not an embedded subscription");
+        }
+        if (mAccessRules == null) {
+            return false;
+        }
+        PackageManager packageManager = context.getPackageManager();
+        PackageInfo packageInfo;
+        try {
+            packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException("Unknown package: " + packageName, e);
+        }
+        for (UiccAccessRule rule : mAccessRules) {
+            if (rule.getCarrierPrivilegeStatus(packageInfo)
+                    == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription.
+     * @throws UnsupportedOperationException if this subscription is not embedded.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public @Nullable UiccAccessRule[] getAccessRules() {
+        if (!isEmbedded()) {
+            throw new UnsupportedOperationException("Not an embedded subscription");
+        }
+        return mAccessRules;
+    }
+
     public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
         @Override
         public SubscriptionInfo createFromParcel(Parcel source) {
@@ -300,9 +403,12 @@
             int mnc = source.readInt();
             String countryIso = source.readString();
             Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
+            boolean isEmbedded = source.readBoolean();
+            UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR);
 
             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
-                    nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso);
+                    nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
+                    isEmbedded, accessRules);
         }
 
         @Override
@@ -326,6 +432,8 @@
         dest.writeInt(mMnc);
         dest.writeString(mCountryIso);
         mIconBitmap.writeToParcel(dest, flags);
+        dest.writeBoolean(mIsEmbedded);
+        dest.writeTypedArray(mAccessRules, flags);
     }
 
     @Override
@@ -355,6 +463,7 @@
                 + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
                 + " nameSource=" + mNameSource + " iconTint=" + mIconTint
                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
-                + " mnc " + mMnc + "}";
+                + " mnc " + mMnc + " isEmbedded " + mIsEmbedded
+                + " accessRules " + Arrays.toString(mAccessRules) + "}";
     }
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 709877d..0d1764b 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -25,17 +25,17 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.net.Uri;
-import android.telephony.Rlog;
 import android.os.Handler;
 import android.os.Message;
-import android.os.ServiceManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.DisplayMetrics;
 
-import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
+import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.ITelephonyRegistry;
 import com.android.internal.telephony.PhoneConstants;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,7 +43,8 @@
  * SubscriptionManager is the application interface to SubscriptionController
  * and provides information about the current Telephony Subscriptions.
  * <p>
- * All SDK public methods require android.Manifest.permission.READ_PHONE_STATE.
+ * All SDK public methods require android.Manifest.permission.READ_PHONE_STATE unless otherwise
+ * specified.
  */
 @SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
 public class SubscriptionManager {
@@ -259,6 +260,32 @@
     public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status";
 
     /**
+     * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
+     * eSIM).
+     * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
+     * @hide
+     */
+    public static final String IS_EMBEDDED = "is_embedded";
+
+    /**
+     * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
+     * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
+     * <p>TYPE: BLOB
+     * @hide
+     */
+    public static final String ACCESS_RULES = "access_rules";
+
+    /**
+     * TelephonyProvider column name identifying whether an embedded subscription is on a removable
+     * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
+     * Otherwise, they will remain accessible unless explicitly deleted. Only present if
+     * {@link #IS_EMBEDDED} is 1.
+     * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
+     * @hide
+     */
+    public static final String IS_REMOVABLE = "is_removable";
+
+    /**
      *  TelephonyProvider column name for extreme threat in CB settings
      * @hide
      */
@@ -632,6 +659,112 @@
     }
 
     /**
+     * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
+     *
+     * <p>Available subscriptions include active ones (those with a non-negative
+     * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
+     * subscriptions.
+     *
+     * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
+     * {@link SubscriptionInfo#getSubscriptionId}.
+     *
+     * @return Sorted list of the current {@link SubscriptionInfo} records available on the
+     * device.
+     * <ul>
+     * <li>
+     * If null is returned the current state is unknown but if a
+     * {@link OnSubscriptionsChangedListener} has been registered
+     * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
+     * <li>
+     * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
+     * <li>
+     * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
+     * then by {@link SubscriptionInfo#getSubscriptionId}.
+     * </ul>
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
+        List<SubscriptionInfo> result = null;
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+        return result;
+    }
+
+    /**
+     * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
+     * any.
+     *
+     * <p>Only those subscriptions for which the calling app has carrier privileges per the
+     * subscription metadata, if any, will be included in the returned list.
+     *
+     * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
+     * {@link SubscriptionInfo#getSubscriptionId}.
+     *
+     * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
+     * device which are accessible to the caller.
+     * <ul>
+     * <li>
+     * If null is returned the current state is unknown but if a
+     * {@link OnSubscriptionsChangedListener} has been registered
+     * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
+     * <li>
+     * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
+     * <li>
+     * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
+     * then by {@link SubscriptionInfo#getSubscriptionId}.
+     * </ul>
+     * @hide
+     *
+     * TODO(b/35851809): Make this public.
+     */
+    public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
+        List<SubscriptionInfo> result = null;
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+        return result;
+    }
+
+    /**
+     * Request a refresh of the platform cache of profile information.
+     *
+     * <p>Should be called by the EuiccService implementation whenever this information changes due
+     * to an operation done outside the scope of a request initiated by the platform to the
+     * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
+     * were made through the EuiccService.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void requestEmbeddedSubscriptionInfoListRefresh() {
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                iSub.requestEmbeddedSubscriptionInfoListRefresh();
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+    }
+
+    /**
      * @return the count of all subscriptions in the database, this includes
      * all subscriptions that have been seen.
      * @hide
diff --git a/telephony/java/android/telephony/Telephony.java b/telephony/java/android/telephony/Telephony.java
index 3282f5f..e64e815 100644
--- a/telephony/java/android/telephony/Telephony.java
+++ b/telephony/java/android/telephony/Telephony.java
@@ -2765,6 +2765,13 @@
         public static final String USER_VISIBLE = "user_visible";
 
         /**
+         * Is the user allowed to edit this APN?
+         * <p>Type: INTEGER (boolean) </p>
+         * @hide
+         */
+        public static final String USER_EDITABLE = "user_editable";
+
+        /**
          * Following are possible values for the EDITED field
          * @hide
          */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b9429b9..450f485 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1635,8 +1635,7 @@
      * @hide
      */
     public String getNetworkCountryIso(int subId) {
-        int phoneId = SubscriptionManager.getPhoneId(subId);
-        return getNetworkCountryIsoForPhone(phoneId);
+        return getNetworkCountryIsoForPhone(getPhoneId(subId));
     }
 
     /**
@@ -1651,7 +1650,14 @@
      */
     /** {@hide} */
     public String getNetworkCountryIsoForPhone(int phoneId) {
-        return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null)
+                return "";
+            return telephony.getNetworkCountryIsoForPhone(phoneId);
+        } catch (RemoteException ex) {
+                return "";
+        }
     }
 
     /*
@@ -3773,7 +3779,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) {
         }
@@ -6704,6 +6710,25 @@
     }
 
     /**
+     * Action set from carrier signalling broadcast receivers to start/stop reporting default
+     * network available events
+     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+     * @param subId the subscription ID that this action applies to.
+     * @param report control start/stop reporting network status.
+     * @hide
+     */
+    public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                service.carrierActionReportDefaultNetworkStatus(subId, report);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#carrierActionReportDefaultNetworkStatus", e);
+        }
+    }
+
+    /**
      * Get aggregated video call data usage since boot.
      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
      *
@@ -6812,4 +6837,3 @@
         return null;
     }
 }
-
diff --git a/telephony/java/android/telephony/UiccAccessRule.aidl b/telephony/java/android/telephony/UiccAccessRule.aidl
new file mode 100644
index 0000000..f923c45
--- /dev/null
+++ b/telephony/java/android/telephony/UiccAccessRule.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony;
+
+parcelable UiccAccessRule;
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
new file mode 100644
index 0000000..e42a758
--- /dev/null
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -0,0 +1,230 @@
+/*
+ * 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.telephony;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.uicc.IccUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+/**
+ * Describes a single UICC access rule according to the GlobalPlatform Secure Element Access Control
+ * specification.
+ *
+ * @hide
+ *
+ * TODO(b/35851809): Make this a SystemApi.
+ */
+public final class UiccAccessRule implements Parcelable {
+    private static final String TAG = "UiccAccessRule";
+
+    private static final int ENCODING_VERSION = 1;
+
+    public static final Creator<UiccAccessRule> CREATOR = new Creator<UiccAccessRule>() {
+        @Override
+        public UiccAccessRule createFromParcel(Parcel in) {
+            return new UiccAccessRule(in);
+        }
+
+        @Override
+        public UiccAccessRule[] newArray(int size) {
+            return new UiccAccessRule[size];
+        }
+    };
+
+    /**
+     * Encode these access rules as a byte array which can be parsed with {@link #decodeRules}.
+     * @hide
+     */
+    @Nullable
+    public static byte[] encodeRules(@Nullable UiccAccessRule[] accessRules) {
+        if (accessRules == null) {
+            return null;
+        }
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream output = new DataOutputStream(baos);
+            output.writeInt(ENCODING_VERSION);
+            output.writeInt(accessRules.length);
+            for (UiccAccessRule accessRule : accessRules) {
+                output.writeInt(accessRule.mCertificateHash.length);
+                output.write(accessRule.mCertificateHash);
+                if (accessRule.mPackageName != null) {
+                    output.writeBoolean(true);
+                    output.writeUTF(accessRule.mPackageName);
+                } else {
+                    output.writeBoolean(false);
+                }
+                output.writeLong(accessRule.mAccessType);
+            }
+            output.close();
+            return baos.toByteArray();
+        } catch (IOException e) {
+            throw new IllegalStateException(
+                    "ByteArrayOutputStream should never lead to an IOException", e);
+        }
+    }
+
+    /**
+     * Decodes a byte array generated with {@link #encodeRules}.
+     * @hide
+     */
+    @Nullable
+    public static UiccAccessRule[] decodeRules(@Nullable byte[] encodedRules) {
+        if (encodedRules == null) {
+            return null;
+        }
+        ByteArrayInputStream bais = new ByteArrayInputStream(encodedRules);
+        try (DataInputStream input = new DataInputStream(bais)) {
+            input.readInt(); // version; currently ignored
+            int count = input.readInt();
+            UiccAccessRule[] accessRules = new UiccAccessRule[count];
+            for (int i = 0; i < count; i++) {
+                int certificateHashLength = input.readInt();
+                byte[] certificateHash = new byte[certificateHashLength];
+                input.readFully(certificateHash);
+                String packageName = input.readBoolean() ? input.readUTF() : null;
+                long accessType = input.readLong();
+                accessRules[i] = new UiccAccessRule(certificateHash, packageName, accessType);
+            }
+            input.close();
+            return accessRules;
+        } catch (IOException e) {
+            throw new IllegalStateException(
+                    "ByteArrayInputStream should never lead to an IOException", e);
+        }
+    }
+
+    private final byte[] mCertificateHash;
+    private final @Nullable String mPackageName;
+    // This bit is not currently used, but reserved for future use.
+    private final long mAccessType;
+
+    public UiccAccessRule(byte[] certificateHash, @Nullable String packageName, long accessType) {
+        this.mCertificateHash = certificateHash;
+        this.mPackageName = packageName;
+        this.mAccessType = accessType;
+    }
+
+    UiccAccessRule(Parcel in) {
+        mCertificateHash = in.createByteArray();
+        mPackageName = in.readString();
+        mAccessType = in.readLong();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByteArray(mCertificateHash);
+        dest.writeString(mPackageName);
+        dest.writeLong(mAccessType);
+    }
+
+    /**
+     * Return the package name this rule applies to.
+     *
+     * @return the package name, or null if this rule applies to any package signed with the given
+     *     certificate.
+     */
+    public @Nullable String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the carrier privilege status associated with the given package.
+     *
+     * @param packageInfo package info fetched from
+     *     {@link android.content.pm.PackageManager#getPackageInfo}.
+     *     {@link android.content.pm.PackageManager#GET_SIGNATURES} must have been passed in.
+     * @return either {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_HAS_ACCESS} or
+     *     {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_NO_ACCESS}.
+     */
+    public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
+        if (packageInfo.signatures == null || packageInfo.signatures.length == 0) {
+            throw new IllegalArgumentException(
+                    "Must use GET_SIGNATURES when looking up package info");
+        }
+
+        for (Signature sig : packageInfo.signatures) {
+            int accessStatus = getCarrierPrivilegeStatus(sig, packageInfo.packageName);
+            if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) {
+                return accessStatus;
+            }
+        }
+
+        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+    }
+
+    /**
+     * Returns the carrier privilege status for the given certificate and package name.
+     *
+     * @param signature The signature of the certificate.
+     * @param packageName name of the package.
+     * @return either {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_HAS_ACCESS} or
+     *     {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_NO_ACCESS}.
+     */
+    public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
+        // SHA-1 is for backward compatible support only, strongly discouraged for new use.
+        byte[] certHash = getCertHash(signature, "SHA-1");
+        byte[] certHash256 = getCertHash(signature, "SHA-256");
+        if (matches(certHash, packageName) || matches(certHash256, packageName)) {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+        }
+
+        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+    }
+
+    private boolean matches(byte[] certHash, String packageName) {
+        return certHash != null && Arrays.equals(this.mCertificateHash, certHash) &&
+                (TextUtils.isEmpty(this.mPackageName) || this.mPackageName.equals(packageName));
+    }
+
+    @Override
+    public String toString() {
+        return "cert: " + IccUtils.bytesToHexString(mCertificateHash) + " pkg: " +
+                mPackageName + " access: " + mAccessType;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Converts a Signature into a Certificate hash usable for comparison.
+     */
+    private static byte[] getCertHash(Signature signature, String algo) {
+        try {
+            MessageDigest md = MessageDigest.getInstance(algo);
+            return md.digest(signature.toByteArray());
+        } catch (NoSuchAlgorithmException ex) {
+            Rlog.e(TAG, "NoSuchAlgorithmException: " + ex);
+        }
+        return null;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl b/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl
new file mode 100644
index 0000000..26679c9
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.euicc;
+
+parcelable DownloadableSubscription;
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
new file mode 100644
index 0000000..b5484e34
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -0,0 +1,145 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.UiccAccessRule;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Information about a subscription which is available for download.
+ *
+ * TODO(b/35851809): Make this public.
+ * @hide
+ */
+public final class DownloadableSubscription implements Parcelable {
+
+    public static final Creator<DownloadableSubscription> CREATOR =
+            new Creator<DownloadableSubscription>() {
+                @Override
+                public DownloadableSubscription createFromParcel(Parcel in) {
+                    return new DownloadableSubscription(in);
+                }
+
+                @Override
+                public DownloadableSubscription[] newArray(int size) {
+                    return new DownloadableSubscription[size];
+                }
+            };
+
+    /**
+     * Activation code. May be null for subscriptions which are not based on activation codes, e.g.
+     * to download a default subscription assigned to this device.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @Nullable
+    public final String encodedActivationCode;
+
+    // see getCarrierName and setCarrierName
+    @Nullable
+    private String carrierName;
+    // see getAccessRules and setAccessRules
+    private UiccAccessRule[] accessRules;
+
+    /** @hide */
+    private DownloadableSubscription(String encodedActivationCode) {
+        this.encodedActivationCode = encodedActivationCode;
+    }
+
+    private DownloadableSubscription(Parcel in) {
+        encodedActivationCode = in.readString();
+        carrierName = in.readString();
+        accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+    }
+
+    /**
+     * Create a DownloadableSubscription for the given activation code.
+     *
+     * @param encodedActivationCode the activation code to use. Must not be null.
+     * @return the {@link DownloadableSubscription} which may be passed to
+     *     {@link EuiccManager#downloadSubscription}.
+     */
+    public static DownloadableSubscription forActivationCode(String encodedActivationCode) {
+        Preconditions.checkNotNull(encodedActivationCode, "Activation code may not be null");
+        return new DownloadableSubscription(encodedActivationCode);
+    }
+
+    /**
+     * Set the user-visible carrier name.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void setCarrierName(String carrierName) {
+        this.carrierName = carrierName;
+    }
+
+    /**
+     * Returns the user-visible carrier name.
+     *
+     * <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
+     * those created with {@link #forActivationCode}). May be populated with
+     * {@link EuiccManager#getDownloadableSubscriptionMetadata}.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @Nullable
+    public String getCarrierName() {
+        return carrierName;
+    }
+
+    /**
+     * Returns the {@link UiccAccessRule}s dictating access to this subscription.
+     *
+     * <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
+     * those created with {@link #forActivationCode}). May be populated with
+     * {@link EuiccManager#getDownloadableSubscriptionMetadata}.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public UiccAccessRule[] getAccessRules() {
+        return accessRules;
+    }
+
+    /**
+     * Set the {@link UiccAccessRule}s dictating access to this subscription.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void setAccessRules(UiccAccessRule[] accessRules) {
+        this.accessRules = accessRules;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(encodedActivationCode);
+        dest.writeString(carrierName);
+        dest.writeTypedArray(accessRules, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.aidl b/telephony/java/android/telephony/euicc/EuiccInfo.aidl
new file mode 100644
index 0000000..3cfba75
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.telephony.euicc;
+
+parcelable EuiccInfo;
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java
new file mode 100644
index 0000000..5bfff08
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.java
@@ -0,0 +1,72 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about an eUICC chip/device.
+ *
+ * @see EuiccManager#getEuiccInfo
+ * @hide
+ *
+ * TODO(b/35851809): Make this public.
+ */
+// WARNING: Do not add any privacy-sensitive fields to this class (such as an eUICC identifier)!
+// This API is accessible to all applications. Privacy-sensitive fields should be returned in their
+// own APIs guarded with appropriate permission checks.
+public final class EuiccInfo implements Parcelable {
+
+    public static final Creator<EuiccInfo> CREATOR =
+            new Creator<EuiccInfo>() {
+                @Override
+                public EuiccInfo createFromParcel(Parcel in) {
+                    return new EuiccInfo(in);
+                }
+
+                @Override
+                public EuiccInfo[] newArray(int size) {
+                    return new EuiccInfo[size];
+                }
+            };
+
+    /**
+     * Version of the operating system running on the eUICC. This field is hardware-specific and is
+     * not guaranteed to match any particular format.
+     */
+    @Nullable
+    public final String osVersion;
+
+    public EuiccInfo(@Nullable String osVersion) {
+        this.osVersion = osVersion;
+    }
+
+    private EuiccInfo(Parcel in) {
+        osVersion = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(osVersion);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
new file mode 100644
index 0000000..8304d84
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -0,0 +1,515 @@
+/*
+ * 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.telephony.euicc;
+
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.euicc.IEuiccController;
+
+/**
+ * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs.
+ *
+ * <p>You do not instantiate this class directly; instead, you retrieve an instance through
+ * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}.
+ *
+ * <p>See {@link #isEnabled} before attempting to use these APIs.
+ *
+ * TODO(b/35851809): Make this public.
+ * @hide
+ */
+public class EuiccManager {
+
+    /**
+     * Intent action to launch the embedded SIM (eUICC) management settings screen.
+     *
+     * <p>This screen shows a list of embedded profiles and offers the user the ability to switch
+     * between them, download new profiles, and delete unused profiles.
+     *
+     * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+     * {@link #isEnabled} is false.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
+            "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+
+    /**
+     * Intent action to provision an embedded subscription.
+     *
+     * <p>May be called during device provisioning to launch a screen to perform embedded SIM
+     * provisioning, e.g. if no physical SIM is present and the user elects to configure their
+     * embedded SIM.
+     *
+     * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
+     * {@link #isEnabled} is false or if the device is already provisioned.
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
+            "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+
+    /**
+     * Intent action to handle a resolvable error.
+     * @hide
+     */
+    public static final String ACTION_RESOLVE_ERROR =
+            "android.telephony.euicc.action.RESOLVE_ERROR";
+
+    /**
+     * Result code for an operation indicating that the operation succeeded.
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
+
+    /**
+     * Result code for an operation indicating that the user must take some action before the
+     * operation can continue.
+     *
+     * @see #startResolutionActivity
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1;
+
+    /**
+     * Result code for an operation indicating that an unresolvable error occurred.
+     *
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error
+     * code for logging/debugging purposes only.
+     */
+    public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2;
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result
+     * code.
+     *
+     * <p>This code is an implementation detail of the embedded subscription manager and is only
+     * intended for logging or debugging purposes.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
+
+    /**
+     * Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
+     * callbacks providing the downloadable subscription metadata.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+
+    /**
+     * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
+     * callbacks providing the list of available downloadable subscriptions.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
+     * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
+
+    /**
+     * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+     * containing the EuiccService action to launch for resolution.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION";
+
+    /**
+     * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
+     * providing the callback to execute after resolution is completed.
+     * @hide
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT";
+
+    /**
+     * Optional meta-data attribute for a carrier app providing an icon to use to represent the
+     * carrier. If not provided, the app's launcher icon will be used as a fallback.
+     */
+    public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
+
+    private final Context mContext;
+    private final IEuiccController mController;
+
+    /** @hide */
+    public EuiccManager(Context context) {
+        mContext = context;
+        mController = IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
+    }
+
+    /**
+     * Whether embedded subscriptions are currently enabled.
+     *
+     * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded
+     * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted
+     * physical SIM. Therefore, this runtime check should be used before accessing embedded
+     * subscription APIs.
+     *
+     * @return true if embedded subscriptions are currently enabled.
+     */
+    public boolean isEnabled() {
+        // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
+        // restrictions.
+        return mController != null;
+    }
+
+    /**
+     * Returns the EID identifying the eUICC hardware.
+     *
+     * <p>Requires that the calling app has carrier privileges on the active subscription on the
+     * eUICC.
+     *
+     * @return the EID. May be null if {@link #isEnabled()} is false or the eUICC is not ready.
+     */
+    @Nullable
+    public String getEid() {
+        if (!isEnabled()) {
+            return null;
+        }
+        try {
+            return mController.getEid();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Attempt to download the given {@link DownloadableSubscription}.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+     * or the calling app must be authorized to manage both the currently-active subscription and
+     * the subscription to be downloaded according to the subscription metadata. Without the former,
+     * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
+     * intent to prompt the user to accept the download.
+     *
+     * @param subscription the subscription to download.
+     * @param switchAfterDownload if true, the profile will be activated upon successful download.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void downloadSubscription(DownloadableSubscription subscription,
+            boolean switchAfterDownload, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.downloadSubscription(subscription, switchAfterDownload,
+                    mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Start an activity to resolve a user-resolvable error.
+     *
+     * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
+     * method may be called to prompt the user to resolve the issue.
+     *
+     * <p>This method may only be called once for a particular error.
+     *
+     * @param activity the calling activity (which should be in the foreground).
+     * @param requestCode an application-specific request code which will be provided to
+     *     {@link Activity#onActivityResult} upon completion. Note that the operation may still be
+     *     in progress when the resolution activity completes; it is not fully finished until the
+     *     callback intent is triggered.
+     * @param resultIntent the Intent provided to the initial callback intent which failed with
+     *     {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
+     * @param callbackIntent a PendingIntent to launch when the operation completes. This is
+     *     trigered upon completion of the original operation that required user resolution.
+     * @throws android.content.IntentSender.SendIntentException if called more than once.
+     */
+    public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
+            PendingIntent callbackIntent) throws IntentSender.SendIntentException {
+        PendingIntent resolutionIntent =
+                resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
+        if (resolutionIntent == null) {
+            throw new IllegalArgumentException("Invalid result intent");
+        }
+        Intent fillInIntent = new Intent();
+        fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
+                callbackIntent);
+        activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
+                fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
+    }
+
+    /**
+     * Continue an operation after the user resolves an error.
+     *
+     * <p>To be called by the LUI upon completion of a resolvable error flow.
+     *
+     * @param resolutionIntent The original intent used to start the LUI.
+     * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
+     *     For example, this may indicate whether the user has consented or may include the input
+     *     they provided.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
+        if (!isEnabled()) {
+            PendingIntent callbackIntent =
+                    resolutionIntent.getParcelableExtra(
+                            EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
+            if (callbackIntent != null) {
+                sendUnavailableError(callbackIntent);
+            }
+            return;
+        }
+        try {
+            mController.continueOperation(resolutionIntent, resolutionExtras);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Fills in the metadata for a DownloadableSubscription.
+     *
+     * <p>May be used in cases that a DownloadableSubscription was constructed to download a
+     * profile, but the metadata for the profile is unknown (e.g. we only know the activation code).
+     * The callback will be triggered with an Intent with
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the
+     * downloadable subscription metadata upon success.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param subscription the subscription which needs metadata filled in
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void getDownloadableSubscriptionMetadata(
+            DownloadableSubscription subscription, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.getDownloadableSubscriptionMetadata(
+                    subscription, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets metadata for subscription which are available for download on this device.
+     *
+     * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have
+     * been pre-assigned to this particular device, for example. The callback will be triggered with
+     * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the
+     * list of available subscriptions upon success.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     *
+     * TODO(b/35851809): Make this a SystemApi.
+     */
+    public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.getDefaultDownloadableSubscriptionList(
+                    mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns information about the eUICC chip/device.
+     *
+     * @return the {@link EuiccInfo}. May be null if {@link #isEnabled()} is false or the eUICC is
+     *     not ready.
+     */
+    @Nullable
+    public EuiccInfo getEuiccInfo() {
+        if (!isEnabled()) {
+            return null;
+        }
+        try {
+            return mController.getEuiccInfo();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Deletes the given subscription.
+     *
+     * <p>If this subscription is currently active, the device will first switch away from it onto
+     * an "empty" subscription.
+     *
+     * <p>Requires that the calling app has carrier privileges according to the metadata of the
+     * profile to be deleted, or the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+     *
+     * @param subscriptionId the ID of the subscription to delete.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.deleteSubscription(
+                    subscriptionId, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Switch to (enable) the given subscription.
+     *
+     * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+     * or the calling app must be authorized to manage both the currently-active subscription and
+     * the subscription to be enabled according to the subscription metadata. Without the former,
+     * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
+     * intent to prompt the user to accept the download.
+     *
+     * @param subscriptionId the ID of the subscription to enable. May be
+     *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
+     *     current profile without activating another profile to replace it.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     */
+    public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.switchToSubscription(
+                    subscriptionId, mContext.getOpPackageName(), callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Update the nickname for the given subscription.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param subscriptionId the ID of the subscription to update.
+     * @param nickname the new nickname to apply.
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void updateSubscriptionNickname(
+            int subscriptionId, String nickname, PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.updateSubscriptionNickname(subscriptionId, nickname, callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Erase all subscriptions and reset the eUICC.
+     *
+     * <p>Requires that the calling app has the
+     * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
+     * internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void eraseSubscriptions(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.eraseSubscriptions(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Ensure that subscriptions will be retained on the next factory reset.
+     *
+     * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
+     * and after factory resets). This ensures that the data is wiped after a factory reset is
+     * performed via fastboot or recovery mode, as these modes do not support the necessary radio
+     * communication needed to wipe the eSIM.
+     *
+     * <p>However, this method may be called right before a factory reset issued via settings when
+     * the user elects to retain subscriptions. Doing so will mark them for retention so that they
+     * are not cleared after the ensuing reset.
+     *
+     * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
+     * permission. This is for internal system use only.
+     *
+     * @param callbackIntent a PendingIntent to launch when the operation completes.
+     * @hide
+     */
+    public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
+        if (!isEnabled()) {
+            sendUnavailableError(callbackIntent);
+            return;
+        }
+        try {
+            mController.retainSubscriptionsForFactoryReset(callbackIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private static void sendUnavailableError(PendingIntent callbackIntent) {
+        try {
+            callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
+        } catch (PendingIntent.CanceledException e) {
+            // Caller canceled the callback; do nothing.
+        }
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 71f2c6b..644ad49 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -94,6 +94,21 @@
     int getActiveSubInfoCountMax();
 
     /**
+     * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
+     */
+    List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage);
+
+    /**
+     * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
+     */
+    List<SubscriptionInfo> getAccessibleSubscriptionInfoList(String callingPackage);
+
+    /**
+     * @see android.telephony.SubscriptionManager#requestEmbeddedSubscriptionInfoListRefresh
+     */
+    oneway void requestEmbeddedSubscriptionInfoListRefresh();
+
+    /**
      * Add a new SubscriptionInfo to subinfo database if needed
      * @param iccId the IccId of the SIM card
      * @param slotIndex the slot which the SIM is inserted
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 0dd846e..2ac11b5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -377,6 +377,13 @@
     Bundle getCellLocation(String callingPkg);
 
     /**
+     * Returns the ISO country code equivalent of the current registered
+     * operator's MCC (Mobile Country Code).
+     * @see android.telephony.TelephonyManager#getNetworkCountryIso
+     */
+    String getNetworkCountryIsoForPhone(int phoneId);
+
+    /**
      * Returns the neighboring cell information of the device.
      */
     List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
@@ -623,11 +630,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.
@@ -1303,6 +1312,16 @@
     void carrierActionSetRadioEnabled(int subId, boolean enabled);
 
     /**
+     * Action set from carrier signalling broadcast receivers to start/stop reporting default
+     * network conditions.
+     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+     * @param subId the subscription ID that this action applies to.
+     * @param report control start/stop reporting default network events.
+     * @hide
+     */
+    void carrierActionReportDefaultNetworkStatus(int subId, boolean report);
+
+    /**
      * Get aggregated video call data usage since boot.
      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
      *
diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
index 8b09848..95f39d7 100644
--- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java
+++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java
@@ -19,7 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.CellInfo;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -76,17 +75,15 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(scanStatus);
         dest.writeInt(scanError);
-        CellInfo[] ci = networkInfos.toArray(new CellInfo[networkInfos.size()]);
-        dest.writeParcelableArray(ci, flags);
+        dest.writeParcelableList(networkInfos, flags);
     }
 
     private NetworkScanResult(Parcel in) {
         scanStatus = in.readInt();
         scanError = in.readInt();
-        CellInfo[] ci = (CellInfo[]) in.readParcelableArray(
-                Object.class.getClassLoader(),
-                CellInfo.class);
-        networkInfos = Arrays.asList(ci);
+        List<CellInfo> ni = new ArrayList<>();
+        in.readParcelableList(ni, Object.class.getClassLoader());
+        networkInfos = ni;
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 0343890..f29d993c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -447,6 +447,20 @@
             "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
 
     /**
+     * <p>Broadcast Action: when system default network available/unavailable with
+     * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when
+     * other network becomes system default network, Wi-Fi for example.
+     * The intent will have the following extra values:</p>
+     * <ul>
+     *   <li>defaultNetworkAvailable</li><dd>A boolean indicates default network available.</dd>
+     *   <li>subId</li><dd>Sub Id which associated the default data.</dd>
+     * </ul>
+     * <p class="note">This is a protected intent that can only be sent by the system. </p>
+     */
+    public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE =
+            "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+
+    /**
      * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent.
      * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app
      * The intent will have the following extra values:</p>
@@ -465,7 +479,7 @@
     public static final String EXTRA_APN_PROTO_KEY = "apnProto";
     public static final String EXTRA_PCO_ID_KEY = "pcoId";
     public static final String EXTRA_PCO_VALUE_KEY = "pcoValue";
-
+    public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable";
 
    /**
      * Broadcast action to trigger CI OMA-DM Session.
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
new file mode 100644
index 0000000..b3fc90d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.internal.telephony.euicc;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.euicc.DownloadableSubscription;
+import android.telephony.euicc.EuiccInfo;
+
+/** @hide */
+interface IEuiccController {
+    oneway void continueOperation(in Intent resolutionIntent, in Bundle resolutionExtras);
+    oneway void getDownloadableSubscriptionMetadata(in DownloadableSubscription subscription,
+        String callingPackage, in PendingIntent callbackIntent);
+    oneway void getDefaultDownloadableSubscriptionList(
+        String callingPackage, in PendingIntent callbackIntent);
+    String getEid();
+    oneway void downloadSubscription(in DownloadableSubscription subscription,
+        boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent);
+    EuiccInfo getEuiccInfo();
+    oneway void deleteSubscription(int subscriptionId, String callingPackage,
+        in PendingIntent callbackIntent);
+    oneway void switchToSubscription(int subscriptionId, String callingPackage,
+        in PendingIntent callbackIntent);
+    oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
+        in PendingIntent callbackIntent);
+    oneway void eraseSubscriptions(in PendingIntent callbackIntent);
+    oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index f28d126..0fabc2f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -30,10 +30,6 @@
     /** Private constructor for utility class. */
     private SmsCbConstants() { }
 
-    /** Channel 50 required by Brazil. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50
-            = 0x0032;
-
     /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
     public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER
             = 0x1100; // 4352
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 24e7bff..5e5ba46 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -149,6 +149,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public void reloadSharedPreferences() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
         throw new UnsupportedOperationException();
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index bcde519..3cb1f39 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -17,6 +17,7 @@
 package android.test.mock;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -1168,4 +1169,13 @@
     public String getInstantAppAndroidId(String packageName, UserHandle user) {
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void registerDexModule(String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
new file mode 100644
index 0000000..fc001e9
--- /dev/null
+++ b/tests/Internal/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_USE_AAPT2 := true
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+
+# Include some source files directly to be able to access package members
+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 \
+    mockito-target-minus-junit4
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PACKAGE_NAME := InternalTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/Internal/AndroidManifest.xml b/tests/Internal/AndroidManifest.xml
new file mode 100644
index 0000000..a2c95fb
--- /dev/null
+++ b/tests/Internal/AndroidManifest.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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.internal.tests">
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.internal.tests"
+                     android:label="Internal Tests" />
+</manifest>
diff --git a/tests/Internal/AndroidTest.xml b/tests/Internal/AndroidTest.xml
new file mode 100644
index 0000000..6531c93
--- /dev/null
+++ b/tests/Internal/AndroidTest.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
+  -->
+<configuration description="Runs tests for internal classes/utilities.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="InternalTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="InternalTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.internal.tests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
new file mode 100644
index 0000000..fb529b9
--- /dev/null
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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);
+    }
+
+    /**
+     * WallpaperColors should not recycle bitmaps that it didn't create.
+     */
+    @Test
+    public void wallpaperRecycleBitmapTest() {
+        Bitmap image = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
+        WallpaperColors.fromBitmap(image);
+        Canvas canvas = new Canvas();
+        // This would crash:
+        canvas.drawBitmap(image, 0, 0, new Paint());
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
new file mode 100644
index 0000000..cb6a83d
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -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
+ */
+package com.android.internal.colorextraction;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+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;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests color extraction generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ColorExtractorTest {
+
+    Context mContext;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void ColorExtractor_extractWhenInitialized() {
+        ExtractionType type = mock(Tonal.class);
+        new ColorExtractor(mContext, type);
+        // 1 for lock and 1 for system
+        verify(type, times(2))
+                .extractInto(any(), any(), any(), any());
+    }
+
+    @Test
+    public void getColors_usesExtractedColors() {
+        GradientColors colorsExpectedNormal = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.RED);
+        colorsExpectedNormal.setSecondaryColor(Color.GRAY);
+
+        GradientColors colorsExpectedDark = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.BLACK);
+        colorsExpectedNormal.setSecondaryColor(Color.BLUE);
+
+        GradientColors colorsExpectedExtraDark = new GradientColors();
+        colorsExpectedNormal.setMainColor(Color.MAGENTA);
+        colorsExpectedNormal.setSecondaryColor(Color.GREEN);
+
+        ExtractionType type =
+                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
+                        outGradientColorsExtraDark) -> {
+                    outGradientColorsNormal.set(colorsExpectedNormal);
+                    outGradientColorsDark.set(colorsExpectedDark);
+                    outGradientColorsExtraDark.set(colorsExpectedExtraDark);
+                };
+        ColorExtractor extractor = new ColorExtractor(mContext, type);
+
+        GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
+                ColorExtractor.TYPE_NORMAL);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedNormal);
+        colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_DARK);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedDark);
+        colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_EXTRA_DARK);
+        assertEquals("Extracted colors not being used!", colors, colorsExpectedExtraDark);
+    }
+
+    @Test
+    public void addOnColorsChangedListener_invokesListener() {
+        ColorExtractor.OnColorsChangedListener mockedListeners =
+                mock(ColorExtractor.OnColorsChangedListener.class);
+        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext));
+        extractor.addOnColorsChangedListener(mockedListeners);
+
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+                WallpaperManager.FLAG_LOCK);
+        verify(mockedListeners, times(1)).onColorsChanged(any(),
+                eq(WallpaperManager.FLAG_LOCK));
+
+        extractor.removeOnColorsChangedListener(mockedListeners);
+        extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+                WallpaperManager.FLAG_LOCK);
+        verifyNoMoreInteractions(mockedListeners);
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
new file mode 100644
index 0000000..6dc9ba7
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.internal.colorextraction.types;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.WallpaperColors;
+import android.graphics.Color;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Range;
+
+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.Arrays;
+
+/**
+ * Tests tonal palette generation.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TonalTest {
+
+    @Test
+    public void extractInto_usesFallback() {
+        GradientColors normal = new GradientColors();
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        tonal.extractInto(null, normal, new GradientColors(),
+                new GradientColors());
+        assertFalse("Should use fallback color if WallpaperColors is null.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+    }
+
+    @Test
+    public void extractInto_usesFallbackWhenTooLightOrDark() {
+        GradientColors normal = new GradientColors();
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        tonal.extractInto(new WallpaperColors(Color.valueOf(0xff000000), null, null, 0),
+                normal, new GradientColors(), new GradientColors());
+        assertTrue("Should use fallback color if WallpaperColors is too dark.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
+
+        tonal.extractInto(new WallpaperColors(Color.valueOf(0xffffffff), null, null,
+                        WallpaperColors.HINT_SUPPORTS_DARK_TEXT),
+                normal, new GradientColors(), new GradientColors());
+        assertTrue("Should use fallback color if WallpaperColors is too light.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+    }
+
+    @Test
+    public void colorRange_containsColor() {
+        Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
+                new Range<>(0f, 1f), new Range<>(0f, 1f));
+        float[] hsl = new float[] {25, 0, 0};
+        assertTrue("Range " + colorRange + " doesn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+    }
+
+    @Test
+    public void colorRange_doesntContainColor() {
+        Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
+                new Range<>(0f, 0.5f), new Range<>(0f, 0.5f));
+        float[] hsl = new float[] {100, 0, 0};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+        hsl = new float[] {0, 0.6f, 0};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+        hsl = new float[] {0, 0, 0.6f};
+        assertFalse("Range " + colorRange + " shouldn't contain " + Arrays.toString(hsl),
+                colorRange.containsColor(hsl[0], hsl[1], hsl[2]));
+    }
+
+    @Test
+    public void configParser_dataSanity() {
+        Tonal.ConfigParser config = new Tonal.ConfigParser(InstrumentationRegistry.getContext());
+        // 1 to avoid regression where only first item would be parsed.
+        assertTrue("Tonal palettes are empty", config.getTonalPalettes().size() > 1);
+        assertTrue("Blacklisted colors are empty", config.getBlacklistedColors().size() > 1);
+    }
+
+    @Test
+    public void tonal_excludeBlacklistedColor() {
+        // Make sure that palette generation will fail.
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+
+        // Creating a WallpaperColors object that contains *only* blacklisted colors.
+        float[] hsl = tonal.getBlacklistedColors().get(0).getCenter();
+        WallpaperColors colors = new WallpaperColors(Color.valueOf(ColorUtils.HSLToColor(hsl)),
+                null, null, 0);
+
+        // Make sure that palette generation will fail
+        GradientColors normal = new GradientColors();
+        tonal.extractInto(colors, normal, new GradientColors(),
+                new GradientColors());
+        assertTrue("Cannot generate a tonal palette from blacklisted colors.",
+                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
new file mode 100644
index 0000000..73df9a0
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.internal.graphics;
+
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+@SmallTest
+public class ColorUtilsTest {
+
+    @Test
+    public void calculateMinimumBackgroundAlpha_satisfiestContrast() {
+
+        int alpha = ColorUtils.calculateMinimumBackgroundAlpha(Color.WHITE, Color.BLACK, 4.5f);
+        assertTrue("Alpha doesn't need to be 255 to satisfy contrast", alpha < 255);
+
+        int worstCase = ColorUtils.blendARGB(Color.WHITE, Color.BLACK, alpha/255f);
+        worstCase = ColorUtils.setAlphaComponent(worstCase, 255);
+        double contrast = ColorUtils.calculateContrast(Color.WHITE, worstCase);
+        assertTrue("Blended color should satisfy contrast", contrast >= 4.5);
+
+    }
+}
diff --git a/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
new file mode 100644
index 0000000..a64f8a6
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.internal.ml.clustering;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.SuppressLint;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KMeansTest {
+
+    // Error tolerance (epsilon)
+    private static final double EPS = 0.01;
+
+    private KMeans mKMeans;
+
+    @Before
+    public void setUp() {
+        // Setup with a random seed to have predictable results
+        mKMeans = new KMeans(new Random(0), 30, 0);
+    }
+
+    @Test
+    public void getCheckDataSanityTest() {
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    {0, 1, 2},
+                    {1, 2, 3}
+            });
+        } catch (IllegalArgumentException e) {
+            Assert.fail("Valid data didn't pass sanity check");
+        }
+
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    null,
+                    {1, 2, 3}
+            });
+            Assert.fail("Data has null items and passed");
+        } catch (IllegalArgumentException e) {}
+
+        try {
+            mKMeans.checkDataSetSanity(new float[][] {
+                    {0, 1, 2, 4},
+                    {1, 2, 3}
+            });
+            Assert.fail("Data has invalid shape and passed");
+        } catch (IllegalArgumentException e) {}
+
+        try {
+            mKMeans.checkDataSetSanity(null);
+            Assert.fail("Null data should throw exception");
+        } catch (IllegalArgumentException e) {}
+    }
+
+    @Test
+    public void sqDistanceTest() {
+        float a[] = {4, 10};
+        float b[] = {5, 2};
+        float sqDist = (float) (Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
+
+        assertEquals("Squared distance not valid", mKMeans.sqDistance(a, b), sqDist, EPS);
+    }
+
+    @Test
+    public void nearestMeanTest() {
+        KMeans.Mean meanA = new KMeans.Mean(0, 1);
+        KMeans.Mean meanB = new KMeans.Mean(1, 1);
+        List<KMeans.Mean> means = Arrays.asList(meanA, meanB);
+
+        KMeans.Mean nearest = mKMeans.nearestMean(new float[] {1, 1}, means);
+
+        assertEquals("Unexpected nearest mean for point {1, 1}", nearest, meanB);
+    }
+
+    @SuppressLint("DefaultLocale")
+    @Test
+    public void scoreTest() {
+        List<KMeans.Mean> closeMeans = Arrays.asList(new KMeans.Mean(0, 0.1f, 0.1f),
+                new KMeans.Mean(0, 0.1f, 0.15f),
+                new KMeans.Mean(0.1f, 0.2f, 0.1f));
+        List<KMeans.Mean> farMeans = Arrays.asList(new KMeans.Mean(0, 0, 0),
+                new KMeans.Mean(0, 0.5f, 0.5f),
+                new KMeans.Mean(1, 0.9f, 0.9f));
+
+        double closeScore = KMeans.score(closeMeans);
+        double farScore = KMeans.score(farMeans);
+        assertTrue(String.format("Score of well distributed means should be greater than "
+                + "close means but got: %f, %f", farScore, closeScore), farScore > closeScore);
+    }
+
+    @Test
+    public void predictTest() {
+        float[] expectedCentroid1 = {1, 1, 1};
+        float[] expectedCentroid2 = {0, 0, 0};
+        float[][] X = new float[][] {
+                {1, 1, 1},
+                {1, 1, 1},
+                {1, 1, 1},
+                {0, 0, 0},
+                {0, 0, 0},
+                {0, 0, 0},
+        };
+
+        final int numClusters = 2;
+
+        // Here we assume that we won't get stuck into a local optima.
+        // It's fine because we're seeding a random, we won't ever have
+        // unstable results but in real life we need multiple initialization
+        // and score comparison
+        List<KMeans.Mean> means = mKMeans.predict(numClusters, X);
+
+        assertEquals("Expected number of clusters is invalid", numClusters, means.size());
+
+        boolean exists1 = false, exists2 = false;
+        for (KMeans.Mean mean : means) {
+            if (Arrays.equals(mean.getCentroid(), expectedCentroid1)) {
+                exists1 = true;
+            } else if (Arrays.equals(mean.getCentroid(), expectedCentroid2)) {
+                exists2 = true;
+            } else {
+                throw new AssertionError("Unexpected mean: " + mean);
+            }
+        }
+        assertTrue("Expected means were not predicted, got: " + means,
+                exists1 && exists2);
+    }
+}
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
index b550cfa..00bf33a 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
@@ -689,8 +689,20 @@
         AudioFormat format =  event.getCaptureAudioFormat();
         result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString());
         byte[] triggerAudio = event.getTriggerAudio();
-        result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
-        result = result + "CaptureSession: " + event.getCaptureSession();
+        result = result + ", TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
+        byte[] data = event.getData();
+        result = result + ", Data: " + (data == null ? "null" : data.length);
+        if (data != null) {
+          try {
+            String decodedData = new String(data, "UTF-8");
+            if (decodedData.chars().allMatch(c -> (c >= 32 && c < 128) || c == 0)) {
+                result = result + ", Decoded Data: '" + decodedData + "'";
+            }
+          } catch (Exception e) {
+            Log.e(TAG, "Failed to decode data");
+          }
+        }
+        result = result + ", CaptureSession: " + event.getCaptureSession();
         result += " )";
         return result;
     }
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index 81442bf..6a082e9 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -6,6 +6,7 @@
     <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" />
 
     <application>
         <activity android:name="StatusBarTest" android:label="_StatusBar">
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 5dd42dd..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;
 
@@ -129,6 +129,42 @@
                     mNM.notify(7001, n);
                 }
             },
+            new Test("with zen") {
+                public void run()
+                {
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS);
+                    Notification n = new Notification.Builder(NotificationTestList.this,
+                            "default")
+                            .setSmallIcon(R.drawable.icon2)
+                            .setContentTitle("Default priority")
+                            .build();
+                    mNM.notify("default", 7004, n);
+                    try {
+                        Thread.sleep(8000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    mNM.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
+                }
+            },
+            new Test("repeated") {
+                public void run()
+                {
+                    for (int i = 0; i < 50; i++) {
+                        Notification n = new Notification.Builder(NotificationTestList.this,
+                                "default")
+                                .setSmallIcon(R.drawable.icon2)
+                                .setContentTitle("Default priority")
+                                .build();
+                        mNM.notify("default", 7004, n);
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            },
             new Test("Post a group") {
                 public void run()
                 {
@@ -402,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() {
@@ -498,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(
@@ -988,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);
+
+                }
+            },
 
     };
 
@@ -1176,4 +1212,3 @@
         return Bitmap.createBitmap(bd.getBitmap());
     }
 }
-
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
index 1cb394e..42f7955 100644
--- a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
+++ b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbDeviceStateController.java
@@ -89,7 +89,10 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            mCloseGuard.warnIfOpen();
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
             release();
         } finally {
             super.finalize();
diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml
index 6c0a6d0..f8ecc6b 100644
--- a/tests/net/AndroidTest.xml
+++ b/tests/net/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksNetTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.net" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 212f477..a115146 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -40,7 +40,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.mock;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -60,14 +59,12 @@
 import android.net.util.SharedLog;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.INetworkManagementService;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -279,6 +276,31 @@
         mIntents.remove(bcast);
     }
 
+    public void failingLocalOnlyHotspotLegacyApBroadcast(
+            boolean emulateInterfaceStatusChanged) throws Exception {
+        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+
+        // Emulate externally-visible WifiManager effects, causing the
+        // per-interface state machine to start up, and telling us that
+        // hotspot mode is to be started.
+        if (emulateInterfaceStatusChanged) {
+            mTethering.interfaceStatusChanged(mTestIfname, true);
+        }
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
+        mLooper.dispatchAll();
+
+        // If, and only if, Tethering received an interface status changed
+        // then it creates a TetherInterfaceStateMachine and sends out a
+        // broadcast indicating that the interface is "available".
+        if (emulateInterfaceStatusChanged) {
+            verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+            verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+        }
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+        verifyNoMoreInteractions(mWifiManager);
+    }
+
     @Test
     public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
         when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
@@ -305,31 +327,6 @@
         verify(mNMService, times(1)).listInterfaces();
     }
 
-    public void failingLocalOnlyHotspotLegacyApBroadcast(
-            boolean emulateInterfaceStatusChanged) throws Exception {
-        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
-
-        // Emulate externally-visible WifiManager effects, causing the
-        // per-interface state machine to start up, and telling us that
-        // hotspot mode is to be started.
-        if (emulateInterfaceStatusChanged) {
-            mTethering.interfaceStatusChanged(mTestIfname, true);
-        }
-        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
-        mLooper.dispatchAll();
-
-        // If, and only if, Tethering received an interface status changed
-        // then it creates a TetherInterfaceStateMachine and sends out a
-        // broadcast indicating that the interface is "available".
-        if (emulateInterfaceStatusChanged) {
-            verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
-            verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
-        }
-        verifyNoMoreInteractions(mConnectivityManager);
-        verifyNoMoreInteractions(mNMService);
-        verifyNoMoreInteractions(mWifiManager);
-    }
-
     @Test
     public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
         failingLocalOnlyHotspotLegacyApBroadcast(true);
@@ -410,7 +407,7 @@
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
-        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+        mTethering.startTethering(TETHERING_WIFI, null, false);
         mLooper.dispatchAll();
         verify(mWifiManager, times(1)).startSoftAp(null);
         verifyNoMoreInteractions(mWifiManager);
@@ -561,90 +558,6 @@
         verifyNoMoreInteractions(mNMService);
     }
 
-    private void userRestrictionsListenerBehaviour(
-        boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
-        int expectedInteractionsWithShowNotification) throws  Exception {
-        final int userId = 0;
-        final Bundle currRestrictions = new Bundle();
-        final Bundle newRestrictions = new Bundle();
-        Tethering tethering = mock(Tethering.class);
-        Tethering.TetheringUserRestrictionListener turl =
-                new Tethering.TetheringUserRestrictionListener(tethering);
-
-        currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow);
-        newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
-        when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
-
-        turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions);
-
-        verify(tethering, times(expectedInteractionsWithShowNotification))
-                .showTetheredNotification(anyInt(), eq(false));
-
-        verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll();
-    }
-
-    @Test
-    public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] emptyActiveIfacesList = new String[]{};
-        final boolean currDisallow = false;
-        final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final boolean currDisallow = false;
-        final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 1;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{};
-        final boolean currDisallow = true;
-        final boolean nextDisallow = false;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final boolean currDisallow = true;
-        final boolean nextDisallow = false;
-        final int expectedInteractionsWithShowNotification = 0;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testDisallowTetheringUnchanged() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
-        final int expectedInteractionsWithShowNotification = 0;
-        boolean currDisallow = true;
-        boolean nextDisallow = true;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-
-        currDisallow = false;
-        nextDisallow = false;
-
-        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-
     // TODO: Test that a request for hotspot mode doesn't interfere with an
     // already operating tethering mode interface.
 }
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 2a8efc0..b98f63b 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -69,7 +69,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -110,13 +109,11 @@
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        // TODO: call this when available.
-        // FakeSettingsProvider.clearSettingsProvider();
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     @After public void tearDown() throws Exception {
-        // TODO: call this when available.
-        // FakeSettingsProvider.clearSettingsProvider();
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     private void setupFunctioningHardwareInterface() {
@@ -147,7 +144,6 @@
     }
 
     @Test
-    @Ignore("Restore when FakeSettingsProvider.clearSettingsProvider() is available.")
     public void testNoSettingsValueDefaultDisabledDoesNotStart() throws Exception {
         setupFunctioningHardwareInterface();
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
@@ -168,7 +164,6 @@
     }
 
     @Test
-    @Ignore("Restore when FakeSettingsProvider.clearSettingsProvider() is available.")
     public void testNoSettingsValueDefaultEnabledDoesStart() throws Exception {
         setupFunctioningHardwareInterface();
         when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
diff --git a/tests/radio/Android.mk b/tests/radio/Android.mk
new file mode 100644
index 0000000..dc55d0b
--- /dev/null
+++ b/tests/radio/Android.mk
@@ -0,0 +1,33 @@
+# 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_PACKAGE_NAME := RadioTests
+
+LOCAL_MODULE_TAGS := tests
+# TODO(b/13282254): uncomment when b/13282254 is fixed
+# LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test testng
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_DEX_PREOPT := false
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/radio/AndroidManifest.xml b/tests/radio/AndroidManifest.xml
new file mode 100644
index 0000000..150edbf
--- /dev/null
+++ b/tests/radio/AndroidManifest.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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.hardware.radio.tests">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.hardware.radio.tests"
+        android:label="Tests for broadcast radio API" >
+    </instrumentation>
+</manifest>
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
new file mode 100644
index 0000000..47e104c
--- /dev/null
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -0,0 +1,375 @@
+/*
+ * 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.hardware.radio.tests;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioTuner;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.testng.Assert.assertThrows;
+
+/**
+ * A test for broadcast radio API.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RadioTest {
+    private static final String TAG = "RadioTest";
+
+    public final Context mContext = InstrumentationRegistry.getContext();
+
+    private final int kConfigCallbackTimeoutMs = 10000;
+    private final int kCancelTimeoutMs = 1000;
+    private final int kTuneCallbackTimeoutMs = 30000;
+
+    private RadioManager mRadioManager;
+    private RadioTuner mRadioTuner;
+    private RadioManager.ModuleProperties mModule;
+    private final List<RadioManager.ModuleProperties> mModules = new ArrayList<>();
+    @Mock private RadioTuner.Callback mCallback;
+
+    RadioManager.AmBandDescriptor mAmBandDescriptor;
+    RadioManager.FmBandDescriptor mFmBandDescriptor;
+
+    RadioManager.BandConfig mAmBandConfig;
+    RadioManager.BandConfig mFmBandConfig;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        // check if radio is supported and skip the test if it's not
+        PackageManager packageManager = mContext.getPackageManager();
+        boolean isRadioSupported = packageManager.hasSystemFeature(PackageManager.FEATURE_RADIO);
+        assumeTrue(isRadioSupported);
+
+        mRadioManager = (RadioManager)mContext.getSystemService(Context.RADIO_SERVICE);
+        assertNotNull(mRadioManager);
+
+        int status = mRadioManager.listModules(mModules);
+        assertEquals(RadioManager.STATUS_OK, status);
+        assertFalse(mModules.isEmpty());
+    }
+
+    @After
+    public void tearDown() {
+        mRadioManager = null;
+        mModules.clear();
+        if (mRadioTuner != null) {
+            mRadioTuner.close();
+            mRadioTuner = null;
+        }
+        verifyNoMoreInteractions(mCallback);
+    }
+
+    private void openTuner() {
+        openTuner(true);
+    }
+
+    private void resetCallback() {
+        verifyNoMoreInteractions(mCallback);
+        Mockito.reset(mCallback);
+    }
+
+    private void openTuner(boolean withAudio) {
+        assertNull(mRadioTuner);
+
+        // find FM band and build its config
+        mModule = mModules.get(0);
+        for (RadioManager.BandDescriptor band : mModule.getBands()) {
+            if (band.getType() == RadioManager.BAND_AM) {
+                mAmBandDescriptor = (RadioManager.AmBandDescriptor)band;
+            }
+            if (band.getType() == RadioManager.BAND_FM) {
+                mFmBandDescriptor = (RadioManager.FmBandDescriptor)band;
+            }
+        }
+        assertNotNull(mAmBandDescriptor);
+        assertNotNull(mFmBandDescriptor);
+        mAmBandConfig = new RadioManager.AmBandConfig.Builder(mAmBandDescriptor).build();
+        mFmBandConfig = new RadioManager.FmBandConfig.Builder(mFmBandDescriptor).build();
+
+        mRadioTuner = mRadioManager.openTuner(mModule.getId(),
+                mFmBandConfig, withAudio, mCallback, null);
+        assertNotNull(mRadioTuner);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+        resetCallback();
+    }
+
+    private void checkAntenna() {
+        boolean isConnected = mRadioTuner.isAntennaConnected();
+        assertTrue(isConnected);
+    }
+
+    @Test
+    public void testOpenTuner() {
+        openTuner();
+    }
+
+    @Test
+    public void testReopenTuner() throws Throwable {
+        openTuner();
+        mRadioTuner.close();
+        mRadioTuner = null;
+        Thread.sleep(100);  // TODO(b/36122635): force reopen
+        openTuner();
+    }
+
+    @Test
+    public void testDoubleClose() {
+        openTuner();
+        mRadioTuner.close();
+        mRadioTuner.close();
+    }
+
+    @Test
+    public void testUseAfterClose() {
+        openTuner();
+        mRadioTuner.close();
+        int ret = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_INVALID_OPERATION, ret);
+    }
+
+    @Test
+    public void testSetAndGetConfiguration() {
+        openTuner();
+
+        // set
+        int ret = mRadioTuner.setConfiguration(mAmBandConfig);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+
+        // get
+        RadioManager.BandConfig[] config = new RadioManager.BandConfig[1];
+        ret = mRadioTuner.getConfiguration(config);
+        assertEquals(RadioManager.STATUS_OK, ret);
+
+        assertEquals(mAmBandConfig, config[0]);
+    }
+
+    @Test
+    public void testSetBadConfiguration() throws Throwable {
+        openTuner();
+
+        // set bad config
+        Constructor<RadioManager.AmBandConfig> configConstr =
+                RadioManager.AmBandConfig.class.getDeclaredConstructor(
+                        int.class, int.class, int.class, int.class, int.class, boolean.class);
+        configConstr.setAccessible(true);
+        RadioManager.AmBandConfig badConfig = configConstr.newInstance(
+                0 /*region*/, RadioManager.BAND_AM /*type*/,
+                10000 /*lowerLimit*/, 1 /*upperLimit*/, 100 /*spacing*/, false /*stereo*/);
+        int ret = mRadioTuner.setConfiguration(badConfig);
+        assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
+        verify(mCallback, never()).onConfigurationChanged(any());
+
+        // set null config
+        ret = mRadioTuner.setConfiguration(null);
+        assertEquals(RadioManager.STATUS_BAD_VALUE, ret);
+        verify(mCallback, never()).onConfigurationChanged(any());
+
+        // setting good config should recover
+        ret = mRadioTuner.setConfiguration(mAmBandConfig);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+    }
+
+    @Test
+    public void testMute() {
+        openTuner();
+
+        boolean isMuted = mRadioTuner.getMute();
+        assertFalse(isMuted);
+
+        int ret = mRadioTuner.setMute(true);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        isMuted = mRadioTuner.getMute();
+        assertTrue(isMuted);
+
+        ret = mRadioTuner.setMute(false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        isMuted = mRadioTuner.getMute();
+        assertFalse(isMuted);
+    }
+
+    @Test
+    public void testMuteNoAudio() {
+        openTuner(false);
+
+        int ret = mRadioTuner.setMute(false);
+        assertEquals(RadioManager.STATUS_ERROR, ret);
+
+        boolean isMuted = mRadioTuner.getMute();
+        assertTrue(isMuted);
+    }
+
+    @Test
+    public void testStep() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, true);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        resetCallback();
+
+        ret = mRadioTuner.step(RadioTuner.DIRECTION_UP, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+    }
+
+    @Test
+    public void testTuneAndGetPI() {
+        openTuner();
+        checkAntenna();
+
+        int channel = mFmBandConfig.getLowerLimit() + mFmBandConfig.getSpacing();
+
+        // test tune
+        int ret = mRadioTuner.tune(channel, 0);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        ArgumentCaptor<RadioManager.ProgramInfo> infoc =
+                ArgumentCaptor.forClass(RadioManager.ProgramInfo.class);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs))
+                .onProgramInfoChanged(infoc.capture());
+        assertEquals(channel, infoc.getValue().getChannel());
+
+        // test getProgramInformation
+        RadioManager.ProgramInfo[] info = new RadioManager.ProgramInfo[1];
+        ret = mRadioTuner.getProgramInformation(info);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        assertNotNull(info[0]);
+        assertEquals(channel, info[0].getChannel());
+    }
+
+    @Test
+    public void testDummyCancel() {
+        openTuner();
+
+        int ret = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, ret);
+    }
+
+    @Test
+    public void testLateCancel() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        int cancelRet = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+    }
+
+    @Test
+    public void testScanAndCancel() {
+        openTuner();
+        checkAntenna();
+
+        /* There is a possible race condition between scan and cancel commands - the scan may finish
+         * before cancel command is issued. Thus we accept both outcomes in this test.
+         */
+        int scanRet = mRadioTuner.scan(RadioTuner.DIRECTION_DOWN, true);
+        int cancelRet = mRadioTuner.cancel();
+
+        assertEquals(RadioManager.STATUS_OK, scanRet);
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+
+        verify(mCallback, after(kCancelTimeoutMs).atMost(1)).onError(RadioTuner.ERROR_CANCELLED);
+        verify(mCallback, atMost(1)).onProgramInfoChanged(any());
+    }
+
+    @Test
+    public void testStartBackgroundScan() {
+        openTuner();
+        checkAntenna();
+
+        boolean ret = mRadioTuner.startBackgroundScan();
+        boolean isSupported = mModule.isBackgroundScanningSupported();
+        assertEquals(isSupported, ret);
+    }
+
+    @Test
+    public void testGetProgramList() {
+        openTuner();
+        checkAntenna();
+
+        try {
+            List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(null);
+            assertNotNull(list);
+        } catch (IllegalStateException e) {
+            // the list may or may not be ready at this point
+            Log.i(TAG, "Background list is not ready");
+        }
+    }
+
+    @Test
+    public void testForcedAnalog() {
+        openTuner();
+
+        boolean isSupported = true;
+        boolean isForced;
+        try {
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } catch (IllegalStateException ex) {
+            Log.i(TAG, "Forced analog switch is not supported by this tuner");
+            isSupported = false;
+        }
+
+        if (isSupported) {
+            mRadioTuner.setAnalogForced(true);
+            isForced = mRadioTuner.isAnalogForced();
+            assertTrue(isForced);
+
+            mRadioTuner.setAnalogForced(false);
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } else {
+            assertThrows(IllegalStateException.class, () -> mRadioTuner.setAnalogForced(true));
+        }
+    }
+}
diff --git a/tests/testables/Android.mk b/tests/testables/Android.mk
index 759bc35..0e36981 100644
--- a/tests/testables/Android.mk
+++ b/tests/testables/Android.mk
@@ -31,3 +31,5 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/testables/src/android/testing/AndroidTestingRunner.java b/tests/testables/src/android/testing/AndroidTestingRunner.java
index a425f70..cf5d4cf 100644
--- a/tests/testables/src/android/testing/AndroidTestingRunner.java
+++ b/tests/testables/src/android/testing/AndroidTestingRunner.java
@@ -35,6 +35,8 @@
 
 /**
  * A runner with support for extra annotations provided by the Testables library.
+ * @see UiThreadTest
+ * @see TestableLooper.RunWithLooper
  */
 public class AndroidTestingRunner extends BlockJUnit4ClassRunner {
 
diff --git a/tests/testables/src/android/testing/BaseFragmentTest.java b/tests/testables/src/android/testing/BaseFragmentTest.java
index f1e4d21..5fa065a 100644
--- a/tests/testables/src/android/testing/BaseFragmentTest.java
+++ b/tests/testables/src/android/testing/BaseFragmentTest.java
@@ -84,6 +84,10 @@
         });
     }
 
+    /**
+     * Allows tests to sub-class TestableContext if they want to provide any extended functionality
+     * or provide a {@link LeakCheck} to the TestableContext upon instantiation.
+     */
     protected TestableContext getContext() {
         return new TestableContext(InstrumentationRegistry.getContext());
     }
diff --git a/tests/testables/src/android/testing/LeakCheck.java b/tests/testables/src/android/testing/LeakCheck.java
index 8daaa8f..949215b 100644
--- a/tests/testables/src/android/testing/LeakCheck.java
+++ b/tests/testables/src/android/testing/LeakCheck.java
@@ -14,6 +14,7 @@
 
 package android.testing;
 
+import android.content.Context;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -28,6 +29,35 @@
 import java.util.List;
 import java.util.Map;
 
+/**
+ * Utility for dealing with the facts of Lifecycle. Creates trackers to check that for every
+ * call to registerX, addX, bindX, a corresponding call to unregisterX, removeX, and unbindX
+ * is performed. This should be applied to a test as a {@link org.junit.rules.TestRule}
+ * and will only check for leaks on successful tests.
+ * <p>
+ * Example that will catch an allocation and fail:
+ * <pre class="prettyprint">
+ * public class LeakCheckTest {
+ *    &#064;Rule public LeakCheck mLeakChecker = new LeakCheck();
+ *
+ *    &#064;Test
+ *    public void testLeak() {
+ *        Context context = new ContextWrapper(...) {
+ *            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ *                mLeakChecker.getTracker("receivers").addAllocation(new Throwable());
+ *            }
+ *            public void unregisterReceiver(BroadcastReceiver receiver) {
+ *                mLeakChecker.getTracker("receivers").clearAllocations();
+ *            }
+ *        };
+ *        context.registerReceiver(...);
+ *    }
+ *  }
+ * </pre>
+ *
+ * Note: {@link TestableContext} supports leak tracking when using
+ * {@link TestableContext#TestableContext(Context, LeakCheck)}.
+ */
 public class LeakCheck extends TestWatcher {
 
     private final Map<String, Tracker> mTrackers = new HashMap<>();
@@ -40,6 +70,13 @@
         verify();
     }
 
+    /**
+     * Acquire a {@link Tracker}. Gets a tracker for the specified tag, creating one if necessary.
+     * There should be one tracker for each pair of add/remove callbacks (e.g. one tracker for
+     * registerReceiver/unregisterReceiver).
+     *
+     * @param tag Unique tag to use for this set of allocation tracking.
+     */
     public Tracker getTracker(String tag) {
         Tracker t = mTrackers.get(tag);
         if (t == null) {
@@ -49,10 +86,13 @@
         return t;
     }
 
-    public void verify() {
+    private void verify() {
         mTrackers.values().forEach(Tracker::verify);
     }
 
+    /**
+     * Holds allocations associated with a specific callback (such as a BroadcastReceiver).
+     */
     public static class LeakInfo {
         private static final String TAG = "LeakInfo";
         private List<Throwable> mThrowables = new ArrayList<>();
@@ -60,11 +100,20 @@
         LeakInfo() {
         }
 
+        /**
+         * Should be called once for each callback/listener added. addAllocation may be
+         * called several times, but it only takes one clearAllocations call to remove all
+         * of them.
+         */
         public void addAllocation(Throwable t) {
             // TODO: Drop off the first element in the stack trace here to have a cleaner stack.
             mThrowables.add(t);
         }
 
+        /**
+         * Should be called when the callback/listener has been removed. One call to
+         * clearAllocations will counteract any number of calls to addAllocation.
+         */
         public void clearAllocations() {
             mThrowables.clear();
         }
@@ -82,9 +131,16 @@
         }
     }
 
+    /**
+     * Tracks allocations related to a specific tag or method(s).
+     * @see #getTracker(String)
+     */
     public static class Tracker {
         private Map<Object, LeakInfo> mObjects = new ArrayMap<>();
 
+        private Tracker() {
+        }
+
         public LeakInfo getLeakInfo(Object object) {
             LeakInfo leakInfo = mObjects.get(object);
             if (leakInfo == null) {
diff --git a/tests/testables/src/android/testing/TestableContentResolver.java b/tests/testables/src/android/testing/TestableContentResolver.java
index bfafbe0..0850916 100644
--- a/tests/testables/src/android/testing/TestableContentResolver.java
+++ b/tests/testables/src/android/testing/TestableContentResolver.java
@@ -27,7 +27,11 @@
 import java.util.Map;
 
 /**
- * Alternative to a MockContentResolver that falls back to real providers.
+ * A version of ContentResolver that allows easy mocking of providers.
+ * By default it acts as a normal ContentResolver and returns all the
+ * same providers.
+ * @see #addProvider(String, ContentProvider)
+ * @see #setFallbackToExisting(boolean)
  */
 public class TestableContentResolver extends ContentResolver {
 
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index 630a287..498d517 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -43,6 +43,7 @@
  * <ul>
  * <li>System services can be mocked out with {@link #addMockSystemService}</li>
  * <li>Service binding can be mocked out with {@link #addMockService}</li>
+ * <li>Resources can be mocked out using {@link #getOrCreateTestableResources()}</li>
  * <li>Settings support {@link TestableSettingsProvider}</li>
  * <li>Has support for {@link LeakCheck} for services and receivers</li>
  * </ul>
@@ -50,10 +51,8 @@
  * <p>TestableContext should be defined as a rule on your test so it can clean up after itself.
  * Like the following:</p>
  * <pre class="prettyprint">
- * {@literal
- * @Rule
+ * &#064;Rule
  * private final TestableContext mContext = new TestableContext(InstrumentationRegister.getContext());
- * }
  * </pre>
  */
 public class TestableContext extends ContextWrapper implements TestRule {
@@ -69,6 +68,7 @@
     private LeakCheck.Tracker mReceiver;
     private LeakCheck.Tracker mService;
     private LeakCheck.Tracker mComponent;
+    private TestableResources mTestableResources;
 
     public TestableContext(Context base) {
         this(base, null);
@@ -98,25 +98,59 @@
         return super.getPackageManager();
     }
 
-    @Override
-    public Resources getResources() {
-        return super.getResources();
+    /**
+     * Makes sure the resources being returned by this TestableContext are a version of
+     * TestableResources.
+     * @see #getResources()
+     */
+    public void ensureTestableResources() {
+        if (mTestableResources == null) {
+            mTestableResources = new TestableResources(super.getResources());
+        }
     }
 
+    /**
+     * Get (and create if necessary) {@link TestableResources} for this TestableContext.
+     */
+    public TestableResources getOrCreateTestableResources() {
+        ensureTestableResources();
+        return mTestableResources;
+    }
+
+    /**
+     * Returns a Resources instance for the test.
+     *
+     * By default this returns the same resources object that would come from the
+     * {@link ContextWrapper}, but if {@link #ensureTestableResources()} or
+     * {@link #getOrCreateTestableResources()} has been called, it will return resources gotten from
+     * {@link TestableResources}.
+     */
+    @Override
+    public Resources getResources() {
+        return mTestableResources != null ? mTestableResources.getResources()
+                : super.getResources();
+    }
+
+    /**
+     * @see #getSystemService(String)
+     */
     public <T> void addMockSystemService(Class<T> service, T mock) {
         addMockSystemService(getSystemServiceName(service), mock);
     }
 
+    /**
+     * @see #getSystemService(String)
+     */
     public void addMockSystemService(String name, Object service) {
         if (mMockSystemServices == null) mMockSystemServices = new ArrayMap<>();
         mMockSystemServices.put(name, service);
     }
 
-    public void addMockService(ComponentName component, IBinder service) {
-        if (mMockServices == null) mMockServices = new ArrayMap<>();
-        mMockServices.put(component, service);
-    }
-
+    /**
+     * If a matching mock service has been added through {@link #addMockSystemService} then
+     * that will be returned, otherwise the real service will be acquired from the base
+     * context.
+     */
     @Override
     public Object getSystemService(String name) {
         if (mMockSystemServices != null && mMockSystemServices.containsKey(name)) {
@@ -137,6 +171,10 @@
         return mTestableContentResolver;
     }
 
+    /**
+     * Will always return itself for a TestableContext to ensure the testable effects extend
+     * to the application context.
+     */
     @Override
     public Context getApplicationContext() {
         // Return this so its always a TestableContext.
@@ -170,6 +208,24 @@
         super.unregisterReceiver(receiver);
     }
 
+    /**
+     * Adds a mock service to be connected to by a bindService call.
+     * <p>
+     *     Normally a TestableContext will pass through all bind requests to the base context
+     *     but when addMockService has been called for a ComponentName being bound, then
+     *     TestableContext will immediately trigger a {@link ServiceConnection#onServiceConnected}
+     *     with the specified service, and will call {@link ServiceConnection#onServiceDisconnected}
+     *     when the service is unbound.
+     * </p>
+     */
+    public void addMockService(ComponentName component, IBinder service) {
+        if (mMockServices == null) mMockServices = new ArrayMap<>();
+        mMockServices.put(component, service);
+    }
+
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
         if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
@@ -177,6 +233,9 @@
         return super.bindService(service, conn, flags);
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             Handler handler, UserHandle user) {
@@ -185,6 +244,9 @@
         return super.bindServiceAsUser(service, conn, flags, handler, user);
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             UserHandle user) {
@@ -203,6 +265,9 @@
         return false;
     }
 
+    /**
+     * @see #addMockService(ComponentName, IBinder)
+     */
     @Override
     public void unbindService(ServiceConnection conn) {
         if (mService != null) mService.getLeakInfo(conn).clearAllocations();
@@ -214,6 +279,13 @@
         super.unbindService(conn);
     }
 
+    /**
+     * Check if the TestableContext has a mock binding for a specified component. Will return
+     * true between {@link ServiceConnection#onServiceConnected} and
+     * {@link ServiceConnection#onServiceDisconnected} callbacks for a mock service.
+     *
+     * @see #addMockService(ComponentName, IBinder)
+     */
     public boolean isBound(ComponentName component) {
         return mActiveServices != null && mActiveServices.containsValue(component);
     }
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
new file mode 100644
index 0000000..93fed85
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -0,0 +1,181 @@
+/*
+ * 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.testing;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.TestLooperManager;
+import android.support.test.runner.AndroidJUnitRunner;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Wrapper around instrumentation that spins up a TestLooperManager around
+ * the main looper whenever a test is not using it to attempt to stop crashes
+ * from stopping other tests from running.
+ */
+public class TestableInstrumentation extends AndroidJUnitRunner {
+
+    private static final String TAG = "TestableInstrumentation";
+
+    private static final int MAX_CRASHES = 5;
+    private static MainLooperManager sManager;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        sManager = new MainLooperManager();
+        Log.setWtfHandler((tag, what, system) -> {
+            if (system) {
+                Log.e(TAG, "WTF!!", what);
+            } else {
+                // These normally kill the app, but we don't want that in a test, instead we want
+                // it to throw.
+                throw new RuntimeException(what);
+            }
+        });
+        super.onCreate(arguments);
+    }
+
+    @Override
+    public void finish(int resultCode, Bundle results) {
+        sManager.destroy();
+        super.finish(resultCode, results);
+    }
+
+    public static void acquireMain() {
+        if (sManager != null) {
+            sManager.acquireMain();
+        }
+    }
+
+    public static void releaseMain() {
+        if (sManager != null) {
+            sManager.releaseMain();
+        }
+    }
+
+    public class MainLooperManager implements Runnable {
+
+        private final ArrayList<Throwable> mExceptions = new ArrayList<>();
+        private Message mStopMessage;
+        private final Handler mMainHandler;
+        private TestLooperManager mManager;
+
+        public MainLooperManager() {
+            mMainHandler = new Handler(Looper.getMainLooper());
+            startManaging();
+        }
+
+        @Override
+        public void run() {
+            try {
+                synchronized (this) {
+                    // Let the thing starting us know we are up and ready to run.
+                    notify();
+                }
+                while (true) {
+                    Message m = mManager.next();
+                    if (m == mStopMessage) {
+                        mManager.recycle(m);
+                        return;
+                    }
+                    try {
+                        mManager.execute(m);
+                    } catch (Throwable t) {
+                        if (!checkStack(t) || (mExceptions.size() == MAX_CRASHES)) {
+                            throw t;
+                        }
+                        mExceptions.add(t);
+                        Log.d(TAG, "Ignoring exception to run more tests", t);
+                    }
+                    mManager.recycle(m);
+                }
+            } finally {
+                mManager.release();
+                synchronized (this) {
+                    // Let the caller know we are done managing the main thread.
+                    notify();
+                }
+            }
+        }
+
+        private boolean checkStack(Throwable t) {
+            StackTraceElement topStack = t.getStackTrace()[0];
+            String className = topStack.getClassName();
+            if (className.equals(TestLooperManager.class.getName())) {
+                topStack = t.getCause().getStackTrace()[0];
+                className = topStack.getClassName();
+            }
+            // Only interested in blocking exceptions from the app itself, not from android
+            // framework.
+            return !className.startsWith("android.")
+                    && !className.startsWith("com.android.internal");
+        }
+
+        public void destroy() {
+            mStopMessage.sendToTarget();
+            if (mExceptions.size() != 0) {
+                throw new RuntimeException("Exception caught during tests", mExceptions.get(0));
+            }
+        }
+
+        public void acquireMain() {
+            synchronized (this) {
+                mStopMessage.sendToTarget();
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        public void releaseMain() {
+            startManaging();
+        }
+
+        private void startManaging() {
+            mStopMessage = mMainHandler.obtainMessage();
+            synchronized (this) {
+                mManager = acquireLooperManager(Looper.getMainLooper());
+                // This bit needs to happen on a background thread or it will hang if called
+                // from the same thread we are looking to block.
+                new Thread(() -> {
+                    // Post a message to the main handler that will manage executing all future
+                    // messages.
+                    mMainHandler.post(this);
+                    while (!mManager.hasMessages(mMainHandler, null, this));
+                    // Lastly run the message that executes this so it can manage the main thread.
+                    Message next = mManager.next();
+                    // Run through messages until we reach ours.
+                    while (next.getCallback() != this) {
+                        mManager.execute(next);
+                        mManager.recycle(next);
+                        next = mManager.next();
+                    }
+                    mManager.execute(next);
+                }).start();
+                if (Looper.myLooper() != Looper.getMainLooper()) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index 9eddc51..f1a7092 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -29,20 +29,18 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Field;
 import java.util.Map;
 
 /**
- * Creates a looper on the current thread with control over if/when messages are
- * executed. Warning: This class works through some reflection and may break/need
- * to be updated from time to time.
+ * This is a wrapper around {@link TestLooperManager} to make it easier to manage
+ * and provide an easy annotation for use with tests.
+ *
+ * @see TestableLooperTest TestableLooperTest for examples.
  */
 public class TestableLooper {
 
     private Looper mLooper;
     private MessageQueue mQueue;
-    private boolean mMain;
-    private Object mOriginalMain;
     private MessageHandler mMessageHandler;
 
     private Handler mHandler;
@@ -50,7 +48,7 @@
     private TestLooperManager mQueueWrapper;
 
     public TestableLooper(Looper l) throws Exception {
-        this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l);
+        this(acquireLooperManager(l), l);
     }
 
     private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
@@ -72,35 +70,23 @@
         mHandler = new Handler(mLooper);
     }
 
-    public void setAsMainLooper() throws NoSuchFieldException, IllegalAccessException {
-        mMain = true;
-        setAsMainInt();
-    }
-
-    private void setAsMainInt() throws NoSuchFieldException, IllegalAccessException {
-        Field field = mLooper.getClass().getDeclaredField("sMainLooper");
-        field.setAccessible(true);
-        if (mOriginalMain == null) {
-            mOriginalMain = field.get(null);
-        }
-        field.set(null, mLooper);
-    }
-
     /**
-     * Must be called if setAsMainLooper is called to restore the main looper when the
-     * test is complete, otherwise the main looper will not be available for any subsequent
-     * tests.
+     * Must be called to release the looper when the test is complete, otherwise
+     * the looper will not be available for any subsequent tests. This is
+     * automatically handled for tests using {@link RunWithLooper}.
      */
     public void destroy() throws NoSuchFieldException, IllegalAccessException {
         mQueueWrapper.release();
-        if (mMain && mOriginalMain != null) {
-            Field field = mLooper.getClass().getDeclaredField("sMainLooper");
-            field.setAccessible(true);
-            field.set(null, mOriginalMain);
-            mOriginalMain = null;
+        if (mLooper == Looper.getMainLooper()) {
+            TestableInstrumentation.releaseMain();
         }
     }
 
+    /**
+     * Sets a callback for all messages processed on this TestableLooper.
+     *
+     * @see {@link MessageHandler}
+     */
     public void setMessageHandler(MessageHandler handler) {
         mMessageHandler = handler;
     }
@@ -119,6 +105,9 @@
         return num;
     }
 
+    /**
+     * Process messages in the queue until no more are found.
+     */
     public void processAllMessages() {
         while (processQueuedMessages() != 0) ;
     }
@@ -183,6 +172,11 @@
         void run() throws Exception;
     }
 
+    /**
+     * Annotation that tells the {@link AndroidTestingRunner} to create a TestableLooper and
+     * run this test/class on that thread. The {@link TestableLooper} can be acquired using
+     * {@link #get(Object)}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.METHOD, ElementType.TYPE})
     public @interface RunWithLooper {
@@ -204,13 +198,24 @@
         }
     }
 
+    private static TestLooperManager acquireLooperManager(Looper l) {
+        if (l == Looper.getMainLooper()) {
+            TestableInstrumentation.acquireMain();
+        }
+        return InstrumentationRegistry.getInstrumentation().acquireLooperManager(l);
+    }
+
     private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>();
 
+    /**
+     * For use with {@link RunWithLooper}, used to get the TestableLooper that was
+     * automatically created for this test.
+     */
     public static TestableLooper get(Object test) {
         return sLoopers.get(test);
     }
 
-    public static class LooperFrameworkMethod extends FrameworkMethod {
+    static class LooperFrameworkMethod extends FrameworkMethod {
         private HandlerThread mHandlerThread;
 
         private final TestableLooper mTestableLooper;
@@ -251,8 +256,7 @@
             }
             boolean set = mTestableLooper.mQueueWrapper == null;
             if (set) {
-                mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation()
-                        .acquireLooperManager(mLooper);
+                mTestableLooper.mQueueWrapper = acquireLooperManager(mLooper);
             }
             try {
                 Object[] ret = new Object[1];
@@ -287,6 +291,9 @@
                 if (set) {
                     mTestableLooper.mQueueWrapper.release();
                     mTestableLooper.mQueueWrapper = null;
+                    if (mLooper == Looper.getMainLooper()) {
+                        TestableInstrumentation.releaseMain();
+                    }
                 }
             }
         }
@@ -319,6 +326,11 @@
         }
     }
 
+    /**
+     * Callback to control the execution of messages on the looper, when set with
+     * {@link #setMessageHandler(MessageHandler)} then {@link #onMessageHandled(Message)}
+     * will get called back for every message processed on the {@link TestableLooper}.
+     */
     public interface MessageHandler {
         /**
          * Return true to have the message executed and delivered to target.
diff --git a/tests/testables/src/android/testing/TestableResources.java b/tests/testables/src/android/testing/TestableResources.java
new file mode 100644
index 0000000..a2fa95d
--- /dev/null
+++ b/tests/testables/src/android/testing/TestableResources.java
@@ -0,0 +1,101 @@
+/*
+ * 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.testing;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+import android.util.SparseArray;
+
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Provides a version of Resources that defaults to all existing resources, but can have ids
+ * changed to return specific values.
+ * <p>
+ * TestableResources are lazily initialized, be sure to call
+ * {@link TestableContext#ensureTestableResources} before your tested code has an opportunity
+ * to cache {@link Context#getResources}.
+ * </p>
+ */
+public class TestableResources {
+
+    private static final String TAG = "TestableResources";
+    private final Resources mResources;
+    private final SparseArray<Object> mOverrides = new SparseArray<>();
+
+    TestableResources(Resources realResources) {
+        mResources = mock(Resources.class, withSettings()
+                .spiedInstance(realResources)
+                .defaultAnswer(this::answer));
+    }
+
+    /**
+     * Gets the implementation of Resources that will return overridden values when called.
+     */
+    public Resources getResources() {
+        return mResources;
+    }
+
+    /**
+     * Sets the return value for the specified resource id.
+     * <p>
+     * Since resource ids are unique there is a single addOverride that will override the value
+     * whenever it is gotten regardless of which method is used (i.e. getColor or getDrawable).
+     * </p>
+     * @param id The resource id to be overridden
+     * @param value The value of the resource, null to cause a {@link Resources.NotFoundException}
+     *              when gotten.
+     */
+    public void addOverride(int id, Object value) {
+        mOverrides.put(id, value);
+    }
+
+    /**
+     * Removes the override for the specified id.
+     * <p>
+     * This should be called over addOverride(id, null), because specifying a null value will
+     * cause a {@link Resources.NotFoundException} whereas removing the override will actually
+     * switch back to returning the default/real value of the resource.
+     * </p>
+     * @param id
+     */
+    public void removeOverride(int id) {
+        mOverrides.remove(id);
+    }
+
+    private Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+        try {
+            int id = invocationOnMock.getArgument(0);
+            int index = mOverrides.indexOfKey(id);
+            if (index >= 0) {
+                Object value = mOverrides.valueAt(index);
+                if (value == null) throw new Resources.NotFoundException();
+                return value;
+            }
+        } catch (Resources.NotFoundException e) {
+            // Let through NotFoundException.
+            throw e;
+        } catch (Throwable t) {
+            // Generic catching for the many things that can go wrong, fall back to
+            // the real implementation.
+            Log.i(TAG, "Falling back to default resources call " + t);
+        }
+        return invocationOnMock.callRealMethod();
+    }
+}
diff --git a/tests/testables/src/android/testing/UiThreadTest.java b/tests/testables/src/android/testing/UiThreadTest.java
index e40e1d7..32a5824 100644
--- a/tests/testables/src/android/testing/UiThreadTest.java
+++ b/tests/testables/src/android/testing/UiThreadTest.java
@@ -20,8 +20,8 @@
 import java.lang.annotation.Target;
 
 /**
- * When applied to a class, all tests, befores, and afters will behave as if
- * they have @UiThreadTest applied to them.
+ * When applied to a class, all {@link org.junit.Test}s, {@link org.junit.After}s, and
+ * {@link org.junit.Before} will behave as if they have @UiThreadTest applied to them.
  */
 @Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/tests/testables/src/android/testing/ViewUtils.java b/tests/testables/src/android/testing/ViewUtils.java
index fca44ae..1c6016e 100644
--- a/tests/testables/src/android/testing/ViewUtils.java
+++ b/tests/testables/src/android/testing/ViewUtils.java
@@ -21,8 +21,16 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
+/**
+ * Utilities to make testing views easier.
+ */
 public class ViewUtils {
 
+    /**
+     * Causes the view (and its children) to have {@link View#onAttachedToWindow()} called.
+     *
+     * This is currently done by adding the view to a window.
+     */
     public static void attachView(View view) {
         // Make sure hardware acceleration isn't turned on.
         view.getContext().getApplicationInfo().flags &=
@@ -34,6 +42,11 @@
         view.getContext().getSystemService(WindowManager.class).addView(view, lp);
     }
 
+    /**
+     * Causes the view (and its children) to have {@link View#onDetachedFromWindow()} called.
+     *
+     * This is currently done by removing the view from a window.
+     */
     public static void detachView(View view) {
         view.getContext().getSystemService(WindowManager.class).removeViewImmediate(view);
     }
diff --git a/tests/testables/tests/Android.mk b/tests/testables/tests/Android.mk
index a123d80..16fe535 100644
--- a/tests/testables/tests/Android.mk
+++ b/tests/testables/tests/Android.mk
@@ -18,7 +18,7 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_PACKAGE_NAME := TestablesTest
+LOCAL_PACKAGE_NAME := TestablesTests
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, src)
diff --git a/tests/testables/tests/res/values/strings.xml b/tests/testables/tests/res/values/strings.xml
new file mode 100644
index 0000000..1ad0ade
--- /dev/null
+++ b/tests/testables/tests/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="test_string">This is a test string</string>
+</resources>
diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java
index 12f1d0a..13e72ba 100644
--- a/tests/testables/tests/src/android/testing/TestableLooperTest.java
+++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java
@@ -31,9 +31,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 
+@SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class TestableLooperTest {
diff --git a/tests/testables/tests/src/android/testing/TestableResourcesTest.java b/tests/testables/tests/src/android/testing/TestableResourcesTest.java
new file mode 100644
index 0000000..dc7cf95
--- /dev/null
+++ b/tests/testables/tests/src/android/testing/TestableResourcesTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.testing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import android.content.res.Resources;
+import android.support.test.InstrumentationRegistry;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.testables.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class TestableResourcesTest {
+
+    @Rule
+    public TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext());
+
+    @Test
+    public void testLazyInit() {
+        Resources before = mContext.getResources();
+        mContext.ensureTestableResources();
+        Resources after = mContext.getResources();
+        assertNotEquals(before, after);
+    }
+
+    @Test
+    public void testAddingResource() {
+        final int nonExistentId = 3; // Ids don't go this low.
+
+        try {
+            mContext.getColor(nonExistentId);
+            fail("Should throw NotFoundException");
+        } catch (Resources.NotFoundException e) {
+        }
+        mContext.getOrCreateTestableResources().addOverride(nonExistentId, 0xffffff);
+
+        assertEquals(0xffffff, mContext.getColor(nonExistentId));
+    }
+
+    @Test
+    public void testClearingResource() {
+        final int nonExistentId = 3; // Ids don't go this low.
+
+        mContext.getOrCreateTestableResources().addOverride(nonExistentId, 0xffffff);
+        assertEquals(0xffffff, mContext.getColor(nonExistentId));
+        mContext.getOrCreateTestableResources().removeOverride(nonExistentId);
+        try {
+            mContext.getColor(nonExistentId);
+            fail("Should throw NotFoundException");
+        } catch (Resources.NotFoundException e) {
+        }
+    }
+
+    @Test
+    public void testOverrideExisting() {
+        int existentId = R.string.test_string;
+
+        assertNotNull(mContext.getString(existentId));
+        mContext.getOrCreateTestableResources().addOverride(existentId, "Other strings");
+
+        assertEquals("Other strings", mContext.getString(existentId));
+    }
+
+    @Test(expected = Resources.NotFoundException.class)
+    public void testNonExistentException() {
+        int existentId = R.string.test_string;
+
+        assertNotNull(mContext.getString(existentId));
+        mContext.getOrCreateTestableResources().addOverride(existentId, null);
+
+        assertNull(mContext.getString(existentId));
+    }
+}
diff --git a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
index 0e2cc57..ac61deb 100644
--- a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
+++ b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java
@@ -20,6 +20,7 @@
 import android.provider.Settings.Secure;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -27,6 +28,7 @@
 
 import static org.junit.Assert.*;
 
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class TestableSettingsProviderTest {
 
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
index 8ca849b..e482708 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
+++ b/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
@@ -54,7 +54,8 @@
  * Note that this class cannot be used in the same process as real settings. This is because it
  * works by passing an alternate ContentResolver to Settings operations. Unfortunately, the Settings
  * class only fetches the content provider from the passed-in ContentResolver the first time it's
- * used, and after that stores it in a per-process static.
+ * used, and after that stores it in a per-process static. If this needs to be used in this case,
+ * then call {@link #clearSettingsProvider()} before and after using this.
  *
  * TODO: evaluate implementing settings change notifications. This would require:
  *
@@ -90,6 +91,15 @@
         }
     }
 
+    /**
+     * This needs to be called before and after using the FakeSettingsProvider class.
+     */
+    public static void clearSettingsProvider() {
+        Settings.Secure.clearProviderForTest();
+        Settings.Global.clearProviderForTest();
+        Settings.System.clearProviderForTest();
+    }
+
     public Bundle call(String method, String arg, Bundle extras) {
         // Methods are "GET_system", "GET_global", "PUT_secure", etc.
         String[] commands = method.split("_", 2);
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 353c3e0..046de46 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -80,6 +80,7 @@
         "compile/PseudolocaleGenerator.cpp",
         "compile/Pseudolocalizer.cpp",
         "compile/XmlIdCollector.cpp",
+        "configuration/ConfigurationParser.cpp",
         "filter/ConfigFilter.cpp",
         "flatten/Archive.cpp",
         "flatten/TableFlattener.cpp",
@@ -155,8 +156,14 @@
 // ==========================================================
 cc_test_host {
     name: "aapt2_tests",
-    srcs: ["test/Common.cpp", "**/*_test.cpp"],
-    static_libs: ["libaapt2", "libgmock"],
+    srcs: [
+        "test/Common.cpp",
+        "**/*_test.cpp",
+    ],
+    static_libs: [
+        "libaapt2",
+        "libgmock",
+    ],
     defaults: ["aapt2_defaults"],
 }
 
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index 46098cb..7ff0c72 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -877,7 +877,16 @@
 }
 
 bool ConfigDescription::Dominates(const ConfigDescription& o) const {
-  if (*this == DefaultConfig() || *this == o) {
+  if (*this == o) {
+    return true;
+  }
+
+  // Locale de-duping is not-trivial, disable for now (b/62409213).
+  if (diff(o) & CONFIG_LOCALE) {
+    return false;
+  }
+
+  if (*this == DefaultConfig()) {
     return true;
   }
   return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index e89c6be..efc523f 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -69,14 +69,12 @@
 TEST(DominatorTreeTest, DefaultDominatesEverything) {
   const ConfigDescription default_config = {};
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
-  const ConfigDescription sw600dp_land_config =
-      test::ParseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
   configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -91,16 +89,13 @@
 TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
   const ConfigDescription default_config = {};
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
-  const ConfigDescription sw600dp_land_config =
-      test::ParseConfigOrDie("sw600dp-land-v13");
+  const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
   configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(default_config, "phablet"));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
+  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "phablet"));
+  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
 
   DominatorTree tree(configs);
   PrettyPrinter printer;
@@ -118,16 +113,11 @@
   const ConfigDescription en_config = test::ParseConfigOrDie("en");
   const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
   const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
-  const ConfigDescription ldrtl_xhdpi_config =
-      test::ParseConfigOrDie("ldrtl-xhdpi-v4");
-  const ConfigDescription sw300dp_config =
-      test::ParseConfigOrDie("sw300dp-v13");
-  const ConfigDescription sw540dp_config =
-      test::ParseConfigOrDie("sw540dp-v14");
-  const ConfigDescription sw600dp_config =
-      test::ParseConfigOrDie("sw600dp-v14");
-  const ConfigDescription sw720dp_config =
-      test::ParseConfigOrDie("sw720dp-v13");
+  const ConfigDescription ldrtl_xhdpi_config = test::ParseConfigOrDie("ldrtl-xhdpi-v4");
+  const ConfigDescription sw300dp_config = test::ParseConfigOrDie("sw300dp-v13");
+  const ConfigDescription sw540dp_config = test::ParseConfigOrDie("sw540dp-v14");
+  const ConfigDescription sw600dp_config = test::ParseConfigOrDie("sw600dp-v14");
+  const ConfigDescription sw720dp_config = test::ParseConfigOrDie("sw720dp-v13");
   const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
 
   std::vector<std::unique_ptr<ResourceConfigValue>> configs;
@@ -135,8 +125,7 @@
   configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
-  configs.push_back(
-      util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
   configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
@@ -148,15 +137,37 @@
 
   std::string expected =
       "<default>\n"
-      "  en\n"
-      "    en-v21\n"
       "  ldrtl-v4\n"
       "    ldrtl-xhdpi-v4\n"
       "  sw300dp-v13\n"
       "    sw540dp-v14\n"
       "      sw600dp-v14\n"
       "    sw720dp-v13\n"
-      "  v20\n";
+      "  v20\n"
+      "en\n"
+      "  en-v21\n";
+  EXPECT_EQ(expected, printer.ToString(&tree));
+}
+
+TEST(DominatorTreeTest, LocalesAreNeverDominated) {
+  const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+  const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+  const ConfigDescription fr_rFR_config = test::ParseConfigOrDie("fr-rFR");
+
+  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
+  configs.push_back(util::make_unique<ResourceConfigValue>(ConfigDescription::DefaultConfig(), ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_rCA_config, ""));
+  configs.push_back(util::make_unique<ResourceConfigValue>(fr_rFR_config, ""));
+
+  DominatorTree tree(configs);
+  PrettyPrinter printer;
+
+  std::string expected =
+      "<default>\n"
+      "fr\n"
+      "fr-rCA\n"
+      "fr-rFR\n";
   EXPECT_EQ(expected, printer.ToString(&tree));
 }
 
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 5352ca8..c6382b1 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -843,4 +843,9 @@
   EXPECT_THAT(*str->value, Eq(""));
 }
 
+TEST_F(ResourceParserTest, ParsePlatformIndependentNewline) {
+  std::string input = R"(<string name="foo">%1$s %n %2$s</string>)";
+  ASSERT_TRUE(TestParse(input));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index e09a3979..b64cd8c 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -145,7 +145,7 @@
   const std::string& root_dir = options.res_dir.value();
   std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
   if (!d) {
-    context->GetDiagnostics()->Error(DiagMessage()
+    context->GetDiagnostics()->Error(DiagMessage(root_dir) << "failed to open directory: "
                                      << android::base::SystemErrorCodeToString(errno));
     return false;
   }
@@ -164,7 +164,7 @@
 
     std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
     if (!subdir) {
-      context->GetDiagnostics()->Error(DiagMessage()
+      context->GetDiagnostics()->Error(DiagMessage(prefix_path) << "failed to open directory: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -180,7 +180,7 @@
       std::string err_str;
       Maybe<ResourcePathData> path_data = ExtractResourcePathData(full_path, &err_str);
       if (!path_data) {
-        context->GetDiagnostics()->Error(DiagMessage() << err_str);
+        context->GetDiagnostics()->Error(DiagMessage(full_path) << err_str);
         return false;
       }
 
@@ -198,6 +198,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -395,6 +396,7 @@
     std::ifstream fin(path_data.source.path, std::ifstream::binary);
     if (!fin) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
@@ -481,6 +483,7 @@
     if (!android::base::ReadFileToString(path_data.source.path, &content,
                                          true /*follow_symlinks*/)) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
+                                       << "failed to open file: "
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
     }
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 57c4574..aa94723 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -31,21 +31,22 @@
 
 namespace aapt {
 
-void DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
+bool DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
                       const Source& source, IAaptContext* context) {
   std::unique_ptr<ResourceFile> file =
       DeserializeCompiledFileFromPb(pb_file, source, context->GetDiagnostics());
   if (!file) {
     context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-    return;
+    return false;
   }
 
   std::cout << "Resource: " << file->name << "\n"
             << "Config:   " << file->config << "\n"
             << "Source:   " << file->source << "\n";
+  return true;
 }
 
-void TryDumpFile(IAaptContext* context, const std::string& file_path) {
+bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
   std::unique_ptr<ResourceTable> table;
 
   std::string err;
@@ -57,18 +58,18 @@
       if (!data) {
         context->GetDiagnostics()->Error(DiagMessage(file_path)
                                          << "failed to open resources.arsc.flat");
-        return;
+        return false;
       }
 
       pb::ResourceTable pb_table;
       if (!pb_table.ParseFromArray(data->data(), data->size())) {
         context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat");
-        return;
+        return false;
       }
 
       table = DeserializeTableFromPb(pb_table, Source(file_path), context->GetDiagnostics());
       if (!table) {
-        return;
+        return false;
       }
     }
 
@@ -79,14 +80,14 @@
         if (!data) {
           context->GetDiagnostics()->Error(DiagMessage(file_path)
                                            << "failed to open resources.arsc");
-          return;
+          return false;
         }
 
         table = util::make_unique<ResourceTable>();
         BinaryResourceParser parser(context, table.get(), Source(file_path), data->data(),
                                     data->size());
         if (!parser.Parse()) {
-          return;
+          return false;
         }
       }
     }
@@ -96,7 +97,7 @@
     Maybe<android::FileMap> file = file::MmapPath(file_path, &err);
     if (!file) {
       context->GetDiagnostics()->Error(DiagMessage(file_path) << err);
-      return;
+      return false;
     }
 
     android::FileMap* file_map = &file.value();
@@ -113,24 +114,26 @@
 
       uint32_t num_files = 0;
       if (!input.ReadLittleEndian32(&num_files)) {
-        return;
+        return false;
       }
 
       for (uint32_t i = 0; i < num_files; i++) {
         pb::CompiledFile compiled_file;
         if (!input.ReadCompiledFile(&compiled_file)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-          return;
+          return false;
         }
 
         uint64_t offset, len;
         if (!input.ReadDataMetaData(&offset, &len)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read meta data");
-          return;
+          return false;
         }
 
         const void* data = static_cast<const uint8_t*>(file_map->getDataPtr()) + offset;
-        DumpCompiledFile(compiled_file, data, len, Source(file_path), context);
+        if (!DumpCompiledFile(compiled_file, data, len, Source(file_path), context)) {
+          return false;
+        }
       }
     }
   }
@@ -140,6 +143,8 @@
     options.show_sources = true;
     Debug::PrintTable(table.get(), options);
   }
+
+  return true;
 }
 
 class DumpContext : public IAaptContext {
@@ -203,8 +208,11 @@
   context.SetVerbose(verbose);
 
   for (const std::string& arg : flags.GetArgs()) {
-    TryDumpFile(&context, arg);
+    if (!TryDumpFile(&context, arg)) {
+      return 1;
+    }
   }
+
   return 0;
 }
 
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index 7073c13..5af91fd 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -75,7 +75,7 @@
     window_start_ = 0;
     window_end_ = kPngSignatureSize;
   } else {
-    error_msg_ = "PNG does not start with PNG signature";
+    error_msg_ = "file does not start with PNG signature";
   }
 }
 
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index 42443d8..0346a19 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -142,19 +142,24 @@
 }
 
 std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
+  // Create a diagnostics that has the source information encoded.
+  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
+
   // Read the first 8 bytes of the file looking for the PNG signature.
   // Bail early if it does not match.
   const png_byte* signature;
   size_t buffer_size;
   if (!in->Next((const void**)&signature, &buffer_size)) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << android::base::SystemErrorCodeToString(errno));
+    if (in->HadError()) {
+      source_diag.Error(DiagMessage() << "failed to read PNG signature: " << in->GetError());
+    } else {
+      source_diag.Error(DiagMessage() << "not enough data for PNG signature");
+    }
     return {};
   }
 
   if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
-    context->GetDiagnostics()->Error(DiagMessage()
-                                     << "file signature does not match PNG signature");
+    source_diag.Error(DiagMessage() << "file signature does not match PNG signature");
     return {};
   }
 
@@ -166,21 +171,18 @@
   // version of libpng.
   png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
   if (read_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_struct");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_struct");
     return {};
   }
 
   // Create and initialize the memory for image header and data.
   png_infop info_ptr = png_create_info_struct(read_ptr);
   if (info_ptr == nullptr) {
-    context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng read png_info");
+    source_diag.Error(DiagMessage() << "failed to create libpng read png_info");
     png_destroy_read_struct(&read_ptr, nullptr, nullptr);
     return {};
   }
 
-  // Create a diagnostics that has the source information encoded.
-  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
-
   // Automatically release PNG resources at end of scope.
   PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);
 
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
new file mode 100644
index 0000000..89618d3
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -0,0 +1,432 @@
+/*
+ * 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 "configuration/ConfigurationParser.h"
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <utility>
+
+#include <android-base/logging.h>
+
+#include "ConfigDescription.h"
+#include "Diagnostics.h"
+#include "util/Util.h"
+#include "xml/XmlActionExecutor.h"
+#include "xml/XmlDom.h"
+#include "xml/XmlUtil.h"
+
+namespace aapt {
+
+namespace {
+
+using ::aapt::configuration::Abi;
+using ::aapt::configuration::AndroidManifest;
+using ::aapt::configuration::AndroidSdk;
+using ::aapt::configuration::Artifact;
+using ::aapt::configuration::Configuration;
+using ::aapt::configuration::GlTexture;
+using ::aapt::configuration::Group;
+using ::aapt::configuration::Locale;
+using ::aapt::util::TrimWhitespace;
+using ::aapt::xml::Element;
+using ::aapt::xml::FindRootElement;
+using ::aapt::xml::NodeCast;
+using ::aapt::xml::XmlActionExecutor;
+using ::aapt::xml::XmlActionExecutorPolicy;
+using ::aapt::xml::XmlNodeAction;
+
+const std::unordered_map<std::string, Abi> kAbiMap = {
+    {"armeabi", Abi::kArmeV6},
+    {"armeabi-v7a", Abi::kArmV7a},
+    {"arm64-v8a", Abi::kArm64V8a},
+    {"x86", Abi::kX86},
+    {"x86_64", Abi::kX86_64},
+    {"mips", Abi::kMips},
+    {"mips64", Abi::kMips64},
+    {"universal", Abi::kUniversal},
+};
+
+constexpr const char* kAaptXmlNs = "http://schemas.android.com/tools/aapt";
+
+/** A default noop diagnostics context. */
+class NoopDiagnostics : public IDiagnostics {
+ public:
+  void Log(Level level, DiagMessageActual& actualMsg) override {}
+};
+NoopDiagnostics noop_;
+
+std::string GetLabel(const Element* element, IDiagnostics* diag) {
+  std::string label;
+  for (const auto& attr : element->attributes) {
+    if (attr.name == "label") {
+      label = attr.value;
+      break;
+    }
+  }
+
+  if (label.empty()) {
+    diag->Error(DiagMessage() << "No label found for element " << element->name);
+  }
+  return label;
+}
+
+/** XML node visitor that removes all of the namespace URIs from the node and all children. */
+class NamespaceVisitor : public xml::Visitor {
+ public:
+  void Visit(xml::Element* node) override {
+    node->namespace_uri.clear();
+    VisitChildren(node);
+  }
+};
+
+}  // namespace
+
+ConfigurationParser::ConfigurationParser(std::string contents)
+    : contents_(std::move(contents)),
+      diag_(&noop_) {
+}
+
+Maybe<Configuration> ConfigurationParser::Parse() {
+  std::istringstream in(contents_);
+
+  auto doc = xml::Inflate(&in, diag_, Source("config.xml"));
+  if (!doc) {
+    return {};
+  }
+
+  // Strip any namespaces from the XML as the XmlActionExecutor ignores anything with a namespace.
+  auto* root = FindRootElement(doc.get());
+  if (root == nullptr) {
+    diag_->Error(DiagMessage() << "Could not find the root element in the XML document");
+    return {};
+  }
+
+  std::string& xml_ns = root->namespace_uri;
+  if (!xml_ns.empty()) {
+    if (xml_ns != kAaptXmlNs) {
+      diag_->Error(DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
+      return {};
+    }
+
+    xml_ns.clear();
+    NamespaceVisitor visitor;
+    root->Accept(&visitor);
+  }
+
+  XmlActionExecutor executor;
+  XmlNodeAction& root_action = executor["post-process"];
+  XmlNodeAction& artifacts_action = root_action["artifacts"];
+  XmlNodeAction& groups_action = root_action["groups"];
+
+  Configuration config;
+
+  // Helper to bind a static method to an action handler in the DOM executor.
+  auto bind_handler = [&config](std::function<bool(Configuration*, Element*, IDiagnostics*)> h)
+      -> XmlNodeAction::ActionFuncWithDiag {
+    return std::bind(h, &config, std::placeholders::_1, std::placeholders::_2);
+  };
+
+  // Parse the artifact elements.
+  artifacts_action["artifact"].Action(bind_handler(artifact_handler_));
+  artifacts_action["artifact-format"].Action(bind_handler(artifact_format_handler_));
+
+  // Parse the different configuration groups.
+  groups_action["abi-group"].Action(bind_handler(abi_group_handler_));
+  groups_action["screen-density-group"].Action(bind_handler(screen_density_group_handler_));
+  groups_action["locale-group"].Action(bind_handler(locale_group_handler_));
+  groups_action["android-sdk-group"].Action(bind_handler(android_sdk_group_handler_));
+  groups_action["gl-texture-group"].Action(bind_handler(gl_texture_group_handler_));
+  groups_action["device-feature-group"].Action(bind_handler(device_feature_group_handler_));
+
+  if (!executor.Execute(XmlActionExecutorPolicy::kNone, diag_, doc.get())) {
+    diag_->Error(DiagMessage() << "Could not process XML document");
+    return {};
+  }
+
+  return {config};
+}
+
+ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      Artifact artifact{};
+      for (const auto& attr : root_element->attributes) {
+        if (attr.name == "name") {
+          artifact.name = attr.value;
+        } else if (attr.name == "abi-group") {
+          artifact.abi_group = {attr.value};
+        } else if (attr.name == "screen-density-group") {
+          artifact.screen_density_group = {attr.value};
+        } else if (attr.name == "locale-group") {
+          artifact.locale_group = {attr.value};
+        } else if (attr.name == "android-sdk-group") {
+          artifact.android_sdk_group = {attr.value};
+        } else if (attr.name == "gl-texture-group") {
+          artifact.gl_texture_group = {attr.value};
+        } else if (attr.name == "device-feature-group") {
+          artifact.device_feature_group = {attr.value};
+        } else {
+          diag->Note(
+              DiagMessage() << "Unknown artifact attribute: " << attr.name << " = " << attr.value);
+        }
+      }
+      config->artifacts[artifact.name] = artifact;
+      return true;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      for (auto& node : root_element->children) {
+        xml::Text* t;
+        if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+          config->artifact_format = TrimWhitespace(t->text).to_string();
+          break;
+        }
+      }
+      return true;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->abi_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "abi") {
+          diag->Error(
+              DiagMessage() << "Unexpected element in ABI group: " << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              group.push_back(kAbiMap.at(TrimWhitespace(t->text).to_string()));
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->screen_density_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "screen-density") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in screen density group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              ConfigDescription config_descriptor;
+              const android::StringPiece& text = TrimWhitespace(t->text);
+              if (ConfigDescription::Parse(text, &config_descriptor)) {
+                // Copy the density with the minimum SDK version stripped out.
+                group.push_back(config_descriptor.CopyWithoutSdkVersion());
+              } else {
+                diag->Error(
+                    DiagMessage() << "Could not parse config descriptor for screen-density: "
+                                  << text);
+                valid = false;
+              }
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->locale_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "locale") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in screen density group: "
+                            << child->name);
+          valid = false;
+        } else {
+          Locale entry;
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "lang") {
+              entry.lang = {attr.value};
+            } else if (attr.name == "region") {
+              entry.region = {attr.value};
+            } else {
+              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
+                                       << " = " << attr.value);
+            }
+          }
+          group.push_back(entry);
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->android_sdk_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "android-sdk") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
+          valid = false;
+        } else {
+          AndroidSdk entry;
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "minSdkVersion") {
+              entry.min_sdk_version = {attr.value};
+            } else if (attr.name == "targetSdkVersion") {
+              entry.target_sdk_version = {attr.value};
+            } else if (attr.name == "maxSdkVersion") {
+              entry.max_sdk_version = {attr.value};
+            } else {
+              diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
+                                       << " = " << attr.value);
+            }
+          }
+
+          // TODO: Fill in the manifest details when they are finalised.
+          for (auto node : child->GetChildElements()) {
+            if (node->name == "manifest") {
+              if (entry.manifest) {
+                diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
+                continue;
+              }
+              entry.manifest = {AndroidManifest()};
+            }
+          }
+
+          group.push_back(entry);
+        }
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->gl_texture_groups[label];
+      bool valid = true;
+
+      GlTexture result;
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "gl-texture") {
+          diag->Error(
+              DiagMessage() << "Unexpected element in GL texture group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (const auto& attr : child->attributes) {
+            if (attr.name == "name") {
+              result.name = attr.value;
+              break;
+            }
+          }
+
+          for (auto* element : child->GetChildElements()) {
+            if (element->name != "texture-path") {
+              diag->Error(
+                  DiagMessage() << "Unexpected element in gl-texture element: "
+                                << child->name);
+              valid = false;
+              continue;
+            }
+            for (auto& node : element->children) {
+              xml::Text* t;
+              if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+                result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
+              }
+            }
+          }
+        }
+        group.push_back(result);
+      }
+
+      return valid;
+    };
+
+ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_handler_ =
+    [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
+      std::string label = GetLabel(root_element, diag);
+      if (label.empty()) {
+        return false;
+      }
+
+      auto& group = config->device_feature_groups[label];
+      bool valid = true;
+
+      for (auto* child : root_element->GetChildElements()) {
+        if (child->name != "supports-feature") {
+          diag->Error(
+              DiagMessage() << "Unexpected root_element in device feature group: "
+                            << child->name);
+          valid = false;
+        } else {
+          for (auto& node : child->children) {
+            xml::Text* t;
+            if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+              group.push_back(TrimWhitespace(t->text).to_string());
+              break;
+            }
+          }
+        }
+      }
+
+      return valid;
+    };
+
+}  // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
new file mode 100644
index 0000000..0fb2f71
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -0,0 +1,216 @@
+/*
+ * 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 AAPT2_CONFIGURATION_H
+#define AAPT2_CONFIGURATION_H
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <ConfigDescription.h>
+
+#include "util/Maybe.h"
+
+namespace aapt {
+
+namespace configuration {
+
+/** A mapping of group labels to group of configuration items. */
+template<class T>
+using Group = std::unordered_map<std::string, std::vector<T>>;
+
+/** Output artifact configuration options. */
+struct Artifact {
+  /** Name to use for output of processing foo.apk -> foo.<name>.apk. */
+  std::string name;
+  /** If present, uses the ABI group with this name. */
+  Maybe<std::string> abi_group;
+  /** If present, uses the screen density group with this name. */
+  Maybe<std::string> screen_density_group;
+  /** If present, uses the locale group with this name. */
+  Maybe<std::string> locale_group;
+  /** If present, uses the Android SDK group with this name. */
+  Maybe<std::string> android_sdk_group;
+  /** If present, uses the device feature group with this name. */
+  Maybe<std::string> device_feature_group;
+  /** If present, uses the OpenGL texture group with this name. */
+  Maybe<std::string> gl_texture_group;
+};
+
+/** Enumeration of currently supported ABIs. */
+enum class Abi {
+  kArmeV6,
+  kArmV7a,
+  kArm64V8a,
+  kX86,
+  kX86_64,
+  kMips,
+  kMips64,
+  kUniversal
+};
+
+/**
+ * Represents an individual locale. When a locale is included, it must be
+ * declared from least specific to most specific, as a region does not make
+ * sense without a language. If neither the language or region are specified it
+ * acts as a special case for catch all. This can allow all locales to be kept,
+ * or compressed.
+ */
+struct Locale {
+  /** The ISO<?> standard locale language code. */
+  Maybe<std::string> lang;
+  /** The ISO<?> standard locale region code. */
+  Maybe<std::string> region;
+
+  inline friend bool operator==(const Locale& lhs, const Locale& rhs) {
+    return lhs.lang == rhs.lang && lhs.region == rhs.region;
+  }
+};
+
+// TODO: Encapsulate manifest modifications from the configuration file.
+struct AndroidManifest {
+  inline friend bool operator==(const AndroidManifest& lhs, const AndroidManifest& rhs) {
+    return true;  // nothing to compare yet.
+  }
+};
+
+struct AndroidSdk {
+  Maybe<std::string> min_sdk_version;
+  Maybe<std::string> target_sdk_version;
+  Maybe<std::string> max_sdk_version;
+  Maybe<AndroidManifest> manifest;
+
+  inline friend bool operator==(const AndroidSdk& lhs, const AndroidSdk& rhs) {
+    return lhs.min_sdk_version == rhs.min_sdk_version &&
+        lhs.target_sdk_version == rhs.target_sdk_version &&
+        lhs.max_sdk_version == rhs.max_sdk_version &&
+        lhs.manifest == rhs.manifest;
+  }
+};
+
+// TODO: Make device features more than just an arbitrary string?
+using DeviceFeature = std::string;
+
+/** Represents a mapping of texture paths to a GL texture format. */
+struct GlTexture {
+  std::string name;
+  std::vector<std::string> texture_paths;
+
+  inline friend bool operator==(const GlTexture& lhs, const GlTexture& rhs) {
+    return lhs.name == rhs.name && lhs.texture_paths == rhs.texture_paths;
+  }
+};
+
+/**
+ * AAPT2 XML configuration binary representation.
+ */
+struct Configuration {
+  std::unordered_map<std::string, Artifact> artifacts;
+  Maybe<std::string> artifact_format;
+
+  Group<Abi> abi_groups;
+  Group<ConfigDescription> screen_density_groups;
+  Group<Locale> locale_groups;
+  Group<AndroidSdk> android_sdk_groups;
+  Group<DeviceFeature> device_feature_groups;
+  Group<GlTexture> gl_texture_groups;
+};
+
+}  // namespace configuration
+
+// Forward declaration of classes used in the API.
+struct IDiagnostics;
+namespace xml {
+class Element;
+}
+
+/**
+ * XML configuration file parser for the split and optimize commands.
+ */
+class ConfigurationParser {
+ public:
+  /** Returns a ConfigurationParser for the configuration in the provided file contents. */
+  static ConfigurationParser ForContents(const std::string& contents) {
+    ConfigurationParser parser{contents};
+    return parser;
+  }
+
+  /** Returns a ConfigurationParser for the file located at the provided path. */
+  static ConfigurationParser ForPath(const std::string& path) {
+    // TODO: Read XML file into memory.
+    return ForContents(path);
+  }
+
+  /** Sets the diagnostics context to use when parsing. */
+  ConfigurationParser& WithDiagnostics(IDiagnostics* diagnostics) {
+    diag_ = diagnostics;
+    return *this;
+  }
+
+  /**
+   * Parses the configuration file and returns the results. If the configuration could not be parsed
+   * the result is empty and any errors will be displayed with the provided diagnostics context.
+   */
+  Maybe<configuration::Configuration> Parse();
+
+ protected:
+  /**
+   * Instantiates a new ConfigurationParser with the provided configuration file and a no-op
+   * diagnostics context. The default diagnostics context can be overridden with a call to
+   * WithDiagnostics(IDiagnostics *).
+   */
+  explicit ConfigurationParser(std::string contents);
+
+  /** Returns the current diagnostics context to any subclasses. */
+  IDiagnostics* diagnostics() {
+    return diag_;
+  }
+
+  /**
+   * An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
+   * element was successfully processed, otherwise returns false.
+   */
+  using ActionHandler = std::function<bool(configuration::Configuration* config,
+                                           xml::Element* element,
+                                           IDiagnostics* diag)>;
+
+  /** Handler for <artifact> tags. */
+  static ActionHandler artifact_handler_;
+  /** Handler for <artifact-format> tags. */
+  static ActionHandler artifact_format_handler_;
+  /** Handler for <abi-group> tags. */
+  static ActionHandler abi_group_handler_;
+  /** Handler for <screen-density-group> tags. */
+  static ActionHandler screen_density_group_handler_;
+  /** Handler for <locale-group> tags. */
+  static ActionHandler locale_group_handler_;
+  /** Handler for <android-sdk-group> tags. */
+  static ActionHandler android_sdk_group_handler_;
+  /** Handler for <gl-texture-group> tags. */
+  static ActionHandler gl_texture_group_handler_;
+  /** Handler for <device-feature-group> tags. */
+  static ActionHandler device_feature_group_handler_;
+
+ private:
+  /** The contents of the configuration file to parse. */
+  const std::string contents_;
+  /** The diagnostics context to send messages to. */
+  IDiagnostics* diag_;
+};
+
+}  // namespace aapt
+
+#endif //AAPT2_CONFIGURATION_H
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
new file mode 100644
index 0000000..72a97b2
--- /dev/null
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -0,0 +1,401 @@
+/*
+ * 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 "configuration/ConfigurationParser.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "androidfw/ResourceTypes.h"
+
+#include "test/Test.h"
+#include "xml/XmlDom.h"
+
+namespace aapt {
+namespace {
+
+using android::ResTable_config;
+using configuration::Abi;
+using configuration::AndroidSdk;
+using configuration::Configuration;
+using configuration::DeviceFeature;
+using configuration::GlTexture;
+using configuration::Locale;
+using configuration::AndroidManifest;
+using testing::ElementsAre;
+using xml::Element;
+using xml::NodeCast;
+
+constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
+<post-process xmlns="http://schemas.android.com/tools/aapt">
+  <groups>
+    <abi-group label="arm">
+      <abi>armeabi-v7a</abi>
+      <abi>arm64-v8a</abi>
+    </abi-group>
+    <abi-group label="other">
+      <abi>x86</abi>
+      <abi>mips</abi>
+    </abi-group>
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+    <screen-density-group label="alldpi">
+      <screen-density>ldpi</screen-density>
+      <screen-density>mdpi</screen-density>
+      <screen-density>hdpi</screen-density>
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de"/>
+    </locale-group>
+    <locale-group label="north-america">
+      <locale lang="en"/>
+      <locale lang="es" region="MX"/>
+      <locale lang="fr" region="CA"/>
+    </locale-group>
+    <locale-group label="all">
+      <locale/>
+    </locale-group>
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/*</texture-path>
+      </gl-texture>
+    </gl-texture-group>
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+    </device-feature-group>
+  </groups>
+  <artifacts>
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>
+    <artifact
+        name="art1"
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+    <artifact
+        name="art2"
+        abi-group="other"
+        screen-density-group="alldpi"
+        locale-group="north-america"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+  </artifacts>
+</post-process>
+)";
+
+class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
+ public:
+  ConfigurationParserTest() : ConfigurationParser("") {}
+
+ protected:
+  StdErrDiagnostics diag_;
+};
+
+TEST_F(ConfigurationParserTest, ValidateFile) {
+  auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
+  auto result = parser.Parse();
+  ASSERT_TRUE(result);
+  Configuration& value = result.value();
+  EXPECT_EQ(2ul, value.artifacts.size());
+  ASSERT_TRUE(value.artifact_format);
+  EXPECT_EQ(
+      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
+      value.artifact_format.value()
+  );
+
+  EXPECT_EQ(2ul, value.abi_groups.size());
+  EXPECT_EQ(2ul, value.abi_groups["arm"].size());
+  EXPECT_EQ(2ul, value.abi_groups["other"].size());
+
+  EXPECT_EQ(2ul, value.screen_density_groups.size());
+  EXPECT_EQ(3ul, value.screen_density_groups["large"].size());
+  EXPECT_EQ(6ul, value.screen_density_groups["alldpi"].size());
+
+  EXPECT_EQ(3ul, value.locale_groups.size());
+  EXPECT_EQ(4ul, value.locale_groups["europe"].size());
+  EXPECT_EQ(3ul, value.locale_groups["north-america"].size());
+  EXPECT_EQ(1ul, value.locale_groups["all"].size());
+
+  EXPECT_EQ(1ul, value.android_sdk_groups.size());
+  EXPECT_EQ(1ul, value.android_sdk_groups["19"].size());
+
+  EXPECT_EQ(1ul, value.gl_texture_groups.size());
+  EXPECT_EQ(1ul, value.gl_texture_groups["dxt1"].size());
+
+  EXPECT_EQ(1ul, value.device_feature_groups.size());
+  EXPECT_EQ(1ul, value.device_feature_groups["low-latency"].size());
+}
+
+TEST_F(ConfigurationParserTest, InvalidNamespace) {
+  constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
+  <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";
+
+  auto result = ConfigurationParser::ForContents(invalid_ns).Parse();
+  ASSERT_FALSE(result);
+}
+
+TEST_F(ConfigurationParserTest, ArtifactAction) {
+  static constexpr const char* xml = R"xml(
+    <artifact
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.artifacts.size());
+
+  auto& artifact = config.artifacts.begin()->second;
+  EXPECT_EQ("", artifact.name); // TODO: make this fail.
+  EXPECT_EQ("arm", artifact.abi_group.value());
+  EXPECT_EQ("large", artifact.screen_density_group.value());
+  EXPECT_EQ("europe", artifact.locale_group.value());
+  EXPECT_EQ("19", artifact.android_sdk_group.value());
+  EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
+  EXPECT_EQ("low-latency", artifact.device_feature_group.value());
+}
+
+TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
+  static constexpr const char* xml = R"xml(
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+  ASSERT_TRUE(config.artifact_format);
+  EXPECT_EQ(
+      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
+      static_cast<std::string>(config.artifact_format.value())
+  );
+}
+
+TEST_F(ConfigurationParserTest, AbiGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <abi-group label="arm">
+      <!-- First comment. -->
+      <abi>
+        armeabi-v7a
+      </abi>
+      <!-- Another comment. -->
+      <abi>arm64-v8a</abi>
+    </abi-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.abi_groups.size());
+  ASSERT_EQ(1u, config.abi_groups.count("arm"));
+
+  auto& out = config.abi_groups["arm"];
+  ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
+}
+
+TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>
+        xxhdpi
+      </screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok =
+      screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.screen_density_groups.size());
+  ASSERT_EQ(1u, config.screen_density_groups.count("large"));
+
+  ConfigDescription xhdpi;
+  xhdpi.density = ResTable_config::DENSITY_XHIGH;
+  ConfigDescription xxhdpi;
+  xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
+  ConfigDescription xxxhdpi;
+  xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;
+
+  auto& out = config.screen_density_groups["large"];
+  ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
+}
+
+TEST_F(ConfigurationParserTest, LocaleGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de"/>
+    </locale-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  ASSERT_EQ(1ul, config.locale_groups.size());
+  ASSERT_EQ(1u, config.locale_groups.count("europe"));
+
+  auto& out = config.locale_groups["europe"];
+
+  Locale en;
+  en.lang = std::string("en");
+  Locale es;
+  es.lang = std::string("es");
+  Locale fr;
+  fr.lang = std::string("fr");
+  Locale de;
+  de.lang = std::string("de");
+
+  ASSERT_THAT(out, ElementsAre(en, es, fr, de));
+}
+
+TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  ASSERT_EQ(1ul, config.android_sdk_groups.size());
+  ASSERT_EQ(1u, config.android_sdk_groups.count("19"));
+
+  auto& out = config.android_sdk_groups["19"];
+
+  AndroidSdk sdk;
+  sdk.min_sdk_version = std::string("19");
+  sdk.target_sdk_version = std::string("24");
+  sdk.max_sdk_version = std::string("25");
+  sdk.manifest = AndroidManifest();
+
+  ASSERT_EQ(1ul, out.size());
+  ASSERT_EQ(sdk, out[0]);
+}
+
+TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/main/*</texture-path>
+        <texture-path>
+          assets/dxt1/test/*
+        </texture-path>
+      </gl-texture>
+    </gl-texture-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.gl_texture_groups.size());
+  ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));
+
+  auto& out = config.gl_texture_groups["dxt1"];
+
+  GlTexture texture{
+      std::string("GL_EXT_texture_compression_dxt1"),
+      {"assets/dxt1/main/*", "assets/dxt1/test/*"}
+  };
+
+  ASSERT_EQ(1ul, out.size());
+  ASSERT_EQ(texture, out[0]);
+}
+
+TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
+  static constexpr const char* xml = R"xml(
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+      <supports-feature>
+        android.hardware.audio.pro
+      </supports-feature>
+    </device-feature-group>)xml";
+
+  auto doc = test::BuildXmlDom(xml);
+
+  Configuration config;
+  bool ok
+      = device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
+  ASSERT_TRUE(ok);
+
+  EXPECT_EQ(1ul, config.device_feature_groups.size());
+  ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));
+
+  auto& out = config.device_feature_groups["low-latency"];
+
+  DeviceFeature low_latency = "android.hardware.audio.low_latency";
+  DeviceFeature pro = "android.hardware.audio.pro";
+  ASSERT_THAT(out, ElementsAre(low_latency, pro));
+}
+
+}  // namespace
+}  // namespace aapt
diff --git a/tools/aapt2/configuration/aapt2.xsd b/tools/aapt2/configuration/aapt2.xsd
new file mode 100644
index 0000000..47bf99e
--- /dev/null
+++ b/tools/aapt2/configuration/aapt2.xsd
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xsd:schema
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    xmlns="http://schemas.android.com/tools/aapt2"
+    targetNamespace="http://schemas.android.com/tools/aapt2">
+
+  <xsd:element name="post-process">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element name="groups" type="groups"/>
+        <xsd:element name="artifacts" type="artifacts"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="groups">
+    <xsd:sequence>
+      <xsd:element name="abi-group" type="abi-group" maxOccurs="unbounded"/>
+      <xsd:element name="screen-density-group" type="screen-density-group" maxOccurs="unbounded"/>
+      <xsd:element name="locale-group" type="locale-group" maxOccurs="unbounded"/>
+      <xsd:element name="android-sdk-group" type="android-sdk-group" maxOccurs="unbounded"/>
+      <xsd:element
+          name="gl-texture-group"
+          type="gl-texture-group"
+          maxOccurs="unbounded"/>
+      <xsd:element name="device-feature-group" type="device-feature-group" maxOccurs="unbounded"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="artifacts">
+    <xsd:sequence>
+      <xsd:element name="artifact-format" type="xsd:string"/>
+      <xsd:element name="artifact" type="artifact" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="generate-all" type="xsd:boolean"/>
+  </xsd:complexType>
+
+  <!-- Groups output artifacts together by dimension labels. -->
+  <xsd:complexType name="artifact">
+    <xsd:attribute name="name" type="xsd:string"/>
+    <xsd:attribute name="abi-group" type="xsd:string"/>
+    <xsd:attribute name="android-sdk-group" type="xsd:string"/>
+    <xsd:attribute name="device-feature-group" type="xsd:string"/>
+    <xsd:attribute name="gl-texture-group" type="xsd:string"/>
+    <xsd:attribute name="screen-density-group" type="xsd:string"/>
+    <xsd:attribute name="locale-group" type="xsd:string"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="gl-texture-group">
+    <xsd:sequence>
+      <xsd:element name="gl-texture" type="gl-texture" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="gl-texture">
+    <xsd:sequence>
+      <xsd:element name="texture-path" type="xsd:string" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="device-feature-group">
+    <xsd:sequence>
+      <xsd:element name="supports-feature" type="xsd:string" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="abi-group">
+    <xsd:sequence>
+      <xsd:element name="abi" type="abi-name" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:simpleType name="abi-name">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="armeabi"/>
+      <xsd:enumeration value="armeabi-v7a"/>
+      <xsd:enumeration value="arm64-v8a"/>
+      <xsd:enumeration value="x86"/>
+      <xsd:enumeration value="x86_64"/>
+      <xsd:enumeration value="mips"/>
+      <xsd:enumeration value="mips64"/>
+      <xsd:enumeration value="fat"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="screen-density-group">
+    <xsd:sequence>
+      <xsd:element name="screen-density" type="screen-density" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:simpleType name="screen-density">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="alldpi"/>
+      <xsd:enumeration value="ldpi"/>
+      <xsd:enumeration value="mdpi"/>
+      <xsd:enumeration value="hdpi"/>
+      <xsd:enumeration value="xhdpi"/>
+      <xsd:enumeration value="xxhdpi"/>
+      <xsd:enumeration value="xxxhdpi"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="android-sdk-group">
+    <xsd:sequence>
+      <xsd:element name="android-sdk" type="android-sdk" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="android-sdk">
+    <!-- TODO(safarmer): Add permissions to add/remove. -->
+    <!-- TODO(safarmer): Add option for uncompressed native libs. -->
+    <xsd:sequence>
+      <xsd:element name="manifest" type="manifest"/>
+    </xsd:sequence>
+    <xsd:attribute name="minSdkVersion" type="xsd:integer"/>
+    <xsd:attribute name="targetSdkVersion" type="xsd:integer"/>
+    <xsd:attribute name="maxSdkVersion" type="xsd:integer"/>
+  </xsd:complexType>
+
+  <!-- TODO(safarmer): Figure out the best way to handle manifest updates. -->
+  <xsd:simpleType name="manifest">
+    <xsd:restriction base="xsd:string"/>
+  </xsd:simpleType>
+
+  <xsd:complexType name="locale-group">
+    <xsd:sequence>
+      <xsd:element name="locale" type="locale" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="label" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="locale">
+    <xsd:attribute name="lang" type="xsd:string"/>
+    <xsd:attribute name="region" type="xsd:string"/>
+    <xsd:attribute name="compressed" type="xsd:boolean"/>
+  </xsd:complexType>
+
+</xsd:schema>
diff --git a/tools/aapt2/configuration/example/config.xml b/tools/aapt2/configuration/example/config.xml
new file mode 100644
index 0000000..a8360f8
--- /dev/null
+++ b/tools/aapt2/configuration/example/config.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<post-process xmlns="http://schemas.android.com/tools/aapt2">
+  <groups>
+    <abi-group label="arm">
+      <abi>armeabi-v7a</abi>
+      <abi>arm64-v8a</abi>
+    </abi-group>
+
+    <abi-group label="other">
+      <abi>x86</abi>
+      <abi>mips</abi>
+    </abi-group>
+
+    <screen-density-group label="large">
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+
+    <screen-density-group label="alldpi">
+      <screen-density>ldpi</screen-density>
+      <screen-density>mdpi</screen-density>
+      <screen-density>hdpi</screen-density>
+      <screen-density>xhdpi</screen-density>
+      <screen-density>xxhdpi</screen-density>
+      <screen-density>xxxhdpi</screen-density>
+    </screen-density-group>
+
+    <locale-group label="europe">
+      <locale lang="en"/>
+      <locale lang="es"/>
+      <locale lang="fr"/>
+      <locale lang="de" compressed="true"/>
+    </locale-group>
+
+    <locale-group label="north-america">
+      <locale lang="en"/>
+      <locale lang="es" region="MX"/>
+      <locale lang="fr" region="CA" compressed="true"/>
+    </locale-group>
+
+    <locale-group label="all">
+      <locale compressed="true"/>
+    </locale-group>
+
+    <android-sdk-group label="19">
+      <android-sdk
+          minSdkVersion="19"
+          targetSdkVersion="24"
+          maxSdkVersion="25">
+        <manifest>
+          <!--- manifest additions here XSLT? TODO -->
+        </manifest>
+      </android-sdk>
+    </android-sdk-group>
+
+    <gl-texture-group label="dxt1">
+      <gl-texture name="GL_EXT_texture_compression_dxt1">
+        <texture-path>assets/dxt1/*</texture-path>
+      </gl-texture>
+    </gl-texture-group>
+
+    <device-feature-group label="low-latency">
+      <supports-feature>android.hardware.audio.low_latency</supports-feature>
+    </device-feature-group>
+  </groups>
+
+  <artifacts>
+    <artifact-format>
+      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
+    </artifact-format>
+
+    <artifact
+        abi-group="arm"
+        screen-density-group="large"
+        locale-group="europe"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+
+    <artifact
+        abi-group="other"
+        screen-density-group="alldpi"
+        locale-group="north-america"
+        android-sdk-group="19"
+        gl-texture-group="dxt1"
+        device-feature-group="low-latency"/>
+
+  </artifacts>
+</post-process>
diff --git a/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml b/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
index 1a4067f..a5f202d 100644
--- a/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
+++ b/tools/aapt2/integration-tests/AppOne/AndroidManifest.xml
@@ -19,4 +19,11 @@
     <uses-sdk android:minSdkVersion="21" />
 
     <uses-permission-sdk-23 android:name="android.permission.TEST" android:maxSdkVersion="22" />
+
+    <application>
+        <activity android:name=".MyActivity">
+            <layout android:defaultHeight="500dp"
+                android:defaultWidth="600dp" />
+        </activity>
+    </application>
 </manifest>
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index f0ac467..012bb5e 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -327,7 +327,10 @@
   uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
 
   application_action["meta-data"] = meta_data_action;
+
   application_action["activity"] = component_action;
+  application_action["activity"]["layout"];
+
   application_action["activity-alias"] = component_action;
   application_action["service"] = component_action;
   application_action["receiver"] = component_action;
diff --git a/tools/aapt2/optimize/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp
index 4d00fa6..d9f384c0 100644
--- a/tools/aapt2/optimize/ResourceDeduper_test.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp
@@ -19,69 +19,88 @@
 #include "ResourceTable.h"
 #include "test/Test.h"
 
+using ::aapt::test::HasValue;
+using ::testing::Not;
+
 namespace aapt {
 
 TEST(ResourceDeduperTest, SameValuesAreDeduped) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const ConfigDescription default_config = {};
+  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+  const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
   const ConfigDescription en_config = test::ParseConfigOrDie("en");
   const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
-  // Chosen because this configuration is compatible with en.
+  // Chosen because this configuration is compatible with ldrtl/en.
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/dedupe", ResourceId{}, default_config,
-                     "dedupe")
-          .AddString("android:string/dedupe", ResourceId{}, en_config, "dedupe")
-          .AddString("android:string/dedupe", ResourceId{}, land_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, default_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, en_config,
-                     "dedupe")
-          .AddString("android:string/dedupe2", ResourceId{}, en_v21_config,
-                     "keep")
-          .AddString("android:string/dedupe2", ResourceId{}, land_config,
-                     "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, ldrtl_config, "dedupe")
+          .AddString("android:string/dedupe", ResourceId{}, land_config, "dedupe")
+
+          .AddString("android:string/dedupe2", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe2", ResourceId{}, ldrtl_config, "dedupe")
+          .AddString("android:string/dedupe2", ResourceId{}, ldrtl_v21_config, "keep")
+          .AddString("android:string/dedupe2", ResourceId{}, land_config, "dedupe")
+
+          .AddString("android:string/dedupe3", ResourceId{}, default_config, "dedupe")
+          .AddString("android:string/dedupe3", ResourceId{}, en_config, "dedupe")
+          .AddString("android:string/dedupe3", ResourceId{}, en_v21_config, "dedupe")
           .Build();
 
   ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe", en_config));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe", land_config));
-  EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", en_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/dedupe2", en_v21_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe", ldrtl_config)));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe", land_config)));
+
+  EXPECT_THAT(table, HasValue("android:string/dedupe2", ldrtl_v21_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe2", ldrtl_config)));
+
+  EXPECT_THAT(table, HasValue("android:string/dedupe3", default_config));
+  EXPECT_THAT(table, HasValue("android:string/dedupe3", en_config));
+  EXPECT_THAT(table, Not(HasValue("android:string/dedupe3", en_v21_config)));
 }
 
 TEST(ResourceDeduperTest, DifferentValuesAreKept) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const ConfigDescription default_config = {};
-  const ConfigDescription en_config = test::ParseConfigOrDie("en");
-  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
-  // Chosen because this configuration is compatible with en.
+  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+  const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
+  // Chosen because this configuration is compatible with ldrtl.
   const ConfigDescription land_config = test::ParseConfigOrDie("land");
 
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
-          .AddString("android:string/keep", ResourceId{}, default_config,
-                     "keep")
-          .AddString("android:string/keep", ResourceId{}, en_config, "keep")
-          .AddString("android:string/keep", ResourceId{}, en_v21_config,
-                     "keep2")
+          .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, ldrtl_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, ldrtl_v21_config, "keep2")
           .AddString("android:string/keep", ResourceId{}, land_config, "keep2")
           .Build();
 
   ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", en_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", en_v21_config));
-  EXPECT_NE(nullptr, test::GetValueForConfig<String>(
-                         table.get(), "android:string/keep", land_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_v21_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", land_config));
+}
+
+TEST(ResourceDeduperTest, LocalesValuesAreKept) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  const ConfigDescription default_config = {};
+  const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+  const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, fr_config, "keep")
+          .AddString("android:string/keep", ResourceId{}, fr_rCA_config, "keep")
+          .Build();
+
+  ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
+  EXPECT_THAT(table, HasValue("android:string/keep", default_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", fr_config));
+  EXPECT_THAT(table, HasValue("android:string/keep", fr_rCA_config));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 01b2d14..8efd56a 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -156,6 +156,23 @@
   return arg.Equals(&a);
 }
 
+MATCHER_P(StrValueEq, a,
+          std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
+  return *(arg.value) == a;
+}
+
+MATCHER_P(HasValue, name,
+          std::string(negation ? "does not have" : "has") + " value " +
+              ::testing::PrintToString(name)) {
+  return GetValueForConfig<Value>(&(*arg), name, {}) != nullptr;
+}
+
+MATCHER_P2(HasValue, name, config,
+           std::string(negation ? "does not have" : "has") + " value " +
+               ::testing::PrintToString(name) + " for config " + ::testing::PrintToString(config)) {
+  return GetValueForConfig<Value>(&(*arg), name, config) != nullptr;
+}
+
 }  // namespace test
 }  // namespace aapt
 
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index aefc24b..8a8be85 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -203,7 +203,7 @@
     if (*c == '%' && c + 1 < end) {
       c++;
 
-      if (*c == '%') {
+      if (*c == '%' || *c == 'n') {
         c++;
         continue;
       }
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 53501f9..77c1c24 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -429,7 +429,8 @@
         if len(creator) == 0 or len(write) == 0 or len(describe) == 0:
             error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
 
-        if " final class " not in clazz.raw:
+        if ((" final class " not in clazz.raw) and
+            (" final deprecated class " not in clazz.raw)):
             error(clazz, None, "FW8", "Parcelable classes must be final")
 
 
diff --git a/tools/fonts/add_additional_fonts.py b/tools/fonts/add_additional_fonts.py
new file mode 100644
index 0000000..bf4af2b
--- /dev/null
+++ b/tools/fonts/add_additional_fonts.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+import sys
+
+def main(argv):
+    original_file = 'frameworks/base/data/fonts/fonts.xml'
+
+    if len(argv) == 3:
+        output_file_path = argv[1]
+        override_file_path = argv[2]
+    else:
+        raise ValueError("Wrong number of arguments %s" % len(argv))
+
+    fallbackPlaceholderFound = False
+    with open(original_file, 'r') as input_file:
+        with open(output_file_path, 'w') as output_file:
+            for line in input_file:
+                # If we've found the spot to add additional fonts, add them.
+                if line.strip() == '<!-- fallback fonts -->':
+                    fallbackPlaceholderFound = True
+                    with open(override_file_path) as override_file:
+                        for override_line in override_file:
+                            output_file.write(override_line)
+                output_file.write(line)
+    if not fallbackPlaceholderFound:
+        raise ValueError('<!-- fallback fonts --> not found in source file: %s' % original_file)
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index c0475ee..c6ad4c2 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -3,7 +3,6 @@
 import collections
 import copy
 import glob
-import itertools
 from os import path
 import sys
 from xml.etree import ElementTree
@@ -574,8 +573,8 @@
         all_sequences.add(sequence)
         sequence_pieces.update(sequence)
         if _emoji_sequences.get(sequence, None) == 'Emoji_Tag_Sequence':
-            # Add reverse of all emoji ZWJ sequences, which are added to the fonts
-            # as a workaround to get the sequences work in RTL text.
+            # Add reverse of all emoji ZWJ sequences, which are added to the
+            # fonts as a workaround to get the sequences work in RTL text.
             # TODO: test if these are actually needed by Minikin/HarfBuzz.
             reversed_seq = reverse_emoji(sequence)
             all_sequences.add(reversed_seq)
@@ -630,12 +629,26 @@
         if record.name in ['sans-serif', 'sans-serif-condensed']:
             font = open_font(record.font)
             assert font['head'].yMax == 2163 and font['head'].yMin == -555, (
-                'yMax and yMin of %s do not match expected values.' % (record.font,))
+                'yMax and yMin of %s do not match expected values.' % (
+                record.font,))
 
-        if record.name in ['sans-serif', 'sans-serif-condensed', 'serif', 'monospace']:
+        if record.name in ['sans-serif', 'sans-serif-condensed',
+                           'serif', 'monospace']:
             font = open_font(record.font)
-            assert font['hhea'].ascent == 1900 and font['hhea'].descent == -500, (
-                'ascent and descent of %s do not match expected values.' % (record.font,))
+            assert (font['hhea'].ascent == 1900 and
+                    font['hhea'].descent == -500), (
+                        'ascent and descent of %s do not match expected '
+                        'values.' % (record.font,))
+
+
+def check_cjk_punctuation():
+    cjk_scripts = {'Hans', 'Hant', 'Jpan', 'Kore'}
+    cjk_punctuation = range(0x3000, 0x301F + 1)
+    for record in _fallback_chain:
+        if record.scripts.intersection(cjk_scripts):
+            # CJK font seen. Stop checking the rest of the fonts.
+            break
+        assert_font_supports_none_of_chars(record.font, cjk_punctuation)
 
 
 def main():
@@ -651,6 +664,8 @@
     hyphens_dir = path.join(target_out, 'usr', 'hyphen-data')
     check_hyphens(hyphens_dir)
 
+    check_cjk_punctuation()
+
     check_emoji = sys.argv[2]
     if check_emoji == 'true':
         ucd_path = sys.argv[3]
diff --git a/tools/incident_report/main.cpp b/tools/incident_report/main.cpp
index 884b8e4..1d8809f6 100644
--- a/tools/incident_report/main.cpp
+++ b/tools/incident_report/main.cpp
@@ -355,6 +355,7 @@
             args[argpos++] = NULL;
             execvp(args[0], (char*const*)args);
             fprintf(stderr, "execvp failed: %s\n", strerror(errno));
+            free(args);
             return 1;
         } else {
             // parent
@@ -400,6 +401,7 @@
         }
     }
 
+    free(buffer);
     return 0;
 }
 
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
deleted file mode 100644
index 819103d..0000000
--- a/tools/layoutlib/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-bin
-/.idea/workspace.xml
-/out
-/bridge/out
diff --git a/tools/layoutlib/.idea/.name b/tools/layoutlib/.idea/.name
deleted file mode 100644
index 10eb5c1..0000000
--- a/tools/layoutlib/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-layoutlib
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
deleted file mode 100644
index 0450be3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_jar</output-path>
-    <root id="archive" name="studio-android-widgets.jar">
-      <element id="module-output" name="studio-android-widgets" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
deleted file mode 100644
index a844ca3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets-src:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_src_jar</output-path>
-    <root id="archive" name="studio-android-widgets-src.jar">
-      <element id="dir-copy" path="$PROJECT_DIR$/studio-custom-widgets/src" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml
deleted file mode 100644
index ac90d1e..0000000
--- a/tools/layoutlib/.idea/codeStyleSettings.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectCodeStyleSettingsManager">
-    <option name="PER_PROJECT_SETTINGS">
-      <value>
-        <option name="FIELD_NAME_PREFIX" value="m" />
-        <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
-        <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
-        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
-          <value />
-        </option>
-        <option name="IMPORT_LAYOUT_TABLE">
-          <value>
-            <package name="com.android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="org" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="java" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="true" />
-          </value>
-        </option>
-        <option name="RIGHT_MARGIN" value="100" />
-        <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
-        <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
-        <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
-        <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
-        <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
-        <option name="WRAP_COMMENTS" value="true" />
-        <JavaCodeStyleSettings>
-          <option name="CLASS_NAMES_IN_JAVADOC" value="3" />
-        </JavaCodeStyleSettings>
-        <XML>
-          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
-        </XML>
-        <codeStyleSettings language="JAVA">
-          <option name="KEEP_LINE_BREAKS" value="false" />
-          <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
-          <option name="CALL_PARAMETERS_WRAP" value="1" />
-          <option name="METHOD_PARAMETERS_WRAP" value="1" />
-          <option name="THROWS_LIST_WRAP" value="1" />
-          <option name="EXTENDS_KEYWORD_WRAP" value="1" />
-          <option name="THROWS_KEYWORD_WRAP" value="1" />
-          <option name="BINARY_OPERATION_WRAP" value="1" />
-          <option name="TERNARY_OPERATION_WRAP" value="1" />
-          <option name="ARRAY_INITIALIZER_WRAP" value="1" />
-          <option name="ASSIGNMENT_WRAP" value="1" />
-          <option name="ASSERT_STATEMENT_WRAP" value="1" />
-          <option name="IF_BRACE_FORCE" value="3" />
-          <option name="DOWHILE_BRACE_FORCE" value="3" />
-          <option name="WHILE_BRACE_FORCE" value="3" />
-          <option name="FOR_BRACE_FORCE" value="3" />
-          <option name="WRAP_LONG_LINES" value="true" />
-          <arrangement>
-            <groups>
-              <group>
-                <type>GETTERS_AND_SETTERS</type>
-                <order>KEEP</order>
-              </group>
-              <group>
-                <type>OVERRIDDEN_METHODS</type>
-                <order>KEEP</order>
-              </group>
-            </groups>
-          </arrangement>
-        </codeStyleSettings>
-        <codeStyleSettings language="XML">
-          <indentOptions>
-            <option name="CONTINUATION_INDENT_SIZE" value="4" />
-          </indentOptions>
-        </codeStyleSettings>
-      </value>
-    </option>
-    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/compiler.xml b/tools/layoutlib/.idea/compiler.xml
deleted file mode 100644
index 35961a2..0000000
--- a/tools/layoutlib/.idea/compiler.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CompilerConfiguration">
-    <option name="DEFAULT_COMPILER" value="Javac" />
-    <excludeFromCompile>
-      <directory url="file://$PROJECT_DIR$/create/tests/mock_data" includeSubdirectories="true" />
-    </excludeFromCompile>
-    <resourceExtensions />
-    <wildcardResourcePatterns>
-      <entry name="!?*.java" />
-      <entry name="!?*.form" />
-      <entry name="!?*.class" />
-      <entry name="!?*.groovy" />
-      <entry name="!?*.scala" />
-      <entry name="!?*.flex" />
-      <entry name="!?*.kt" />
-      <entry name="!?*.clj" />
-    </wildcardResourcePatterns>
-    <annotationProcessing>
-      <profile default="true" name="Default" enabled="false">
-        <processorPath useClasspath="true" />
-      </profile>
-    </annotationProcessing>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/Android.xml b/tools/layoutlib/.idea/copyright/Android.xml
deleted file mode 100644
index d81d75d..0000000
--- a/tools/layoutlib/.idea/copyright/Android.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="CopyrightManager">
-  <copyright>
-    <option name="notice" value="Copyright (C) &amp;#36;today.year The Android Open Source Project&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;     http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
-    <option name="keyword" value="Copyright" />
-    <option name="allowReplaceKeyword" value="" />
-    <option name="myName" value="Android" />
-    <option name="myLocal" value="true" />
-  </copyright>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/profiles_settings.xml b/tools/layoutlib/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index 20145de..0000000
--- a/tools/layoutlib/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
-  <settings default="Android" />
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/encodings.xml b/tools/layoutlib/.idea/encodings.xml
deleted file mode 100644
index f758959..0000000
--- a/tools/layoutlib/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
-    <file url="PROJECT" charset="UTF-8" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml b/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 74fa549..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0" is_locked="false">
-    <option name="myName" value="Project Default" />
-    <option name="myLocal" value="false" />
-    <inspection_tool class="DefaultFileTemplate" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="CHECK_FILE_HEADER" value="true" />
-      <option name="CHECK_TRY_CATCH_SECTION" value="true" />
-      <option name="CHECK_METHOD_BODY" value="true" />
-    </inspection_tool>
-    <inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
-      <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
-    </inspection_tool>
-    <inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
-      <option name="SUGGEST_PRIVATE_FOR_INNERS" value="true" />
-    </inspection_tool>
-  </profile>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml b/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 3b31283..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="PROJECT_PROFILE" value="Project Default" />
-    <option name="USE_PROJECT_PROFILE" value="true" />
-    <version value="1.0" />
-  </settings>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml
deleted file mode 100644
index 6695a36..0000000
--- a/tools/layoutlib/.idea/libraries/framework_jar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<component name="libraryTable">
-  <library name="framework.jar">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../core/java" />
-      <root url="file://$PROJECT_DIR$/../../graphics/java" />
-      <root url="file://$PROJECT_DIR$/../../../../libcore/luni/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/junit.xml b/tools/layoutlib/.idea/libraries/junit.xml
deleted file mode 100644
index ba46ebf..0000000
--- a/tools/layoutlib/.idea/libraries/junit.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="junit">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/junit-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../../../external/junit/src" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
deleted file mode 100644
index a873600..0000000
--- a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="layoutlib_api-prebuilt">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/mockito.xml b/tools/layoutlib/.idea/libraries/mockito.xml
deleted file mode 100644
index 032963e..0000000
--- a/tools/layoutlib/.idea/libraries/mockito.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="mockito">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/mockito-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/objenesis.xml b/tools/layoutlib/.idea/libraries/objenesis.xml
deleted file mode 100644
index 1484de5..0000000
--- a/tools/layoutlib/.idea/libraries/objenesis.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="objenesis">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/objenesis-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/misc.xml b/tools/layoutlib/.idea/misc.xml
deleted file mode 100644
index 44b47f2..0000000
--- a/tools/layoutlib/.idea/misc.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="EntryPointsManager">
-    <entry_points version="2.0" />
-    <list size="1">
-      <item index="0" class="java.lang.String" itemvalue="com.android.tools.layoutlib.annotations.LayoutlibDelegate" />
-    </list>
-  </component>
-  <component name="FrameworkDetectionExcludesConfiguration">
-    <type id="android" />
-  </component>
-  <component name="NullableNotNullManager">
-    <option name="myDefaultNullable" value="android.annotation.Nullable" />
-    <option name="myDefaultNotNull" value="android.annotation.NonNull" />
-    <option name="myNullables">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.Nullable" />
-        </list>
-      </value>
-    </option>
-    <option name="myNotNulls">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
-        </list>
-      </value>
-    </option>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/out" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/modules.xml b/tools/layoutlib/.idea/modules.xml
deleted file mode 100644
index 6ffc1cc..0000000
--- a/tools/layoutlib/.idea/modules.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/bridge/bridge.iml" filepath="$PROJECT_DIR$/bridge/bridge.iml" />
-      <module fileurl="file://$PROJECT_DIR$/create/create.iml" filepath="$PROJECT_DIR$/create/create.iml" />
-      <module fileurl="file://$PROJECT_DIR$/legacy/legacy.iml" filepath="$PROJECT_DIR$/legacy/legacy.iml" />
-      <module fileurl="file://$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" filepath="$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml b/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
deleted file mode 100644
index 0b22717..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in bridge" type="JUnit" factoryName="JUnit" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml b/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
deleted file mode 100644
index b9cd419d..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in create" type="JUnit" factoryName="JUnit" singleton="false" nameIsGenerated="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="create" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml b/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
deleted file mode 100644
index b402849..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Bridge quick" type="JUnit" factoryName="JUnit">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="pattern" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns>
-      <pattern testClass="com.android.layoutlib.bridge.TestDelegates" />
-      <pattern testClass="android.graphics.Matrix_DelegateTest" />
-      <pattern testClass="com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest" />
-    </patterns>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
diff --git a/tools/layoutlib/.idea/runConfigurations/Create.xml b/tools/layoutlib/.idea/runConfigurations/Create.xml
deleted file mode 100644
index 536a23f..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Create.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Create" type="Application" factoryName="Application" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icudata-host-jarjar_intermediates/classes-jarjar.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-host-jarjar_intermediates/classes-jarjar.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../../../../" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="ENABLE_SWING_INSPECTOR" value="false" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <module name="create" />
-    <envs />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/scopes/scope_settings.xml b/tools/layoutlib/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 922003b..0000000
--- a/tools/layoutlib/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="DependencyValidationManager">
-  <state>
-    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
-  </state>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/uiDesigner.xml b/tools/layoutlib/.idea/uiDesigner.xml
deleted file mode 100644
index 3b00020..0000000
--- a/tools/layoutlib/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Palette2">
-    <group name="Swing">
-      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
-      </item>
-      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
-        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
-        <initial-values>
-          <property name="text" value="Button" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="RadioButton" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="CheckBox" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="Label" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
-          <preferred-size width="-1" height="20" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
-      </item>
-    </group>
-  </component>
-</project>
-
diff --git a/tools/layoutlib/.idea/vcs.xml b/tools/layoutlib/.idea/vcs.xml
deleted file mode 100644
index 9ab281a..0000000
--- a/tools/layoutlib/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
-  </component>
-</project>
-
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
deleted file mode 100644
index 29c933a..0000000
--- a/tools/layoutlib/Android.mk
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright (C) 2008 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 := $(my-dir)
-include $(CLEAR_VARS)
-
-#
-# Define rules to build temp_layoutlib.jar, which contains a subset of
-# the classes in framework.jar.  The layoutlib_create tool is used to
-# transform the framework jar into the temp_layoutlib jar.
-#
-
-# We need to process the framework classes.jar file, but we can't
-# depend directly on it (private vars won't be inherited correctly).
-# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework)
-built_framework_classes := $(call java-lib-files,framework)
-
-built_oj_dep := $(call java-lib-deps,core-oj)
-built_oj_classes := $(call java-lib-files,core-oj)
-
-built_core_dep := $(call java-lib-deps,core-libart)
-built_core_classes := $(call java-lib-files,core-libart)
-
-built_ext_dep := $(call java-lib-deps,ext)
-built_ext_classes := $(call java-lib-files,ext)
-
-built_icudata_dep := $(call java-lib-deps,icu4j-icudata-host-jarjar,HOST)
-built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-host-jarjar,HOST)
-
-built_layoutlib_create_jar := $(call java-lib-files,layoutlib_create,HOST)
-
-# This is mostly a copy of config/host_java_library.mk
-LOCAL_MODULE := temp_layoutlib
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_BUILT_MODULE_STEM := classes.jar
-
-#######################################
-include $(BUILD_SYSTEM)/base_rules.mk
-#######################################
-
-$(LOCAL_BUILT_MODULE): $(built_oj_dep) \
-                       $(built_core_dep) \
-                       $(built_framework_dep) \
-                       $(built_ext_dep) \
-		       $(built_icudata_dep) \
-		       $(built_icutzdata_dep) \
-                       $(built_layoutlib_create_jar)
-	$(hide) echo "host layoutlib_create: $@"
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -f $@
-	$(hide) ls -l $(built_framework_classes)
-	$(hide) java -ea -jar $(built_layoutlib_create_jar) \
-	             $@ \
-	             $(built_oj_classes) \
-	             $(built_core_classes) \
-	             $(built_framework_classes) \
-	             $(built_ext_classes) \
-		     $(built_icudata_dep) \
-		     $(built_icutzdata_dep) \
-	             $(built_ext_data)
-	$(hide) ls -l $(built_framework_classes)
-
-
-#
-# Include the subdir makefiles.
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/README b/tools/layoutlib/README
deleted file mode 100644
index 0fea9bd..0000000
--- a/tools/layoutlib/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Layoutlib is a custom version of the android View framework designed to run inside Eclipse.
-The goal of the library is to provide layout rendering in Eclipse that are very very close to their rendering on devices.
-
-None of the com.android.* or android.* classes in layoutlib run on devices.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
deleted file mode 100644
index 9c4160c..0000000
--- a/tools/layoutlib/bridge/.classpath
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
-	<classpathentry kind="src" path="tests/src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/sdk-common/sdk-common.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/guavalib_intermediates/javalib.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/.project b/tools/layoutlib/bridge/.project
deleted file mode 100644
index e36e71b..0000000
--- a/tools/layoutlib/bridge/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/.settings/README.txt b/tools/layoutlib/bridge/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/bridge/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
deleted file mode 100644
index 3dd8002..0000000
--- a/tools/layoutlib/bridge/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2008 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)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt \
-	tools-common-prebuilt
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	temp_layoutlib \
-	ninepatch-prebuilt
-
-LOCAL_MODULE := layoutlib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
deleted file mode 100644
index 85ec3eb..0000000
--- a/tools/layoutlib/bridge/bridge.iml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-      <excludeFolder url="file://$MODULE_DIR$/bin" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.idea" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/generated" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/assets" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/dependency-cache" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/incremental" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/libs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/manifests" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/res" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/rs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/symbols" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/gradle" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="module-library">
-      <library name="ninepatch-prebuilt">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library">
-      <library name="tools-common-prebuilt">
-        <ANNOTATIONS>
-          <root url="file://$MODULE_DIR$/.." />
-        </ANNOTATIONS>
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module-library" scope="TEST">
-      <library name="kxml2-2.3.0">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="guava">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="sdk-common">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-    <orderEntry type="library" scope="TEST" name="mockito" level="project" />
-    <orderEntry type="library" scope="TEST" name="objenesis" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/resources/bars/README b/tools/layoutlib/bridge/resources/bars/README
deleted file mode 100644
index c84ef80..0000000
--- a/tools/layoutlib/bridge/resources/bars/README
+++ /dev/null
@@ -1,8 +0,0 @@
-The directory contains the resources for StatusBar and Navigation Bar.
-
-The resources are not arranged as per the standard resources configuration.
-They are stored per API. However, to prevent duplication of resources, each API
-resource directory is used as a backup for all earlier API levels.
-
-For example, for the back icon for ICS, we search first in v18, where we don't
-find it, and then in v19.
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
deleted file mode 100644
index 55bd1d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
+++ /dev/null
@@ -1,49 +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.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
deleted file mode 100644
index e208a0d..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
+++ /dev/null
@@ -1,49 +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.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-		  	android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
deleted file mode 100644
index 04571e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"/>
-    <!-- The exact size of the wifi icon is specified in order to scale it properly.
-    Without scaling, it appeared huge. This is currently, 70% of the actual size. -->
-    <ImageView
-            android:layout_height="22.4dp"
-            android:layout_width="20.65dp"
-            android:layout_marginTop="1dp"/>
-    <ImageView
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_marginLeft="3dp"
-            android:layout_marginRight="5dp"
-            android:layout_marginTop="4dp"/>
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="4dp"
-            android:layout_marginRight="5dp"
-            android:gravity="center_vertical"
-            android:textSize="16dp"
-            android:fontFamily="sans-serif-medium"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
deleted file mode 100644
index 76d78d9..0000000
--- a/tools/layoutlib/bridge/resources/bars/title_bar.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index c920ec4..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 943332e..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 36c61e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
deleted file mode 100644
index 84e6bc8..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
deleted file mode 100644
index 38e4f45..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index bf9f300..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 782ebfe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 677b471..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index a1b8062..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index fcdbefe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 633d864..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 4665e2a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
deleted file mode 100644
index a00bc5b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
deleted file mode 100644
index dc3183b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index b07f611..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index bd60cd6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index c5bc5c9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index f621d9c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 79cfcee..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 64f6a22..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6e0b071..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 494b005..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
deleted file mode 100644
index d2760bb..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
deleted file mode 100644
index df43e21..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6fab1d6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index f17189a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 2fcfdde..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 48708a5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 3d73184..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 786935d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
deleted file mode 100644
index 1d8c3af..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
deleted file mode 100644
index 66de0ec..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 30c65f5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 2a9757d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index a356285..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index ba2d0b2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 94a74b1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 555bcd9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
deleted file mode 100644
index 0498b6c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-</vector>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 29da099..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 59b32f2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ba66d27..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 6474aad..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index 754cdf6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index b5326d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
deleted file mode 100644
index 7023ea7..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 17a955d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 19165ab..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-b.png b/tools/layoutlib/bridge/resources/icons/shadow-b.png
deleted file mode 100644
index 68f4f4b..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-bl.png b/tools/layoutlib/bridge/resources/icons/shadow-bl.png
deleted file mode 100644
index ee7dbe8..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-br.png b/tools/layoutlib/bridge/resources/icons/shadow-br.png
deleted file mode 100644
index c45ad77..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-l.png b/tools/layoutlib/bridge/resources/icons/shadow-l.png
deleted file mode 100644
index 77d0bd0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-r.png b/tools/layoutlib/bridge/resources/icons/shadow-r.png
deleted file mode 100644
index 4af7a33..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tl.png b/tools/layoutlib/bridge/resources/icons/shadow-tl.png
deleted file mode 100644
index 424fb36..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tr.png b/tools/layoutlib/bridge/resources/icons/shadow-tr.png
deleted file mode 100644
index 1fd0c77..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-b.png b/tools/layoutlib/bridge/resources/icons/shadow2-b.png
deleted file mode 100644
index 963973e..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png b/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
deleted file mode 100644
index 7612487..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-br.png b/tools/layoutlib/bridge/resources/icons/shadow2-br.png
deleted file mode 100644
index 8e20252..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-l.png b/tools/layoutlib/bridge/resources/icons/shadow2-l.png
deleted file mode 100644
index 2db18a0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-r.png b/tools/layoutlib/bridge/resources/icons/shadow2-r.png
deleted file mode 100644
index 8e026f1..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png b/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
deleted file mode 100644
index a8045ed..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png b/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
deleted file mode 100644
index 590373c..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
deleted file mode 100644
index ce2aec7..0000000
--- a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-
-import android.os.Handler;
-import android.os.Handler_Delegate;
-import android.os.Message;
-
-import java.util.PriorityQueue;
-import java.util.Queue;
-
-/**
- * Abstract animation thread.
- * <p/>
- * This does not actually start an animation, instead it fakes a looper that will play whatever
- * animation is sending messages to its own {@link Handler}.
- * <p/>
- * Classes should implement {@link #preAnimation()} and {@link #postAnimation()}.
- * <p/>
- * If {@link #preAnimation()} does not start an animation somehow then the thread doesn't do
- * anything.
- *
- */
-public abstract class AnimationThread extends Thread {
-
-    private static class MessageBundle implements Comparable<MessageBundle> {
-        final Handler mTarget;
-        final Message mMessage;
-        final long mUptimeMillis;
-
-        MessageBundle(Handler target, Message message, long uptimeMillis) {
-            mTarget = target;
-            mMessage = message;
-            mUptimeMillis = uptimeMillis;
-        }
-
-        @Override
-        public int compareTo(MessageBundle bundle) {
-            if (mUptimeMillis < bundle.mUptimeMillis) {
-                return -1;
-            }
-            return 1;
-        }
-    }
-
-    private final RenderSessionImpl mSession;
-
-    private Queue<MessageBundle> mQueue = new PriorityQueue<MessageBundle>();
-    private final IAnimationListener mListener;
-
-    public AnimationThread(RenderSessionImpl scene, String threadName,
-            IAnimationListener listener) {
-        super(threadName);
-        mSession = scene;
-        mListener = listener;
-    }
-
-    public abstract Result preAnimation();
-    public abstract void postAnimation();
-
-    @Override
-    public void run() {
-        Bridge.prepareThread();
-        try {
-            /* FIXME: The ANIMATION_FRAME message no longer exists.  Instead, the
-             * animation timing loop is completely based on a Choreographer objects
-             * that schedules animation and drawing frames.  The animation handler is
-             * no longer even a handler; it is just a Runnable enqueued on the Choreographer.
-            Handler_Delegate.setCallback(new IHandlerCallback() {
-                @Override
-                public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-                    if (msg.what == ValueAnimator.ANIMATION_START ||
-                            msg.what == ValueAnimator.ANIMATION_FRAME) {
-                        mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
-                    } else {
-                        // just ignore.
-                    }
-                }
-            });
-            */
-
-            // call out to the pre-animation work, which should start an animation or more.
-            Result result = preAnimation();
-            if (result.isSuccess() == false) {
-                mListener.done(result);
-            }
-
-            // loop the animation
-            RenderSession session = mSession.getSession();
-            do {
-                // check early.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // get the next message.
-                MessageBundle bundle = mQueue.poll();
-                if (bundle == null) {
-                    break;
-                }
-
-                // sleep enough for this bundle to be on time
-                long currentTime = System.currentTimeMillis();
-                if (currentTime < bundle.mUptimeMillis) {
-                    try {
-                        sleep(bundle.mUptimeMillis - currentTime);
-                    } catch (InterruptedException e) {
-                        // FIXME log/do something/sleep again?
-                        e.printStackTrace();
-                    }
-                }
-
-                // check after sleeping.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // ready to do the work, acquire the scene.
-                result = mSession.acquire(250);
-                if (result.isSuccess() == false) {
-                    mListener.done(result);
-                    return;
-                }
-
-                // process the bundle. If the animation is not finished, this will enqueue
-                // the next message, so mQueue will have another one.
-                try {
-                    // check after acquiring in case it took a while.
-                    if (mListener.isCanceled()) {
-                        break;
-                    }
-
-                    bundle.mTarget.handleMessage(bundle.mMessage);
-                    if (mSession.render(false /*freshRender*/).isSuccess()) {
-                        mListener.onNewFrame(session);
-                    }
-                } finally {
-                    mSession.release();
-                }
-            } while (mListener.isCanceled() == false && mQueue.size() > 0);
-
-            mListener.done(Status.SUCCESS.createResult());
-
-        } catch (Throwable throwable) {
-            // can't use Bridge.getLog() as the exception might be thrown outside
-            // of an acquire/release block.
-            mListener.done(Status.ERROR_UNKNOWN.createResult("Error playing animation", throwable));
-
-        } finally {
-            postAnimation();
-            Handler_Delegate.setCallback(null);
-            Bridge.cleanupThread();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
deleted file mode 100644
index 28a489a..0000000
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.animation.PropertyValuesHolder
- *
- * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- * The main goal of this class' methods are to provide a native way to access setters and getters
- * on some object. We override these methods to use reflection since the original reflection
- * implementation of the PropertyValuesHolder won't be able to access protected methods.
- *
- */
-/*package*/
-@SuppressWarnings("unused")
-class PropertyValuesHolder_Delegate {
-    // This code is copied from android.animation.PropertyValuesHolder and must be kept in sync
-    // We try several different types when searching for appropriate setter/getter functions.
-    // The caller may have supplied values in a type that does not match the setter/getter
-    // functions (such as the integers 0 and 1 to represent floating point values for alpha).
-    // Also, the use of generics in constructors means that we end up with the Object versions
-    // of primitive types (Float vs. float). But most likely, the setter/getter functions
-    // will take primitive types instead.
-    // So we supply an ordered array of other types to try before giving up.
-    private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
-            Double.class, Integer.class};
-    private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
-            Float.class, Double.class};
-
-    private static final Object sMethodIndexLock = new Object();
-    private static final Map<Long, Method> ID_TO_METHOD = new HashMap<Long, Method>();
-    private static final Map<String, Long> METHOD_NAME_TO_ID = new HashMap<String, Long>();
-    private static long sNextId = 1;
-
-    private static long registerMethod(Class<?> targetClass, String methodName, Class[] types,
-            int nArgs) {
-        // Encode the number of arguments in the method name
-        String methodIndexName = String.format("%1$s.%2$s#%3$d", targetClass.getSimpleName(),
-                methodName, nArgs);
-        synchronized (sMethodIndexLock) {
-            Long methodId = METHOD_NAME_TO_ID.get(methodIndexName);
-
-            if (methodId != null) {
-                // The method was already registered
-                return methodId;
-            }
-
-            Class[] args = new Class[nArgs];
-            Method method = null;
-            for (Class typeVariant : types) {
-                for (int i = 0; i < nArgs; i++) {
-                    args[i] = typeVariant;
-                }
-                try {
-                    method = targetClass.getDeclaredMethod(methodName, args);
-                } catch (NoSuchMethodException ignore) {
-                }
-            }
-
-            if (method != null) {
-                methodId = sNextId++;
-                ID_TO_METHOD.put(methodId, method);
-                METHOD_NAME_TO_ID.put(methodIndexName, methodId);
-
-                return methodId;
-            }
-        }
-
-        // Method not found
-        return 0;
-    }
-
-    private static void callMethod(Object target, long methodID, Object... args) {
-        Method method = ID_TO_METHOD.get(methodID);
-        assert method != null;
-
-        try {
-            method.setAccessible(true);
-            method.invoke(target, args);
-        } catch (IllegalAccessException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        } catch (InvocationTargetException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetIntMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleIntMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetFloatMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleFloatMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, INTEGER_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, FLOAT_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1,
-            int arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1,
-            int arg2, int arg3, int arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleIntMethod(Object target, long methodID,
-            int[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1,
-            float arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1,
-            float arg2, float arg3, float arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID,
-            float[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
deleted file mode 100644
index f7654ce..0000000
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Bundle;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Fragment}
- *
- * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
- * Because the classes of these objects are found in the project, these methods need access to
- * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
- */
-public class Fragment_Delegate {
-
-    private static LayoutlibCallback sLayoutlibCallback;
-
-    /**
-     * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
-     * from the project being rendered.
-     */
-    public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
-        sLayoutlibCallback = layoutlibCallback;
-    }
-
-    /**
-     * Like {@link #instantiate(Context, String, Bundle)} but with a null
-     * argument Bundle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname) {
-        return instantiate(context, fname, null);
-    }
-
-    /**
-     * Create a new instance of a Fragment with the given class name.  This is
-     * the same as calling its empty constructor.
-     *
-     * @param context The calling context being used to instantiate the fragment.
-     * This is currently just used to get its ClassLoader.
-     * @param fname The class name of the fragment to instantiate.
-     * @param args Bundle of arguments to supply to the fragment, which it
-     * can retrieve with {@link Fragment#getArguments()}.  May be null.
-     * @return Returns a new fragment instance.
-     * @throws Fragment.InstantiationException If there is a failure in instantiating
-     * the given fragment class.  This is a runtime exception; it is not
-     * normally expected to happen.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
-        try {
-            if (sLayoutlibCallback != null) {
-                Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
-                        new Class[0], new Object[0]);
-
-                if (args != null) {
-                    args.setClassLoader(f.getClass().getClassLoader());
-                    f.mArguments = args;
-                }
-                return f;
-            }
-
-            return null;
-        } catch (ClassNotFoundException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (java.lang.InstantiationException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (IllegalAccessException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (Exception e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java b/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
deleted file mode 100644
index 591aee0..0000000
--- a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
+++ /dev/null
@@ -1,29 +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.
- */
-
-package android.app;
-
-/**
- * Class to allow accessing {@link SystemServiceRegistry#getSystemServiceName}
- */
-public class SystemServiceRegistry_Accessor {
-    /**
-     * Gets the name of the system-level service that is represented by the specified class.
-     */
-    public static String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry.getSystemServiceName(serviceClass);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
deleted file mode 100644
index b4d5288..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
+++ /dev/null
@@ -1,47 +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 android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.SparseArray;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link AssetManager}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of AssetManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AssetManager_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static long newTheme(AssetManager manager) {
-        return Resources_Theme_Delegate.getDelegateManager()
-                .addNewDelegate(new Resources_Theme_Delegate());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void deleteTheme(AssetManager manager, long theme) {
-        Resources_Theme_Delegate.getDelegateManager().removeJavaReferenceFor(theme);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static SparseArray<String> getAssignedPackageIdentifiers(AssetManager manager) {
-        return new SparseArray<>();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java b/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
deleted file mode 100644
index 2691e56..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 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.content.res;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layoutlib.bridge.Bridge;
-
-public class BridgeAssetManager extends AssetManager {
-
-    private AssetRepository mAssetRepository;
-
-    /**
-     * This initializes the static field {@link AssetManager#sSystem} which is used
-     * by methods who get a global asset manager using {@link AssetManager#getSystem()}.
-     * <p/>
-     * They will end up using our bridge asset manager.
-     * <p/>
-     * {@link Bridge} calls this method after setting up a new bridge.
-     */
-    public static AssetManager initSystem() {
-        if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
-            // Note that AssetManager() creates a system AssetManager and we override it
-            // with our BridgeAssetManager.
-            AssetManager.sSystem = new BridgeAssetManager();
-            AssetManager.sSystem.makeStringBlocks(null);
-        }
-        return AssetManager.sSystem;
-    }
-
-    /**
-     * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
-     * around that would prevent us from unloading the library.
-     */
-    public static void clearSystem() {
-        AssetManager.sSystem = null;
-    }
-
-    public void setAssetRepository(AssetRepository assetRepository) {
-        mAssetRepository = assetRepository;
-    }
-
-    public AssetRepository getAssetRepository() {
-        return mAssetRepository;
-    }
-
-    public BridgeAssetManager() {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
deleted file mode 100644
index cda8e6a..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * Copyright (C) 2008 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.content.res;
-
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater_Delegate;
-import android.view.ViewGroup.LayoutParams;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-
-import static android.util.TypedValue.TYPE_ATTRIBUTE;
-import static android.util.TypedValue.TYPE_DIMENSION;
-import static android.util.TypedValue.TYPE_FLOAT;
-import static android.util.TypedValue.TYPE_INT_BOOLEAN;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
-import static android.util.TypedValue.TYPE_INT_DEC;
-import static android.util.TypedValue.TYPE_INT_HEX;
-import static android.util.TypedValue.TYPE_NULL;
-import static android.util.TypedValue.TYPE_REFERENCE;
-import static android.util.TypedValue.TYPE_STRING;
-import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
-import static com.android.SdkConstants.PREFIX_THEME_REF;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED;
-
-/**
- * Custom implementation of TypedArray to handle non compiled resources.
- */
-public final class BridgeTypedArray extends TypedArray {
-
-    private final Resources mBridgeResources;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private final ResourceValue[] mResourceData;
-    private final String[] mNames;
-    private final boolean[] mIsFramework;
-
-    // Contains ids that are @empty. We still store null in mResourceData for that index, since we
-    // want to save on the check against empty, each time a resource value is requested.
-    @Nullable
-    private int[] mEmptyIds;
-
-    public BridgeTypedArray(Resources resources, BridgeContext context, int len,
-            boolean platformFile) {
-        super(resources);
-        mBridgeResources = resources;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mResourceData = new ResourceValue[len];
-        mNames = new String[len];
-        mIsFramework = new boolean[len];
-    }
-
-    /**
-     * A bridge-specific method that sets a value in the type array
-     * @param index the index of the value in the TypedArray
-     * @param name the name of the attribute
-     * @param isFramework whether the attribute is in the android namespace.
-     * @param value the value of the attribute
-     */
-    public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) {
-        mResourceData[index] = value;
-        mNames[index] = name;
-        mIsFramework[index] = isFramework;
-    }
-
-    /**
-     * Seals the array after all calls to
-     * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done.
-     * <p/>This allows to compute the list of non default values, permitting
-     * {@link #getIndexCount()} to return the proper value.
-     */
-    public void sealArray() {
-        // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
-        // first count the array size
-        int count = 0;
-        ArrayList<Integer> emptyIds = null;
-        for (int i = 0; i < mResourceData.length; i++) {
-            ResourceValue data = mResourceData[i];
-            if (data != null) {
-                String dataValue = data.getValue();
-                if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
-                    mResourceData[i] = null;
-                } else if (REFERENCE_EMPTY.equals(dataValue)) {
-                    mResourceData[i] = null;
-                    if (emptyIds == null) {
-                        emptyIds = new ArrayList<Integer>(4);
-                    }
-                    emptyIds.add(i);
-                } else {
-                    count++;
-                }
-            }
-        }
-
-        if (emptyIds != null) {
-            mEmptyIds = new int[emptyIds.size()];
-            for (int i = 0; i < emptyIds.size(); i++) {
-                mEmptyIds[i] = emptyIds.get(i);
-            }
-        }
-
-        // allocate the table with an extra to store the size
-        mIndices = new int[count+1];
-        mIndices[0] = count;
-
-        // fill the array with the indices.
-        int index = 1;
-        for (int i = 0 ; i < mResourceData.length ; i++) {
-            if (mResourceData[i] != null) {
-                mIndices[index++] = i;
-            }
-        }
-    }
-
-    /**
-     * Set the theme to be used for inflating drawables.
-     */
-    public void setTheme(Theme theme) {
-        mTheme = theme;
-    }
-
-    /**
-     * Return the number of values in this array.
-     */
-    @Override
-    public int length() {
-        return mResourceData.length;
-    }
-
-    /**
-     * Return the Resources object this array was loaded from.
-     */
-    @Override
-    public Resources getResources() {
-        return mBridgeResources;
-    }
-
-    /**
-     * Retrieve the styled string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence holding string data.  May be styled.  Returns
-     *         null if the attribute is not defined.
-     */
-    @Override
-    public CharSequence getText(int index) {
-        // FIXME: handle styled strings!
-        return getString(index);
-    }
-
-    /**
-     * Retrieve the string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return String holding string data.  Any styling information is
-     * removed.  Returns null if the attribute is not defined.
-     */
-    @Override
-    public String getString(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        // As unfortunate as it is, it's possible to use enums with all attribute formats,
-        // not just integers/enums. So, we need to search the enums always. In case
-        // enums are used, the returned value is an integer.
-        Integer v = resolveEnumAttribute(index);
-        return v == null ? mResourceData[index].getValue() : String.valueOf((int) v);
-    }
-
-    /**
-     * Retrieve the boolean value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute boolean value, or defValue if not defined.
-     */
-    @Override
-    public boolean getBoolean(int index, boolean defValue) {
-        String s = getString(index);
-        return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue);
-
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute int value, or defValue if not defined.
-     */
-    @Override
-    public int getInt(int index, int defValue) {
-        String s = getString(index);
-        try {
-            return convertValueToInt(s, defValue);
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the float value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute float value, or defValue if not defined..
-     */
-    @Override
-    public float getFloat(int index, float defValue) {
-        String s = getString(index);
-        try {
-            if (s != null) {
-                    return Float.parseFloat(s);
-            }
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the color value for the attribute at <var>index</var>.  If
-     * the attribute references a color resource holding a complex
-     * {@link android.content.res.ColorStateList}, then the default color from
-     * the set is returned.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute color value, or defValue if not defined.
-     */
-    @Override
-    public int getColor(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        ColorStateList colorStateList = ResourceHelper.getColorStateList(
-                mResourceData[index], mContext);
-        if (colorStateList != null) {
-            return colorStateList.getDefaultColor();
-        }
-
-        return defValue;
-    }
-
-    @Override
-    public ColorStateList getColorStateList(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getColorStateList(mResourceData[index], mContext);
-    }
-
-    @Override
-    public ComplexColor getComplexColor(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getComplexColor(mResourceData[index], mContext);
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute integer value, or defValue if not defined.
-     */
-    @Override
-    public int getInteger(int index, int defValue) {
-        return getInt(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var>.  Unit
-     * conversions are based on the current {@link DisplayMetrics}
-     * associated with the resources this {@link TypedArray} object
-     * came from.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric, or defValue if not defined.
-     *
-     * @see #getDimensionPixelOffset
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public float getDimension(int index, float defValue) {
-        String s = getString(index);
-        if (s == null) {
-            return defValue;
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            return mValue.getDimension(mBridgeResources.getDisplayMetrics());
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as an offset in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for you.  An offset conversion involves simply
-     * truncating the base value to an integer.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public int getDimensionPixelOffset(int index, int defValue) {
-        return (int) getDimension(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as a size in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for use as a size.  A size conversion involves
-     * rounding the base value, and ensuring that a non-zero base value
-     * is at least one pixel in size.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelOffset
-     */
-    @Override
-    public int getDimensionPixelSize(int index, int defValue) {
-        try {
-            return getDimension(index, null);
-        } catch (RuntimeException e) {
-            String s = getString(index);
-
-            if (s != null) {
-                // looks like we were unable to resolve the dimension value
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                                s, mNames[index]), null);
-            }
-
-            return defValue;
-        }
-    }
-
-    /**
-     * Special version of {@link #getDimensionPixelSize} for retrieving
-     * {@link android.view.ViewGroup}'s layout_width and layout_height
-     * attributes.  This is only here for performance reasons; applications
-     * should use {@link #getDimensionPixelSize}.
-     *
-     * @param index Index of the attribute to retrieve.
-     * @param name Textual name of attribute for error reporting.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels.
-     */
-    @Override
-    public int getLayoutDimension(int index, String name) {
-        try {
-            // this will throw an exception if not found.
-            return getDimension(index, name);
-        } catch (RuntimeException e) {
-
-            if (LayoutInflater_Delegate.sIsInInclude) {
-                throw new RuntimeException("Layout Dimension '" + name + "' not found.");
-            }
-
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    "You must supply a " + name + " attribute.", null);
-
-            return 0;
-        }
-    }
-
-    @Override
-    public int getLayoutDimension(int index, int defValue) {
-        return getDimensionPixelSize(index, defValue);
-    }
-
-    /** @param name attribute name, used for error reporting. */
-    private int getDimension(int index, @Nullable String name) {
-        String s = getString(index);
-        if (s == null) {
-            if (name != null) {
-                throw new RuntimeException("Attribute '" + name + "' not found");
-            }
-            throw new RuntimeException();
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
-
-            final int res = (int)(f+0.5f);
-            if (res != 0) return res;
-            if (f == 0) return 0;
-            if (f > 0) return 1;
-        }
-
-        throw new RuntimeException();
-    }
-
-    /**
-     * Retrieve a fractional unit attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param base The base value of this fraction.  In other words, a
-     *             standard fraction is multiplied by this value.
-     * @param pbase The parent base value of this fraction.  In other
-     *             words, a parent fraction (nn%p) is multiplied by this
-     *             value.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute fractional value multiplied by the appropriate
-     * base value, or defValue if not defined.
-     */
-    @Override
-    public float getFraction(int index, int base, int pbase, float defValue) {
-        String value = getString(index);
-        if (value == null) {
-            return defValue;
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) {
-            return mValue.getFraction(base, pbase);
-        }
-
-        // looks like we were unable to resolve the fraction value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                        "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
-                        value, mNames[index]), null);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the resource identifier for the attribute at
-     * <var>index</var>.  Note that attribute resource as resolved when
-     * the overall {@link TypedArray} object is retrieved.  As a
-     * result, this function will return the resource identifier of the
-     * final resource value that was found, <em>not</em> necessarily the
-     * original resource that was specified by the attribute.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute resource identifier, or defValue if not defined.
-     */
-    @Override
-    public int getResourceId(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        // get the Resource for this index
-        ResourceValue resValue = mResourceData[index];
-
-        // no data, return the default value.
-        if (resValue == null) {
-            return defValue;
-        }
-
-        // check if this is a style resource
-        if (resValue instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
-        }
-
-        // if the attribute was a reference to a resource, and not a declaration of an id (@+id),
-        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
-        // valid getType() and getName() returning a resource name.
-        // (and getValue() returning null!). We need to handle this!
-        if (resValue.getResourceType() != null) {
-            // if this is a framework id
-            if (mPlatformFile || resValue.isFramework()) {
-                // look for idName in the android R classes
-                return mContext.getFrameworkResourceValue(
-                        resValue.getResourceType(), resValue.getName(), defValue);
-            }
-
-            // look for idName in the project R class.
-            return mContext.getProjectResourceValue(
-                    resValue.getResourceType(), resValue.getName(), defValue);
-        }
-
-        // else, try to get the value, and resolve it somehow.
-        String value = resValue.getValue();
-        if (value == null) {
-            return defValue;
-        }
-        value = value.trim();
-
-        // if the value is just an integer, return it.
-        try {
-            int i = Integer.parseInt(value);
-            if (Integer.toString(i).equals(value)) {
-                return i;
-            }
-        } catch (NumberFormatException e) {
-            // pass
-        }
-
-        if (value.startsWith("#")) {
-            // this looks like a color, do not try to parse it
-            return defValue;
-        }
-
-        // Handle the @id/<name>, @+id/<name> and @android:id/<name>
-        // We need to return the exact value that was compiled (from the various R classes),
-        // as these values can be reused internally with calls to findViewById().
-        // There's a trick with platform layouts that not use "android:" but their IDs are in
-        // fact in the android.R and com.android.internal.R classes.
-        // The field mPlatformFile will indicate that all IDs are to be looked up in the android R
-        // classes exclusively.
-
-        // if this is a reference to an id, find it.
-        if (value.startsWith("@id/") || value.startsWith("@+") ||
-                value.startsWith("@android:id/")) {
-
-            int pos = value.indexOf('/');
-            String idName = value.substring(pos + 1);
-            boolean create = value.startsWith("@+");
-            boolean isFrameworkId =
-                    mPlatformFile || value.startsWith("@android") || value.startsWith("@+android");
-
-            // Look for the idName in project or android R class depending on isPlatform.
-            if (create) {
-                Integer idValue;
-                if (isFrameworkId) {
-                    idValue = Bridge.getResourceId(ResourceType.ID, idName);
-                } else {
-                    idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
-                }
-                return idValue == null ? defValue : idValue;
-            }
-            // This calls the same method as in if(create), but doesn't create a dynamic id, if
-            // one is not found.
-            if (isFrameworkId) {
-                return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
-            } else {
-                return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
-            }
-        }
-        else if (value.startsWith("@aapt:_aapt")) {
-            return mContext.getLayoutlibCallback().getResourceId(ResourceType.AAPT, value);
-        }
-
-        // not a direct id valid reference. First check if it's an enum (this is a corner case
-        // for attributes that have a reference|enum type), then fallback to resolve
-        // as an ID without prefix.
-        Integer enumValue = resolveEnumAttribute(index);
-        if (enumValue != null) {
-            return enumValue;
-        }
-
-        // Ok, not an enum, resolve as an ID
-        Integer idValue;
-
-        if (resValue.isFramework()) {
-            idValue = Bridge.getResourceId(resValue.getResourceType(),
-                    resValue.getName());
-        } else {
-            idValue = mContext.getLayoutlibCallback().getResourceId(
-                    resValue.getResourceType(), resValue.getName());
-        }
-
-        if (idValue != null) {
-            return idValue;
-        }
-
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
-                String.format(
-                    "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
-                    resValue);
-
-        return defValue;
-    }
-
-    @Override
-    public int getThemeAttributeId(int index, int defValue) {
-        // TODO: Get the right Theme Attribute ID to enable caching of the drawables.
-        return defValue;
-    }
-
-    /**
-     * Retrieve the Drawable for the attribute at <var>index</var>.  This
-     * gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getDrawable Resources.getDrawable} of the owning
-     * Resources object to retrieve its Drawable.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Drawable for the attribute, or null if not defined.
-     */
-    @Override
-    public Drawable getDrawable(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getDrawable(value, mContext, mTheme);
-    }
-
-
-    /**
-     * Retrieve the Typeface for the attribute at <var>index</var>.
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Typeface for the attribute, or null if not defined.
-     */
-    @Override
-    public Typeface getFont(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getFont(value, mContext, mTheme);
-    }
-
-    /**
-     * Retrieve the CharSequence[] for the attribute at <var>index</var>.
-     * This gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getTextArray Resources.getTextArray} of the owning
-     * Resources object to retrieve its String[].
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence[] for the attribute, or null if not defined.
-     */
-    @Override
-    public CharSequence[] getTextArray(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        ResourceValue resVal = mResourceData[index];
-        if (resVal instanceof ArrayResourceValue) {
-            ArrayResourceValue array = (ArrayResourceValue) resVal;
-            int count = array.getElementCount();
-            return count >= 0 ? Resources_Delegate.fillValues(mBridgeResources, array, new CharSequence[count]) :
-                    null;
-        }
-        int id = getResourceId(index, 0);
-        String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : "";
-        assert false :
-                String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(),
-                        mNames[index], resIdMessage);
-
-        return new CharSequence[0];
-    }
-
-    @Override
-    public int[] extractThemeAttrs() {
-        // The drawables are always inflated with a Theme and we don't care about caching. So,
-        // just return.
-        return null;
-    }
-
-    @Override
-    public int getChangingConfigurations() {
-        // We don't care about caching. Any change in configuration is a fresh render. So,
-        // just return.
-        return 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param outValue TypedValue object in which to place the attribute's
-     *                 data.
-     *
-     * @return Returns true if the value was retrieved, else false.
-     */
-    @Override
-    public boolean getValue(int index, TypedValue outValue) {
-        String s = getString(index);
-        return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
-    }
-
-    @Override
-    @SuppressWarnings("ResultOfMethodCallIgnored")
-    public int getType(int index) {
-        String value = getString(index);
-        if (value == null) {
-            return TYPE_NULL;
-        }
-        if (value.startsWith(PREFIX_RESOURCE_REF)) {
-            return TYPE_REFERENCE;
-        }
-        if (value.startsWith(PREFIX_THEME_REF)) {
-            return TYPE_ATTRIBUTE;
-        }
-        try {
-            // Don't care about the value. Only called to check if an exception is thrown.
-            convertValueToInt(value, 0);
-            if (value.startsWith("0x") || value.startsWith("0X")) {
-                return TYPE_INT_HEX;
-            }
-            // is it a color?
-            if (value.startsWith("#")) {
-                int length = value.length() - 1;
-                if (length == 3) {  // rgb
-                    return TYPE_INT_COLOR_RGB4;
-                }
-                if (length == 4) {  // argb
-                    return TYPE_INT_COLOR_ARGB4;
-                }
-                if (length == 6) {  // rrggbb
-                    return TYPE_INT_COLOR_RGB8;
-                }
-                if (length == 8) {  // aarrggbb
-                    return TYPE_INT_COLOR_ARGB8;
-                }
-            }
-            if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
-                return TYPE_INT_BOOLEAN;
-            }
-            return TYPE_INT_DEC;
-        } catch (NumberFormatException ignored) {
-            try {
-                Float.parseFloat(value);
-                return TYPE_FLOAT;
-            } catch (NumberFormatException ignore) {
-            }
-            // Might be a dimension.
-            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
-                return TYPE_DIMENSION;
-            }
-        }
-        // TODO: handle fractions.
-        return TYPE_STRING;
-    }
-
-    /**
-     * Determines whether there is an attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return True if the attribute has a value, false otherwise.
-     */
-    @Override
-    public boolean hasValue(int index) {
-        return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
-    }
-
-    @Override
-    public boolean hasValueOrEmpty(int index) {
-        return hasValue(index) || index >= 0 && index < mResourceData.length &&
-                mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>
-     * and return a temporary object holding its data.  This object is only
-     * valid until the next call on to {@link TypedArray}.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Returns a TypedValue object if the attribute is defined,
-     *         containing its data; otherwise returns null.  (You will not
-     *         receive a TypedValue whose type is TYPE_NULL.)
-     */
-    @Override
-    public TypedValue peekValue(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (getValue(index, mValue)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a message about the parser state suitable for printing error messages.
-     */
-    @Override
-    public String getPositionDescription() {
-        return "<internal -- stub if needed>";
-    }
-
-    /**
-     * Give back a previously retrieved TypedArray, for later re-use.
-     */
-    @Override
-    public void recycle() {
-        // pass
-    }
-
-    @Override
-    public String toString() {
-        return Arrays.toString(mResourceData);
-    }
-
-    /**
-     * Searches for the string in the attributes (flag or enums) and returns the integer.
-     * If found, it will return an integer matching the value.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute int value, or null if not defined.
-     */
-    private Integer resolveEnumAttribute(int index) {
-        // Get the map of attribute-constant -> IntegerValue
-        Map<String, Integer> map = null;
-        if (mIsFramework[index]) {
-            map = Bridge.getEnumValues(mNames[index]);
-        } else {
-            // get the styleable matching the resolved name
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
-            if (attr instanceof AttrResourceValue) {
-                map = ((AttrResourceValue) attr).getAttributeValues();
-            }
-        }
-
-        if (map != null) {
-            // accumulator to store the value of the 1+ constants.
-            int result = 0;
-            boolean found = false;
-
-            // split the value in case this is a mix of several flags.
-            String[] keywords = mResourceData[index].getValue().split("\\|");
-            for (String keyword : keywords) {
-                Integer i = map.get(keyword.trim());
-                if (i != null) {
-                    result |= i;
-                    found = true;
-                }
-                // TODO: We should act smartly and log a warning for incorrect keywords. However,
-                // this method is currently called even if the resourceValue is not an enum.
-            }
-            if (found) {
-                return result;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account
-     * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle
-     * "XXXXXXXX" > 80000000.
-     */
-    private static int convertValueToInt(@Nullable String charSeq, int defValue) {
-        if (null == charSeq || charSeq.isEmpty())
-            return defValue;
-
-        int sign = 1;
-        int index = 0;
-        int len = charSeq.length();
-        int base = 10;
-
-        if ('-' == charSeq.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == charSeq.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = charSeq.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                // Leave the base as 10. aapt removes the preceding zero, and thus when framework
-                // sees the value, it only gets the decimal value.
-            }
-        } else if ('#' == charSeq.charAt(index)) {
-            return ResourceHelper.getColor(charSeq) * sign;
-        } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) {
-            return -1;
-        } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) {
-            return 0;
-        }
-
-        // Use Long, since we want to handle hex ints > 80000000.
-        return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
-    }
-
-    static TypedArray obtain(Resources res, int len) {
-        return new BridgeTypedArray(res, null, len, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java b/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
deleted file mode 100644
index 09c0260..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
+++ /dev/null
@@ -1,46 +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 android.content.res;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.Theme;
-import android.util.AttributeSet;
-
-import java.io.IOException;
-
-/**
- * Class that provides access to the {@link GradientColor#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} and {@link ColorStateList#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} methods
- */
-public class ComplexColor_Accessor {
-    public static GradientColor createGradientColorFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return GradientColor.createFromXmlInner(r, parser, attrs, theme);
-    }
-
-    public static ColorStateList createColorStateListFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return ColorStateList.createFromXmlInner(r, parser, attrs, theme);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
deleted file mode 100644
index c20ee12..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ /dev/null
@@ -1,1025 +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 android.content.res;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.PluralsResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import com.android.ninepatch.NinePatch;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.icu.text.PluralRules;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.LruCache;
-import android.util.TypedValue;
-import android.view.DisplayAdjustments;
-import android.view.ViewGroup.LayoutParams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Iterator;
-
-@SuppressWarnings("deprecation")
-public class Resources_Delegate {
-
-    private static boolean[] mPlatformResourceFlag = new boolean[1];
-    // TODO: This cache is cleared every time a render session is disposed. Look into making this
-    // more long lived.
-    private static LruCache<String, Drawable.ConstantState> sDrawableCache = new LruCache<>(50);
-
-    public static Resources initSystem(BridgeContext context,
-            AssetManager assets,
-            DisplayMetrics metrics,
-            Configuration config,
-            LayoutlibCallback layoutlibCallback) {
-        Resources resources = new Resources(Resources_Delegate.class.getClassLoader());
-        resources.setImpl(new ResourcesImpl(assets, metrics, config, new DisplayAdjustments()));
-        resources.mContext = context;
-        resources.mLayoutlibCallback = layoutlibCallback;
-        return Resources.mSystem = resources;
-    }
-
-    /**
-     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects around that
-     * would prevent us from unloading the library.
-     */
-    public static void disposeSystem() {
-        sDrawableCache.evictAll();
-        Resources.mSystem.mContext = null;
-        Resources.mSystem.mLayoutlibCallback = null;
-        Resources.mSystem = null;
-    }
-
-    public static BridgeTypedArray newTypeArray(Resources resources, int numEntries,
-            boolean platformFile) {
-        return new BridgeTypedArray(resources, resources.mContext, numEntries, platformFile);
-    }
-
-    private static Pair<ResourceType, String> getResourceInfo(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        // Set the layoutlib callback and context for resources
-        if (resources != Resources.mSystem && resources.mLayoutlibCallback == null) {
-            resources.mLayoutlibCallback = Resources.mSystem.mLayoutlibCallback;
-            resources.mContext = Resources.mSystem.mContext;
-        }
-
-        if (resourceInfo != null) {
-            platformResFlag_out[0] = true;
-            return resourceInfo;
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (resources.mLayoutlibCallback != null) {
-            resourceInfo = resources.mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                platformResFlag_out[0] = false;
-                return resourceInfo;
-            }
-        }
-        return null;
-    }
-
-    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        Pair<ResourceType, String> resourceInfo =
-                getResourceInfo(resources, id, platformResFlag_out);
-
-        if (resourceInfo != null) {
-            String attributeName = resourceInfo.getSecond();
-            RenderResources renderResources = resources.mContext.getRenderResources();
-            ResourceValue value = platformResFlag_out[0] ?
-                    renderResources.getFrameworkResource(resourceInfo.getFirst(), attributeName) :
-                    renderResources.getProjectResource(resourceInfo.getFirst(), attributeName);
-
-            if (value == null) {
-                // Unable to resolve the attribute, just leave the unresolved value
-                value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName,
-                        platformResFlag_out[0]);
-            }
-            return Pair.of(attributeName, value);
-        }
-
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id) {
-        return getDrawable(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id, Theme theme) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            String key = value.getSecond().getValue();
-
-            Drawable.ConstantState constantState = key != null ? sDrawableCache.get(key) : null;
-            Drawable drawable;
-            if (constantState != null) {
-                drawable = constantState.newDrawable(resources, theme);
-            } else {
-                drawable =
-                        ResourceHelper.getDrawable(value.getSecond(), resources.mContext, theme);
-
-                if (key != null) {
-                    sDrawableCache.put(key, drawable.getConstantState());
-                }
-            }
-
-            return drawable;
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id) {
-        return getColor(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id, Theme theme) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resourceValue = value.getSecond();
-            try {
-                return ResourceHelper.getColor(resourceValue.getValue());
-            } catch (NumberFormatException e) {
-                // Check if the value passed is a file. If it is, mostly likely, user is referencing
-                // a color state list from a place where they should reference only a pure color.
-                String message;
-                if (new File(resourceValue.getValue()).isFile()) {
-                    String resource = (resourceValue.isFramework() ? "@android:" : "@") + "color/"
-                            + resourceValue.getName();
-                    message = "Hexadecimal color expected, found Color State List for " + resource;
-                } else {
-                    message = e.getMessage();
-                }
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null);
-                return 0;
-            }
-        }
-
-        // Suppress possible NPE. getColorStateList will never return null, it will instead
-        // throw an exception, but intelliJ can't figure that out
-        //noinspection ConstantConditions
-        return getColorStateList(resources, id, theme).getDefaultColor();
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id) throws NotFoundException {
-        return getColorStateList(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id, Theme theme)
-            throws NotFoundException {
-        Pair<String, ResourceValue> resValue =
-                getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (resValue != null) {
-            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
-                    resources.mContext);
-            if (stateList != null) {
-                return stateList.obtainForTheme(theme);
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id, CharSequence def) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence[] getTextArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new CharSequence[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new CharSequence[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new CharSequence[arv.getElementCount()]);
-    }
-
-    @LayoutlibDelegate
-    static String[] getStringArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new String[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new String[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new String[arv.getElementCount()]);
-    }
-
-    /**
-     * Resolve each element in resValue and copy them to {@code values}. The values copied are
-     * always Strings. The ideal signature for the method should be &lt;T super String&gt;, but java
-     * generics don't support it.
-     */
-    static <T extends CharSequence> T[] fillValues(Resources resources, ArrayResourceValue resValue,
-            T[] values) {
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            @SuppressWarnings("unchecked")
-            T s = (T) resolveReference(resources, iterator.next(), resValue.isFramework());
-            values[i] = s;
-        }
-        return values;
-    }
-
-    @LayoutlibDelegate
-    static int[] getIntArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue rv = getArrayResourceValue(resources, id);
-        if (rv == null) {
-            // Error already logged by getArrayResourceValue.
-            return new int[0];
-        } else if (!(rv instanceof ArrayResourceValue)) {
-            // This is an older IDE that can only give us the first element of the array.
-            String firstValue = resolveReference(resources, rv.getValue(), rv.isFramework());
-            try {
-                return new int[]{getInt(firstValue)};
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " +
-                                firstValue, null);
-                return new int[1];
-            }
-        }
-        ArrayResourceValue resValue = ((ArrayResourceValue) rv);
-        int[] values = new int[resValue.getElementCount()];
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            String element = resolveReference(resources, iterator.next(), resValue.isFramework());
-            try {
-                values[i] = getInt(element);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " + element, null);
-            }
-        }
-        return values;
-    }
-
-    /**
-     * Try to find the ArrayResourceValue for the given id.
-     * <p/>
-     * If the ResourceValue found is not of type {@link ResourceType#ARRAY}, the method logs an
-     * error and return null. However, if the ResourceValue found has type {@code
-     * ResourceType.ARRAY}, but the value is not an instance of {@link ArrayResourceValue}, the
-     * method returns the ResourceValue. This happens on older versions of the IDE, which did not
-     * parse the array resources properly.
-     * <p/>
-     *
-     * @throws NotFoundException if no resource if found
-     */
-    @Nullable
-    private static ResourceValue getArrayResourceValue(Resources resources, int id)
-            throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue resValue = v.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                final ResourceType type = resValue.getResourceType();
-                if (type != ResourceType.ARRAY) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                            String.format(
-                                    "Resource with id 0x%1$X is not an array resource, but %2$s",
-                                    id, type == null ? "null" : type.getDisplayName()),
-                            null);
-                    return null;
-                }
-                if (!(resValue instanceof ArrayResourceValue)) {
-                    Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
-                            "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.",
-                            null);
-                }
-                return resValue;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @NonNull
-    private static String resolveReference(Resources resources, @NonNull String ref,
-            boolean forceFrameworkOnly) {
-        if (ref.startsWith(SdkConstants.PREFIX_RESOURCE_REF) || ref.startsWith
-                (SdkConstants.PREFIX_THEME_REF)) {
-            ResourceValue rv =
-                    resources.mContext.getRenderResources().findResValue(ref, forceFrameworkOnly);
-            rv = resources.mContext.getRenderResources().resolveResValue(rv);
-            if (rv != null) {
-                return rv.getValue();
-            }
-        }
-        // Not a reference.
-        return ref;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getLayout(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser = null;
-
-            try {
-                // check if the current parser can provide us with a custom parser.
-                if (!mPlatformResourceFlag[0]) {
-                    parser = resources.mLayoutlibCallback.getParser(value);
-                }
-
-                // create a new one manually if needed.
-                if (parser == null) {
-                    File xml = new File(value.getValue());
-                    if (xml.isFile()) {
-                        // we need to create a pull parser around the layout XML file, and then
-                        // give that to our XmlBlockParser
-                        parser = ParserFactory.create(xml, true);
-                    }
-                }
-
-                if (parser != null) {
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getAnimation(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser;
-
-            try {
-                File xml = new File(value.getValue());
-                if (xml.isFile()) {
-                    // we need to create a pull parser around the layout XML file, and then
-                    // give that to our XmlBlockParser
-                    parser = ParserFactory.create(xml);
-
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, AttributeSet set, int[] attrs) {
-        return resources.mContext.obtainStyledAttributes(set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, Resources.Theme theme, AttributeSet
-            set, int[] attrs) {
-        return Resources.obtainAttributes_Original(resources, theme, set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainTypedArray(Resources resources, int id) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static float getDimension(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
-                            v.equals(BridgeConstants.FILL_PARENT)) {
-                        return LayoutParams.MATCH_PARENT;
-                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
-                        return LayoutParams.WRAP_CONTENT;
-                    }
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return tmpValue.getDimension(resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelOffset(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelOffset(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelSize(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelSize(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getInteger(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    try {
-                        return getInt(v);
-                    } catch (NumberFormatException e) {
-                        // return exception below
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static boolean getBoolean(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return Boolean.parseBoolean(v);
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return false;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceEntryName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-
-    }
-
-    @LayoutlibDelegate
-    static String getResourceName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        String packageName;
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                packageName = SdkConstants.ANDROID_NS_NAME;
-            } else {
-                packageName = resources.mContext.getPackageName();
-                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
-            }
-            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
-                    resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourcePackageName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                return SdkConstants.ANDROID_NS_NAME;
-            }
-            String packageName = resources.mContext.getPackageName();
-            return packageName == null ? SdkConstants.APP_PREFIX : packageName;
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceTypeName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getFirst().getName();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id, Object... formatArgs)
-            throws NotFoundException {
-        String s = getString(resources, id);
-        if (s != null) {
-            return String.format(s, formatArgs);
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null && value.getSecond().getValue() != null) {
-            return value.getSecond().getValue();
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            if (value.getSecond() instanceof PluralsResourceValue) {
-                PluralsResourceValue pluralsResourceValue = (PluralsResourceValue) value.getSecond();
-                PluralRules pluralRules = PluralRules.forLocale(resources.getConfiguration().getLocales()
-                        .get(0));
-                String strValue = pluralsResourceValue.getValue(pluralRules.select(quantity));
-                if (strValue == null) {
-                    strValue = pluralsResourceValue.getValue(PluralRules.KEYWORD_OTHER);
-                }
-
-                return strValue;
-            }
-            else {
-                return value.getSecond().getValue();
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity, Object... formatArgs)
-            throws NotFoundException {
-        String raw = getQuantityString(resources, id, quantity);
-        return String.format(resources.getConfiguration().getLocales().get(0), raw, formatArgs);
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getQuantityText(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        return getQuantityString(resources, id, quantity);
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, int id) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            return ResourceHelper.getFont(value.getSecond(), resources.mContext, null);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, TypedValue outValue, int id) throws
-            NotFoundException {
-        Resources_Delegate.getValue(resources, id, outValue, true);
-        if (outValue.string != null) {
-            return ResourceHelper.getFont(outValue.string.toString(), resources.mContext, null,
-                    mPlatformResourceFlag[0]);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, int id, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resVal = value.getSecond();
-            String v = resVal.getValue();
-
-            if (v != null) {
-                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
-                        false /*requireUnit*/)) {
-                    return;
-                }
-                if (resVal instanceof DensityBasedResourceValue) {
-                    outValue.density =
-                            ((DensityBasedResourceValue) resVal).getResourceDensity().getDpiValue();
-                }
-
-                // else it's a string
-                outValue.type = TypedValue.TYPE_STRING;
-                outValue.string = v;
-                return;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, String name, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getXml(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String v = value.getSecond().getValue();
-
-            if (v != null) {
-                // check this is a file
-                File f = new File(v);
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f);
-
-                        return new BridgeXmlBlockParser(parser, resources.mContext,
-                                mPlatformResourceFlag[0]);
-                    } catch (XmlPullParserException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, int id,
-            String type) throws NotFoundException {
-        return resources.loadXmlResourceParser_Original(id, type);
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, String file, int id,
-            int assetCookie, String type) throws NotFoundException {
-        // even though we know the XML file to load directly, we still need to resolve the
-        // id so that we can know if it's a platform or project resource.
-        // (mPlatformResouceFlag will get the result and will be used later).
-        getResourceValue(resources, id, mPlatformResourceFlag);
-
-        File f = new File(file);
-        try {
-            XmlPullParser parser = ParserFactory.create(f);
-
-            return new BridgeXmlBlockParser(parser, resources.mContext, mPlatformResourceFlag[0]);
-        } catch (XmlPullParserException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        } catch (FileNotFoundException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        }
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String path = value.getSecond().getValue();
-
-            if (path != null) {
-                // check this is a file
-                File f = new File(path);
-                if (f.isFile()) {
-                    try {
-                        // if it's a nine-patch return a custom input stream so that
-                        // other methods (mainly bitmap factory) can detect it's a 9-patch
-                        // and actually load it as a 9-patch instead of a normal bitmap
-                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                            return new NinePatchInputStream(f);
-                        }
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id, TypedValue value) throws
-            NotFoundException {
-        getValue(resources, id, value, true);
-
-        String path = value.string.toString();
-
-        File f = new File(path);
-        if (f.isFile()) {
-            try {
-                // if it's a nine-patch return a custom input stream so that
-                // other methods (mainly bitmap factory) can detect it's a 9-patch
-                // and actually load it as a 9-patch instead of a normal bitmap
-                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                    return new NinePatchInputStream(f);
-                }
-                return new FileInputStream(f);
-            } catch (FileNotFoundException e) {
-                NotFoundException exception = new NotFoundException();
-                exception.initCause(e);
-                throw exception;
-            }
-        }
-
-        throw new NotFoundException();
-    }
-
-    @LayoutlibDelegate
-    static AssetFileDescriptor openRawResourceFd(Resources resources, int id) throws
-            NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource
-     * type.
-     *
-     * @param id the id of the resource
-     *
-     * @throws NotFoundException
-     */
-    private static void throwException(Resources resources, int id) throws NotFoundException {
-        throwException(id, getResourceInfo(resources, id, new boolean[1]));
-    }
-
-    private static void throwException(int id, @Nullable Pair<ResourceType, String> resourceInfo) {
-        String message;
-        if (resourceInfo != null) {
-            message = String.format(
-                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
-                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
-        } else {
-            message = String.format("Could not resolve resource value: 0x%1$X.", id);
-        }
-
-        throw new NotFoundException(message);
-    }
-
-    private static int getInt(String v) throws NumberFormatException {
-        int radix = 10;
-        if (v.startsWith("0x")) {
-            v = v.substring(2);
-            radix = 16;
-        } else if (v.startsWith("0")) {
-            radix = 8;
-        }
-        return Integer.parseInt(v, radix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
deleted file mode 100644
index f1e8fc21..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 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.content.res;
-
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources.ThemeKey;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme}
- *
- * Through the layoutlib_create tool, the original  methods of Theme have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Resources_Theme_Delegate {
-
-    // ---- delegate manager ----
-
-    private static final DelegateManager<Resources_Theme_Delegate> sManager =
-            new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class);
-
-    public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
-        return sManager;
-    }
-
-    // ---- delegate methods. ----
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int[] attrs) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int resid, int[] attrs)
-            throws NotFoundException {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid,
-                attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set,
-                attrs, defStyleAttr, defStyleRes);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean resolveAttribute(
-            Resources thisResources, Theme thisTheme,
-            int resid, TypedValue outValue,
-            boolean resolveRefs) {
-        boolean changed = setupResources(thisTheme);
-        boolean found =  RenderSessionImpl.getCurrentContext().resolveThemeAttribute(resid,
-                outValue, resolveRefs);
-        restoreResources(changed);
-        return found;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme,
-            int[] values, int[] attrs) {
-        // FIXME
-        return null;
-    }
-
-    // ---- private helper methods ----
-
-    private static boolean setupResources(Theme thisTheme) {
-        // Key is a space-separated list of theme ids applied that have been merged into the
-        // BridgeContext's theme to make thisTheme.
-        final ThemeKey key = thisTheme.getKey();
-        final int[] resId = key.mResId;
-        final boolean[] force = key.mForce;
-
-        boolean changed = false;
-        for (int i = 0, N = key.mCount; i < N; i++) {
-            StyleResourceValue style = resolveStyle(resId[i]);
-            if (style != null) {
-                RenderSessionImpl.getCurrentContext().getRenderResources().applyStyle(
-                        style, force[i]);
-                changed = true;
-            }
-
-        }
-        return changed;
-    }
-
-    private static void restoreResources(boolean changed) {
-        if (changed) {
-            RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
-        }
-    }
-
-    @Nullable
-    private static StyleResourceValue resolveStyle(int nativeResid) {
-        if (nativeResid == 0) {
-            return null;
-        }
-        BridgeContext context = RenderSessionImpl.getCurrentContext();
-        ResourceReference theme = context.resolveId(nativeResid);
-        if (theme.isFramework()) {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getFrameworkResource(ResourceType.STYLE, theme.getName());
-        } else {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getProjectResource(ResourceType.STYLE, theme.getName());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
deleted file mode 100644
index faa8852..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011 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.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.TypedValue;
-
-public class TypedArray_Delegate {
-
-    @LayoutlibDelegate
-    public static boolean getValueAt(TypedArray theTypedArray, int index, TypedValue outValue) {
-        // pass
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtain(Resources res, int len) {
-        return BridgeTypedArray.obtain(res, len);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
deleted file mode 100644
index cc71053..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
+++ /dev/null
@@ -1,762 +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 android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.layoutlib.bridge.impl.PorterDuffUtility;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.text.TextUtils;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-
-public class BaseCanvas_Delegate {
-    // ---- delegate manager ----
-    protected static DelegateManager<BaseCanvas_Delegate> sManager =
-            new DelegateManager<>(BaseCanvas_Delegate.class);
-
-    // ---- delegate helper data ----
-    private final static boolean[] sBoolOut = new boolean[1];
-
-
-    // ---- delegate data ----
-    protected Bitmap_Delegate mBitmap;
-    protected GcSnapshot mSnapshot;
-
-    // ---- Public Helper methods ----
-
-    protected BaseCanvas_Delegate(Bitmap_Delegate bitmap) {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
-    }
-
-    protected BaseCanvas_Delegate() {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
-    }
-
-    /**
-     * Disposes of the {@link Graphics2D} stack.
-     */
-    protected void dispose() {
-        mSnapshot.dispose();
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-        float right = left + image.getWidth();
-        float bottom = top + image.getHeight();
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                0, 0, image.getWidth(), image.getHeight(),
-                (int)left, (int)top, (int)right, (int)bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft, float srcTop,
-            float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
-            float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, (int) srcLeft, (int) srcTop,
-                (int) srcRight, (int) srcBottom, (int) dstLeft, (int) dstTop, (int) dstRight,
-                (int) dstBottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
-            final float x, final float y, int width, int height, boolean hasAlpha,
-            long nativePaintOrZero) {
-        // create a temp BufferedImage containing the content.
-        final BufferedImage image = new BufferedImage(width, height,
-                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
-        image.setRGB(0, 0, width, height, colors, offset, stride);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    graphics.drawImage(image, (int) x, (int) y, null);
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawColor(long nativeCanvas, final int color, final int mode) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        final int w = canvasDelegate.mBitmap.getImage().getWidth();
-        final int h = canvasDelegate.mBitmap.getImage().getHeight();
-        draw(nativeCanvas, (graphics, paint) -> {
-            // reset its transform just in case
-            graphics.setTransform(new AffineTransform());
-
-            // set the color
-            graphics.setColor(new java.awt.Color(color, true /*alpha*/));
-
-            Composite composite = PorterDuffUtility.getComposite(
-                    PorterDuffUtility.getPorterDuffMode(mode), 0xFF);
-            if (composite != null) {
-                graphics.setComposite(composite);
-            }
-
-            graphics.fillRect(0, 0, w, h);
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPaint(long nativeCanvas, long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPaint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoint(long nativeCanvas, float x, float y,
-            long nativePaint) {
-        // TODO: need to support the attribute (e.g. stroke width) of paint
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.fillRect((int)x, (int)y, 1, 1));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoints(long nativeCanvas, float[] pts, int offset, int count,
-            long nativePaint) {
-        if (offset < 0 || count < 0 || offset + count > pts.length) {
-            throw new IllegalArgumentException("Invalid argument set");
-        }
-        // ignore the last point if the count is odd (It means it is not paired).
-        count = (count >> 1) << 1;
-        for (int i = offset; i < offset + count; i += 2) {
-            nDrawPoint(nativeCanvas, pts[i], pts[i + 1], nativePaint);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLine(long nativeCanvas,
-            final float startX, final float startY, final float stopX, final float stopY,
-            long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLines(long nativeCanvas,
-            final float[] pts, final int offset, final int count,
-            long nativePaint) {
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/,
-                false /*forceSrcMode*/, (graphics, paintDelegate) -> {
-                    for (int i = 0; i < count; i += 4) {
-                        graphics.drawLine((int) pts[i + offset], (int) pts[i + offset + 1],
-                                (int) pts[i + offset + 2], (int) pts[i + offset + 3]);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom, long paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawOval(long nativeCanvas, final float left,
-            final float top, final float right, final float bottom, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fillOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.drawOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawCircle(long nativeCanvas,
-            float cx, float cy, float radius, long paint) {
-        nDrawOval(nativeCanvas,
-                cx - radius, cy - radius, cx + radius, cy + radius,
-                paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawArc(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float startAngle, final float sweep,
-            final boolean useCenter, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        Arc2D.Float arc = new Arc2D.Float(
-                                left, top, right - left, bottom - top,
-                                -startAngle, -sweep,
-                                useCenter ? Arc2D.PIE : Arc2D.OPEN);
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fill(arc);
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.draw(arc);
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRoundRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float rx, final float ry, long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    public static void nDrawPath(long nativeCanvas, long path, long paint) {
-        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    Shape shape = pathDelegate.getJavaShape();
-                    Rectangle2D bounds = shape.getBounds2D();
-                    if (bounds.isEmpty()) {
-                        // Apple JRE 1.6 doesn't like drawing empty shapes.
-                        // http://b.android.com/178278
-
-                        if (pathDelegate.isEmpty()) {
-                            // This means that the path doesn't have any lines or curves so
-                            // nothing to draw.
-                            return;
-                        }
-
-                        // The stroke width is not consider for the size of the bounds so,
-                        // for example, a horizontal line, would be considered as an empty
-                        // rectangle.
-                        // If the strokeWidth is not 0, we use it to consider the size of the
-                        // path as well.
-                        float strokeWidth = paintDelegate.getStrokeWidth();
-                        if (strokeWidth <= 0.0f) {
-                            return;
-                        }
-                        bounds.setRect(bounds.getX(), bounds.getY(),
-                                Math.max(strokeWidth, bounds.getWidth()),
-                                Math.max(strokeWidth, bounds.getHeight()));
-                    }
-
-                    int style = paintDelegate.getStyle();
-
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fill(shape);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.draw(shape);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRegion(long nativeCanvas, long nativeRegion,
-            long nativePaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Some canvas paths may not be drawn", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
-            final float dstLeft, final float dstTop, final float dstRight, final float dstBottom,
-            long nativePaintOrZero, final int screenDensity, final int bitmapDensity) {
-
-        // get the delegate from the native int.
-        final Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        byte[] c = NinePatch_Delegate.getChunk(ninePatch);
-        if (c == null) {
-            // not a 9-patch?
-            BufferedImage image = bitmapDelegate.getImage();
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, 0, 0, image.getWidth(),
-                    image.getHeight(), (int) dstLeft, (int) dstTop, (int) dstRight,
-                    (int) dstBottom);
-            return;
-        }
-
-        final NinePatchChunk chunkObject = NinePatch_Delegate.getChunk(c);
-        assert chunkObject != null;
-        if (chunkObject == null) {
-            return;
-        }
-
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // this one can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
-            @Override
-            public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                chunkObject.draw(bitmapDelegate.getImage(), graphics, (int) dstLeft, (int) dstTop,
-                        (int) (dstRight - dstLeft), (int) (dstBottom - dstTop), screenDensity,
-                        bitmapDensity);
-            }
-        }, paintDelegate, true, false);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
-            long nMatrix, long nPaint) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the delegate from the native int, which can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        final AffineTransform mtx = matrixDelegate.getAffineTransform();
-
-        canvasDelegate.getSnapshot().draw((graphics, paint) -> {
-            if (paint != null && paint.isFilterBitmap()) {
-                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-            }
-
-            //FIXME add support for canvas, screen and bitmap densities.
-            graphics.drawImage(image, mtx, null);
-        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMesh(long nCanvas, Bitmap bitmap,
-            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
-            int colorOffset, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawVertices(long nCanvas, int mode, int n,
-            float[] verts, int vertOffset,
-            float[] texs, int texOffset,
-            int[] colors, int colorOffset,
-            short[] indices, int indexOffset,
-            int indexCount, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawVertices is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, char[] text, int index, int count,
-            float startX, float startY, int flags, long paint, long typeface) {
-        drawText(nativeCanvas, text, index, count, startX, startY, (flags & 1) != 0,
-                paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, String text,
-            int start, int end, float x, float y, final int flags, long paint,
-            long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        nDrawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, String text,
-            int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        drawText(nativeCanvas, buffer, 0, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, char[] text,
-            int start, int count, int contextStart, int contextCount,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        drawText(nativeCanvas, text, start, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            char[] text, int index,
-            int count, long path,
-            float hOffset,
-            float vOffset, int bidiFlags,
-            long paint, long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            String text, long path,
-            float hOffset,
-            float vOffset,
-            int bidiFlags, long paint,
-            long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, long nPaint, boolean compositeOnly, boolean forceSrcMode,
-            GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint which can be null if nPaint is 0;
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
-    }
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
-     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mSnapshot.draw(drawable);
-    }
-
-    private static void drawText(long nativeCanvas, final char[] text, final int index,
-            final int count, final float startX, final float startY, final boolean isRtl,
-            long paint, final long typeface) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
-                    // Any change to this method should be reflected in Paint.measureText
-
-                    // assert that the typeface passed is actually the one stored in paint.
-                    assert (typeface == paintDelegate.mNativeTypeface);
-
-                    // Paint.TextAlign indicates how the text is positioned relative to X.
-                    // LEFT is the default and there's nothing to do.
-                    float x = startX;
-                    int limit = index + count;
-                    if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
-                        RectF bounds =
-                                paintDelegate.measureText(text, index, count, null, 0, isRtl);
-                        float m = bounds.right - bounds.left;
-                        if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
-                            x -= m / 2;
-                        } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
-                            x -= m;
-                        }
-                    }
-
-                    new BidiRenderer(graphics, paintDelegate, text).setRenderLocation(x,
-                            startY).renderText(index, limit, isRtl, null, 0, true);
-                });
-    }
-
-    private static void drawBitmap(long nativeCanvas, Bitmap_Delegate bitmap,
-            long nativePaintOrZero, final int sleft, final int stop, final int sright,
-            final int sbottom, final int dleft, final int dtop, final int dright,
-            final int dbottom) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint, which could be null if the int is 0
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    //FIXME add support for canvas, screen and bitmap densities.
-                    graphics.drawImage(image, dleft, dtop, dright, dbottom, sleft, stop, sright,
-                            sbottom, null);
-                });
-    }
-
-    /**
-     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
-     * The image returns, through a 1-size boolean array, whether the drawing code should
-     * use a SRC composite no matter what the paint says.
-     *
-     * @param bitmap the bitmap
-     * @param paint the paint that will be used to draw
-     * @param forceSrcMode whether the composite will have to be SRC
-     * @return the image to draw
-     */
-    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
-            boolean[] forceSrcMode) {
-        BufferedImage image = bitmap.getImage();
-        forceSrcMode[0] = false;
-
-        // if the bitmap config is alpha_8, then we erase all color value from it
-        // before drawing it or apply the texture from the shader if present.
-        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
-            Shader_Delegate shader = paint.getShader();
-            java.awt.Paint javaPaint = null;
-            if (shader instanceof BitmapShader_Delegate) {
-                javaPaint = shader.getJavaPaint();
-            }
-
-            fixAlpha8Bitmap(image, javaPaint);
-        } else if (!bitmap.hasAlpha()) {
-            // hasAlpha is merely a rendering hint. There can in fact be alpha values
-            // in the bitmap but it should be ignored at drawing time.
-            // There is two ways to do this:
-            // - override the composite to be SRC. This can only be used if the composite
-            //   was going to be SRC or SRC_OVER in the first place
-            // - Create a different bitmap to draw in which all the alpha channel values is set
-            //   to 0xFF.
-            if (paint != null) {
-                PorterDuff.Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-
-                forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER || mode == PorterDuff.Mode.SRC;
-            }
-
-            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
-            if (!forceSrcMode[0]) {
-                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
-            }
-        }
-
-        return image;
-    }
-
-    /**
-     * This method will apply the correct color to the passed "only alpha" image. Colors on the
-     * passed image will be destroyed.
-     * If the passed javaPaint is null, the color will be set to 0. If a paint is passed, it will
-     * be used to obtain the color that will be applied.
-     * <p/>
-     * This will destroy the passed image color channel.
-     */
-    private static void fixAlpha8Bitmap(final BufferedImage image,
-            @Nullable java.awt.Paint javaPaint) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        DataBuffer texture = null;
-        if (javaPaint != null) {
-            PaintContext context = javaPaint.createContext(ColorModel.getRGBdefault(), null, null,
-                    new AffineTransform(), null);
-            texture = context.getRaster(0, 0, w, h).getDataBuffer();
-        }
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        final int length = argb.length;
-        for (int i = 0; i < length; i++) {
-            argb[i] &= 0xFF000000;
-            if (texture != null) {
-                argb[i] |= texture.getElem(i) & 0x00FFFFFF;
-            }
-        }
-
-        image.setRGB(0, 0, w, h, argb, 0, w);
-    }
-
-    protected int save(int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.save(saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    protected int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
-        Paint_Delegate paint = new Paint_Delegate();
-        paint.setAlpha(alpha);
-        return saveLayer(rect, paint, saveFlags);
-    }
-
-    protected int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
-     */
-    protected void restoreTo(int saveCount) {
-        mSnapshot = mSnapshot.restoreTo(saveCount);
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}
-     */
-    protected void restore() {
-        mSnapshot = mSnapshot.restore();
-    }
-
-    protected boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
deleted file mode 100644
index c6827a3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Paint_Delegate.FontInfo;
-import android.icu.lang.UScript;
-import android.icu.lang.UScriptRun;
-import android.icu.text.Bidi;
-import android.icu.text.BidiRun;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Render the text by breaking it into various scripts and using the right font for each script.
- * Can be used to measure the text without actually drawing it.
- */
-@SuppressWarnings("deprecation")
-public class BidiRenderer {
-    private static String JAVA_VENDOR = System.getProperty("java.vendor");
-
-    private static class ScriptRun {
-        int start;
-        int limit;
-        boolean isRtl;
-        int scriptCode;
-        Font font;
-
-        public ScriptRun(int start, int limit, boolean isRtl) {
-            this.start = start;
-            this.limit = limit;
-            this.isRtl = isRtl;
-            this.scriptCode = UScript.INVALID_CODE;
-        }
-    }
-
-    private final Graphics2D mGraphics;
-    private final Paint_Delegate mPaint;
-    private char[] mText;
-    // This List can contain nulls. A null font implies that the we weren't able to load the font
-    // properly. So, if we encounter a situation where we try to use that font, log a warning.
-    private List<Font> mFonts;
-    // Bounds of the text drawn so far.
-    private RectF mBounds;
-    private float mBaseline;
-
-    /**
-     * @param graphics May be null.
-     * @param paint The Paint to use to get the fonts. Should not be null.
-     * @param text Unidirectional text. Should not be null.
-     */
-    public BidiRenderer(Graphics2D graphics, Paint_Delegate paint, char[] text) {
-        assert (paint != null);
-        mGraphics = graphics;
-        mPaint = paint;
-        mText = text;
-        mFonts = new ArrayList<Font>(paint.getFonts().size());
-        for (FontInfo fontInfo : paint.getFonts()) {
-            if (fontInfo == null) {
-                mFonts.add(null);
-                continue;
-            }
-            mFonts.add(fontInfo.mFont);
-        }
-        mBounds = new RectF();
-    }
-
-    /**
-     *
-     * @param x The x-coordinate of the left edge of where the text should be drawn on the given
-     *            graphics.
-     * @param y The y-coordinate at which to draw the text on the given mGraphics.
-     *
-     */
-    public BidiRenderer setRenderLocation(float x, float y) {
-        mBounds = new RectF(x, y, x, y);
-        mBaseline = y;
-        return this;
-    }
-
-    /**
-     * Perform Bidi Analysis on the text and then render it.
-     * <p/>
-     * To skip the analysis and render unidirectional text, see {@link
-     * #renderText(int, int, boolean, float[], int, boolean)}
-     */
-    public RectF renderText(int start, int limit, int bidiFlags, float[] advances,
-            int advancesIndex, boolean draw) {
-        Bidi bidi = new Bidi(mText, start, null, 0, limit - start, getIcuFlags(bidiFlags));
-        for (int i = 0; i < bidi.countRuns(); i++) {
-            BidiRun visualRun = bidi.getVisualRun(i);
-            boolean isRtl = visualRun.getDirection() == Bidi.RTL;
-            renderText(visualRun.getStart(), visualRun.getLimit(), isRtl, advances,
-                    advancesIndex, draw);
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render unidirectional text.
-     * <p/>
-     * This method can also be used to measure the width of the text without actually drawing it.
-     * <p/>
-     * @param start index of the first character
-     * @param limit index of the first character that should not be rendered.
-     * @param isRtl is the text right-to-left
-     * @param advances If not null, then advances for each character to be rendered are returned
-     *            here.
-     * @param advancesIndex index into advances from where the advances need to be filled.
-     * @param draw If true and {@code graphics} is not null, draw the rendered text on the graphics
-     *            at the given co-ordinates
-     * @return A rectangle specifying the bounds of the text drawn.
-     */
-    public RectF renderText(int start, int limit, boolean isRtl, float[] advances,
-            int advancesIndex, boolean draw) {
-        // We break the text into scripts and then select font based on it and then render each of
-        // the script runs.
-        for (ScriptRun run : getScriptRuns(mText, start, limit, isRtl, mFonts)) {
-            int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT;
-            flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
-            renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw);
-            advancesIndex += run.limit - run.start;
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render a script run to the right of the bounds passed. Use the preferred font to render as
-     * much as possible. This also implements a fallback mechanism to render characters that cannot
-     * be drawn using the preferred font.
-     */
-    private void renderScript(int start, int limit, Font preferredFont, int flag,
-            float[] advances, int advancesIndex, boolean draw) {
-        if (mFonts.size() == 0 || preferredFont == null) {
-            return;
-        }
-
-        while (start < limit) {
-            boolean foundFont = false;
-            int canDisplayUpTo = preferredFont.canDisplayUpTo(mText, start, limit);
-            if (canDisplayUpTo == -1) {
-                // We can draw all characters in the text.
-                render(start, limit, preferredFont, flag, advances, advancesIndex, draw);
-                return;
-            }
-            if (canDisplayUpTo > start) {
-                // We can draw something.
-                render(start, canDisplayUpTo, preferredFont, flag, advances, advancesIndex, draw);
-                advancesIndex += canDisplayUpTo - start;
-                start = canDisplayUpTo;
-            }
-
-            // The current character cannot be drawn with the preferred font. Cycle through all the
-            // fonts to check which one can draw it.
-            int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1;
-            for (Font font : mFonts) {
-                if (font == null) {
-                    logFontWarning();
-                    continue;
-                }
-                canDisplayUpTo = font.canDisplayUpTo(mText, start, start + charCount);
-                if (canDisplayUpTo == -1) {
-                    render(start, start+charCount, font, flag, advances, advancesIndex, draw);
-                    start += charCount;
-                    advancesIndex += charCount;
-                    foundFont = true;
-                    break;
-                }
-            }
-            if (!foundFont) {
-                // No font can display this char. Use the preferred font. The char will most
-                // probably appear as a box or a blank space. We could, probably, use some
-                // heuristics and break the character into the base character and diacritics and
-                // then draw it, but it's probably not worth the effort.
-                render(start, start + charCount, preferredFont, flag, advances, advancesIndex,
-                        draw);
-                start += charCount;
-                advancesIndex += charCount;
-            }
-        }
-    }
-
-    private static void logFontWarning() {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                "Some fonts could not be loaded. The rendering may not be perfect. " +
-                        "Try running the IDE with JRE 7.", null, null);
-    }
-
-    /**
-     * Renders the text to the right of the bounds with the given font.
-     * @param font The font to render the text with.
-     */
-    private void render(int start, int limit, Font font, int flag, float[] advances,
-            int advancesIndex, boolean draw) {
-
-        FontRenderContext frc;
-        if (mGraphics != null) {
-            frc = mGraphics.getFontRenderContext();
-        } else {
-            frc = Toolkit.getDefaultToolkit().getFontMetrics(font).getFontRenderContext();
-
-            // Metrics obtained this way don't have anti-aliasing set. So,
-            // we create a new FontRenderContext with anti-aliasing set.
-            AffineTransform transform = font.getTransform();
-            if (mPaint.isAntiAliased() &&
-                    // Workaround for http://b.android.com/211659
-                    (transform.getScaleX() <= 9.9 ||
-                    !"JetBrains s.r.o".equals(JAVA_VENDOR))) {
-                frc = new FontRenderContext(transform, true, frc.usesFractionalMetrics());
-            }
-        }
-        GlyphVector gv = font.layoutGlyphVector(frc, mText, start, limit, flag);
-        int ng = gv.getNumGlyphs();
-        int[] ci = gv.getGlyphCharIndices(0, ng, null);
-        if (advances != null) {
-            for (int i = 0; i < ng; i++) {
-                int adv_idx = advancesIndex + ci[i];
-                advances[adv_idx] += gv.getGlyphMetrics(i).getAdvanceX();
-            }
-        }
-        if (draw && mGraphics != null) {
-            mGraphics.drawGlyphVector(gv, mBounds.right, mBaseline);
-        }
-
-        // Update the bounds.
-        Rectangle2D awtBounds = gv.getLogicalBounds();
-        RectF bounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline);
-        // If the width of the bounds is zero, no text had been drawn earlier. Hence, use the
-        // coordinates from the bounds as an offset.
-        if (Math.abs(mBounds.right - mBounds.left) == 0) {
-            mBounds = bounds;
-        } else {
-            mBounds.union(bounds);
-        }
-    }
-
-    // --- Static helper methods ---
-
-    private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY) {
-        float left = (float) awtRec.getX();
-        float top = (float) awtRec.getY();
-        float right = (float) (left + awtRec.getWidth());
-        float bottom = (float) (top + awtRec.getHeight());
-        RectF androidRect = new RectF(left, top, right, bottom);
-        androidRect.offset(offsetX, offsetY);
-        return androidRect;
-    }
-
-    /* package */  static List<ScriptRun> getScriptRuns(char[] text, int start, int limit,
-            boolean isRtl, List<Font> fonts) {
-        LinkedList<ScriptRun> scriptRuns = new LinkedList<ScriptRun>();
-
-        int count = limit - start;
-        UScriptRun uScriptRun = new UScriptRun(text, start, count);
-        while (uScriptRun.next()) {
-            int scriptStart = uScriptRun.getScriptStart();
-            int scriptLimit = uScriptRun.getScriptLimit();
-            ScriptRun run = new ScriptRun(scriptStart, scriptLimit, isRtl);
-            run.scriptCode = uScriptRun.getScriptCode();
-            setScriptFont(text, run, fonts);
-            scriptRuns.add(run);
-        }
-
-        return scriptRuns;
-    }
-
-    // TODO: Replace this method with one which returns the font based on the scriptCode.
-    private static void setScriptFont(char[] text, ScriptRun run,
-            List<Font> fonts) {
-        for (Font font : fonts) {
-            if (font == null) {
-                logFontWarning();
-                continue;
-            }
-            if (font.canDisplayUpTo(text, run.start, run.limit) == -1) {
-                run.font = font;
-                return;
-            }
-        }
-        run.font = fonts.get(0);
-    }
-
-    private static int getIcuFlags(int bidiFlag) {
-        switch (bidiFlag) {
-            case Paint.BIDI_LTR:
-            case Paint.BIDI_FORCE_LTR:
-                return Bidi.DIRECTION_LEFT_TO_RIGHT;
-            case Paint.BIDI_RTL:
-            case Paint.BIDI_FORCE_RTL:
-                return Bidi.DIRECTION_RIGHT_TO_LEFT;
-            case Paint.BIDI_DEFAULT_LTR:
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-            case Paint.BIDI_DEFAULT_RTL:
-                return Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
-            default:
-                assert false;
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
deleted file mode 100644
index 8bd2a7a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Bitmap_Delegate.BitmapCreateFlags;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapFactory
- *
- * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ class BitmapFactory_Delegate {
-
-    // ------ Native Delegates ------
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            @Nullable Rect padding, @Nullable Options opts) {
-        Bitmap bm = null;
-
-        Density density = Density.MEDIUM;
-        Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
-        if (opts != null) {
-            density = Density.getEnum(opts.inDensity);
-            if (opts.inPremultiplied) {
-                bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
-            }
-            opts.inScaled = false;
-        }
-
-        try {
-            if (is instanceof NinePatchInputStream) {
-                NinePatchInputStream npis = (NinePatchInputStream) is;
-                npis.disableFakeMarkSupport();
-
-                // load the bitmap as a nine patch
-                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
-                        npis, true /*is9Patch*/, false /*convert*/);
-
-                // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
-                        density);
-                NinePatchChunk chunk = ninePatch.getChunk();
-
-                // put the chunk in the bitmap
-                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
-
-                if (padding != null) {
-                    // read the padding
-                    int[] paddingArray = chunk.getPadding();
-                    padding.left = paddingArray[0];
-                    padding.top = paddingArray[1];
-                    padding.right = paddingArray[2];
-                    padding.bottom = paddingArray[3];
-                }
-            } else {
-                // load the bitmap directly.
-                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
-            }
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to load image", e, null);
-        }
-
-        return bm;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
-            Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeAsset(long asset, Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
-            int length, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
-        return true;
-    }
-
-    /**
-     * Set the newly decoded bitmap's density based on the Options.
-     *
-     * Copied from {@link BitmapFactory#setDensityFromOptions(Bitmap, Options)}.
-     */
-    @LayoutlibDelegate
-    /*package*/ static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
-        if (outputBitmap == null || opts == null) return;
-
-        final int density = opts.inDensity;
-        if (density != 0) {
-            outputBitmap.setDensity(density);
-            final int targetDensity = opts.inTargetDensity;
-            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
-                return;
-            }
-
-            // --- Change from original implementation begins ---
-            // LayoutLib doesn't scale the nine patch when decoding it. Hence, don't change the
-            // density of the source bitmap in case of ninepatch.
-
-            if (opts.inScaled) {
-            // --- Change from original implementation ends. ---
-                outputBitmap.setDensity(targetDensity);
-            }
-        } else if (opts.inBitmap != null) {
-            // bitmap was reused, ensure density is reset
-            outputBitmap.setDensity(Bitmap.getDefaultDensity());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
deleted file mode 100644
index 4914a48..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.PaintContext;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapShader
- *
- * Through the layoutlib_create tool, the original native methods of BitmapShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BitmapShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class BitmapShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, Bitmap androidBitmap,
-            int shaderTileModeX, int shaderTileModeY) {
-        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
-        if (bitmap == null) {
-            return 0;
-        }
-
-        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(nativeMatrix,
-                bitmap.getImage(),
-                Shader_Delegate.getTileMode(shaderTileModeX),
-                Shader_Delegate.getTileMode(shaderTileModeY));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private BitmapShader_Delegate(long matrix, BufferedImage image,
-            TileMode tileModeX, TileMode tileModeY) {
-        super(matrix);
-        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
-    }
-
-    private class BitmapShaderPaint implements java.awt.Paint {
-        private final BufferedImage mImage;
-        private final TileMode mTileModeX;
-        private final TileMode mTileModeY;
-
-        BitmapShaderPaint(BufferedImage image,
-                TileMode tileModeX, TileMode tileModeY) {
-            mImage = image;
-            mTileModeX = tileModeX;
-            mTileModeY = tileModeY;
-        }
-
-        @Override
-        public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds,
-                Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
-            AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                canvasMatrix = new AffineTransform();
-            }
-
-            AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                localMatrix = new AffineTransform();
-            }
-
-            if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
-                // Fallback to the default ARGB color model
-                colorModel = ColorModel.getRGBdefault();
-            }
-
-            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class BitmapShaderContext implements PaintContext {
-
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
-            private final ColorModel mColorModel;
-
-            public BitmapShaderContext(
-                    AffineTransform canvasMatrix,
-                    AffineTransform localMatrix,
-                    ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public Raster getRaster(int x, int y, int w, int h) {
-                BufferedImage image = new BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float fx, float fy) {
-            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
-            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
-
-            return mImage.getRGB(x, y);
-        }
-
-        private int getCoordinate(int i, int size, TileMode mode) {
-            if (i < 0) {
-                switch (mode) {
-                    case CLAMP:
-                        i = 0;
-                        break;
-                    case REPEAT:
-                        i = size - 1 - (-i % size);
-                        break;
-                    case MIRROR:
-                        // this is the same as the positive side, just make the value positive
-                        // first.
-                        i = -i;
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            } else if (i >= size) {
-                switch (mode) {
-                    case CLAMP:
-                        i = size - 1;
-                        break;
-                    case REPEAT:
-                        i = i % size;
-                        break;
-                    case MIRROR:
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            }
-
-            return i;
-        }
-
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
deleted file mode 100644
index 43c95f4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-import android.os.Parcel;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Set;
-
-import javax.imageio.ImageIO;
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Bitmap
- *
- * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Bitmap class.
- *
- * @see DelegateManager
- *
- */
-public final class Bitmap_Delegate {
-
-
-    public enum BitmapCreateFlags {
-        NONE, PREMULTIPLIED, MUTABLE
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Bitmap_Delegate> sManager =
-            new DelegateManager<>(Bitmap_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private final Config mConfig;
-    private final BufferedImage mImage;
-    private boolean mHasAlpha = true;
-    private boolean mHasMipMap = false;      // TODO: check the default.
-    private boolean mIsPremultiplied = true;
-    private int mGenerationId = 0;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
-     */
-    public static Bitmap_Delegate getDelegate(long native_bitmap) {
-        return sManager.getDelegate(native_bitmap);
-    }
-
-    @Nullable
-    public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
-        return bitmap == null ? null : getDelegate(bitmap.getNativeInstance());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    private static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the file.
-        BufferedImage image = ImageIO.read(input);
-        if (image == null && input.exists()) {
-            // There was a problem decoding the image, or the decoder isn't registered. Webp maybe.
-            // Replace with a broken image icon.
-            BridgeContext currentContext = RenderAction.getCurrentContext();
-            if (currentContext != null) {
-                RenderResources resources = currentContext.getRenderResources();
-                ResourceValue broken = resources.getFrameworkResource(ResourceType.DRAWABLE,
-                        "ic_menu_report_image");
-                File brokenFile = new File(broken.getValue());
-                if (brokenFile.exists()) {
-                    image = ImageIO.read(brokenFile);
-                }
-            }
-        }
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) {
-        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
-            Density density) {
-        // create a delegate with the given image.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    private static int getBufferedImageType() {
-        return BufferedImage.TYPE_INT_ARGB;
-    }
-
-    /**
-     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
-     */
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    /**
-     * Returns the Android bitmap config. Note that this not the config of the underlying
-     * Java2D bitmap.
-     */
-    public Config getConfig() {
-        return mConfig;
-    }
-
-    /**
-     * Returns the hasAlpha rendering hint
-     * @return true if the bitmap alpha should be used at render time
-     */
-    public boolean hasAlpha() {
-        return mHasAlpha && mConfig != Config.RGB_565;
-    }
-
-    /**
-     * Update the generationId.
-     *
-     * @see Bitmap#getGenerationId()
-     */
-    public void change() {
-        mGenerationId++;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
-            int height, int nativeConfig, boolean isMutable) {
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        if (colors != null) {
-            image.setRGB(0, 0, width, height, colors, offset, stride);
-        }
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                            Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        int width = srcImage.getWidth();
-        int height = srcImage.getHeight();
-
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        // copy the source image into the image.
-        int[] argb = new int[width * height];
-        srcImage.getRGB(0, 0, width, height, argb, 0, width);
-        image.setRGB(0, 0, width, height, argb, 0, width);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmem(long nativeSrcBitmap) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetNativeFinalizer() {
-        synchronized (Bitmap_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-            return sFinalizer;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeRecycle(long nativeBitmap) {
-        // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap.
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height,
-            int config, boolean isPremultiplied) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.reconfigure() is not supported", null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
-            OutputStream stream, byte[] tempStorage) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.compress() is not supported", null /*data*/);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeErase(long nativeBitmap, int color) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        BufferedImage image = delegate.mImage;
-
-        Graphics2D g = image.createGraphics();
-        try {
-            g.setColor(new java.awt.Color(color, true));
-
-            g.fillRect(0, 0, image.getWidth(), image.getHeight());
-        } finally {
-            g.dispose();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeRowBytes(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConfig(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mConfig.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasAlpha;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasMipMap;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getRGB(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, color);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGenerationId(long nativeBitmap) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mGenerationId;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
-        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
-                null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable,
-            int density, Parcel p) {
-        // This is only called when sending a bitmap through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint,
-            int[] offsetXY) {
-        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
-        if (bitmap == null) {
-            return null;
-        }
-
-        // get the paint which can be null if nativePaint is 0.
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-
-        if (paint != null && paint.getMaskFilter() != null) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    "MaskFilter not supported in Bitmap.extractAlpha",
-                    null, null /*data*/);
-        }
-
-        int alpha = paint != null ? paint.getAlpha() : 0xFF;
-        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
-
-        // create the delegate. The actual Bitmap config is only an alpha channel
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
-
-        // the density doesn't matter, it's set by the Java method.
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
-                Density.DEFAULT_DENSITY /*density*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate != null && delegate.mIsPremultiplied;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mIsPremultiplied = isPremul;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha,
-            boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasAlpha = hasAlpha;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasMipMap = hasMipMap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSameAs(long nb0, long nb1) {
-        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
-        if (delegate1 == null) {
-            return false;
-        }
-
-        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
-        if (delegate2 == null) {
-            return false;
-        }
-
-        BufferedImage image1 = delegate1.getImage();
-        BufferedImage image2 = delegate2.getImage();
-        if (delegate1.mConfig != delegate2.mConfig ||
-                image1.getWidth() != image2.getWidth() ||
-                image1.getHeight() != image2.getHeight()) {
-            return false;
-        }
-
-        // get the internal data
-        int w = image1.getWidth();
-        int h = image2.getHeight();
-        int[] argb1 = new int[w*h];
-        int[] argb2 = new int[w*h];
-
-        image1.getRGB(0, 0, w, h, argb1, 0, w);
-        image2.getRGB(0, 0, w, h, argb2, 0, w);
-
-        // compares
-        if (delegate1.mConfig == Config.ALPHA_8) {
-            // in this case we have to manually compare the alpha channel as the rest is garbage.
-            final int length = w*h;
-            for (int i = 0 ; i < length ; i++) {
-                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        return Arrays.equals(argb1, argb2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetAllocationByteCount(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-        return nativeRowBytes(nativeBitmap) * delegate.mImage.getHeight();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
-        // do nothing as Bitmap_Delegate does not have caches
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(nativeBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        // create the image
-        BufferedImage image = new BufferedImage(srcImage.getColorModel(), srcImage.copyData(null),
-                srcImage.isAlphaPremultiplied(), null);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, srcBmpDelegate.getConfig());
-
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSRGB(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Bitmap_Delegate(BufferedImage image, Config config) {
-        mImage = image;
-        mConfig = config;
-    }
-
-    private static Bitmap createBitmap(Bitmap_Delegate delegate,
-            Set<BitmapCreateFlags> createFlags, int density) {
-        // get its native_int
-        long nativeInt = sManager.addNewDelegate(delegate);
-
-        int width = delegate.mImage.getWidth();
-        int height = delegate.mImage.getHeight();
-        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
-        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
-
-        // and create/return a new Bitmap with it
-        return new Bitmap(nativeInt, width, height, density, isMutable,
-                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
-    }
-
-    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
-        Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
-        if (isMutable) {
-            createFlags.add(BitmapCreateFlags.MUTABLE);
-        }
-        return createFlags;
-    }
-
-    /**
-     * Creates and returns a copy of a given BufferedImage.
-     * <p/>
-     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
-     *
-     * @param image the image to copy
-     * @param imageType the type of the new image
-     * @param alpha an optional alpha modifier
-     * @return a new BufferedImage
-     */
-    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        BufferedImage result = new BufferedImage(w, h, imageType);
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        if (alpha != 255) {
-            final int length = argb.length;
-            for (int i = 0 ; i < length; i++) {
-                int a = (argb[i] >>> 24 * alpha) / 255;
-                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
-            }
-        }
-
-        result.setRGB(0, 0, w, h, argb, 0, w);
-
-        return result;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
deleted file mode 100644
index 5cc964a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
+++ /dev/null
@@ -1,287 +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 android.graphics;
-
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/*
- * (non-Javadoc)
- * The class is adapted from a demo tool for Blending Modes written by
- * Romain Guy (romainguy@android.com). The tool is available at
- * http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
- *
- * This class has been adapted for applying color filters. When applying color filters, the src
- * image should not extend beyond the dest image, but in our implementation of the filters, it does.
- * To compensate for the effect, we recompute the alpha value of the src image before applying
- * the color filter as it should have been applied.
- */
-public final class BlendComposite implements Composite {
-    public enum BlendingMode {
-        MULTIPLY(),
-        SCREEN(),
-        DARKEN(),
-        LIGHTEN(),
-        OVERLAY(),
-        ADD();
-
-        private final BlendComposite mComposite;
-
-        BlendingMode() {
-            mComposite = new BlendComposite(this);
-        }
-
-        BlendComposite getBlendComposite() {
-            return mComposite;
-        }
-    }
-
-    private float alpha;
-    private BlendingMode mode;
-
-    private BlendComposite(BlendingMode mode) {
-        this(mode, 1.0f);
-    }
-
-    private BlendComposite(BlendingMode mode, float alpha) {
-        this.mode = mode;
-        setAlpha(alpha);
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode) {
-        return mode.getBlendComposite();
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode, float alpha) {
-        if (alpha > 0.9999f) {
-            return getInstance(mode);
-        }
-        return new BlendComposite(mode, alpha);
-    }
-
-    public float getAlpha() {
-        return alpha;
-    }
-
-    public BlendingMode getMode() {
-        return mode;
-    }
-
-    private void setAlpha(float alpha) {
-        if (alpha < 0.0f || alpha > 1.0f) {
-            assert false : "alpha must be comprised between 0.0f and 1.0f";
-            alpha = Math.min(alpha, 1.0f);
-            alpha = Math.max(alpha, 0.0f);
-        }
-
-        this.alpha = alpha;
-    }
-
-    @Override
-    public int hashCode() {
-        return Float.floatToIntBits(alpha) * 31 + mode.ordinal();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof BlendComposite)) {
-            return false;
-        }
-
-        BlendComposite bc = (BlendComposite) obj;
-
-        return mode == bc.mode && alpha == bc.alpha;
-    }
-
-    public CompositeContext createContext(ColorModel srcColorModel,
-                                          ColorModel dstColorModel,
-                                          RenderingHints hints) {
-        return new BlendingContext(this);
-    }
-
-    private static final class BlendingContext implements CompositeContext {
-        private final Blender blender;
-        private final BlendComposite composite;
-
-        private BlendingContext(BlendComposite composite) {
-            this.composite = composite;
-            this.blender = Blender.getBlenderFor(composite);
-        }
-
-        public void dispose() {
-        }
-
-        public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
-            if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
-                throw new IllegalStateException(
-                        "Source and destination must store pixels as INT.");
-            }
-
-            int width = Math.min(src.getWidth(), dstIn.getWidth());
-            int height = Math.min(src.getHeight(), dstIn.getHeight());
-
-            float alpha = composite.getAlpha();
-
-            int[] srcPixel = new int[4];
-            int[] dstPixel = new int[4];
-            int[] result = new int[4];
-            int[] srcPixels = new int[width];
-            int[] dstPixels = new int[width];
-
-            for (int y = 0; y < height; y++) {
-                dstIn.getDataElements(0, y, width, 1, dstPixels);
-                if (alpha != 0) {
-                    src.getDataElements(0, y, width, 1, srcPixels);
-                    for (int x = 0; x < width; x++) {
-                        // pixels are stored as INT_ARGB
-                        // our arrays are [R, G, B, A]
-                        int pixel = srcPixels[x];
-                        srcPixel[0] = (pixel >> 16) & 0xFF;
-                        srcPixel[1] = (pixel >>  8) & 0xFF;
-                        srcPixel[2] = (pixel      ) & 0xFF;
-                        srcPixel[3] = (pixel >> 24) & 0xFF;
-
-                        pixel = dstPixels[x];
-                        dstPixel[0] = (pixel >> 16) & 0xFF;
-                        dstPixel[1] = (pixel >>  8) & 0xFF;
-                        dstPixel[2] = (pixel      ) & 0xFF;
-                        dstPixel[3] = (pixel >> 24) & 0xFF;
-
-                        // ---- Modified from original ----
-                        // recompute src pixel for transparency.
-                        srcPixel[3] *= dstPixel[3] / 0xFF;
-                        // ---- Modification ends ----
-
-                        result = blender.blend(srcPixel, dstPixel, result);
-
-                        // mixes the result with the opacity
-                        if (alpha == 1) {
-                            dstPixels[x] = (result[3] & 0xFF) << 24 |
-                                           (result[0] & 0xFF) << 16 |
-                                           (result[1] & 0xFF) <<  8 |
-                                           result[2] & 0xFF;
-                        } else {
-                            dstPixels[x] =
-                                    ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
-                                    ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
-                                    ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) <<  8 |
-                                    (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;
-                        }
-
-                    }
-            }
-                dstOut.setDataElements(0, y, width, 1, dstPixels);
-            }
-        }
-    }
-
-    private static abstract class Blender {
-        public abstract int[] blend(int[] src, int[] dst, int[] result);
-
-        public static Blender getBlenderFor(BlendComposite composite) {
-            switch (composite.getMode()) {
-                case ADD:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 4; i++) {
-                                result[i] = Math.min(255, src[i] + dst[i]);
-                            }
-                            return result;
-                        }
-                    };
-                case DARKEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.min(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case LIGHTEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.max(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case MULTIPLY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = (src[i] * dst[i]) >> 8;
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
-                            return result;
-                        }
-                    };
-                case OVERLAY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = dst[i] < 128 ? dst[i] * src[i] >> 7 :
-                                    255 - ((255 - dst[i]) * (255 - src[i]) >> 7);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case SCREEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = 255 - ((255 - src[0]) * (255 - dst[0]) >> 8);
-                            result[1] = 255 - ((255 - src[1]) * (255 - dst[1]) >> 8);
-                            result[2] = 255 - ((255 - src[2]) * (255 - dst[2]) >> 8);
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                default:
-                    assert false : "Blender not implement for " + composite.getMode().name();
-
-                    // Ignore the blend
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = dst[0];
-                            result[1] = dst[1];
-                            result[2] = dst[2];
-                            result[3] = dst[3];
-                            return result;
-                        }
-                    };
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
deleted file mode 100644
index d2569c7..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.BlurMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of BlurMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BlurMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class BlurMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Blur Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float radius, int style) {
-        BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
deleted file mode 100644
index 47216ee..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-
-/**
- * Delegate implementing the native methods of android.graphics.Canvas
- *
- * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Canvas class.
- *
- * @see DelegateManager
- *
- */
-public final class Canvas_Delegate extends BaseCanvas_Delegate {
-
-    // ---- delegate manager ----
-    private static long sFinalizer = -1;
-
-    private DrawFilter_Delegate mDrawFilter = null;
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(Canvas canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(canvas.getNativeCanvasWrapper());
-    }
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(long native_canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(native_canvas);
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    /**
-     * Returns the {@link DrawFilter} delegate or null if none have been set.
-     *
-     * @return the delegate or null.
-     */
-    public DrawFilter_Delegate getDrawFilter() {
-        return mDrawFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeCaches() {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeTextLayoutCaches() {
-        // nothing to be done here yet.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitRaster(@Nullable Bitmap bitmap) {
-        long nativeBitmapOrZero = 0;
-        if (bitmap != null) {
-            nativeBitmapOrZero = bitmap.getNativeInstance();
-        }
-        if (nativeBitmapOrZero > 0) {
-            // get the Bitmap from the int
-            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
-
-            // create a new Canvas_Delegate with the given bitmap and return its new native int.
-            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
-
-            return sManager.addNewDelegate(newDelegate);
-        }
-
-        // create a new Canvas_Delegate and return its new native int.
-        Canvas_Delegate newDelegate = new Canvas_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetBitmap(long canvas, Bitmap bitmap) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (canvasDelegate == null || bitmapDelegate==null) {
-            return;
-        }
-        canvasDelegate.mBitmap = bitmapDelegate;
-        canvasDelegate.mSnapshot = GcSnapshot.createDefaultSnapshot(bitmapDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nIsOpaque(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetHighContrastText(long nativeCanvas, boolean highContrastText){}
-
-    @LayoutlibDelegate
-    public static int nGetWidth(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getWidth();
-    }
-
-    @LayoutlibDelegate
-    public static int nGetHeight(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getHeight();
-    }
-
-    @LayoutlibDelegate
-    public static int nSave(long nativeCanvas, int saveFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.save(saveFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayer(long nativeCanvas, float l,
-                                               float t, float r, float b,
-                                               long paint, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
-        if (paintDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
-                paintDelegate, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayerAlpha(long nativeCanvas, float l,
-                                                    float t, float r, float b,
-                                                    int alpha, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nRestore(long nativeCanvas) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        canvasDelegate.restore();
-        return true;
-    }
-
-    @LayoutlibDelegate
-    public static void nRestoreToCount(long nativeCanvas, int saveCount) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.restoreTo(saveCount);
-    }
-
-    @LayoutlibDelegate
-    public static int nGetSaveCount(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.getSnapshot().size();
-    }
-
-    @LayoutlibDelegate
-   public static void nTranslate(long nativeCanvas, float dx, float dy) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().translate(dx, dy);
-    }
-
-    @LayoutlibDelegate
-       public static void nScale(long nativeCanvas, float sx, float sy) {
-            // get the delegate from the native int.
-            Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-            if (canvasDelegate == null) {
-                return;
-            }
-
-            canvasDelegate.getSnapshot().scale(sx, sy);
-        }
-
-    @LayoutlibDelegate
-    public static void nRotate(long nativeCanvas, float degrees) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
-    }
-
-    @LayoutlibDelegate
-   public static void nSkew(long nativeCanvas, float kx, float ky) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot g = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = g.getTransform();
-        // get the AffineTransform for the given skew.
-        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
-        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
-
-        // combine them so that the given matrix is applied after.
-        currentTx.preConcatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        g.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nConcat(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = snapshot.getTransform();
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // combine them so that the given matrix is applied after.
-        currentTx.concatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetMatrix(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(matrixTx);
-
-        if (matrixDelegate.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipRect(long nCanvas,
-                                                  float left, float top,
-                                                  float right, float bottom,
-                                                  int regionOp) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipPath(long nativeCanvas,
-                                                  long nativePath,
-                                                  int regionOp) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return true;
-        }
-
-        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
-        if (pathDelegate == null) {
-            return true;
-        }
-
-        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetDrawFilter(long nativeCanvas, long nativeFilter) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
-
-        if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
-                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nGetClipBounds(long nativeCanvas,
-                                                       Rect bounds) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
-        if (rect != null && !rect.isEmpty()) {
-            bounds.left = rect.x;
-            bounds.top = rect.y;
-            bounds.right = rect.x + rect.width;
-            bounds.bottom = rect.y + rect.height;
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static void nGetMatrix(long canvas, long matrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
-        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas, long path) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas,
-                                                     float left, float top,
-                                                     float right, float bottom) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Canvas_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(nativePtr -> {
-                    Canvas_Delegate delegate = Canvas_Delegate.getDelegate(nativePtr);
-                    if (delegate != null) {
-                        delegate.dispose();
-                    }
-                    sManager.removeJavaReferenceFor(nativePtr);
-                });
-            }
-        }
-        return sFinalizer;
-    }
-
-    private Canvas_Delegate(Bitmap_Delegate bitmap) {
-        super(bitmap);
-    }
-
-    private Canvas_Delegate() {
-        super();
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
deleted file mode 100644
index cb013b6..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Graphics2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorFilter class.
- *
- * This also serve as a base class for all ColorFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class ColorFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<ColorFilter_Delegate> sManager =
-            new DelegateManager<ColorFilter_Delegate>(ColorFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static ColorFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract String getSupportMessage();
-
-    public boolean isSupported() {
-        return false;
-    }
-
-    public void applyFilter(Graphics2D g, int width, int height) {
-        // This should never be called directly. If supported, the sub class should override this.
-        assert false;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nSafeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
deleted file mode 100644
index 6739484..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorMatrixColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorMatrixColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorMatrixColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "ColorMatrix Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeColorMatrixFilter(float[] array) {
-        ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
deleted file mode 100644
index bc3df7d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class ComposePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long outerpe, long innerpe) {
-        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
deleted file mode 100644
index ab37968..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Paint;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposeShader
- *
- * Through the layoutlib_create tool, the original native methods of ComposeShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposeShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class ComposeShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Paint getJavaPaint() {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Shaders are not supported in Layout Preview mode.";
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, long native_shaderA,
-            long native_shaderB, int native_mode) {
-        // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(nativeMatrix);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private ComposeShader_Delegate(long nativeMatrix) {
-        super(nativeMatrix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
deleted file mode 100644
index 73745c3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.CornerPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original CornerPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class CornerPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Corner Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float radius) {
-        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
deleted file mode 100644
index 881afde..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.BasicStroke;
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public final class DashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    private final float[] mIntervals;
-    private final float mPhase;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        return new BasicStroke(
-                paint.getStrokeWidth(),
-                paint.getJavaCap(),
-                paint.getJavaJoin(),
-                paint.getJavaStrokeMiter(),
-                mIntervals,
-                mPhase);
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float intervals[], float phase) {
-        DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private DashPathEffect_Delegate(float intervals[], float phase) {
-        mIntervals = new float[intervals.length];
-        System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
-        mPhase = phase;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
deleted file mode 100644
index 46109f3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DiscretePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DiscretePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Discrete Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float length, float deviation) {
-        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
deleted file mode 100644
index 2e10740..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.DrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of DrawFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DrawFilter class.
- *
- * This also serve as a base class for all DrawFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class DrawFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<DrawFilter_Delegate> sManager =
-            new DelegateManager<DrawFilter_Delegate>(DrawFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static DrawFilter_Delegate getDelegate(long nativeDrawFilter) {
-        return sManager.getDelegate(nativeDrawFilter);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long nativeDrawFilter) {
-        sManager.removeJavaReferenceFor(nativeDrawFilter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
deleted file mode 100644
index e5040cc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.EmbossMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of EmbossMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original EmbossMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Emboss Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float[] direction, float ambient,
-            float specular, float blurRadius) {
-        EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
deleted file mode 100644
index 78b6f71..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ /dev/null
@@ -1,515 +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 android.graphics;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-
-import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
-import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
-
-/**
- * Delegate implementing the native methods of android.graphics.FontFamily
- *
- * Through the layoutlib_create tool, the original native methods of FontFamily have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original FontFamily class.
- *
- * @see DelegateManager
- */
-public class FontFamily_Delegate {
-
-    public static final int DEFAULT_FONT_WEIGHT = 400;
-    public static final int BOLD_FONT_WEIGHT_DELTA = 300;
-    public static final int BOLD_FONT_WEIGHT = 700;
-
-    private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
-    private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt";
-    private static final String EXTENSION_OTF = ".otf";
-
-    private static final int CACHE_SIZE = 10;
-    // The cache has a drawback that if the font file changed after the font object was created,
-    // we will not update it.
-    private static final Map<String, FontInfo> sCache =
-            new LinkedHashMap<String, FontInfo>(CACHE_SIZE) {
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<String, FontInfo> eldest) {
-            return size() > CACHE_SIZE;
-        }
-
-        @Override
-        public FontInfo put(String key, FontInfo value) {
-            // renew this entry.
-            FontInfo removed = remove(key);
-            super.put(key, value);
-            return removed;
-        }
-    };
-
-    /**
-     * A class associating {@link Font} with its metadata.
-     */
-    private static final class FontInfo {
-        @Nullable
-        Font mFont;
-        int mWeight;
-        boolean mIsItalic;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<FontFamily_Delegate> sManager =
-            new DelegateManager<FontFamily_Delegate>(FontFamily_Delegate.class);
-
-    // ---- delegate helper data ----
-    private static String sFontLocation;
-    private static final List<FontFamily_Delegate> sPostInitDelegate = new
-            ArrayList<FontFamily_Delegate>();
-    private static Set<String> SDK_FONTS;
-
-
-    // ---- delegate data ----
-    private List<FontInfo> mFonts = new ArrayList<FontInfo>();
-
-    /**
-     * The variant of the Font Family - compact or elegant.
-     * <p/>
-     * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
-     * android.graphics.FontFamily
-     *
-     * @see Paint#setElegantTextHeight(boolean)
-     */
-    private FontVariant mVariant;
-    // List of runnables to process fonts after sFontLoader is initialized.
-    private List<Runnable> mPostInitRunnables = new ArrayList<Runnable>();
-    /** @see #isValid() */
-    private boolean mValid = false;
-
-
-    // ---- Public helper class ----
-
-    public enum FontVariant {
-        // The order needs to be kept in sync with android.graphics.FontFamily.
-        NONE, COMPACT, ELEGANT
-    }
-
-    // ---- Public Helper methods ----
-
-    public static FontFamily_Delegate getDelegate(long nativeFontFamily) {
-        return sManager.getDelegate(nativeFontFamily);
-    }
-
-    public static synchronized void setFontLocation(String fontLocation) {
-        sFontLocation = fontLocation;
-        // init list of bundled fonts.
-        File allFonts = new File(fontLocation, FN_ALL_FONTS_LIST);
-        // Current number of fonts is 103. Use the next round number to leave scope for more fonts
-        // in the future.
-        Set<String> allFontsList = new HashSet<String>(128);
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(allFonts);
-            while (scanner.hasNext()) {
-                String name = scanner.next();
-                // Skip font configuration files.
-                if (!name.endsWith(".xml")) {
-                    allFontsList.add(name);
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.",
-                    e, null);
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-        SDK_FONTS = Collections.unmodifiableSet(allFontsList);
-        for (FontFamily_Delegate fontFamily : sPostInitDelegate) {
-            fontFamily.init();
-        }
-        sPostInitDelegate.clear();
-    }
-
-    @Nullable
-    public Font getFont(int desiredWeight, boolean isItalic) {
-        FontInfo desiredStyle = new FontInfo();
-        desiredStyle.mWeight = desiredWeight;
-        desiredStyle.mIsItalic = isItalic;
-        FontInfo bestFont = null;
-        int bestMatch = Integer.MAX_VALUE;
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            int match = computeMatch(font, desiredStyle);
-            if (match < bestMatch) {
-                bestMatch = match;
-                bestFont = font;
-            }
-        }
-        if (bestFont == null) {
-            return null;
-        }
-        if (bestMatch == 0) {
-            return bestFont.mFont;
-        }
-        // Derive the font as required and add it to the list of Fonts.
-        deriveFont(bestFont, desiredStyle);
-        addFont(desiredStyle);
-        return desiredStyle.mFont;
-    }
-
-    public FontVariant getVariant() {
-        return mVariant;
-    }
-
-    /**
-     * Returns if the FontFamily should contain any fonts. If this returns true and
-     * {@link #getFont(int, boolean)} returns an empty list, it means that an error occurred while
-     * loading the fonts. However, some fonts are deliberately skipped, for example they are not
-     * bundled with the SDK. In such a case, this method returns false.
-     */
-    public boolean isValid() {
-        return mValid;
-    }
-
-    private static Font loadFont(String path) {
-        if (path.startsWith(SYSTEM_FONTS) ) {
-            String relativePath = path.substring(SYSTEM_FONTS.length());
-            File f = new File(sFontLocation, relativePath);
-
-            try {
-                return Font.createFont(Font.TRUETYPE_FONT, f);
-            } catch (Exception e) {
-                if (path.endsWith(EXTENSION_OTF) && e instanceof FontFormatException) {
-                    // If we aren't able to load an Open Type font, don't log a warning just yet.
-                    // We wait for a case where font is being used. Only then we try to log the
-                    // warning.
-                    return null;
-                }
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unable to load font %1$s", relativePath),
-                        e, null);
-            }
-        } else {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
-                    null, null);
-        }
-
-        return null;
-    }
-
-    @Nullable
-    /*package*/ static String getFontLocation() {
-        return sFontLocation;
-    }
-
-    // ---- delegate methods ----
-    @LayoutlibDelegate
-    /*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex,
-            FontVariationAxis[] axes, int weight, int italic) {
-        if (thisFontFamily.mBuilderPtr == 0) {
-            assert false : "Unable to call addFont after freezing.";
-            return false;
-        }
-        final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr);
-        return delegate != null && delegate.addFont(path, ttcIndex, weight, italic);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitBuilder(String lang, int variant) {
-        // TODO: support lang. This is required for japanese locale.
-        FontFamily_Delegate delegate = new FontFamily_Delegate();
-        // variant can be 0, 1 or 2.
-        assert variant < 3;
-        delegate.mVariant = FontVariant.values()[variant];
-        if (sFontLocation != null) {
-            delegate.init();
-        } else {
-            sPostInitDelegate.add(delegate);
-        }
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateFamily(long builderPtr) {
-        return builderPtr;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nUnrefFamily(long nativePtr) {
-        // Removing the java reference for the object doesn't mean that it's freed for garbage
-        // collection. Typeface_Delegate may still hold a reference for it.
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
-            int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
-            int ttcIndex, int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddAxisValue(long builderPtr, int tag, float value) {
-        assert false : "The only client of this method has been overridden.";
-    }
-
-    static boolean addFont(long builderPtr, final String path, final int weight,
-            final boolean isItalic) {
-        final FontFamily_Delegate delegate = getDelegate(builderPtr);
-        int italic = isItalic ? 1 : 0;
-        if (delegate != null) {
-            if (sFontLocation == null) {
-                delegate.mPostInitRunnables.add(() -> delegate.addFont(path, weight, italic));
-                return true;
-            }
-            return delegate.addFont(path, weight, italic);
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
-            int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic) {
-        FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
-        if (ffd == null) {
-            return false;
-        }
-        ffd.mValid = true;
-        if (mgr == null) {
-            return false;
-        }
-        if (mgr instanceof BridgeAssetManager) {
-            InputStream fontStream = null;
-            try {
-                AssetRepository assetRepository = ((BridgeAssetManager) mgr).getAssetRepository();
-                if (assetRepository == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            null);
-                    return false;
-                }
-                if (!assetRepository.isSupported()) {
-                    // Don't log any warnings on unsupported IDEs.
-                    return false;
-                }
-                // Check cache
-                FontInfo fontInfo = sCache.get(path);
-                if (fontInfo != null) {
-                    // renew the font's lease.
-                    sCache.put(path, fontInfo);
-                    ffd.addFont(fontInfo);
-                    return true;
-                }
-                fontStream = isAsset ?
-                        assetRepository.openAsset(path, AssetManager.ACCESS_STREAMING) :
-                        assetRepository.openNonAsset(cookie, path, AssetManager.ACCESS_STREAMING);
-                if (fontStream == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            path);
-                    return false;
-                }
-                Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
-                fontInfo = new FontInfo();
-                fontInfo.mFont = font;
-                if (weight == RESOLVE_BY_FONT_TABLE) {
-                    fontInfo.mWeight = font.isBold() ? BOLD_FONT_WEIGHT : DEFAULT_FONT_WEIGHT;
-                } else {
-                    fontInfo.mWeight = weight;
-                }
-                fontInfo.mIsItalic = isItalic == RESOLVE_BY_FONT_TABLE ? font.isItalic() :
-                        isItalic == 1;
-                ffd.addFont(fontInfo);
-                return true;
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Unable to load font " + path, e,
-                        path);
-            } catch (FontFormatException e) {
-                if (path.endsWith(EXTENSION_OTF)) {
-                    // otf fonts are not supported on the user's config (JRE version + OS)
-                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                            "OpenType fonts are not supported yet: " + path, null, path);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Unable to load font " + path, e, path);
-                }
-            } finally {
-                if (fontStream != null) {
-                    try {
-                        fontStream.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-            return false;
-        }
-        // This should never happen. AssetManager is a final class (from user's perspective), and
-        // we've replaced every creation of AssetManager with our implementation. We create an
-        // exception and log it, but continue with rest of the rendering, without loading this font.
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                "You have found a bug in the rendering library. Please file a bug at b.android.com.",
-                new RuntimeException("Asset Manager is not an instance of BridgeAssetManager"),
-                null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAbort(long builderPtr) {
-        sManager.removeJavaReferenceFor(builderPtr);
-    }
-
-    // ---- private helper methods ----
-
-    private void init() {
-        for (Runnable postInitRunnable : mPostInitRunnables) {
-            postInitRunnable.run();
-        }
-        mPostInitRunnables = null;
-    }
-
-    private boolean addFont(final String path, int ttcIndex, int weight, int italic) {
-        // FIXME: support ttc fonts. Hack JRE??
-        if (sFontLocation == null) {
-            mPostInitRunnables.add(() -> addFont(path, weight, italic));
-            return true;
-        }
-        return addFont(path, weight, italic);
-    }
-
-     private boolean addFont(@NonNull String path) {
-         return addFont(path, DEFAULT_FONT_WEIGHT, path.endsWith(FONT_SUFFIX_ITALIC) ? 1 : RESOLVE_BY_FONT_TABLE);
-     }
-
-    private boolean addFont(@NonNull String path, int weight, int italic) {
-        if (path.startsWith(SYSTEM_FONTS) &&
-                !SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
-            return mValid = false;
-        }
-        // Set valid to true, even if the font fails to load.
-        mValid = true;
-        Font font = loadFont(path);
-        if (font == null) {
-            return false;
-        }
-        FontInfo fontInfo = new FontInfo();
-        fontInfo.mFont = font;
-        fontInfo.mWeight = weight;
-        fontInfo.mIsItalic = italic == RESOLVE_BY_FONT_TABLE ? font.isItalic() : italic == 1;
-        addFont(fontInfo);
-        return true;
-    }
-
-    private boolean addFont(@NonNull FontInfo fontInfo) {
-        int weight = fontInfo.mWeight;
-        boolean isItalic = fontInfo.mIsItalic;
-        // The list is usually just two fonts big. So iterating over all isn't as bad as it looks.
-        // It's biggest for roboto where the size is 12.
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            if (font.mWeight == weight && font.mIsItalic == isItalic) {
-                return false;
-            }
-        }
-        mFonts.add(fontInfo);
-        return true;
-    }
-
-    /**
-     * Compute matching metric between two styles - 0 is an exact match.
-     */
-    private static int computeMatch(@NonNull FontInfo font1, @NonNull FontInfo font2) {
-        int score = Math.abs(font1.mWeight - font2.mWeight);
-        if (font1.mIsItalic != font2.mIsItalic) {
-            score += 200;
-        }
-        return score;
-    }
-
-    /**
-     * Try to derive a font from {@code srcFont} for the style in {@code outFont}.
-     * <p/>
-     * {@code outFont} is updated to reflect the style of the derived font.
-     * @param srcFont the source font
-     * @param outFont contains the desired font style. Updated to contain the derived font and
-     *                its style
-     * @return outFont
-     */
-    @NonNull
-    private FontInfo deriveFont(@NonNull FontInfo srcFont, @NonNull FontInfo outFont) {
-        int desiredWeight = outFont.mWeight;
-        int srcWeight = srcFont.mWeight;
-        assert srcFont.mFont != null;
-        Font derivedFont = srcFont.mFont;
-        // Embolden the font if required.
-        if (desiredWeight >= BOLD_FONT_WEIGHT && desiredWeight - srcWeight > BOLD_FONT_WEIGHT_DELTA / 2) {
-            derivedFont = derivedFont.deriveFont(Font.BOLD);
-            srcWeight += BOLD_FONT_WEIGHT_DELTA;
-        }
-        // Italicize the font if required.
-        if (outFont.mIsItalic && !srcFont.mIsItalic) {
-            derivedFont = derivedFont.deriveFont(Font.ITALIC);
-        } else if (outFont.mIsItalic != srcFont.mIsItalic) {
-            // The desired font is plain, but the src font is italics. We can't convert it back. So
-            // we update the value to reflect the true style of the font we're deriving.
-            outFont.mIsItalic = srcFont.mIsItalic;
-        }
-        outFont.mFont = derivedFont;
-        outFont.mWeight = srcWeight;
-        // No need to update mIsItalics, as it's already been handled above.
-        return outFont;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
deleted file mode 100644
index 64410e4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Base class for true Gradient shader delegate.
- */
-public abstract class Gradient_Delegate extends Shader_Delegate {
-
-    protected final int[] mColors;
-    protected final float[] mPositions;
-
-    @Override
-    public boolean isSupported() {
-        // all gradient shaders are supported.
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // all gradient shaders are supported, no need for a gradient support
-        return null;
-    }
-
-    /**
-     * Creates the base shader and do some basic test on the parameters.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     */
-    protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) {
-        super(nativeMatrix);
-        assert colors.length >= 2 : "needs >= 2 number of colors";
-
-        if (positions == null) {
-            float spacing = 1.f / (colors.length - 1);
-            positions = new float[colors.length];
-            positions[0] = 0.f;
-            positions[colors.length - 1] = 1.f;
-            for (int i = 1; i < colors.length - 1; i++) {
-                positions[i] = spacing * i;
-            }
-        } else {
-            assert colors.length == positions.length :
-                    "color and position " + "arrays must be of equal length";
-        }
-
-        mColors = colors;
-        mPositions = positions;
-    }
-
-    /**
-     * Base class for (Java) Gradient Paints. This handles computing the gradient colors based
-     * on the color and position lists, as well as the {@link TileMode}
-     *
-     */
-    protected abstract static class GradientPaint implements java.awt.Paint {
-        private final static int GRADIENT_SIZE = 100;
-
-        private final int[] mColors;
-        private final float[] mPositions;
-        private final TileMode mTileMode;
-        private int[] mGradient;
-
-        protected GradientPaint(int[] colors, float[] positions, TileMode tileMode) {
-            mColors = colors;
-            mPositions = positions;
-            mTileMode = tileMode;
-        }
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-
-        /**
-         * Pre-computes the colors for the gradient. This must be called once before any call
-         * to {@link #getGradientColor(float)}
-         */
-        protected void precomputeGradientColors() {
-            if (mGradient == null) {
-                // actually create an array with an extra size, so that we can really go
-                // from 0 to SIZE (100%), or currentPos in the loop below will never equal 1.0
-                mGradient = new int[GRADIENT_SIZE+1];
-
-                int prevPos = 0;
-                int nextPos = 1;
-                for (int i  = 0 ; i <= GRADIENT_SIZE ; i++) {
-                    // compute current position
-                    float currentPos = (float)i/GRADIENT_SIZE;
-                    while (currentPos > mPositions[nextPos]) {
-                        prevPos = nextPos++;
-                    }
-
-                    float percent = (currentPos - mPositions[prevPos]) /
-                            (mPositions[nextPos] - mPositions[prevPos]);
-
-                    mGradient[i] = computeColor(mColors[prevPos], mColors[nextPos], percent);
-                }
-            }
-        }
-
-        /**
-         * Returns the color based on the position in the gradient.
-         * <var>pos</var> can be anything, even &lt; 0 or &gt; > 1, as the gradient
-         * will use {@link TileMode} value to convert it into a [0,1] value.
-         */
-        protected int getGradientColor(float pos) {
-            if (pos < 0.f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 0.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range.
-                            // we also need to invert the value from [-1,0] to [0, 1]
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // this is the same as the positive side, just make the value positive
-                            // first.
-                            pos = Math.abs(pos);
-
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 0.0f;
-                }
-            } else if (pos > 1f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 1.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 1.0f;
-                }
-            }
-
-            int index = (int)((pos * GRADIENT_SIZE) + .5);
-
-            return mGradient[index];
-        }
-
-        /**
-         * Returns the color between c1, and c2, based on the percent of the distance
-         * between c1 and c2.
-         */
-        private int computeColor(int c1, int c2, float percent) {
-            int a = computeChannel((c1 >> 24) & 0xFF, (c2 >> 24) & 0xFF, percent);
-            int r = computeChannel((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF, percent);
-            int g = computeChannel((c1 >>  8) & 0xFF, (c2 >>  8) & 0xFF, percent);
-            int b = computeChannel((c1      ) & 0xFF, (c2      ) & 0xFF, percent);
-            return a << 24 | r << 16 | g << 8 | b;
-        }
-
-        /**
-         * Returns the channel value between 2 values based on the percent of the distance between
-         * the 2 values..
-         */
-        private int computeChannel(int c1, int c2, float percent) {
-            return c1 + (int)((percent * (c2-c1)) + .5);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
deleted file mode 100644
index 0dd9703..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.LightingColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of LightingColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LightingColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "Lighting Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreateLightingFilter(int mul, int add) {
-        LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
deleted file mode 100644
index cd4393a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.LinearGradient
- *
- * Through the layoutlib_create tool, the original native methods of LinearGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LinearGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public final class LinearGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int colors[], float positions[], int tileMode) {
-        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(matrix, x0, y0,
-                x1, y1, colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(thisGradient, matrix, x0, y0, x1, y1, new int[] { color0, color1},
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    private LinearGradient_Delegate(long nativeMatrix, float x0, float y0, float x1,
-            float y1, int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
-    }
-
-    // ---- Custom Java Paint ----
-    /**
-     * Linear Gradient (Java) Paint able to handle more than 2 points, as
-     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
-     * modes.
-     */
-    private class LinearGradientPaint extends GradientPaint {
-
-        private final float mX0;
-        private final float mY0;
-        private final float mDx;
-        private final float mDy;
-        private final float mDSize2;
-
-        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
-                float positions[], TileMode tile) {
-            super(colors, positions, tile);
-            mX0 = x0;
-            mY0 = y0;
-            mDx = x1 - x0;
-            mDy = y1 - y0;
-            mDSize2 = mDx * mDx + mDy * mDy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class LinearGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            private LinearGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float x, float y) {
-            float pos;
-            if (mDx == 0) {
-                pos = (y - mY0) / mDy;
-            } else if (mDy == 0) {
-                pos = (x - mX0) / mDx;
-            } else {
-                // find the x position on the gradient vector.
-                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-                // from it get the position relative to the vector
-                pos = (_x - mX0) / mDx;
-            }
-
-            return getGradientColor(pos);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
deleted file mode 100644
index e726c59..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.MaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of MaskFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original MaskFilter class.
- *
- * This also serve as a base class for all MaskFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class MaskFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<MaskFilter_Delegate> sManager =
-            new DelegateManager<MaskFilter_Delegate>(MaskFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static MaskFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_filter) {
-        sManager.removeJavaReferenceFor(native_filter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
deleted file mode 100644
index 354f919..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix.ScaleToFit;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Matrix
- *
- * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Matrix class.
- *
- * @see DelegateManager
- *
- */
-public final class Matrix_Delegate {
-
-    private final static int MATRIX_SIZE = 9;
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Matrix_Delegate> sManager =
-            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate data ----
-    private float mValues[] = new float[MATRIX_SIZE];
-
-    // ---- Public Helper methods ----
-
-    public static Matrix_Delegate getDelegate(long native_instance) {
-        return sManager.getDelegate(native_instance);
-    }
-
-    /**
-     * Returns an {@link AffineTransform} matching the given Matrix.
-     */
-    public static AffineTransform getAffineTransform(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.getAffineTransform();
-    }
-
-    public static boolean hasPerspective(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return false;
-        }
-
-        return delegate.hasPerspective();
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix.
-     */
-    public void set(Matrix_Delegate matrix) {
-        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix represented as an array
-     * of values.
-     */
-    public void set(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Resets the matrix to be the identity matrix.
-     */
-    public void reset() {
-        reset(mValues);
-    }
-
-    /**
-     * Returns whether or not the matrix is identity.
-     */
-    public boolean isIdentity() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                if (mValues[k] != ((i==j) ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public static float[] makeValues(AffineTransform matrix) {
-        float[] values = new float[MATRIX_SIZE];
-        values[0] = (float) matrix.getScaleX();
-        values[1] = (float) matrix.getShearX();
-        values[2] = (float) matrix.getTranslateX();
-        values[3] = (float) matrix.getShearY();
-        values[4] = (float) matrix.getScaleY();
-        values[5] = (float) matrix.getTranslateY();
-        values[6] = 0.f;
-        values[7] = 0.f;
-        values[8] = 1.f;
-
-        return values;
-    }
-
-    public static Matrix_Delegate make(AffineTransform matrix) {
-        return new Matrix_Delegate(makeValues(matrix));
-    }
-
-    public boolean mapRect(RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        mapPoints(corners);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-
-
-        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-
-    /**
-     * Returns an {@link AffineTransform} matching the matrix.
-     */
-    public AffineTransform getAffineTransform() {
-        return getAffineTransform(mValues);
-    }
-
-    public boolean hasPerspective() {
-        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
-    }
-
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(long native_src_or_zero) {
-        // create the delegate
-        Matrix_Delegate newDelegate = new Matrix_Delegate();
-
-        // copy from values if needed.
-        if (native_src_or_zero > 0) {
-            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
-            if (oldDelegate != null) {
-                System.arraycopy(
-                        oldDelegate.mValues, 0,
-                        newDelegate.mValues, 0,
-                        MATRIX_SIZE);
-            }
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsIdentity(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.isIdentity();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsAffine(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kPerspective_Mask) == 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nRectStaysRect(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        reset(d.mValues);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_object, long other) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        Matrix_Delegate src = sManager.getDelegate(other);
-        if (src == null) {
-            return;
-        }
-
-        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setTranslate(d.mValues, dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getScale(sx, sy, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = sx;
-        d.mValues[1] = 0;
-        d.mValues[2] = 0;
-        d.mValues[3] = 0;
-        d.mValues[4] = sy;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees, float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getRotate(degrees, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, degrees);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(d.mValues, -px, -py);
-
-        // scale
-        d.postTransform(getRotate(sinValue, cosValue));
-        // translate back the pivot
-        d.postTransform(getTranslate(px, py));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, sinValue, cosValue);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getSkew(kx, ky, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = 1;
-        d.mValues[1] = kx;
-        d.mValues[2] = -0;
-        d.mValues[3] = ky;
-        d.mValues[4] = 1;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetConcat(long native_object, long a, long b) {
-        if (a == native_object) {
-            nPreConcat(native_object, b);
-            return;
-        } else if (b == native_object) {
-            nPostConcat(native_object, a);
-            return;
-        }
-
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate a_mtx = sManager.getDelegate(a);
-        Matrix_Delegate b_mtx = sManager.getDelegate(b);
-        if (d != null && a_mtx != null && b_mtx != null) {
-            multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-
-            double rad = Math.toRadians(degrees);
-            float sin = (float) Math.sin(rad);
-            float cos = (float) Math.cos(rad);
-
-            d.preTransform(getRotate(sin, cos));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.preTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.postTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRectToRect(long native_object, RectF src,
-            RectF dst, int stf) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        if (src.isEmpty()) {
-            reset(d.mValues);
-            return false;
-        }
-
-        if (dst.isEmpty()) {
-            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
-               = d.mValues[6] = d.mValues[7] = 0;
-            d.mValues[8] = 1;
-        } else {
-            float    tx, sx = dst.width() / src.width();
-            float    ty, sy = dst.height() / src.height();
-            boolean  xLarger = false;
-
-            if (stf != ScaleToFit.FILL.nativeInt) {
-                if (sx > sy) {
-                    xLarger = true;
-                    sx = sy;
-                } else {
-                    sy = sx;
-                }
-            }
-
-            tx = dst.left - src.left * sx;
-            ty = dst.top - src.top * sy;
-            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
-                float diff;
-
-                if (xLarger) {
-                    diff = dst.width() - src.width() * sy;
-                } else {
-                    diff = dst.height() - src.height() * sy;
-                }
-
-                if (stf == ScaleToFit.CENTER.nativeInt) {
-                    diff = diff / 2;
-                }
-
-                if (xLarger) {
-                    tx += diff;
-                } else {
-                    ty += diff;
-                }
-            }
-
-            d.mValues[0] = sx;
-            d.mValues[4] = sy;
-            d.mValues[2] = tx;
-            d.mValues[5] = ty;
-            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;
-
-        }
-        // shared cleanup
-        d.mValues[8] = 1;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex,
-            float[] dst, int dstIndex, int pointCount) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Matrix.setPolyToPoly is not supported.",
-                null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInvert(long native_object, long inverse) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
-        if (inv_mtx == null) {
-            return false;
-        }
-
-        try {
-            AffineTransform affineTransform = d.getAffineTransform();
-            AffineTransform inverseTransform = affineTransform.createInverse();
-            inv_mtx.mValues[0] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[1] = (float)inverseTransform.getShearX();
-            inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX();
-            inv_mtx.mValues[3] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[4] = (float)inverseTransform.getShearY();
-            inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY();
-
-            return true;
-        } catch (NoninvertibleTransformException e) {
-            return false;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMapPoints(long native_object, float[] dst, int dstIndex,
-            float[] src, int srcIndex, int ptCount, boolean isPts) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        if (isPts) {
-            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-        } else {
-            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nMapRect(long native_object, RectF dst, RectF src) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.mapRect(dst, src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nMapRadius(long native_object, float radius) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return 0.f;
-        }
-
-        float[] src = new float[] { radius, 0.f, 0.f, radius };
-        d.mapVectors(src, 0, src, 0, 2);
-
-        float l1 = (float) Math.hypot(src[0], src[1]);
-        float l2 = (float) Math.hypot(src[2], src[3]);
-        return (float) Math.sqrt(l1 * l2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nEquals(long native_a, long native_b) {
-        Matrix_Delegate a = sManager.getDelegate(native_a);
-        if (a == null) {
-            return false;
-        }
-
-        Matrix_Delegate b = sManager.getDelegate(native_b);
-        if (b == null) {
-            return false;
-        }
-
-        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
-            if (a.mValues[i] != b.mValues[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Matrix_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    // ---- Private helper methods ----
-
-    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
-        // the AffineTransform constructor takes the value in a different order
-        // for a matrix [ 0 1 2 ]
-        //              [ 3 4 5 ]
-        // the order is 0, 3, 1, 4, 2, 5...
-        return new AffineTransform(
-                matrix[0], matrix[3], matrix[1],
-                matrix[4], matrix[2], matrix[5]);
-    }
-
-    /**
-     * Reset a matrix to the identity
-     */
-    private static void reset(float[] mtx) {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                mtx[k] = ((i==j) ? 1 : 0);
-            }
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private final static int kIdentity_Mask      = 0;
-    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
-    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
-    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
-    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
-    private final static int kRectStaysRect_Mask = 0x10;
-    @SuppressWarnings("unused")
-    private final static int kUnknown_Mask       = 0x80;
-
-    @SuppressWarnings("unused")
-    private final static int kAllMasks           = kTranslate_Mask |
-                                                   kScale_Mask |
-                                                   kAffine_Mask |
-                                                   kPerspective_Mask |
-                                                   kRectStaysRect_Mask;
-
-    // these guys align with the masks, so we can compute a mask from a variable 0/1
-    @SuppressWarnings("unused")
-    private final static int kTranslate_Shift = 0;
-    @SuppressWarnings("unused")
-    private final static int kScale_Shift = 1;
-    @SuppressWarnings("unused")
-    private final static int kAffine_Shift = 2;
-    @SuppressWarnings("unused")
-    private final static int kPerspective_Shift = 3;
-    private final static int kRectStaysRect_Shift = 4;
-
-    private int computeTypeMask() {
-        int mask = 0;
-
-        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
-            mask |= kPerspective_Mask;
-        }
-
-        if (mValues[2] != 0. || mValues[5] != 0.) {
-            mask |= kTranslate_Mask;
-        }
-
-        float m00 = mValues[0];
-        float m01 = mValues[1];
-        float m10 = mValues[3];
-        float m11 = mValues[4];
-
-        if (m01 != 0. || m10 != 0.) {
-            mask |= kAffine_Mask;
-        }
-
-        if (m00 != 1. || m11 != 1.) {
-            mask |= kScale_Mask;
-        }
-
-        if ((mask & kPerspective_Mask) == 0) {
-            // map non-zero to 1
-            int im00 = m00 != 0 ? 1 : 0;
-            int im01 = m01 != 0 ? 1 : 0;
-            int im10 = m10 != 0 ? 1 : 0;
-            int im11 = m11 != 0 ? 1 : 0;
-
-            // record if the (p)rimary and (s)econdary diagonals are all 0 or
-            // all non-zero (answer is 0 or 1)
-            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
-            int dp1 = im00 & im11;        // true if both are 1
-            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
-            int ds1 = im01 & im10;        // true if both are 1
-
-            // return 1 if primary is 1 and secondary is 0 or
-            // primary is 0 and secondary is 1
-            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
-        }
-
-        return mask;
-    }
-
-    private Matrix_Delegate() {
-        reset();
-    }
-
-    private Matrix_Delegate(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = this*matrix
-     * @param matrix
-     */
-    private void postTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, mValues, matrix);
-        mValues = tmp;
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = matrix*this
-     * @param matrix
-     */
-    private void preTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, matrix, mValues);
-        mValues = tmp;
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points specified by src, and write
-      * the transformed points into the array of points specified by dst. The
-      * two arrays represent their "points" as pairs of floats [x, y].
-      *
-      * @param dst   The array of dst points (x,y pairs)
-      * @param dstIndex The index of the first [x,y] pair of dst floats
-      * @param src   The array of src points (x,y pairs)
-      * @param srcIndex The index of the first [x,y] pair of src floats
-      * @param pointCount The number of points (x,y pairs) to transform
-      */
-
-     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
-                           int pointCount) {
-         final int count = pointCount * 2;
-
-         float[] tmpDest = dst;
-         boolean inPlace = dst == src;
-         if (inPlace) {
-             tmpDest = new float[dstIndex + count];
-         }
-
-         for (int i = 0 ; i < count ; i += 2) {
-             // just in case we are doing in place, we better put this in temp vars
-             float x = mValues[0] * src[i + srcIndex] +
-                       mValues[1] * src[i + srcIndex + 1] +
-                       mValues[2];
-             float y = mValues[3] * src[i + srcIndex] +
-                       mValues[4] * src[i + srcIndex + 1] +
-                       mValues[5];
-
-             tmpDest[i + dstIndex]     = x;
-             tmpDest[i + dstIndex + 1] = y;
-         }
-
-         if (inPlace) {
-             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
-         }
-     }
-
-     /**
-      * Apply this matrix to the array of 2D points, and write the transformed
-      * points back into the array
-      *
-      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
-      */
-
-     private void mapPoints(float[] pts) {
-         mapPoints(pts, 0, pts, 0, pts.length >> 1);
-     }
-
-     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
-         if (hasPerspective()) {
-             // transform the (0,0) point
-             float[] origin = new float[] { 0.f, 0.f};
-             mapPoints(origin);
-
-             // translate the vector data as points
-             mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-
-             // then substract the transformed origin.
-             final int count = ptCount * 2;
-             for (int i = 0 ; i < count ; i += 2) {
-                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
-                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
-             }
-         } else {
-             // make a copy of the matrix
-             Matrix_Delegate copy = new Matrix_Delegate(mValues);
-
-             // remove the translation
-             setTranslate(copy.mValues, 0, 0);
-
-             // map the content as points.
-             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-         }
-     }
-
-    /**
-     * multiply two matrices and store them in a 3rd.
-     * <p/>This in effect does dest = a*b
-     * dest cannot be the same as a or b.
-     */
-     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
-        // first row
-        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
-        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
-        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];
-
-        // 2nd row
-        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
-        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
-        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];
-
-        // 3rd row
-        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
-        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
-        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
-    }
-
-    /**
-     * Returns a matrix that represents a given translate
-     * @param dx
-     * @param dy
-     * @return
-     */
-    /*package*/ static float[] getTranslate(float dx, float dy) {
-        return setTranslate(new float[9], dx, dy);
-    }
-
-    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
-        dest[0] = 1;
-        dest[1] = 0;
-        dest[2] = dx;
-        dest[3] = 0;
-        dest[4] = 1;
-        dest[5] = dy;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getScale(float sx, float sy) {
-        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
-    }
-
-    /**
-     * Returns a matrix that represents the given scale info.
-     * @param sx
-     * @param sy
-     * @param px
-     * @param py
-     */
-    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate tmp so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // scale into tmp2
-        multiply(tmp2, tmp, getScale(sx, sy));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-
-    /*package*/ static float[] getRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return getRotate(sin, cos);
-    }
-
-    /*package*/ static float[] getRotate(float sin, float cos) {
-        return setRotate(new float[9], sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return setRotate(dest, sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
-        dest[0] = cos;
-        dest[1] = -sin;
-        dest[2] = 0;
-        dest[3] = sin;
-        dest[4] = cos;
-        dest[5] = 0;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getRotate(float degrees, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // rotate into tmp2
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        multiply(tmp2, tmp, getRotate(sin, cos));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky) {
-        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // skew into tmp2
-        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
deleted file mode 100644
index 1f0eb3b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.drawable.NinePatchDrawable;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.graphics.NinePatch
- *
- * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public final class NinePatch_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NinePatch_Delegate> sManager =
-            new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class);
-
-    // ---- delegate helper data ----
-    /**
-     * Cache map for {@link NinePatchChunk}.
-     * When the chunks are created they are serialized into a byte[], and both are put
-     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
-     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
-     * provide this for drawing.
-     * Using the cache map allows us to not have to deserialize the byte[] back into a
-     * {@link NinePatchChunk} every time a rendering is done.
-     */
-    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
-        new HashMap<byte[], SoftReference<NinePatchChunk>>();
-
-    // ---- delegate data ----
-    private byte[] chunk;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Serializes the given chunk.
-     *
-     * @return the serialized data for the chunk.
-     */
-    public static byte[] serialize(NinePatchChunk chunk) {
-        // serialize the chunk to get a byte[]
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = null;
-        try {
-            oos = new ObjectOutputStream(baos);
-            oos.writeObject(chunk);
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
-            return null;
-        } finally {
-            if (oos != null) {
-                try {
-                    oos.close();
-                } catch (IOException ignored) {
-                }
-            }
-        }
-
-        // get the array and add it to the cache
-        byte[] array = baos.toByteArray();
-        sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-        return array;
-    }
-
-    /**
-     * Returns a {@link NinePatchChunk} object for the given serialized representation.
-     *
-     * If the chunk is present in the cache then the object from the cache is returned, otherwise
-     * the array is deserialized into a {@link NinePatchChunk} object.
-     *
-     * @param array the serialized representation of the chunk.
-     * @return the NinePatchChunk or null if deserialization failed.
-     */
-    public static NinePatchChunk getChunk(byte[] array) {
-        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
-        NinePatchChunk chunk = chunkRef.get();
-        if (chunk == null) {
-            ByteArrayInputStream bais = new ByteArrayInputStream(array);
-            ObjectInputStream ois = null;
-            try {
-                ois = new ObjectInputStream(bais);
-                chunk = (NinePatchChunk) ois.readObject();
-
-                // put back the chunk in the cache
-                if (chunk != null) {
-                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-                }
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
-                return null;
-            } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
-                return null;
-            } finally {
-                if (ois != null) {
-                    try {
-                        ois.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-        }
-
-        return chunk;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
-        NinePatchChunk chunkObject = getChunk(chunk);
-        return chunkObject != null;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long validateNinePatchChunk(byte[] chunk) {
-        // the default JNI implementation only checks that the byte[] has the same
-        // size as the C struct it represent. Since we cannot do the same check (serialization
-        // will return different size depending on content), we do nothing.
-        NinePatch_Delegate newDelegate = new NinePatch_Delegate();
-        newDelegate.chunk = chunk;
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeFinalize(long chunk) {
-        sManager.removeJavaReferenceFor(chunk);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) {
-        return 0;
-    }
-
-    static byte[] getChunk(long nativeNinePatch) {
-        NinePatch_Delegate delegate = sManager.getDelegate(nativeNinePatch);
-        if (delegate != null) {
-            return delegate.chunk;
-        }
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
deleted file mode 100644
index fa20746..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.PaintFlagsDrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of PaintFlagsDrawFilter have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PaintFlagsDrawFilter class.
- *
- * Because this extends {@link DrawFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the DrawFilter classes will be added to the manager owned by
- * {@link DrawFilter_Delegate}.
- *
- * @see DrawFilter_Delegate
- *
- */
-public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Paint Flags Draw Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(int clearBits, int setBits) {
-        PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
deleted file mode 100644
index 1bb56e3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.Paint.FontMetrics;
-import android.graphics.Paint.FontMetricsInt;
-import android.text.TextUtils;
-
-import java.awt.BasicStroke;
-import java.awt.Font;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Paint
- *
- * Through the layoutlib_create tool, the original native methods of Paint have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Paint class.
- *
- * @see DelegateManager
- *
- */
-public class Paint_Delegate {
-
-    /**
-     * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
-     */
-    /*package*/ static final class FontInfo {
-        Font mFont;
-        java.awt.FontMetrics mMetrics;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Paint_Delegate> sManager =
-            new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // This list can contain null elements.
-    private List<FontInfo> mFonts;
-
-    // ---- delegate data ----
-    private int mFlags;
-    private int mColor;
-    private int mStyle;
-    private int mCap;
-    private int mJoin;
-    private int mTextAlign;
-    private Typeface_Delegate mTypeface;
-    private float mStrokeWidth;
-    private float mStrokeMiter;
-    private float mTextSize;
-    private float mTextScaleX;
-    private float mTextSkewX;
-    private int mHintingMode = Paint.HINTING_ON;
-    private int mHyphenEdit;
-    private float mLetterSpacing;  // not used in actual text rendering.
-    private float mWordSpacing;  // not used in actual text rendering.
-    // Variant of the font. A paint's variant can only be compact or elegant.
-    private FontVariant mFontVariant = FontVariant.COMPACT;
-
-    private int mPorterDuffMode = Xfermode.DEFAULT;
-    private ColorFilter_Delegate mColorFilter;
-    private Shader_Delegate mShader;
-    private PathEffect_Delegate mPathEffect;
-    private MaskFilter_Delegate mMaskFilter;
-
-    private Locale mLocale = Locale.getDefault();
-
-    // Used only to assert invariants.
-    public long mNativeTypeface;
-
-    // ---- Public Helper methods ----
-
-    @Nullable
-    public static Paint_Delegate getDelegate(long native_paint) {
-        return sManager.getDelegate(native_paint);
-    }
-
-    /**
-     * Returns the list of {@link Font} objects.
-     */
-    public List<FontInfo> getFonts() {
-        return mFonts;
-    }
-
-    public boolean isAntiAliased() {
-        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
-    }
-
-    public boolean isFilterBitmap() {
-        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
-    }
-
-    public int getStyle() {
-        return mStyle;
-    }
-
-    public int getColor() {
-        return mColor;
-    }
-
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
-    public void setAlpha(int alpha) {
-        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
-    }
-
-    public int getTextAlign() {
-        return mTextAlign;
-    }
-
-    public float getStrokeWidth() {
-        return mStrokeWidth;
-    }
-
-    /**
-     * returns the value of stroke miter needed by the java api.
-     */
-    public float getJavaStrokeMiter() {
-        return mStrokeMiter;
-    }
-
-    public int getJavaCap() {
-        switch (Paint.sCapArray[mCap]) {
-            case BUTT:
-                return BasicStroke.CAP_BUTT;
-            case ROUND:
-                return BasicStroke.CAP_ROUND;
-            default:
-            case SQUARE:
-                return BasicStroke.CAP_SQUARE;
-        }
-    }
-
-    public int getJavaJoin() {
-        switch (Paint.sJoinArray[mJoin]) {
-            default:
-            case MITER:
-                return BasicStroke.JOIN_MITER;
-            case ROUND:
-                return BasicStroke.JOIN_ROUND;
-            case BEVEL:
-                return BasicStroke.JOIN_BEVEL;
-        }
-    }
-
-    public Stroke getJavaStroke() {
-        if (mPathEffect != null) {
-            if (mPathEffect.isSupported()) {
-                Stroke stroke = mPathEffect.getStroke(this);
-                assert stroke != null;
-                if (stroke != null) {
-                    return stroke;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
-                        mPathEffect.getSupportMessage(),
-                        null, null /*data*/);
-            }
-        }
-
-        // if no custom stroke as been set, set the default one.
-        return new BasicStroke(
-                    getStrokeWidth(),
-                    getJavaCap(),
-                    getJavaJoin(),
-                    getJavaStrokeMiter());
-    }
-
-    /**
-     * Returns the {@link PorterDuff.Mode} as an int
-     */
-    public int getPorterDuffMode() {
-        return mPorterDuffMode;
-    }
-
-    /**
-     * Returns the {@link ColorFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public ColorFilter_Delegate getColorFilter() {
-        return mColorFilter;
-    }
-
-    public void setColorFilter(long colorFilterPtr) {
-        mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
-    }
-
-    public void setShader(long shaderPtr) {
-        mShader = Shader_Delegate.getDelegate(shaderPtr);
-    }
-
-    /**
-     * Returns the {@link Shader} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Shader_Delegate getShader() {
-        return mShader;
-    }
-
-    /**
-     * Returns the {@link MaskFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public MaskFilter_Delegate getMaskFilter() {
-        return mMaskFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFlags(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mFlags;
-    }
-
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFlags(long nativePaint, int flags) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFlags = flags;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFilterBitmap(long nativePaint, boolean filter) {
-        setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHinting(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return Paint.HINTING_ON;
-        }
-
-        return delegate.mHintingMode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHinting(long nativePaint, int mode) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHintingMode = mode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAntiAlias(long nativePaint, boolean aa) {
-        setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSubpixelText(long nativePaint,
-            boolean subpixelText) {
-        setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetUnderlineText(long nativePaint,
-            boolean underlineText) {
-        setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrikeThruText(long nativePaint,
-            boolean strikeThruText) {
-        setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFakeBoldText(long nativePaint,
-            boolean fakeBoldText) {
-        setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetDither(long nativePaint, boolean dither) {
-        setFlag(nativePaint, Paint.DITHER_FLAG, dither);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLinearText(long nativePaint, boolean linearText) {
-        setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetColor(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mColor;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetColor(long nativePaint, int color) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mColor = color;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetAlpha(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getAlpha();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAlpha(long nativePaint, int a) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.setAlpha(a);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeWidth(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeWidth;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeWidth(long nativePaint, float width) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeWidth = width;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeMiter(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeMiter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeMiter(long nativePaint, float miter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeMiter = miter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
-            int color) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.setShadowLayer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasShadowLayer(long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.hasShadowLayer is not supported.", null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsElegantTextHeight(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetElegantTextHeight(long nativePaint,
-            boolean elegant) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSize(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSize;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSize(long nativePaint, float textSize) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSize != textSize) {
-            delegate.mTextSize = textSize;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextScaleX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextScaleX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextScaleX(long nativePaint, float scaleX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextScaleX != scaleX) {
-            delegate.mTextScaleX = scaleX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSkewX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSkewX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSkewX(long nativePaint, float skewX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSkewX != skewX) {
-            delegate.mTextSkewX = skewX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAscent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            // Android expects negative ascent so we invert the value from Java.
-            return - javaMetrics.getAscent();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nDescent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            return javaMetrics.getDescent();
-        }
-
-        return 0;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetFontMetrics(long nativePaint, long nativeTypeface,
-            FontMetrics metrics) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getFontMetrics(metrics);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFontMetricsInt(long nativePaint,
-            long nativeTypeface, FontMetricsInt fmi) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            if (fmi != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                fmi.top = - javaMetrics.getMaxAscent();
-                fmi.ascent = - javaMetrics.getAscent();
-                fmi.descent = javaMetrics.getDescent();
-                fmi.bottom = javaMetrics.getMaxDescent();
-                fmi.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
-            int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
-
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        int inc = count > 0 ? 1 : -1;
-
-        int measureIndex = 0;
-        for (int i = index; i != index + count; i += inc, measureIndex++) {
-            int start, end;
-            if (i < index) {
-                start = i;
-                end = index;
-            } else {
-                start = index;
-                end = i;
-            }
-
-            // measure from start to end
-            RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
-            float res = bounds.right - bounds.left;
-
-            if (measuredWidth != null) {
-                measuredWidth[measureIndex] = res;
-            }
-
-            if (res > maxWidth) {
-                // we should not return this char index, but since it's 0-based
-                // and we need to return a count, we simply return measureIndex;
-                return measureIndex;
-            }
-
-        }
-
-        return measureIndex;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
-            boolean measureForwards,
-            float maxWidth, int bidiFlags, float[] measuredWidth) {
-        return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
-                maxWidth, bidiFlags, measuredWidth);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        Paint_Delegate newDelegate = new Paint_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitWithPaint(long paint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(paint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long native_src) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
-        if (delegate_dst == null) {
-            return;
-        }
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
-        if (delegate_src == null) {
-            return;
-        }
-
-        delegate_dst.set(delegate_src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStyle(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStyle(long native_object, int style) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStyle = style;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeCap(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mCap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeCap(long native_object, int cap) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mCap = cap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeJoin(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mJoin;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeJoin(long native_object, int join) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mJoin = join;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
-        Paint_Delegate paint = sManager.getDelegate(native_object);
-        if (paint == null) {
-            return false;
-        }
-
-        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
-        if (srcPath == null) {
-            return true;
-        }
-
-        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
-        if (dstPath == null) {
-            return true;
-        }
-
-        Stroke stroke = paint.getJavaStroke();
-        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
-
-        dstPath.setJavaShape(strokeShape);
-
-        // FIXME figure out the return value?
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetShader(long native_object, long shader) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return shader;
-        }
-
-        delegate.mShader = Shader_Delegate.getDelegate(shader);
-
-        return shader;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetColorFilter(long native_object, long filter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return filter;
-        }
-
-        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
-
-        // Log warning if it's not supported.
-        if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
-                    delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return filter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetXfermode(long native_object, int xfermode) {
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mPorterDuffMode = xfermode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetPathEffect(long native_object, long effect) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return effect;
-        }
-
-        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
-
-        return effect;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return maskfilter;
-        }
-
-        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return maskfilter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetTypeface(long native_object, long typeface) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
-        if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
-            delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
-            delegate.mNativeTypeface = typeface;
-            delegate.updateFontObject();
-        }
-        return typeface;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextAlign(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mTextAlign;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextAlign(long native_object, int align) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextAlign = align;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nSetTextLocales(long native_object, String locale) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        delegate.setTextLocale(locale);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
-            int mMinikinLangListId) {
-        // FIXME
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            char[] text, int index, int count, int contextIndex, int contextCount,
-            int bidiFlags, float[] advances, int advancesIndex) {
-
-        if (advances != null)
-            for (int i = advancesIndex; i< advancesIndex+count; i++)
-                advances[i]=0;
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0.f;
-        }
-
-        // native_typeface is passed here since Framework's old implementation did not have the
-        // typeface object associated with the Paint. Since, we follow the new framework way,
-        // we store the typeface with the paint and use it directly.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
-        return bounds.right - bounds.left;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            String text, int start, int end, int contextStart, int contextEnd,
-            int bidiFlags, float[] advances, int advancesIndex) {
-        // FIXME: support contextStart and contextEnd
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            char[] text, int contextStart, int contextLength, int flags, int offset,
-            int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, String text, int start, int end, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
-            String text, int start, int end, int bidiFlags, Rect bounds) {
-        nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
-                end - start, bidiFlags, bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
-            char[] text, int index, int count, int bidiFlags, Rect bounds) {
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        // assert that the typeface passed is actually the one that we had stored.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Paint_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
-                        sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetLetterSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mLetterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setLetterSpacing() not supported.", null, null);
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mLetterSpacing = letterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetWordSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mWordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mWordSpacing = wordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setFontFeatureSettings() not supported.", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHyphenEdit(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mHyphenEdit;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mHyphenEdit = hyphen;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
-            String string) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return false;
-        }
-        if (string.length() == 0) {
-            return false;
-        }
-        if (string.length() > 1) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                    "Paint.hasGlyph() is not supported for ligatures.", null, null);
-            return false;
-        }
-        assert nativeTypeface == delegate.mNativeTypeface;
-        Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
-
-        char c = string.charAt(0);
-        for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
-            if (font.canDisplay(c)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
-            @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
-            boolean isRtl, int offset) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        int startOffset = offset - start;  // offset from start.
-        float sum = 0;
-        for (int i = 0; i < startOffset; i++) {
-            sum += advances[i];
-        }
-        return sum;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
-            char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
-            float advance) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        float sum = 0;
-        int i;
-        for (i = 0; i < count && sum < advance; i++) {
-            sum += advances[i];
-        }
-        float distanceToI = sum - advance;
-        float distanceToIMinus1 = advance - (sum - advances[i]);
-        return distanceToI > distanceToIMinus1 ? i : i - 1;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /*package*/ Paint_Delegate() {
-        reset();
-    }
-
-    private Paint_Delegate(Paint_Delegate paint) {
-        set(paint);
-    }
-
-    private void set(Paint_Delegate paint) {
-        mFlags = paint.mFlags;
-        mColor = paint.mColor;
-        mStyle = paint.mStyle;
-        mCap = paint.mCap;
-        mJoin = paint.mJoin;
-        mTextAlign = paint.mTextAlign;
-
-        boolean needsFontUpdate = false;
-        if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
-            mTypeface = paint.mTypeface;
-            mNativeTypeface = paint.mNativeTypeface;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSize != paint.mTextSize) {
-            mTextSize = paint.mTextSize;
-            needsFontUpdate = true;
-        }
-
-        if (mTextScaleX != paint.mTextScaleX) {
-            mTextScaleX = paint.mTextScaleX;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSkewX != paint.mTextSkewX) {
-            mTextSkewX = paint.mTextSkewX;
-            needsFontUpdate = true;
-        }
-
-        mStrokeWidth = paint.mStrokeWidth;
-        mStrokeMiter = paint.mStrokeMiter;
-        mPorterDuffMode = paint.mPorterDuffMode;
-        mColorFilter = paint.mColorFilter;
-        mShader = paint.mShader;
-        mPathEffect = paint.mPathEffect;
-        mMaskFilter = paint.mMaskFilter;
-        mHintingMode = paint.mHintingMode;
-
-        if (needsFontUpdate) {
-            updateFontObject();
-        }
-    }
-
-    private void reset() {
-        mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
-        mColor = 0xFF000000;
-        mStyle = Paint.Style.FILL.nativeInt;
-        mCap = Paint.Cap.BUTT.nativeInt;
-        mJoin = Paint.Join.MITER.nativeInt;
-        mTextAlign = 0;
-        mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
-        mNativeTypeface = 0;
-        mStrokeWidth = 1.f;
-        mStrokeMiter = 4.f;
-        mTextSize = 20.f;
-        mTextScaleX = 1.f;
-        mTextSkewX = 0.f;
-        mPorterDuffMode = Xfermode.DEFAULT;
-        mColorFilter = null;
-        mShader = null;
-        mPathEffect = null;
-        mMaskFilter = null;
-        updateFontObject();
-        mHintingMode = Paint.HINTING_ON;
-    }
-
-    /**
-     * Update the {@link Font} object from the typeface, text size and scaling
-     */
-    @SuppressWarnings("deprecation")
-    private void updateFontObject() {
-        if (mTypeface != null) {
-            // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts(mFontVariant);
-
-            if (fonts.isEmpty()) {
-                mFonts = Collections.emptyList();
-                return;
-            }
-
-            // create new font objects as well as FontMetrics, based on the current text size
-            // and skew info.
-            int nFonts = fonts.size();
-            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
-            //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-            for (int i = 0; i < nFonts; i++) {
-                Font font = fonts.get(i);
-                if (font == null) {
-                    // If the font is null, add null to infoList. When rendering the text, if this
-                    // null is reached, a warning will be logged.
-                    infoList.add(null);
-                    continue;
-                }
-                FontInfo info = new FontInfo();
-                info.mFont = font.deriveFont(mTextSize);
-                if (mTextScaleX != 1.0 || mTextSkewX != 0) {
-                    // TODO: support skew
-                    info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mTextScaleX, mTextSkewX, 0, 1, 0, 0));
-                }
-                // The metrics here don't have anti-aliasing set.
-                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
-
-                infoList.add(info);
-            }
-
-            mFonts = Collections.unmodifiableList(infoList);
-        }
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, int bidiFlags) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, boolean isRtl) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, isRtl, advances, advancesIndex, false);
-    }
-
-    private float getFontMetrics(FontMetrics metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    private void setTextLocale(String locale) {
-        mLocale = new Locale(locale);
-    }
-
-    private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (flagValue) {
-            delegate.mFlags |= flagMask;
-        } else {
-            delegate.mFlags &= ~flagMask;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
deleted file mode 100644
index fd9ba62..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathDashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathDashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Path Dash Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long native_path, float advance, float phase,
-            int native_style) {
-        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
deleted file mode 100644
index 000481e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathEffect class.
- *
- * This also serve as a base class for all PathEffect delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class PathEffect_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<PathEffect_Delegate> sManager =
-            new DelegateManager<PathEffect_Delegate>(PathEffect_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static PathEffect_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract Stroke getStroke(Paint_Delegate paint);
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_patheffect) {
-        sManager.removeJavaReferenceFor(native_patheffect);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
deleted file mode 100644
index 7f707c9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator;
-
-import java.awt.geom.PathIterator;
-
-/**
- * Delegate implementing the native methods of {@link android.graphics.PathMeasure}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of PathMeasure have been
- * replaced by
- * calls to methods of the same name in this delegate class.
- * <p/>
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between it
- * and the original PathMeasure class.
- *
- * @see DelegateManager
- */
-public final class PathMeasure_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<PathMeasure_Delegate> sManager =
-            new DelegateManager<PathMeasure_Delegate>(PathMeasure_Delegate.class);
-
-    // ---- delegate data ----
-    private CachedPathIteratorFactory mOriginalPathIterator;
-
-    private long mNativePath;
-
-
-    private PathMeasure_Delegate(long native_path, boolean forceClosed) {
-        mNativePath = native_path;
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_create(long native_path, boolean forceClosed) {
-        return sManager.addNewDelegate(new PathMeasure_Delegate(native_path, forceClosed));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_destroy(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getPosTan(long native_instance, float distance, float pos[],
-            float tan[]) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getPostTan is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getMatrix(long native_instance, float distance, long
-            native_matrix, int flags) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getMatrix is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_nextContour(long native_instance) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.nextContour is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setPath(long native_instance, long native_path, boolean
-            forceClosed) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            pathMeasure.mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-
-        pathMeasure.mNativePath = native_path;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_getLength(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (pathMeasure.mOriginalPathIterator == null) {
-            return 0;
-        }
-
-        return pathMeasure.mOriginalPathIterator.iterator().getTotalLength();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isClosed(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        Path_Delegate path = Path_Delegate.getDelegate(pathMeasure.mNativePath);
-        if (path == null) {
-            return false;
-        }
-
-        int type = 0;
-        float segment[] = new float[6];
-        for (PathIterator pi = path.getJavaShape().getPathIterator(null); !pi.isDone(); pi.next()) {
-            type = pi.currentSegment(segment);
-        }
-
-        // A path is a closed path if the last element is SEG_CLOSE
-        return type == PathIterator.SEG_CLOSE;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getSegment(long native_instance, float startD, float stopD,
-            long native_dst_path, boolean startWithMoveTo) {
-        if (startD < 0) {
-            startD = 0;
-        }
-
-        if (startD >= stopD) {
-            return false;
-        }
-
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        CachedPathIterator iterator = pathMeasure.mOriginalPathIterator.iterator();
-        float accLength = startD;
-        boolean isZeroLength = true; // Whether the output has zero length or not
-        float[] points = new float[6];
-
-        iterator.jumpToSegment(accLength);
-        while (!iterator.isDone() && (stopD - accLength > 0.1f)) {
-            int type = iterator.currentSegment(points, stopD - accLength);
-
-            if (accLength - iterator.getCurrentSegmentLength() <= stopD) {
-                if (startWithMoveTo) {
-                    startWithMoveTo = false;
-
-                    // If this segment is a MOVETO, then we just use that one. If not, then we issue
-                    // a first moveto
-                    if (type != PathIterator.SEG_MOVETO) {
-                        float[] lastPoint = new float[2];
-                        iterator.getCurrentSegmentEnd(lastPoint);
-                        Path_Delegate.nMoveTo(native_dst_path, lastPoint[0], lastPoint[1]);
-                    }
-                }
-
-                isZeroLength = isZeroLength && iterator.getCurrentSegmentLength() > 0;
-                switch (type) {
-                    case PathIterator.SEG_MOVETO:
-                        Path_Delegate.nMoveTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_LINETO:
-                        Path_Delegate.nLineTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_CLOSE:
-                        Path_Delegate.nClose(native_dst_path);
-                        break;
-                    case PathIterator.SEG_CUBICTO:
-                        Path_Delegate.nCubicTo(native_dst_path, points[0], points[1],
-                                points[2], points[3],
-                                points[4], points[5]);
-                        break;
-                    case PathIterator.SEG_QUADTO:
-                        Path_Delegate.nQuadTo(native_dst_path, points[0], points[1],
-                                points[2],
-                                points[3]);
-                        break;
-                    default:
-                        assert false;
-                }
-            }
-
-            accLength += iterator.getCurrentSegmentLength();
-            iterator.next();
-        }
-
-        return !isZeroLength;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
deleted file mode 100644
index 50b9165..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path.Direction;
-import android.graphics.Path.FillType;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Area;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Path2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
-import java.util.ArrayList;
-
-/**
- * Delegate implementing the native methods of android.graphics.Path
- *
- * Through the layoutlib_create tool, the original native methods of Path have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Path class.
- *
- * @see DelegateManager
- *
- */
-public final class Path_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Path_Delegate> sManager =
-            new DelegateManager<Path_Delegate>(Path_Delegate.class);
-
-    private static final float EPSILON = 1e-4f;
-
-    // ---- delegate data ----
-    private FillType mFillType = FillType.WINDING;
-    private Path2D mPath = new Path2D.Double();
-
-    private float mLastX = 0;
-    private float mLastY = 0;
-
-    // true if the path contains does not contain a curve or line.
-    private boolean mCachedIsEmpty = true;
-
-    // ---- Public Helper methods ----
-
-    public static Path_Delegate getDelegate(long nPath) {
-        return sManager.getDelegate(nPath);
-    }
-
-    public Path2D getJavaShape() {
-        return mPath;
-    }
-
-    public void setJavaShape(Shape shape) {
-        reset();
-        mPath.append(shape, false /*connect*/);
-    }
-
-    public void reset() {
-        mPath.reset();
-        mLastX = 0;
-        mLastY = 0;
-    }
-
-    public void setPathIterator(PathIterator iterator) {
-        reset();
-        mPath.append(iterator, false /*connect*/);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit(long nPath) {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        // get the delegate to copy, which could be null if nPath is 0
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate != null) {
-            newDelegate.set(pathDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRewind(long nPath) {
-        // call out to reset since there's nothing to optimize in
-        // terms of data structs.
-        nReset(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long nSrc) {
-        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
-        if (pathDstDelegate == null) {
-            return;
-        }
-
-        Path_Delegate pathSrcDelegate = sManager.getDelegate(nSrc);
-        if (pathSrcDelegate == null) {
-            return;
-        }
-
-        pathDstDelegate.set(pathSrcDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsConvex(long nPath) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Path.isConvex is not supported.", null, null);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFillType(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return 0;
-        }
-
-        return pathDelegate.mFillType.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetFillType(long nPath, int ft) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.setFillType(Path.sFillTypeArray[ft]);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsEmpty(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        return pathDelegate == null || pathDelegate.isEmpty();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsRect(long nPath, RectF rect) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return false;
-        }
-
-        // create an Area that can test if the path is a rect
-        Area area = new Area(pathDelegate.mPath);
-        if (area.isRectangular()) {
-            if (rect != null) {
-                pathDelegate.fillBounds(rect);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nComputeBounds(long nPath, RectF bounds) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.fillBounds(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nIncReserve(long nPath, int extraPtCount) {
-        // since we use a java2D path, there's no way to pre-allocate new points,
-        // so we do nothing.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMoveTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.moveTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRMoveTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rMoveTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nLineTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.lineTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRLineTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rLineTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nQuadTo(long nPath, float x1, float y1, float x2, float y2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.quadTo(x1, y1, x2, y2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nArcTo(long nPath, float left, float top, float right,
-            float bottom,
-                    float startAngle, float sweepAngle, boolean forceMoveTo) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.arcTo(left, top, right, bottom, startAngle, sweepAngle, forceMoveTo);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nClose(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.close();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRect(long nPath,
-            float left, float top, float right, float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.addRect(left, top, right, bottom, dir);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddOval(long nPath, float left, float top, float right,
-            float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                left, top, right - left, bottom - top), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddCircle(long nPath, float x, float y, float radius, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                x - radius, y - radius, radius * 2, radius * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddArc(long nPath, float left, float top, float right,
-            float bottom, float startAngle, float sweepAngle) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Arc2D.Float(
-                left, top, right - left, bottom - top,
-                -startAngle, -sweepAngle, Arc2D.OPEN), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float rx, float ry, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new RoundRectangle2D.Float(
-                left, top, right - left, bottom - top, rx * 2, ry * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float[] radii, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        float[] cornerDimensions = new float[radii.length];
-        for (int i = 0; i < radii.length; i++) {
-            cornerDimensions[i] = 2 * radii[i];
-        }
-        pathDelegate.mPath.append(new RoundRectangle(left, top, right - left, bottom - top,
-                cornerDimensions), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, float dx, float dy) {
-        addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src) {
-        addPath(nPath, src, null /*transform*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, long matrix) {
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        addPath(nPath, src, matrixDelegate.getAffineTransform());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nOffset(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.offset(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLastPoint(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mLastX = dx;
-        pathDelegate.mLastY = dy;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix,
-                                                long dst_path) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // this can be null if dst_path is 0
-        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
-
-        pathDelegate.transform(matrixDelegate, dstDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix) {
-        nTransform(nPath, matrix, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nOp(long nPath1, long nPath2, int op, long result) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nPath) {
-        sManager.removeJavaReferenceFor(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float[] nApproximate(long nPath, float error) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return null;
-        }
-        // Get a FlatteningIterator
-        PathIterator iterator = pathDelegate.getJavaShape().getPathIterator(null, error);
-
-        float segment[] = new float[6];
-        float totalLength = 0;
-        ArrayList<Point2D.Float> points = new ArrayList<Point2D.Float>();
-        Point2D.Float previousPoint = null;
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            Point2D.Float currentPoint = new Point2D.Float(segment[0], segment[1]);
-            // MoveTo shouldn't affect the length
-            if (previousPoint != null && type != PathIterator.SEG_MOVETO) {
-                totalLength += currentPoint.distance(previousPoint);
-            }
-            previousPoint = currentPoint;
-            points.add(currentPoint);
-            iterator.next();
-        }
-
-        int nPoints = points.size();
-        float[] result = new float[nPoints * 3];
-        previousPoint = null;
-        for (int i = 0; i < nPoints; i++) {
-            Point2D.Float point = points.get(i);
-            float distance = previousPoint != null ? (float) previousPoint.distance(point) : .0f;
-            result[i * 3] = distance / totalLength;
-            result[i * 3 + 1] = point.x;
-            result[i * 3 + 2] = point.y;
-
-            totalLength += distance;
-            previousPoint = point;
-        }
-
-        return result;
-    }
-
-    // ---- Private helper methods ----
-
-    private void set(Path_Delegate delegate) {
-        mPath.reset();
-        setFillType(delegate.mFillType);
-        mPath.append(delegate.mPath, false /*connect*/);
-    }
-
-    private void setFillType(FillType fillType) {
-        mFillType = fillType;
-        mPath.setWindingRule(getWindingRule(fillType));
-    }
-
-    /**
-     * Returns the Java2D winding rules matching a given Android {@link FillType}.
-     * @param type the android fill type
-     * @return the matching java2d winding rule.
-     */
-    private static int getWindingRule(FillType type) {
-        switch (type) {
-            case WINDING:
-            case INVERSE_WINDING:
-                return GeneralPath.WIND_NON_ZERO;
-            case EVEN_ODD:
-            case INVERSE_EVEN_ODD:
-                return GeneralPath.WIND_EVEN_ODD;
-
-            default:
-                assert false;
-                return GeneralPath.WIND_NON_ZERO;
-        }
-    }
-
-    @NonNull
-    private static Direction getDirection(int direction) {
-        for (Direction d : Direction.values()) {
-            if (direction == d.nativeInt) {
-                return d;
-            }
-        }
-
-        assert false;
-        return null;
-    }
-
-    public static void addPath(long destPath, long srcPath, AffineTransform transform) {
-        Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
-        if (destPathDelegate == null) {
-            return;
-        }
-
-        Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
-        if (srcPathDelegate == null) {
-            return;
-        }
-
-        if (transform != null) {
-            destPathDelegate.mPath.append(
-                    srcPathDelegate.mPath.getPathIterator(transform), false);
-        } else {
-            destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
-        }
-    }
-
-
-    /**
-     * Returns whether the path already contains any points.
-     * Note that this is different to
-     * {@link #isEmpty} because if all elements are {@link PathIterator#SEG_MOVETO},
-     * {@link #isEmpty} will return true while hasPoints will return false.
-     */
-    public boolean hasPoints() {
-        return !mPath.getPathIterator(null).isDone();
-    }
-
-    /**
-     * Returns whether the path is empty (contains no lines or curves).
-     * @see Path#isEmpty
-     */
-    public boolean isEmpty() {
-        if (!mCachedIsEmpty) {
-            return false;
-        }
-
-        float[] coords = new float[6];
-        mCachedIsEmpty = Boolean.TRUE;
-        for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
-            int type = it.currentSegment(coords);
-            if (type != PathIterator.SEG_MOVETO) {
-                // Once we know that the path is not empty, we do not need to check again unless
-                // Path#reset is called.
-                mCachedIsEmpty = false;
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Fills the given {@link RectF} with the path bounds.
-     * @param bounds the RectF to be filled.
-     */
-    public void fillBounds(RectF bounds) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    public void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    public void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    public void lineTo(float x, float y) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    public void rLineTo(float dx, float dy) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-
-        if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON) {
-            // The delta is so small that this shouldn't generate a line
-            return;
-        }
-
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    public void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        if (!hasPoints()) {
-            mPath.moveTo(0, 0);
-        }
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param left        The left of oval defining shape and size of the arc
-     * @param top         The top of oval defining shape and size of the arc
-     * @param right       The right of oval defining shape and size of the arc
-     * @param bottom      The bottom of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    public void arcTo(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle,
-            boolean forceMoveTo) {
-        Arc2D arc = new Arc2D.Float(left, top, right - left, bottom - top, -startAngle,
-                -sweepAngle, Arc2D.OPEN);
-        mPath.append(arc, true /*connect*/);
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    public void close() {
-        mPath.closePath();
-    }
-
-    private void resetLastPointFromPath() {
-        Point2D last = mPath.getCurrentPoint();
-        mLastX = (float) last.getX();
-        mLastY = (float) last.getY();
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    public void addRect(float left, float top, float right, float bottom,
-                        int dir) {
-        moveTo(left, top);
-
-        Direction direction = getDirection(dir);
-
-        switch (direction) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     */
-    public void offset(float dx, float dy) {
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-
-        newPath.append(iterator, false /*connect*/);
-        mPath = newPath;
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
-        if (matrix.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Path#transform() only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
-
-        newPath.append(iterator, false /*connect*/);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
deleted file mode 100644
index ff3f19f..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.PorterDuff.Mode;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getComposite;
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getPorterDuffMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.PorterDuffColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of PorterDuffColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PorterDuffColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    private final java.awt.Color mSrcColor;
-    private final Mode mMode;
-
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "PorterDuff Color Filter is not supported for mode: " + mMode.name() + ".";
-    }
-
-    @Override
-    public void applyFilter(Graphics2D g, int width, int height) {
-        g.setComposite(getComposite(mMode, 0xFF));
-        g.setColor(mSrcColor);
-        g.fillRect(0, 0, width, height);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) {
-        PorterDuffColorFilter_Delegate newDelegate =
-                new PorterDuffColorFilter_Delegate(srcColor, porterDuffMode);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private PorterDuffColorFilter_Delegate(int srcColor, int mode) {
-        mSrcColor = new java.awt.Color(srcColor, true /* hasAlpha */);
-        mMode = getCompatibleMode(getPorterDuffMode(mode));
-    }
-
-    // For filtering the colors, the src image should contain the "color" only for pixel values
-    // which are not transparent in the target image. But, we are using a simple rectangular image
-    // completely filled with color. Hence some Composite rules do not apply as intended. However,
-    // in such cases, they can usually be mapped to some other mode, which produces an approximately
-    // equivalent result.
-    private Mode getCompatibleMode(Mode mode) {
-        Mode m = mode;
-        // Modes that are directly supported:
-        // CLEAR, DST, SRC_IN, DST_IN, DST_OUT, SRC_ATOP, DARKEN, LIGHTEN, MULTIPLY, SCREEN,
-        // ADD, OVERLAY
-        switch (mode) {
-        // Modes that can be mapped to one of the supported modes.
-        case SRC:
-            m = Mode.SRC_IN;
-            break;
-        case SRC_OVER:
-            m = Mode.SRC_ATOP;
-            break;
-        case DST_OVER:
-            m = Mode.DST;
-            break;
-        case SRC_OUT:
-            m = Mode.CLEAR;
-            break;
-        case DST_ATOP:
-            m = Mode.DST_IN;
-            break;
-        case XOR:
-            m = Mode.DST_OUT;
-            break;
-        }
-        return m;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
deleted file mode 100644
index b5ba468..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.RadialGradient
- *
- * Through the layoutlib_create tool, the original native methods of RadialGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original RadialGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class RadialGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, float radius,
-            int colors[], float positions[], int tileMode) {
-        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(matrix, x, y, radius,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, float radius,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(matrix, x, y, radius, new int[] { color0, color1 },
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param colors The colors to be distributed between the center and edge of
-     *            the circle
-     * @param positions May be NULL. The relative position of each corresponding
-     *            color in the colors array. If this is NULL, the the colors are
-     *            distributed evenly between the center and edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    private RadialGradient_Delegate(long nativeMatrix, float x, float y, float radius,
-            int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
-    }
-
-    private class RadialGradientPaint extends GradientPaint {
-
-        private final float mX;
-        private final float mY;
-        private final float mRadius;
-
-        public RadialGradientPaint(float x, float y, float radius,
-                int[] colors, float[] positions, TileMode mode) {
-            super(colors, positions, mode);
-            mX = x;
-            mY = y;
-            mRadius = radius;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class RadialGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public RadialGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute distance from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mX;
-                        pt1[1] = pt2[1] - mY;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float _x = pt2[0];
-                        float _y = pt2[1];
-                        float distance = (float) Math.hypot(_x, _y);
-
-                        data[index++] = getGradientColor(distance / mRadius);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
deleted file mode 100644
index edb7025..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.os.Parcel;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.Region
- *
- * Through the layoutlib_create tool, the original native methods of Region have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Region class.
- *
- * This also serve as a base class for all Region delegate classes.
- *
- * @see DelegateManager
- *
- */
-public class Region_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Region_Delegate> sManager =
-            new DelegateManager<Region_Delegate>(Region_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Area mArea = new Area();
-
-    // ---- Public Helper methods ----
-
-    public static Region_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public Area getJavaArea() {
-        return mArea;
-    }
-
-    /**
-     * Combines two {@link Shape} into another one (actually an {@link Area}), according
-     * to the given {@link Region.Op}.
-     *
-     * If the Op is not one that combines two shapes, then this return null
-     *
-     * @param shape1 the firt shape to combine which can be null if there's no original clip.
-     * @param shape2 the 2nd shape to combine
-     * @param regionOp the operande for the combine
-     * @return a new area or null.
-     */
-    public static Area combineShapes(Shape shape1, Shape shape2, int regionOp) {
-        if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
-            // if shape1 is null (empty), then the result is null.
-            if (shape1 == null) {
-                return null;
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.subtract(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.INTERSECT.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.intersect(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.UNION.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.add(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.XOR.nativeInt) {
-            // if shape1 is null, then the result is simply shape2
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.exclusiveOr(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
-            // result is always a new area.
-            Area result = new Area(shape2);
-
-            if (shape1 != null) {
-                result.subtract(shape1 instanceof Area ? (Area) shape1 : new Area(shape1));
-            }
-
-            return result;
-        }
-
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isEmpty(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isEmpty();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isRect(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isRectangular();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isComplex(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isSingular() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean contains(Region thisRegion, int x, int y) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.contains(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickContains(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isRectangular() &&
-                regionDelegate.mArea.contains(left, top, right - left, bottom - top);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.getBounds().intersects(
-                        targetRegionDelegate.mArea.getBounds()) == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.translate(dx, dy);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.scale(scale, scale);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor() {
-        Region_Delegate newDelegate = new Region_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_region) {
-        sManager.removeJavaReferenceFor(native_region);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetRegion(long native_dst, long native_src) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return;
-        }
-
-        Region_Delegate srcRegion = sManager.getDelegate(native_src);
-        if (srcRegion == null) {
-            return;
-        }
-
-        dstRegion.mArea.reset();
-        dstRegion.mArea.add(srcRegion.mArea);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRect(long native_dst,
-            int left, int top, int right, int bottom) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(new Rectangle2D.Float(left, top, right - left, bottom - top));
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetPath(long native_dst, long native_path, long native_clip) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(path.getJavaShape());
-
-        Region_Delegate clip = sManager.getDelegate(native_clip);
-        if (clip != null) {
-            dstRegion.mArea.subtract(clip.getJavaArea());
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBounds(long native_region, Rect rect) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return true;
-        }
-
-        Rectangle bounds = region.mArea.getBounds();
-        if (bounds.isEmpty()) {
-            rect.left = rect.top = rect.right = rect.bottom = 0;
-            return false;
-        }
-
-        rect.left = bounds.x;
-        rect.top = bounds.y;
-        rect.right = bounds.x + bounds.width;
-        rect.bottom = bounds.y + bounds.height;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBoundaryPath(long native_region, long native_path) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return false;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return false;
-        }
-
-        if (region.mArea.isEmpty()) {
-            path.reset();
-            return false;
-        }
-
-        path.setPathIterator(region.mArea.getPathIterator(new AffineTransform()));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            int left, int top, int right, int bottom, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(left, top, right - left, bottom - top), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst, Rect rect, long native_region, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(rect.left, rect.top, rect.width(), rect.height()), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            long native_region1, long native_region2, int op) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Region_Delegate region1 = sManager.getDelegate(native_region1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_region2);
-        if (region2 == null) {
-            return false;
-        }
-
-        dstRegion.mArea = combineShapes(region1.mArea, region2.mArea, op);
-
-        assert dstRegion.mArea != null;
-        if (dstRegion.mArea != null) {
-            dstRegion.mArea = new Area();
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateFromParcel(Parcel p) {
-        // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
-                null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long native_region,
-                                                      Parcel p) {
-        // This is only called when sending a region through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeEquals(long native_r1, long native_r2) {
-        Region_Delegate region1 = sManager.getDelegate(native_r1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_r2);
-        if (region2 == null) {
-            return false;
-        }
-
-        return region1.mArea.equals(region2.mArea);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String nativeToString(long native_region) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return "not found";
-        }
-
-        return region.mArea.toString();
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
deleted file mode 100644
index 736f03e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
+++ /dev/null
@@ -1,368 +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 android.graphics;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RectangularShape;
-import java.awt.geom.RoundRectangle2D;
-import java.util.EnumSet;
-import java.util.NoSuchElementException;
-
-/**
- * Defines a rectangle with rounded corners, where the sizes of the corners
- * are potentially different.
- */
-public class RoundRectangle extends RectangularShape {
-    public double x;
-    public double y;
-    public double width;
-    public double height;
-    public double ulWidth;
-    public double ulHeight;
-    public double urWidth;
-    public double urHeight;
-    public double lrWidth;
-    public double lrHeight;
-    public double llWidth;
-    public double llHeight;
-
-    private enum Zone {
-        CLOSE_OUTSIDE,
-        CLOSE_INSIDE,
-        MIDDLE,
-        FAR_INSIDE,
-        FAR_OUTSIDE
-    }
-
-    private final EnumSet<Zone> close = EnumSet.of(Zone.CLOSE_OUTSIDE, Zone.CLOSE_INSIDE);
-    private final EnumSet<Zone> far = EnumSet.of(Zone.FAR_OUTSIDE, Zone.FAR_INSIDE);
-
-    /**
-     * @param cornerDimensions array of 8 floating-point number corresponding to the width and
-     * the height of each corner in the following order: upper-left, upper-right, lower-right,
-     * lower-left. It assumes for the size the same convention as {@link RoundRectangle2D}, that
-     * is that the width and height of a corner correspond to the total width and height of the
-     * ellipse that corner is a quarter of.
-     */
-    public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
-        assert cornerDimensions.length == 8 : "The array of corner dimensions must have eight " +
-                    "elements";
-
-        this.x = x;
-        this.y = y;
-        this.width = width;
-        this.height = height;
-
-        float[] dimensions = cornerDimensions.clone();
-        // If a value is negative, the corresponding corner is squared
-        for (int i = 0; i < dimensions.length; i += 2) {
-            if (dimensions[i] < 0 || dimensions[i + 1] < 0) {
-                dimensions[i] = 0;
-                dimensions[i + 1] = 0;
-            }
-        }
-
-        double topCornerWidth = (dimensions[0] + dimensions[2]) / 2d;
-        double bottomCornerWidth = (dimensions[4] + dimensions[6]) / 2d;
-        double leftCornerHeight = (dimensions[1] + dimensions[7]) / 2d;
-        double rightCornerHeight = (dimensions[3] + dimensions[5]) / 2d;
-
-        // Rescale the corner dimensions if they are bigger than the rectangle
-        double scale = Math.min(1.0, width / topCornerWidth);
-        scale = Math.min(scale, width / bottomCornerWidth);
-        scale = Math.min(scale, height / leftCornerHeight);
-        scale = Math.min(scale, height / rightCornerHeight);
-
-        this.ulWidth = dimensions[0] * scale;
-        this.ulHeight = dimensions[1] * scale;
-        this.urWidth = dimensions[2] * scale;
-        this.urHeight = dimensions[3] * scale;
-        this.lrWidth = dimensions[4] * scale;
-        this.lrHeight = dimensions[5] * scale;
-        this.llWidth = dimensions[6] * scale;
-        this.llHeight = dimensions[7] * scale;
-    }
-
-    @Override
-    public double getX() {
-        return x;
-    }
-
-    @Override
-    public double getY() {
-        return y;
-    }
-
-    @Override
-    public double getWidth() {
-        return width;
-    }
-
-    @Override
-    public double getHeight() {
-        return height;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return (width <= 0d) || (height <= 0d);
-    }
-
-    @Override
-    public void setFrame(double x, double y, double w, double h) {
-        this.x = x;
-        this.y = y;
-        this.width = w;
-        this.height = h;
-    }
-
-    @Override
-    public Rectangle2D getBounds2D() {
-        return new Rectangle2D.Double(x, y, width, height);
-    }
-
-    @Override
-    public boolean contains(double x, double y) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - point is outside bounding rectangle
-        if (x < x0 || y < y0 || x >= x1 || y >= y1) {
-            return false;
-        }
-
-        double insideTopX0 = x0 + ulWidth / 2d;
-        double insideLeftY0 = y0 + ulHeight / 2d;
-        if (x < insideTopX0 && y < insideLeftY0) {
-            // In the upper-left corner
-            return isInsideCorner(x - insideTopX0, y - insideLeftY0, ulWidth / 2d, ulHeight / 2d);
-        }
-
-        double insideTopX1 = x1 - urWidth / 2d;
-        double insideRightY0 = y0 + urHeight / 2d;
-        if (x > insideTopX1 && y < insideRightY0) {
-            // In the upper-right corner
-            return isInsideCorner(x - insideTopX1, y - insideRightY0, urWidth / 2d, urHeight / 2d);
-        }
-
-        double insideBottomX1 = x1 - lrWidth / 2d;
-        double insideRightY1 = y1 - lrHeight / 2d;
-        if (x > insideBottomX1 && y > insideRightY1) {
-            // In the lower-right corner
-            return isInsideCorner(x - insideBottomX1, y - insideRightY1, lrWidth / 2d,
-                    lrHeight / 2d);
-        }
-
-        double insideBottomX0 = x0 + llWidth / 2d;
-        double insideLeftY1 = y1 - llHeight / 2d;
-        if (x < insideBottomX0 && y > insideLeftY1) {
-            // In the lower-left corner
-            return isInsideCorner(x - insideBottomX0, y - insideLeftY1, llWidth / 2d,
-                    llHeight / 2d);
-        }
-
-        // In the central part of the rectangle
-        return true;
-    }
-
-    private boolean isInsideCorner(double x, double y, double width, double height) {
-        double squareDist = height * height * x * x + width * width * y * y;
-        return squareDist <= width * width * height * height;
-    }
-
-    private Zone classify(double coord, double side1, double arcSize1, double side2,
-            double arcSize2) {
-        if (coord < side1) {
-            return Zone.CLOSE_OUTSIDE;
-        } else if (coord < side1 + arcSize1) {
-            return Zone.CLOSE_INSIDE;
-        } else if (coord < side2 - arcSize2) {
-            return Zone.MIDDLE;
-        } else if (coord < side2) {
-            return Zone.FAR_INSIDE;
-        } else {
-            return Zone.FAR_OUTSIDE;
-        }
-    }
-
-    public boolean intersects(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - bounding rectangles do not intersect
-        if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
-            return false;
-        }
-
-        double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
-        double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
-        double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
-        double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
-        Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-        Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-
-        // Trivially accept if any point is inside inner rectangle
-        if (x0class == Zone.MIDDLE || x1class == Zone.MIDDLE || y0class == Zone.MIDDLE || y1class == Zone.MIDDLE) {
-            return true;
-        }
-        // Trivially accept if either edge spans inner rectangle
-        if ((close.contains(x0class) && far.contains(x1class)) || (close.contains(y0class) &&
-                far.contains(y1class))) {
-            return true;
-        }
-
-        // Since neither edge spans the center, then one of the corners
-        // must be in one of the rounded edges.  We detect this case if
-        // a [xy]0class is 3 or a [xy]1class is 1.  One of those two cases
-        // must be true for each direction.
-        // We now find a "nearest point" to test for being inside a rounded
-        // corner.
-        if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
-            // Potentially in upper-left corner
-            x = x + w - x0 - ulWidth / 2d;
-            y = y + h - y0 - ulHeight / 2d;
-            return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
-        }
-        if (x1class == Zone.CLOSE_INSIDE) {
-            // Potentially in lower-left corner
-            x = x + w - x0 - llWidth / 2d;
-            y = y - y1 + llHeight / 2d;
-            return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
-        }
-        if (y1class == Zone.CLOSE_INSIDE) {
-            //Potentially in the upper-right corner
-            x = x - x1 + urWidth / 2d;
-            y = y + h - y0 - urHeight / 2d;
-            return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
-        }
-        // Potentially in the lower-right corner
-        x = x - x1 + lrWidth / 2d;
-        y = y - y1 + lrHeight / 2d;
-        return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
-    }
-
-    @Override
-    public boolean contains(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        return (contains(x, y) &&
-                contains(x + w, y) &&
-                contains(x, y + h) &&
-                contains(x + w, y + h));
-    }
-
-    @Override
-    public PathIterator getPathIterator(final AffineTransform at) {
-        return new PathIterator() {
-            int index;
-
-            // ArcIterator.btan(Math.PI/2)
-            public static final double CtrlVal = 0.5522847498307933;
-            private final double ncv = 1.0 - CtrlVal;
-
-            // Coordinates of control points for Bezier curves approximating the straight lines
-            // and corners of the rounded rectangle.
-            private final double[][] ctrlpts = {
-                    {0.0, 0.0, 0.0, ulHeight},
-                    {0.0, 0.0, 1.0, -llHeight},
-                    {0.0, 0.0, 1.0, -llHeight * ncv, 0.0, ncv * llWidth, 1.0, 0.0, 0.0, llWidth,
-                            1.0, 0.0},
-                    {1.0, -lrWidth, 1.0, 0.0},
-                    {1.0, -lrWidth * ncv, 1.0, 0.0, 1.0, 0.0, 1.0, -lrHeight * ncv, 1.0, 0.0, 1.0,
-                            -lrHeight},
-                    {1.0, 0.0, 0.0, urHeight},
-                    {1.0, 0.0, 0.0, ncv * urHeight, 1.0, -urWidth * ncv, 0.0, 0.0, 1.0, -urWidth,
-                            0.0, 0.0},
-                    {0.0, ulWidth, 0.0, 0.0},
-                    {0.0, ncv * ulWidth, 0.0, 0.0, 0.0, 0.0, 0.0, ncv * ulHeight, 0.0, 0.0, 0.0,
-                            ulHeight},
-                    {}
-            };
-            private final int[] types = {
-                    SEG_MOVETO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_CLOSE,
-            };
-
-            @Override
-            public int getWindingRule() {
-                return WIND_NON_ZERO;
-            }
-
-            @Override
-            public boolean isDone() {
-                return index >= ctrlpts.length;
-            }
-
-            @Override
-            public void next() {
-                index++;
-            }
-
-            @Override
-            public int currentSegment(float[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = (float) (x + ctrls[i] * width + ctrls[i + 1] / 2d);
-                    coords[nc++] = (float) (y + ctrls[i + 2] * height + ctrls[i + 3] / 2d);
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-
-            @Override
-            public int currentSegment(double[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = x + ctrls[i] * width + ctrls[i + 1] / 2d;
-                    coords[nc++] = y + ctrls[i + 2] * height + ctrls[i + 3] / 2d;
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-        };
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
deleted file mode 100644
index 5b75089..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.Shader
- *
- * Through the layoutlib_create tool, the original native methods of Shader have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Shader class.
- *
- * This also serve as a base class for all Shader delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Shader_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Shader_Delegate> sManager =
-            new DelegateManager<Shader_Delegate>(Shader_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Matrix_Delegate mLocalMatrix = null;
-
-    // ---- Public Helper methods ----
-
-    public static Shader_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    /**
-     * Returns the {@link TileMode} matching the given int.
-     * @param tileMode the tile mode int value
-     * @return the TileMode enum.
-     */
-    public static TileMode getTileMode(int tileMode) {
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                return tm;
-            }
-        }
-
-        assert false;
-        return TileMode.CLAMP;
-    }
-
-    public abstract java.awt.Paint getJavaPaint();
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSafeUnref(long nativeInstance) {
-        sManager.removeJavaReferenceFor(nativeInstance);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    protected Shader_Delegate(long nativeMatrix) {
-        mLocalMatrix = Matrix_Delegate.getDelegate(nativeMatrix);
-    }
-
-    protected java.awt.geom.AffineTransform getLocalMatrix() {
-        if (mLocalMatrix != null) {
-            return mLocalMatrix.getAffineTransform();
-        }
-
-        return new java.awt.geom.AffineTransform();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
deleted file mode 100644
index 6d2e9b4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.SumPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SumPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class SumPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Sum Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long first, long second) {
-        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
deleted file mode 100644
index 30152bc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.SweepGradient
- *
- * Through the layoutlib_create tool, the original native methods of SweepGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SweepGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class SweepGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, int colors[], float
-            positions[]) {
-        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(matrix, x, y, colors,
-                positions);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, int color0, int color1) {
-        return nativeCreate1(matrix, x, y, new int[] { color0, color1 },
-                null /*positions*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    private SweepGradient_Delegate(long nativeMatrix, float cx, float cy,
-            int colors[], float positions[]) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
-    }
-
-    private class SweepGradientPaint extends GradientPaint {
-
-        private final float mCx;
-        private final float mCy;
-
-        public SweepGradientPaint(float cx, float cy, int[] colors,
-                float[] positions) {
-            super(colors, positions, null /*tileMode*/);
-            mCx = cx;
-            mCy = cy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class SweepGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public SweepGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute angle from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mCx;
-                        pt1[1] = pt2[1] - mCy;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float dx = pt2[0];
-                        float dy = pt2[1];
-
-                        float angle;
-                        if (dx == 0) {
-                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
-                        } else if (dy == 0) {
-                            angle = (float) (dx < 0 ? Math.PI : 0);
-                        } else {
-                            angle = (float) Math.atan(dy / dx);
-                            if (dx > 0) {
-                                if (dy < 0) {
-                                    angle += Math.PI * 2;
-                                }
-                            } else {
-                                angle += Math.PI;
-                            }
-                        }
-
-                        // convert to 0-1. value and get color
-                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
deleted file mode 100644
index ce669cb..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
+++ /dev/null
@@ -1,28 +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.
- */
-
-package android.graphics;
-
-import android.annotation.NonNull;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Typeface_Accessor {
-    public static boolean isSystemFont(@NonNull String fontName) {
-        return Typeface.sSystemFontMap.containsKey(fontName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
deleted file mode 100644
index c7818a3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static android.graphics.FontFamily_Delegate.getFontLocation;
-
-/**
- * Delegate implementing the native methods of android.graphics.Typeface
- *
- * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Typeface class.
- *
- * @see DelegateManager
- *
- */
-public final class Typeface_Delegate {
-
-    public static final String SYSTEM_FONTS = "/system/fonts/";
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Typeface_Delegate> sManager =
-            new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
-
-
-    // ---- delegate data ----
-
-    @NonNull
-    private final FontFamily_Delegate[] mFontFamilies;  // the reference to FontFamily_Delegate.
-    /** @see Font#getStyle() */
-    private final int mStyle;
-    private final int mWeight;
-
-    private static long sDefaultTypeface;
-
-
-    // ---- Public Helper methods ----
-
-    public static Typeface_Delegate getDelegate(long nativeTypeface) {
-        return sManager.getDelegate(nativeTypeface);
-    }
-
-    /**
-     * Return a list of fonts that match the style and variant. The list is ordered according to
-     * preference of fonts.
-     *
-     * The list may contain null when the font failed to load. If null is reached when trying to
-     * render with this list of fonts, then a warning should be logged letting the user know that
-     * some font failed to load.
-     *
-     * @param variant The variant preferred. Can only be {@link FontVariant#COMPACT} or
-     *                {@link FontVariant#ELEGANT}
-     */
-    @NonNull
-    public List<Font> getFonts(FontVariant variant) {
-        assert variant != FontVariant.NONE;
-
-        // Calculate the required weight based on style and weight of this typeface.
-        int weight = mWeight + ((mStyle & Font.BOLD) == 0 ? 0 : FontFamily_Delegate.BOLD_FONT_WEIGHT_DELTA);
-        if (weight > 900) {
-            weight = 900;
-        }
-        final boolean isItalic = (mStyle & Font.ITALIC) != 0;
-        List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
-        for (int i = 0; i < mFontFamilies.length; i++) {
-            FontFamily_Delegate ffd = mFontFamilies[i];
-            if (ffd != null && ffd.isValid()) {
-                Font font = ffd.getFont(weight, isItalic);
-                if (font != null) {
-                    FontVariant ffdVariant = ffd.getVariant();
-                    if (ffdVariant == FontVariant.NONE) {
-                        fonts.add(font);
-                        continue;
-                    }
-                    // We cannot open each font and get locales supported, etc to match the fonts.
-                    // As a workaround, we hardcode certain assumptions like Elegant and Compact
-                    // always appear in pairs.
-                    assert i < mFontFamilies.length - 1;
-                    FontFamily_Delegate ffd2 = mFontFamilies[++i];
-                    assert ffd2 != null;
-                    FontVariant ffd2Variant = ffd2.getVariant();
-                    Font font2 = ffd2.getFont(weight, isItalic);
-                    assert ffd2Variant != FontVariant.NONE && ffd2Variant != ffdVariant
-                            && font2 != null;
-                    // Add the font with the matching variant to the list.
-                    if (variant == ffd.getVariant()) {
-                        fonts.add(font);
-                    } else {
-                        fonts.add(font2);
-                    }
-                } else {
-                    // The FontFamily is valid but doesn't contain any matching font. This means
-                    // that the font failed to load. We add null to the list of fonts. Don't throw
-                    // the warning just yet. If this is a non-english font, we don't want to warn
-                    // users who are trying to render only english text.
-                    fonts.add(null);
-                }
-            }
-        }
-        return fonts;
-    }
-
-    /**
-     * Clear the default typefaces when disposing bridge.
-     */
-    public static void resetDefaults() {
-        // Sometimes this is called before the Bridge is initialized. In that case, we don't want to
-        // initialize Typeface because the SDK fonts location hasn't been set.
-        if (FontFamily_Delegate.getFontLocation() != null) {
-            Typeface.sDefaults = null;
-        }
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypeface(long native_instance, int style) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-
-        return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style,
-                delegate.mWeight));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypefaceWithVariation(long native_instance,
-            List<FontVariationAxis> axes) {
-        long newInstance = nativeCreateFromTypeface(native_instance, 0);
-
-        if (newInstance != 0) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "nativeCreateFromTypefaceWithVariation is not supported", null, null);
-        }
-        return newInstance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int[] nativeGetSupportedAxes(long native_instance) {
-        // nativeCreateFromTypefaceWithVariation is not supported so we do not keep the axes
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-        Typeface_Delegate weightAlias =
-                new Typeface_Delegate(delegate.mFontFamilies, delegate.mStyle, weight);
-        return sManager.addNewDelegate(weightAlias);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromArray(long[] familyArray) {
-        FontFamily_Delegate[] fontFamilies = new FontFamily_Delegate[familyArray.length];
-        for (int i = 0; i < familyArray.length; i++) {
-            fontFamilies[i] = FontFamily_Delegate.getDelegate(familyArray[i]);
-        }
-        Typeface_Delegate delegate = new Typeface_Delegate(fontFamilies, Typeface.NORMAL);
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetStyle(long native_instance) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetDefault(long native_instance) {
-        sDefaultTypeface = native_instance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemFontConfigLocation() {
-        return new File(getFontLocation());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static FontFamily makeFamilyFromParsed(FontConfig.Family family,
-            Map<String, ByteBuffer> bufferForPath) {
-        FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
-        for (FontConfig.Font font : family.getFonts()) {
-            String fullPathName = "/system/fonts/" + font.getFontName();
-            FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
-                    font.getWeight(), font.isItalic());
-        }
-        fontFamily.freeze();
-        return fontFamily;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style) {
-        this(fontFamilies, style, FontFamily_Delegate.DEFAULT_FONT_WEIGHT);
-    }
-
-    public Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style, int weight) {
-        mFontFamilies = fontFamilies;
-        mStyle = style;
-        mWeight = weight;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
deleted file mode 100644
index ad2c564..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
+++ /dev/null
@@ -1,298 +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 android.graphics.drawable;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
-import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;
-
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * AnimatedVectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of AnimatedVectorDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class AnimatedVectorDrawable_Delegate {
-    private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new
-            DelegateManager<>(AnimatorSetHolder.class);
-    private static DelegateManager<PropertySetter> sHolders = new
-            DelegateManager<>(PropertySetter.class);
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateAnimatorSet() {
-        return sAnimatorSets.addNewDelegate(new AnimatorSetHolder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) {
-        // TODO: implement
-    }
-    @LayoutlibDelegate
-    /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
-            long nativeInterpolator, long startDelay, long duration, int repeatCount,
-            int repeatMode) {
-        PropertySetter holder = sHolders.getDelegate(propertyValuesHolder);
-        if (holder == null || holder.getValues() == null) {
-            return;
-        }
-
-        ObjectAnimator animator = new ObjectAnimator();
-        animator.setValues(holder.getValues());
-        animator.setInterpolator(
-                NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator));
-        animator.setStartDelay(startDelay);
-        animator.setDuration(duration);
-        animator.setRepeatCount(repeatCount);
-        animator.setRepeatMode(repeatMode);
-        animator.setTarget(holder);
-        animator.setPropertyName(holder.getValues().getPropertyName());
-
-        AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr);
-        assert set != null;
-        set.addAnimator(animator);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VGroup_Delegate group = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = group.getPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
-            long endValuePtr) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
-                "animations are not supported.", null, null);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId,
-            int startValue, int endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Integer> setter = path.getIntPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = path.getFloatPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
-            float endValue) {
-        VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha,
-                startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.start();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.reverse();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nEnd(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-        animatorSet.start();
-    }
-
-    private static class AnimatorSetHolder {
-        private ArrayList<Animator> mAnimators = new ArrayList<>();
-        private AnimatorSet mAnimatorSet = null;
-
-        private void addAnimator(@NonNull Animator animator) {
-            mAnimators.add(animator);
-        }
-
-        private void ensureAnimatorSet() {
-            if (mAnimatorSet == null) {
-                mAnimatorSet = new AnimatorSet();
-                mAnimatorSet.playTogether(mAnimators);
-            }
-        }
-
-        private void start() {
-            ensureAnimatorSet();
-
-            mAnimatorSet.start();
-        }
-
-        private void end() {
-            mAnimatorSet.end();
-        }
-
-        private void reset() {
-            end();
-            start();
-        }
-
-        private void reverse() {
-            mAnimatorSet.reverse();
-        }
-    }
-
-    /**
-     * Class that allows setting a value and holds the range of values for the given property.
-     *
-     * @param <T> the type of the property
-     */
-    private static class PropertySetter<T> {
-        final Consumer<T> mValueSetter;
-        private PropertyValuesHolder mValues;
-
-        private PropertySetter(@NonNull Consumer<T> valueSetter) {
-            mValueSetter = valueSetter;
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setIntValue(Integer value) {
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setFloatValue(Float value) {
-        }
-
-        void setValues(float... values) {
-            mValues = PropertyValuesHolder.ofFloat("floatValue", values);
-        }
-
-        @Nullable
-        PropertyValuesHolder getValues() {
-            return mValues;
-        }
-
-        void setValues(int... values) {
-            mValues = PropertyValuesHolder.ofInt("intValue", values);
-        }
-    }
-
-    private static class IntPropertySetter extends PropertySetter<Integer> {
-        private IntPropertySetter(Consumer<Integer> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Integer> valueSetter, int... values) {
-            PropertySetter setter = new IntPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setIntValue(Integer value) {
-            mValueSetter.accept(value);
-        }
-    }
-
-    private static class FloatPropertySetter extends PropertySetter<Float> {
-        private FloatPropertySetter(Consumer<Float> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Float> valueSetter, float... values) {
-            PropertySetter setter = new FloatPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setFloatValue(Float value) {
-            mValueSetter.accept(value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
deleted file mode 100644
index fc848d9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Canvas;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-
-public class AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate {
-    @LayoutlibDelegate
-    /*package*/ static boolean useLastSeenTarget(VectorDrawableAnimatorRT thisDrawableAnimator) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void onDraw(VectorDrawableAnimatorRT thisDrawableAnimator, Canvas canvas) {
-        // Do not attempt to record as we are not using a DisplayListCanvas
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
deleted file mode 100644
index a3ad2aac..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.graphics.drawable.GradientDrawable.GradientState;
-
-import java.lang.reflect.Field;
-
-/**
- * Delegate implementing the native methods of {@link GradientDrawable}
- *
- * Through the layoutlib_create tool, the original native methods of GradientDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class GradientDrawable_Delegate {
-
-    /**
-     * The ring can be built either by drawing full circles, or by drawing arcs in case the
-     * circle isn't complete. LayoutLib cannot handle drawing full circles (requires path
-     * subtraction). So, if we need to draw full circles, we switch to drawing 99% circle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Path buildRing(GradientDrawable thisDrawable, GradientState st) {
-        boolean useLevel = st.mUseLevelForShape;
-        int level = thisDrawable.getLevel();
-        // 10000 is the max level. See android.graphics.drawable.Drawable#getLevel()
-        float sweep = useLevel ? (360.0f * level / 10000.0f) : 360f;
-        Field mLevel = null;
-        if (sweep >= 360 || sweep <= -360) {
-            st.mUseLevelForShape = true;
-            // Use reflection to set the value of the field to prevent setting the drawable to
-            // dirty again.
-            try {
-                mLevel = Drawable.class.getDeclaredField("mLevel");
-                mLevel.setAccessible(true);
-                mLevel.setInt(thisDrawable, 9999);  // set to one less than max.
-            } catch (NoSuchFieldException e) {
-                // The field has been removed in a recent framework change. Fall back to old
-                // buggy behaviour.
-            } catch (IllegalAccessException e) {
-                // We've already set the field to be accessible.
-                assert false;
-            }
-        }
-        Path path = thisDrawable.buildRing_Original(st);
-        st.mUseLevelForShape = useLevel;
-        if (mLevel != null) {
-            try {
-                mLevel.setInt(thisDrawable, level);
-            } catch (IllegalAccessException e) {
-                assert false;
-            }
-        }
-        return path;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
deleted file mode 100644
index 616784c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ /dev/null
@@ -1,1262 +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 android.graphics.drawable;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.BaseCanvas_Delegate;
-import android.graphics.Canvas_Delegate;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint_Delegate;
-import android.graphics.Path;
-import android.graphics.PathMeasure;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.MathUtils;
-import android.util.PathParser_Delegate;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-import static android.graphics.Canvas.CLIP_SAVE_FLAG;
-import static android.graphics.Canvas.MATRIX_SAVE_FLAG;
-import static android.graphics.Paint.Cap.BUTT;
-import static android.graphics.Paint.Cap.ROUND;
-import static android.graphics.Paint.Cap.SQUARE;
-import static android.graphics.Paint.Join.BEVEL;
-import static android.graphics.Paint.Join.MITER;
-import static android.graphics.Paint.Style;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link VectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of VectorDrawable have been replaced by
- * calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class VectorDrawable_Delegate {
-    private static final String LOGTAG = VectorDrawable_Delegate.class.getSimpleName();
-    private static final boolean DBG_VECTOR_DRAWABLE = false;
-
-    private static final DelegateManager<VNativeObject> sPathManager =
-            new DelegateManager<>(VNativeObject.class);
-
-    private static long addNativeObject(VNativeObject object) {
-        long ptr = sPathManager.addNewDelegate(object);
-        object.setNativePtr(ptr);
-
-        return ptr;
-    }
-
-    /**
-     * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is
-     * null.
-     */
-    private static TypedArray obtainAttributes(
-            Resources res, Theme theme, AttributeSet set, int[] attrs) {
-        if (theme == null) {
-            return res.obtainAttributes(set, attrs);
-        }
-        return theme.obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    private static int applyAlpha(int color, float alpha) {
-        int alphaBytes = Color.alpha(color);
-        color &= 0x00FFFFFF;
-        color |= ((int) (alphaBytes * alpha)) << 24;
-        return color;
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTree(long rootGroupPtr) {
-        return addNativeObject(new VPathRenderer_Delegate(rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) {
-        VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr);
-        return addNativeObject(new VPathRenderer_Delegate(rendererToCopy,
-                rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
-            float viewportHeight) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.mViewportWidth = viewportWidth;
-        nativePathRenderer.mViewportHeight = viewportHeight;
-    }
-
-    @LayoutlibDelegate
-    static boolean nSetRootAlpha(long rendererPtr, float alpha) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.setRootAlpha(alpha);
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static float nGetRootAlpha(long rendererPtr) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        return nativePathRenderer.getRootAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetAllowCaching(long rendererPtr, boolean allowCaching) {
-        // ignored
-    }
-
-    @LayoutlibDelegate
-    static int nDraw(long rendererPtr, long canvasWrapperPtr,
-            long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        Canvas_Delegate.nSave(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-        Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.left, bounds.top);
-
-        if (needsMirroring) {
-            Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.width(), 0);
-            Canvas_Delegate.nScale(canvasWrapperPtr, -1.0f, 1.0f);
-        }
-
-        // At this point, canvas has been translated to the right position.
-        // And we use this bound for the destination rect for the drawBitmap, so
-        // we offset to (0, 0);
-        bounds.offsetTo(0, 0);
-        nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
-
-        Canvas_Delegate.nRestore(canvasWrapperPtr);
-
-        return bounds.width() * bounds.height();
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath() {
-        return addNativeObject(new VFullPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath(long nativeFullPathPtr) {
-        VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
-        return addNativeObject(new VFullPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData,
-            int length) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        ByteBuffer properties = ByteBuffer.wrap(propertiesData);
-        properties.order(ByteOrder.nativeOrder());
-
-        properties.putFloat(VFullPath_Delegate.STROKE_WIDTH_INDEX * 4, path.getStrokeWidth());
-        properties.putInt(VFullPath_Delegate.STROKE_COLOR_INDEX * 4, path.getStrokeColor());
-        properties.putFloat(VFullPath_Delegate.STROKE_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putInt(VFullPath_Delegate.FILL_COLOR_INDEX * 4, path.getFillColor());
-        properties.putFloat(VFullPath_Delegate.FILL_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_START_INDEX * 4, path.getTrimPathStart());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_END_INDEX * 4, path.getTrimPathEnd());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_OFFSET_INDEX * 4,
-                path.getTrimPathOffset());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_CAP_INDEX * 4, path.getStrokeLineCap());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_JOIN_INDEX * 4, path.getStrokeLineJoin());
-        properties.putFloat(VFullPath_Delegate.STROKE_MITER_LIMIT_INDEX * 4,
-                path.getStrokeMiterlimit());
-        properties.putInt(VFullPath_Delegate.FILL_TYPE_INDEX * 4, path.getFillType());
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
-            int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
-            float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
-            int strokeLineJoin, int fillType) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeWidth(strokeWidth);
-        path.setStrokeColor(strokeColor);
-        path.setStrokeAlpha(strokeAlpha);
-        path.setFillColor(fillColor);
-        path.setFillAlpha(fillAlpha);
-        path.setTrimPathStart(trimPathStart);
-        path.setTrimPathEnd(trimPathEnd);
-        path.setTrimPathOffset(trimPathOffset);
-        path.setStrokeMiterlimit(strokeMiterLimit);
-        path.setStrokeLineCap(strokeLineCap);
-        path.setStrokeLineJoin(strokeLineJoin);
-        path.setFillType(fillType);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setFillGradient(fillGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeGradient(strokeGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath() {
-        return addNativeObject(new VClipPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath(long clipPathPtr) {
-        VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr);
-        return addNativeObject(new VClipPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup() {
-        return addNativeObject(new VGroup_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup(long groupPtr) {
-        VGroup_Delegate original = VNativeObject.getDelegate(groupPtr);
-        return addNativeObject(new VGroup_Delegate(original, new ArrayMap<>()));
-    }
-
-    @LayoutlibDelegate
-    static void nSetName(long nodePtr, String name) {
-        VNativeObject group = VNativeObject.getDelegate(nodePtr);
-        group.setName(name);
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetGroupProperties(long groupPtr, float[] propertiesData,
-            int length) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        FloatBuffer properties = FloatBuffer.wrap(propertiesData);
-
-        properties.put(VGroup_Delegate.ROTATE_INDEX, group.getRotation());
-        properties.put(VGroup_Delegate.PIVOT_X_INDEX, group.getPivotX());
-        properties.put(VGroup_Delegate.PIVOT_Y_INDEX, group.getPivotY());
-        properties.put(VGroup_Delegate.SCALE_X_INDEX, group.getScaleX());
-        properties.put(VGroup_Delegate.SCALE_Y_INDEX, group.getScaleY());
-        properties.put(VGroup_Delegate.TRANSLATE_X_INDEX, group.getTranslateX());
-        properties.put(VGroup_Delegate.TRANSLATE_Y_INDEX, group.getTranslateY());
-
-        return true;
-    }
-    @LayoutlibDelegate
-    static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
-            float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        group.setRotation(rotate);
-        group.setPivotX(pivotX);
-        group.setPivotY(pivotY);
-        group.setScaleX(scaleX);
-        group.setScaleY(scaleY);
-        group.setTranslateX(translateX);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nAddChild(long groupPtr, long nodePtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.mChildren.add(VNativeObject.getDelegate(nodePtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathString(long pathPtr, String pathString, int length) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString));
-    }
-
-    /**
-     * The setters and getters below for paths and groups are here temporarily, and will be removed
-     * once the animation in AVD is replaced with RenderNodeAnimator, in which case the animation
-     * will modify these properties in native. By then no JNI hopping would be necessary for VD
-     * during animation, and these setters and getters will be obsolete.
-     */
-    // Setters and getters during animation.
-    @LayoutlibDelegate
-    static float nGetRotation(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getRotation();
-    }
-
-    @LayoutlibDelegate
-    static void nSetRotation(long groupPtr, float rotation) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setRotation(rotation);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotX(long groupPtr, float pivotX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotX(pivotX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotY(long groupPtr, float pivotY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotY(pivotY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleX(long groupPtr, float scaleX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleX(scaleX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleY(long groupPtr, float scaleY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleY(scaleY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateX(long groupPtr, float translateX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateX(translateX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateY(long groupPtr, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathData(long pathPtr, long pathDataPtr) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeWidth(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeWidth();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeWidth(long pathPtr, float width) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeWidth(width);
-    }
-
-    @LayoutlibDelegate
-    static int nGetStrokeColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeColor(long pathPtr, int strokeColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeColor(strokeColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeAlpha(long pathPtr, float alpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeAlpha(alpha);
-    }
-
-    @LayoutlibDelegate
-    static int nGetFillColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillColor(long pathPtr, int fillColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillColor(fillColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetFillAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillAlpha(long pathPtr, float fillAlpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillAlpha(fillAlpha);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathStart(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathStart();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathStart(long pathPtr, float trimPathStart) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathStart(trimPathStart);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathEnd(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathEnd();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathEnd(trimPathEnd);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathOffset(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathOffset();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathOffset(trimPathOffset);
-    }
-
-    /**
-     * Base class for all the internal Delegates that does two functions:
-     * <ol>
-     *     <li>Serves as base class to store all the delegates in one {@link DelegateManager}
-     *     <li>Provides setName for all the classes. {@link VPathRenderer_Delegate} does actually
-     *     not need it
-     * </ol>
-     */
-    abstract static class VNativeObject {
-        long mNativePtr = 0;
-
-        @NonNull
-        static <T> T getDelegate(long nativePtr) {
-            //noinspection unchecked
-            T vNativeObject = (T) sPathManager.getDelegate(nativePtr);
-
-            assert vNativeObject != null;
-            return vNativeObject;
-        }
-
-        abstract void setName(String name);
-
-        void setNativePtr(long nativePtr) {
-            mNativePtr = nativePtr;
-        }
-
-        /**
-         * Method to explicitly dispose native objects
-         */
-        void dispose() {
-        }
-    }
-
-    private static class VClipPath_Delegate extends VPath_Delegate {
-        private VClipPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VClipPath_Delegate(VClipPath_Delegate copy) {
-            super(copy);
-        }
-
-        @Override
-        public boolean isClipPath() {
-            return true;
-        }
-    }
-
-    static class VFullPath_Delegate extends VPath_Delegate {
-        // These constants need to be kept in sync with their values in VectorDrawable.VFullPath
-        private static final int STROKE_WIDTH_INDEX = 0;
-        private static final int STROKE_COLOR_INDEX = 1;
-        private static final int STROKE_ALPHA_INDEX = 2;
-        private static final int FILL_COLOR_INDEX = 3;
-        private static final int FILL_ALPHA_INDEX = 4;
-        private static final int TRIM_PATH_START_INDEX = 5;
-        private static final int TRIM_PATH_END_INDEX = 6;
-        private static final int TRIM_PATH_OFFSET_INDEX = 7;
-        private static final int STROKE_LINE_CAP_INDEX = 8;
-        private static final int STROKE_LINE_JOIN_INDEX = 9;
-        private static final int STROKE_MITER_LIMIT_INDEX = 10;
-        private static final int FILL_TYPE_INDEX = 11;
-
-        private static final int LINECAP_BUTT = 0;
-        private static final int LINECAP_ROUND = 1;
-        private static final int LINECAP_SQUARE = 2;
-
-        private static final int LINEJOIN_MITER = 0;
-        private static final int LINEJOIN_ROUND = 1;
-        private static final int LINEJOIN_BEVEL = 2;
-
-        @NonNull
-        public Consumer<Float> getFloatPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_WIDTH_INDEX:
-                    return this::setStrokeWidth;
-                case STROKE_ALPHA_INDEX:
-                    return this::setStrokeAlpha;
-                case FILL_ALPHA_INDEX:
-                    return this::setFillAlpha;
-                case TRIM_PATH_START_INDEX:
-                    return this::setTrimPathStart;
-                case TRIM_PATH_END_INDEX:
-                    return this::setTrimPathEnd;
-                case TRIM_PATH_OFFSET_INDEX:
-                    return this::setTrimPathOffset;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        @NonNull
-        public Consumer<Integer> getIntPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_COLOR_INDEX:
-                    return this::setStrokeColor;
-                case FILL_COLOR_INDEX:
-                    return this::setFillColor;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-
-        int mStrokeColor = Color.TRANSPARENT;
-        float mStrokeWidth = 0;
-
-        int mFillColor = Color.TRANSPARENT;
-        long mStrokeGradient = 0;
-        long mFillGradient = 0;
-        float mStrokeAlpha = 1.0f;
-        float mFillAlpha = 1.0f;
-        float mTrimPathStart = 0;
-        float mTrimPathEnd = 1;
-        float mTrimPathOffset = 0;
-
-        Cap mStrokeLineCap = BUTT;
-        Join mStrokeLineJoin = MITER;
-        float mStrokeMiterlimit = 4;
-
-        int mFillType = 0; // WINDING(0) is the default value. See Path.FillType
-
-        private VFullPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VFullPath_Delegate(VFullPath_Delegate copy) {
-            super(copy);
-
-            mStrokeColor = copy.mStrokeColor;
-            mStrokeWidth = copy.mStrokeWidth;
-            mStrokeAlpha = copy.mStrokeAlpha;
-            mFillColor = copy.mFillColor;
-            mFillAlpha = copy.mFillAlpha;
-            mTrimPathStart = copy.mTrimPathStart;
-            mTrimPathEnd = copy.mTrimPathEnd;
-            mTrimPathOffset = copy.mTrimPathOffset;
-
-            mStrokeLineCap = copy.mStrokeLineCap;
-            mStrokeLineJoin = copy.mStrokeLineJoin;
-            mStrokeMiterlimit = copy.mStrokeMiterlimit;
-
-            mStrokeGradient = copy.mStrokeGradient;
-            mFillGradient = copy.mFillGradient;
-            mFillType = copy.mFillType;
-        }
-
-        private int getStrokeLineCap() {
-            switch (mStrokeLineCap) {
-                case BUTT:
-                    return LINECAP_BUTT;
-                case ROUND:
-                    return LINECAP_ROUND;
-                case SQUARE:
-                    return LINECAP_SQUARE;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineCap(int cap) {
-            switch (cap) {
-                case LINECAP_BUTT:
-                    mStrokeLineCap = BUTT;
-                    break;
-                case LINECAP_ROUND:
-                    mStrokeLineCap = ROUND;
-                    break;
-                case LINECAP_SQUARE:
-                    mStrokeLineCap = SQUARE;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeLineJoin() {
-            switch (mStrokeLineJoin) {
-                case MITER:
-                    return LINEJOIN_MITER;
-                case ROUND:
-                    return LINEJOIN_ROUND;
-                case BEVEL:
-                    return LINEJOIN_BEVEL;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineJoin(int join) {
-            switch (join) {
-                case LINEJOIN_BEVEL:
-                    mStrokeLineJoin = BEVEL;
-                    break;
-                case LINEJOIN_MITER:
-                    mStrokeLineJoin = MITER;
-                    break;
-                case LINEJOIN_ROUND:
-                    mStrokeLineJoin = Join.ROUND;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeColor() {
-            return mStrokeColor;
-        }
-
-        private void setStrokeColor(int strokeColor) {
-            mStrokeColor = strokeColor;
-        }
-
-        private float getStrokeWidth() {
-            return mStrokeWidth;
-        }
-
-        private void setStrokeWidth(float strokeWidth) {
-            mStrokeWidth = strokeWidth;
-        }
-
-        private float getStrokeAlpha() {
-            return mStrokeAlpha;
-        }
-
-        private void setStrokeAlpha(float strokeAlpha) {
-            mStrokeAlpha = strokeAlpha;
-        }
-
-        private int getFillColor() {
-            return mFillColor;
-        }
-
-        private void setFillColor(int fillColor) {
-            mFillColor = fillColor;
-        }
-
-        private float getFillAlpha() {
-            return mFillAlpha;
-        }
-
-        private void setFillAlpha(float fillAlpha) {
-            mFillAlpha = fillAlpha;
-        }
-
-        private float getTrimPathStart() {
-            return mTrimPathStart;
-        }
-
-        private void setTrimPathStart(float trimPathStart) {
-            mTrimPathStart = trimPathStart;
-        }
-
-        private float getTrimPathEnd() {
-            return mTrimPathEnd;
-        }
-
-        private void setTrimPathEnd(float trimPathEnd) {
-            mTrimPathEnd = trimPathEnd;
-        }
-
-        private float getTrimPathOffset() {
-            return mTrimPathOffset;
-        }
-
-        private void setTrimPathOffset(float trimPathOffset) {
-            mTrimPathOffset = trimPathOffset;
-        }
-
-        private void setStrokeMiterlimit(float limit) {
-            mStrokeMiterlimit = limit;
-        }
-
-        private float getStrokeMiterlimit() {
-            return mStrokeMiterlimit;
-        }
-
-        private void setStrokeGradient(long gradientPtr) {
-            mStrokeGradient = gradientPtr;
-        }
-
-        private void setFillGradient(long gradientPtr) {
-            mFillGradient = gradientPtr;
-        }
-
-        private void setFillType(int fillType) {
-            mFillType = fillType;
-        }
-
-        private int getFillType() {
-            return mFillType;
-        }
-    }
-
-    static class VGroup_Delegate extends VNativeObject {
-        // This constants need to be kept in sync with their definitions in VectorDrawable.Group
-        private static final int ROTATE_INDEX = 0;
-        private static final int PIVOT_X_INDEX = 1;
-        private static final int PIVOT_Y_INDEX = 2;
-        private static final int SCALE_X_INDEX = 3;
-        private static final int SCALE_Y_INDEX = 4;
-        private static final int TRANSLATE_X_INDEX = 5;
-        private static final int TRANSLATE_Y_INDEX = 6;
-
-        public Consumer<Float> getPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case ROTATE_INDEX:
-                    return this::setRotation;
-                case PIVOT_X_INDEX:
-                    return this::setPivotX;
-                case PIVOT_Y_INDEX:
-                    return this::setPivotY;
-                case SCALE_X_INDEX:
-                    return this::setScaleX;
-                case SCALE_Y_INDEX:
-                    return this::setScaleY;
-                case TRANSLATE_X_INDEX:
-                    return this::setTranslateX;
-                case TRANSLATE_Y_INDEX:
-                    return this::setTranslateY;
-            }
-
-            assert false : ("Invalid VGroup_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-        final ArrayList<Object> mChildren = new ArrayList<>();
-        // mStackedMatrix is only used temporarily when drawing, it combines all
-        // the parents' local matrices with the current one.
-        private final Matrix mStackedMatrix = new Matrix();
-        // mLocalMatrix is updated based on the update of transformation information,
-        // either parsed from the XML or by animation.
-        private final Matrix mLocalMatrix = new Matrix();
-        private float mRotate = 0;
-        private float mPivotX = 0;
-        private float mPivotY = 0;
-        private float mScaleX = 1;
-        private float mScaleY = 1;
-        private float mTranslateX = 0;
-        private float mTranslateY = 0;
-        private int mChangingConfigurations;
-        private String mGroupName = null;
-
-        private VGroup_Delegate(VGroup_Delegate copy, ArrayMap<String, Object> targetsMap) {
-            mRotate = copy.mRotate;
-            mPivotX = copy.mPivotX;
-            mPivotY = copy.mPivotY;
-            mScaleX = copy.mScaleX;
-            mScaleY = copy.mScaleY;
-            mTranslateX = copy.mTranslateX;
-            mTranslateY = copy.mTranslateY;
-            mGroupName = copy.mGroupName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            if (mGroupName != null) {
-                targetsMap.put(mGroupName, this);
-            }
-
-            mLocalMatrix.set(copy.mLocalMatrix);
-        }
-
-        private VGroup_Delegate() {
-        }
-
-        private void updateLocalMatrix() {
-            // The order we apply is the same as the
-            // RenderNode.cpp::applyViewPropertyTransforms().
-            mLocalMatrix.reset();
-            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
-            mLocalMatrix.postScale(mScaleX, mScaleY);
-            mLocalMatrix.postRotate(mRotate, 0, 0);
-            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
-        }
-
-        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
-        private float getRotation() {
-            return mRotate;
-        }
-
-        private void setRotation(float rotation) {
-            if (rotation != mRotate) {
-                mRotate = rotation;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotX() {
-            return mPivotX;
-        }
-
-        private void setPivotX(float pivotX) {
-            if (pivotX != mPivotX) {
-                mPivotX = pivotX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotY() {
-            return mPivotY;
-        }
-
-        private void setPivotY(float pivotY) {
-            if (pivotY != mPivotY) {
-                mPivotY = pivotY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleX() {
-            return mScaleX;
-        }
-
-        private void setScaleX(float scaleX) {
-            if (scaleX != mScaleX) {
-                mScaleX = scaleX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleY() {
-            return mScaleY;
-        }
-
-        private void setScaleY(float scaleY) {
-            if (scaleY != mScaleY) {
-                mScaleY = scaleY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateX() {
-            return mTranslateX;
-        }
-
-        private void setTranslateX(float translateX) {
-            if (translateX != mTranslateX) {
-                mTranslateX = translateX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateY() {
-            return mTranslateY;
-        }
-
-        private void setTranslateY(float translateY) {
-            if (translateY != mTranslateY) {
-                mTranslateY = translateY;
-                updateLocalMatrix();
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mGroupName = name;
-        }
-
-        @Override
-        protected void dispose() {
-            mChildren.stream().filter(child -> child instanceof VNativeObject).forEach(child
-                    -> {
-                VNativeObject nativeObject = (VNativeObject) child;
-                if (nativeObject.mNativePtr != 0) {
-                    sPathManager.removeJavaReferenceFor(nativeObject.mNativePtr);
-                    nativeObject.mNativePtr = 0;
-                }
-                nativeObject.dispose();
-            });
-            mChildren.clear();
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-        }
-    }
-
-    public static class VPath_Delegate extends VNativeObject {
-        protected PathParser_Delegate.PathDataNode[] mNodes = null;
-        String mPathName;
-        int mChangingConfigurations;
-
-        public VPath_Delegate() {
-            // Empty constructor.
-        }
-
-        public VPath_Delegate(VPath_Delegate copy) {
-            mPathName = copy.mPathName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            mNodes = copy.mNodes != null ? PathParser_Delegate.deepCopyNodes(copy.mNodes) : null;
-        }
-
-        public void toPath(Path path) {
-            path.reset();
-            if (mNodes != null) {
-                PathParser_Delegate.PathDataNode.nodesToPath(mNodes,
-                        Path_Delegate.getDelegate(path.mNativePath));
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mPathName = name;
-        }
-
-        public boolean isClipPath() {
-            return false;
-        }
-
-        private void setPathData(PathParser_Delegate.PathDataNode[] nodes) {
-            if (!PathParser_Delegate.canMorph(mNodes, nodes)) {
-                // This should not happen in the middle of animation.
-                mNodes = PathParser_Delegate.deepCopyNodes(nodes);
-            } else {
-                PathParser_Delegate.updateNodes(mNodes, nodes);
-            }
-        }
-
-        @Override
-        void dispose() {
-            mNodes = null;
-        }
-    }
-
-    static class VPathRenderer_Delegate extends VNativeObject {
-        /* Right now the internal data structure is organized as a tree.
-         * Each node can be a group node, or a path.
-         * A group node can have groups or paths as children, but a path node has
-         * no children.
-         * One example can be:
-         *                 Root Group
-         *                /    |     \
-         *           Group    Path    Group
-         *          /     \             |
-         *         Path   Path         Path
-         *
-         */
-        // Variables that only used temporarily inside the draw() call, so there
-        // is no need for deep copying.
-        private final Path mPath;
-        private final Path mRenderPath;
-        private final Matrix mFinalPathMatrix = new Matrix();
-        private final long mRootGroupPtr;
-        private float mViewportWidth = 0;
-        private float mViewportHeight = 0;
-        private float mRootAlpha = 1.0f;
-        private Paint mStrokePaint;
-        private Paint mFillPaint;
-        private PathMeasure mPathMeasure;
-
-        private VPathRenderer_Delegate(long rootGroupPtr) {
-            mRootGroupPtr = rootGroupPtr;
-            mPath = new Path();
-            mRenderPath = new Path();
-        }
-
-        private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy,
-                long rootGroupPtr) {
-            this(rootGroupPtr);
-            mViewportWidth = rendererToCopy.mViewportWidth;
-            mViewportHeight = rendererToCopy.mViewportHeight;
-            mRootAlpha = rendererToCopy.mRootAlpha;
-        }
-
-        private float getRootAlpha() {
-            return mRootAlpha;
-        }
-
-        void setRootAlpha(float alpha) {
-            mRootAlpha = alpha;
-        }
-
-        private void drawGroupTree(VGroup_Delegate currentGroup, Matrix currentMatrix,
-                long canvasPtr, int w, int h, long filterPtr) {
-            // Calculate current group's matrix by preConcat the parent's and
-            // and the current one on the top of the stack.
-            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
-            // Mi the local matrix at level i of the group tree.
-            currentGroup.mStackedMatrix.set(currentMatrix);
-            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
-
-            // Save the current clip information, which is local to this group.
-            Canvas_Delegate.nSave(canvasPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-            // Draw the group tree in the same order as the XML file.
-            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
-                Object child = currentGroup.mChildren.get(i);
-                if (child instanceof VGroup_Delegate) {
-                    VGroup_Delegate childGroup = (VGroup_Delegate) child;
-                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
-                            canvasPtr, w, h, filterPtr);
-                } else if (child instanceof VPath_Delegate) {
-                    VPath_Delegate childPath = (VPath_Delegate) child;
-                    drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
-                }
-            }
-            Canvas_Delegate.nRestore(canvasPtr);
-        }
-
-        public void draw(long canvasPtr, long filterPtr, int w, int h) {
-            // Traverse the tree in pre-order to draw.
-            drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
-        }
-
-        private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
-                int w,
-                int h,
-                long filterPtr) {
-            final float scaleX = w / mViewportWidth;
-            final float scaleY = h / mViewportHeight;
-            final float minScale = Math.min(scaleX, scaleY);
-            final Matrix groupStackedMatrix = VGroup.mStackedMatrix;
-
-            mFinalPathMatrix.set(groupStackedMatrix);
-            mFinalPathMatrix.postScale(scaleX, scaleY);
-
-            final float matrixScale = getMatrixScale(groupStackedMatrix);
-            if (matrixScale == 0) {
-                // When either x or y is scaled to 0, we don't need to draw anything.
-                return;
-            }
-            VPath.toPath(mPath);
-            final Path path = mPath;
-
-            mRenderPath.reset();
-
-            if (VPath.isClipPath()) {
-                mRenderPath.addPath(path, mFinalPathMatrix);
-                Canvas_Delegate.nClipPath(canvasPtr, mRenderPath.mNativePath, Op
-                        .INTERSECT.nativeInt);
-            } else {
-                VFullPath_Delegate fullPath = (VFullPath_Delegate) VPath;
-                if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
-                    float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
-                    float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
-
-                    if (mPathMeasure == null) {
-                        mPathMeasure = new PathMeasure();
-                    }
-                    mPathMeasure.setPath(mPath, false);
-
-                    float len = mPathMeasure.getLength();
-                    start = start * len;
-                    end = end * len;
-                    path.reset();
-                    if (start > end) {
-                        mPathMeasure.getSegment(start, len, path, true);
-                        mPathMeasure.getSegment(0f, end, path, true);
-                    } else {
-                        mPathMeasure.getSegment(start, end, path, true);
-                    }
-                    path.rLineTo(0, 0); // fix bug in measure
-                }
-                mRenderPath.addPath(path, mFinalPathMatrix);
-
-                if (fullPath.mFillColor != Color.TRANSPARENT) {
-                    if (mFillPaint == null) {
-                        mFillPaint = new Paint();
-                        mFillPaint.setStyle(Style.FILL);
-                        mFillPaint.setAntiAlias(true);
-                    }
-
-                    final Paint fillPaint = mFillPaint;
-                    fillPaint.setColor(applyAlpha(applyAlpha(fullPath.mFillColor, fullPath
-                      .mFillAlpha), getRootAlpha()));
-                    Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
-                            .getNativeInstance());
-                    // mFillPaint can not be null at this point so we will have a delegate
-                    assert fillPaintDelegate != null;
-                    fillPaintDelegate.setColorFilter(filterPtr);
-                    fillPaintDelegate.setShader(fullPath.mFillGradient);
-                    Path_Delegate.nSetFillType(mRenderPath.mNativePath, fullPath.mFillType);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
-                            .getNativeInstance());
-                }
-
-                if (fullPath.mStrokeColor != Color.TRANSPARENT) {
-                    if (mStrokePaint == null) {
-                        mStrokePaint = new Paint();
-                        mStrokePaint.setStyle(Style.STROKE);
-                        mStrokePaint.setAntiAlias(true);
-                    }
-
-                    final Paint strokePaint = mStrokePaint;
-                    if (fullPath.mStrokeLineJoin != null) {
-                        strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
-                    }
-
-                    if (fullPath.mStrokeLineCap != null) {
-                        strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
-                    }
-
-                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
-                    strokePaint.setColor(applyAlpha(applyAlpha(fullPath.mStrokeColor, fullPath
-                      .mStrokeAlpha), getRootAlpha()));
-                    Paint_Delegate strokePaintDelegate = Paint_Delegate.getDelegate(strokePaint
-                            .getNativeInstance());
-                    // mStrokePaint can not be null at this point so we will have a delegate
-                    assert strokePaintDelegate != null;
-                    strokePaintDelegate.setColorFilter(filterPtr);
-                    final float finalStrokeScale = minScale * matrixScale;
-                    strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
-                    strokePaintDelegate.setShader(fullPath.mStrokeGradient);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
-                            .getNativeInstance());
-                }
-            }
-        }
-
-        private float getMatrixScale(Matrix groupStackedMatrix) {
-            // Given unit vectors A = (0, 1) and B = (1, 0).
-            // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
-            // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
-            // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
-            // If  max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
-            //
-            // For non-skew case, which is most of the cases, matrix scale is computing exactly the
-            // scale on x and y axis, and take the minimal of these two.
-            // For skew case, an unit square will mapped to a parallelogram. And this function will
-            // return the minimal height of the 2 bases.
-            float[] unitVectors = new float[]{0, 1, 1, 0};
-            groupStackedMatrix.mapVectors(unitVectors);
-            float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
-            float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
-            float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
-                    unitVectors[2], unitVectors[3]);
-            float maxScale = MathUtils.max(scaleX, scaleY);
-
-            float matrixScale = 0;
-            if (maxScale > 0) {
-                matrixScale = MathUtils.abs(crossProduct) / maxScale;
-            }
-            if (DBG_VECTOR_DRAWABLE) {
-                Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
-            }
-            return matrixScale;
-        }
-
-        @Override
-        public void setName(String name) {
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we
-            // need to free it here.
-            VNativeObject nativeObject = sPathManager.getDelegate(mRootGroupPtr);
-            sPathManager.removeJavaReferenceFor(mRootGroupPtr);
-            assert nativeObject != null;
-            nativeObject.dispose();
-
-            super.finalize();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
deleted file mode 100644
index afbe97c0..0000000
--- a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delegate overriding selected methods of android.os.HandlerThread
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class HandlerThread_Delegate {
-
-    private static Map<BridgeContext, List<HandlerThread>> sThreads =
-            new HashMap<BridgeContext, List<HandlerThread>>();
-
-    public static void cleanUp(BridgeContext context) {
-        List<HandlerThread> list = sThreads.get(context);
-        if (list != null) {
-            for (HandlerThread thread : list) {
-                thread.quit();
-            }
-
-            list.clear();
-            sThreads.remove(context);
-        }
-    }
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static void run(HandlerThread theThread) {
-        // record the thread so that it can be quit() on clean up.
-        BridgeContext context = RenderAction.getCurrentContext();
-        List<HandlerThread> list = sThreads.get(context);
-        if (list == null) {
-            list = new ArrayList<HandlerThread>();
-            sThreads.put(context, list);
-        }
-
-        list.add(theThread);
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        theThread.mTid = Process.myTid();
-        Looper.prepare();
-        synchronized (theThread) {
-            theThread.mLooper = Looper.myLooper();
-            theThread.notifyAll();
-        }
-        Process.setThreadPriority(theThread.mPriority);
-        theThread.onLooperPrepared();
-        Looper.loop();
-        theThread.mTid = -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
deleted file mode 100644
index 2152c8a..0000000
--- a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate overriding selected methods of android.os.Handler
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class Handler_Delegate {
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static boolean sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-        // get the callback
-        IHandlerCallback callback = sCallbacks.get();
-        if (callback != null) {
-            callback.sendMessageAtTime(handler, msg, uptimeMillis);
-        }
-        return true;
-    }
-
-    // -------- Delegate implementation
-
-    public interface IHandlerCallback {
-        void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis);
-    }
-
-    private final static ThreadLocal<IHandlerCallback> sCallbacks =
-        new ThreadLocal<IHandlerCallback>();
-
-    public static void setCallback(IHandlerCallback callback) {
-        sCallbacks.set(callback);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java b/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
deleted file mode 100644
index 09f3e47..0000000
--- a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import java.lang.reflect.Field;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Looper_Accessor {
-
-    public static void cleanupThread() {
-        // clean up the looper
-        Looper.sThreadLocal.remove();
-        try {
-            Field sMainLooper = Looper.class.getDeclaredField("sMainLooper");
-            sMainLooper.setAccessible(true);
-            sMainLooper.set(null, null);
-        } catch (SecurityException e) {
-            catchReflectionException();
-        } catch (IllegalArgumentException e) {
-            catchReflectionException();
-        } catch (NoSuchFieldException e) {
-            catchReflectionException();
-        } catch (IllegalAccessException e) {
-            catchReflectionException();
-        }
-
-    }
-
-    private static void catchReflectionException() {
-        assert(false);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/ServiceManager.java b/tools/layoutlib/bridge/src/android/os/ServiceManager.java
deleted file mode 100644
index 34c7845..0000000
--- a/tools/layoutlib/bridge/src/android/os/ServiceManager.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import java.util.Map;
-
-public final class ServiceManager {
-
-    /**
-     * Returns a reference to a service with the given name.
-     *
-     * @param name the name of the service to get
-     * @return a reference to the service, or <code>null</code> if the service doesn't exist
-     */
-    public static IBinder getService(String name) {
-        return null;
-    }
-
-    /**
-     * Is not supposed to return null, but that is fine for layoutlib.
-     */
-    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
-        throw new ServiceNotFoundException(name);
-    }
-
-    /**
-     * Place a new @a service called @a name into the service
-     * manager.
-     *
-     * @param name the name of the new service
-     * @param service the service object
-     */
-    public static void addService(String name, IBinder service) {
-        // pass
-    }
-
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Non-blocking.
-     */
-    public static IBinder checkService(String name) {
-        return null;
-    }
-
-    /**
-     * Return a list of all currently running services.
-     * @return an array of all currently running services, or <code>null</code> in
-     * case of an exception
-     */
-    public static String[] listServices() {
-        // actual implementation returns null sometimes, so it's ok
-        // to return null instead of an empty list.
-        return null;
-    }
-
-    /**
-     * This is only intended to be called when the process is first being brought
-     * up and bound by the activity manager. There is only one thread in the process
-     * at that time, so no locking is done.
-     *
-     * @param cache the cache of service references
-     * @hide
-     */
-    public static void initServiceCache(Map<String, IBinder> cache) {
-        // pass
-    }
-
-    /**
-     * Exception thrown when no service published for given name. This might be
-     * thrown early during boot before certain services have published
-     * themselves.
-     *
-     * @hide
-     */
-    public static class ServiceNotFoundException extends Exception {
-        // identical to the original implementation
-        public ServiceNotFoundException(String name) {
-            super("No service published for: " + name);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
deleted file mode 100644
index 9677aaf..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-/**
- * Delegate implementing the native methods of android.os.SystemClock
- *
- * Through the layoutlib_create tool, the original native methods of SystemClock have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public class SystemClock_Delegate {
-    /**
-     * Returns milliseconds since boot, not counting time spent in deep sleep.
-     * <b>Note:</b> This value may get reset occasionally (before it would
-     * otherwise wrap around).
-     *
-     * @return milliseconds of non-sleep uptime since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long uptimeMillis() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns milliseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed milliseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtime() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns nanoseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed nanoseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtimeNanos() {
-        return System_Delegate.nanoTime() - System_Delegate.bootTime();
-    }
-
-    /**
-     * Returns milliseconds running in the current thread.
-     *
-     * @return elapsed milliseconds in the thread
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMillis() {
-        return System_Delegate.currentTimeMillis();
-    }
-
-    /**
-     * Returns microseconds running in the current thread.
-     *
-     * @return elapsed microseconds in the thread
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMicro() {
-        return System_Delegate.currentTimeMillis() * 1000;
-    }
-
-    /**
-     * Returns current wall time in  microseconds.
-     *
-     * @return elapsed microseconds in wall time
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentTimeMicro() {
-        return elapsedRealtime() * 1000;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
deleted file mode 100644
index d299add..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
+++ /dev/null
@@ -1,110 +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 android.os;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.os.SystemProperties
- *
- * Through the layoutlib_create tool, the original native methods of SystemProperties have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class SystemProperties_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key) {
-        return native_get(key, "");
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return value;
-        }
-
-        return def;
-    }
-    @LayoutlibDelegate
-    /*package*/ static int native_get_int(String key, int def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Integer.decode(value);
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_get_long(String key, long def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Long.decode(value);
-        }
-
-        return def;
-    }
-
-    /**
-     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
-     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean native_get_boolean(String key, boolean def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-
-        if ("n".equals(value) || "no".equals(value) || "0".equals(value) || "false".equals(value)
-                || "off".equals(value)) {
-            return false;
-        }
-        //noinspection SimplifiableIfStatement
-        if ("y".equals(value) || "yes".equals(value) || "1".equals(value) || "true".equals(value)
-                || "on".equals(value)) {
-            return true;
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        properties.put(key, def);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_add_change_callback() {
-        // pass.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_report_sysprop_change() {
-        // pass.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java b/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
deleted file mode 100644
index aa393a9..0000000
--- a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
+++ /dev/null
@@ -1,61 +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 android.preference;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.InflateException;
-
-public class BridgePreferenceInflater extends PreferenceInflater {
-
-    public BridgePreferenceInflater(Context context, PreferenceManager preferenceManager) {
-        super(context, preferenceManager);
-    }
-
-    @Override
-    protected Preference onCreateItem(String name, AttributeSet attrs)
-            throws ClassNotFoundException {
-        Object viewKey = null;
-        BridgeContext bc = null;
-
-        Context context = getContext();
-        if (context instanceof BridgeContext) {
-            bc = (BridgeContext) context;
-        }
-        if (attrs instanceof BridgeXmlBlockParser) {
-            viewKey = ((BridgeXmlBlockParser) attrs).getViewCookie();
-        }
-
-        Preference preference = null;
-        try {
-            preference = super.onCreateItem(name, attrs);
-        } catch (ClassNotFoundException | InflateException exception) {
-            // name is probably not a valid preference type
-            if ("SwitchPreferenceCompat".equals(name)) {
-                preference = super.onCreateItem("SwitchPreference", attrs);
-            }
-        }
-
-        if (viewKey != null && bc != null) {
-            bc.addCookie(preference, viewKey);
-        }
-        return preference;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java b/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
deleted file mode 100644
index 2e44a77..0000000
--- a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
+++ /dev/null
@@ -1,80 +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 android.preference;
-
-import com.android.internal.R;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-/**
- * Delegate that provides implementation for native methods in {@link Preference}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Preference have been replaced by calls to
- * methods of the same name in this delegate class.
- */
-public class Preference_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static View getView(Preference pref, View convertView, ViewGroup parent) {
-        Context context = pref.getContext();
-        BridgeContext bc = context instanceof BridgeContext ? ((BridgeContext) context) : null;
-        convertView = pref.getView_Original(convertView, parent);
-        if (bc != null) {
-            Object cookie = bc.getCookie(pref);
-            if (cookie != null) {
-                bc.addViewKey(convertView, cookie);
-            }
-        }
-        return convertView;
-    }
-
-    /**
-     * Inflates the parser and returns the ListView containing the Preferences.
-     */
-    public static View inflatePreference(Context context, XmlPullParser parser, ViewGroup root) {
-        PreferenceManager pm = new PreferenceManager(context);
-        PreferenceInflater inflater = new BridgePreferenceInflater(context, pm);
-        PreferenceScreen ps = (PreferenceScreen) inflater.inflate(parser, null, true);
-        pm.setPreferences(ps);
-        ListView preferenceView = createContainerView(context, root);
-        ps.bind(preferenceView);
-        return preferenceView;
-    }
-
-    private static ListView createContainerView(Context context, ViewGroup root) {
-        TypedArray a = context.obtainStyledAttributes(null, R.styleable.PreferenceFragment,
-                R.attr.preferenceFragmentStyle, 0);
-        int mLayoutResId = a.getResourceId(R.styleable.PreferenceFragment_layout,
-                        R.layout.preference_list_fragment);
-        a.recycle();
-
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(mLayoutResId, root, true);
-
-        return (ListView) root.findViewById(android.R.id.list);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
deleted file mode 100644
index 38171dc..0000000
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 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.text;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.Bidi;
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
- *
- * Through the layoutlib_create tool, the original  methods of AndroidBidi have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AndroidBidi_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static int runBidi(int dir, char[] chars, byte[] charInfo, int count,
-            boolean haveInfo) {
-
-        switch (dir) {
-        case 0: // Layout.DIR_REQUEST_LTR
-            dir = Bidi.LTR;
-            break;
-        case 1: // Layout.DIR_REQUEST_RTL
-            dir = Bidi.RTL;
-            break;
-        case -1: // Layout.DIR_REQUEST_DEFAULT_RTL
-            dir = Bidi.LEVEL_DEFAULT_RTL;
-            break;
-        case -2: // Layout.DIR_REQUEST_DEFAULT_LTR
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-            break;
-        default:
-            // Invalid code. Log error, assume LEVEL_DEFAULT_LTR and continue.
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Invalid direction flag", null);
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-        }
-        Bidi bidi = new Bidi(chars, 0, null, 0, count, dir);
-        if (charInfo != null) {
-            for (int i = 0; i < count; ++i)
-            charInfo[i] = bidi.getLevelAt(i);
-        }
-        return bidi.getParaLevel();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
deleted file mode 100644
index 50289e9..0000000
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ /dev/null
@@ -1,192 +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 android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-// Based on the native implementation of GreedyLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class GreedyLineBreaker extends LineBreaker {
-
-    public GreedyLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks lineBreaks) {
-        BreakInfo breakInfo = new BreakInfo();
-        int lineNum = 0;
-        float width = 0, printedWidth = 0;
-        boolean breakFound = false, goodBreakFound = false;
-        int breakIndex = 0, goodBreakIndex = 0;
-        float breakWidth = 0, goodBreakWidth = 0;
-        int firstTabIndex = Integer.MAX_VALUE;
-
-        float maxWidth = mLineWidth.getLineWidth(lineNum);
-
-        int numPrimitives = mPrimitives.size();
-        // greedily fit as many characters as possible on each line
-        // loop over all primitives, and choose the best break point
-        // (if possible, a break point without splitting a word)
-        // after going over the maximum length
-        for (int i = 0; i < numPrimitives; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            // update the current line width
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                width += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    printedWidth = width;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                width = mTabStops.width(width);
-                // keep track of first tab character in the region we are examining
-                // so we can determine whether or not a line contains a tab
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            // find the best break point for the characters examined so far
-            if (printedWidth > maxWidth) {
-                //noinspection StatementWithEmptyBody
-                if (breakFound || goodBreakFound) {
-                    if (goodBreakFound) {
-                        // a true line break opportunity existed in the characters examined so far,
-                        // so there is no need to split a word
-                        i = goodBreakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                        breakInfo.mWidthsList.add(goodBreakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    } else {
-                        // must split a word because there is no other option
-                        i = breakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                        breakInfo.mWidthsList.add(breakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    }
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                } else {
-                    // no choice, keep going... must make progress by putting at least one
-                    // character on a line, even if part of that character is cut off --
-                    // there is no other option
-                }
-            }
-
-            // update possible break points
-            if (p.type == PrimitiveType.PENALTY &&
-                    p.penalty < PENALTY_INFINITY) {
-                // this does not handle penalties with width
-
-                // handle forced line break
-                if (p.penalty == -PENALTY_INFINITY) {
-                    lineNum++;
-                    maxWidth = mLineWidth.getLineWidth(lineNum);
-                    breakInfo.mBreaksList.add(p.location);
-                    breakInfo.mWidthsList.add(printedWidth);
-                    breakInfo.mFlagsList.add(firstTabIndex < i);
-                    firstTabIndex = Integer.MAX_VALUE;
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                }
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-                if (i > goodBreakIndex && printedWidth <= maxWidth) {
-                    goodBreakFound = true;
-                    goodBreakIndex = i;
-                    goodBreakWidth = printedWidth;
-                }
-            } else if (p.type == PrimitiveType.WORD_BREAK) {
-                // only do this if necessary -- we don't want to break words
-                // when possible, but sometimes it is unavoidable
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-            }
-        }
-
-        if (breakFound || goodBreakFound) {
-            // output last break if there are more characters to output
-            if (goodBreakFound) {
-                breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                breakInfo.mWidthsList.add(goodBreakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-            } else {
-                breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                breakInfo.mWidthsList.add(breakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-            }
-        }
-        breakInfo.copyTo(lineBreaks);
-    }
-
-    private static class BreakInfo {
-        List<Integer> mBreaksList = new ArrayList<Integer>();
-        List<Float> mWidthsList = new ArrayList<Float>();
-        List<Boolean> mFlagsList = new ArrayList<Boolean>();
-
-        public void copyTo(LineBreaks lineBreaks) {
-            if (lineBreaks.breaks.length != mBreaksList.size()) {
-                lineBreaks.breaks = new int[mBreaksList.size()];
-                lineBreaks.widths = new float[mWidthsList.size()];
-                lineBreaks.flags = new int[mFlagsList.size()];
-            }
-
-            int i = 0;
-            for (int b : mBreaksList) {
-                lineBreaks.breaks[i] = b;
-                i++;
-            }
-            i = 0;
-            for (float b : mWidthsList) {
-                lineBreaks.widths[i] = b;
-                i++;
-            }
-            i = 0;
-            for (boolean b : mFlagsList) {
-                lineBreaks.flags[i] = b ? TAB_MASK : 0;
-                i++;
-            }
-
-            mBreaksList = null;
-            mWidthsList = null;
-            mFlagsList = null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
deleted file mode 100644
index 499e58a..0000000
--- a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-
-/**
- * Delegate that overrides implementation for certain methods in {@link android.text.Hyphenator}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Hyphenator have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class Hyphenator_Delegate {
-
-    private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new
-            DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class);
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemHyphenatorLocation() {
-        // FIXME
-        return null;
-    }
-
-    /*package*/ @SuppressWarnings("UnusedParameters")  // TODO implement this.
-    static long loadHyphenator(ByteBuffer buffer, int offset, int minPrefix, int minSuffix) {
-        return sDelegateManager.addNewDelegate(new Hyphenator_Delegate());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
deleted file mode 100644
index 06e9c84..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ /dev/null
@@ -1,43 +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 android.text;
-
-import android.annotation.NonNull;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.Collections;
-import java.util.List;
-
-// Based on the native implementation of LineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public abstract class LineBreaker {
-
-    protected static final int TAB_MASK   = 0x20000000;  // keep in sync with StaticLayout
-
-    protected final @NonNull List<Primitive> mPrimitives;
-    protected final @NonNull LineWidth mLineWidth;
-    protected final @NonNull TabStops mTabStops;
-
-    public LineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        mPrimitives = Collections.unmodifiableList(primitives);
-        mLineWidth = lineWidth;
-        mTabStops = tabStops;
-    }
-
-    public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineWidth.java b/tools/layoutlib/bridge/src/android/text/LineWidth.java
deleted file mode 100644
index 2ea886d..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineWidth.java
+++ /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.
- */
-
-package android.text;
-
-// Based on the native implementation of LineWidth in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class LineWidth {
-    private final float mFirstWidth;
-    private final int mFirstWidthLineCount;
-    private float mRestWidth;
-
-    public LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) {
-        mFirstWidth = firstWidth;
-        mFirstWidthLineCount = firstWidthLineCount;
-        mRestWidth = restWidth;
-    }
-
-    public float getLineWidth(int line) {
-        return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
deleted file mode 100644
index ed8e33a..0000000
--- a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
+++ /dev/null
@@ -1,261 +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 android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-
-// Based on the native implementation of OptimizingLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-/**
- * A more complex version of line breaking where we try to prevent the right edge from being too
- * jagged.
- */
-public class OptimizingLineBreaker extends LineBreaker {
-
-    public OptimizingLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks breakInfo) {
-        int numBreaks = mPrimitives.size();
-        assert numBreaks > 0;
-        if (numBreaks == 1) {
-            // This can be true only if it's an empty paragraph.
-            Primitive p = mPrimitives.get(0);
-            assert p.type == PrimitiveType.PENALTY;
-            breakInfo.breaks = new int[]{0};
-            breakInfo.widths = new float[]{p.width};
-            breakInfo.flags = new int[]{0};
-            return;
-        }
-        Node[] opt = new Node[numBreaks];
-        opt[0] = new Node(-1, 0, 0, 0, false);
-        opt[numBreaks - 1] = new Node(-1, 0, 0, 0, false);
-
-        ArrayList<Integer> active = new ArrayList<Integer>();
-        active.add(0);
-        int lastBreak = 0;
-        for (int i = 0; i < numBreaks; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.PENALTY) {
-                boolean finalBreak = (i + 1 == numBreaks);
-                Node bestBreak = null;
-
-                for (ListIterator<Integer> it = active.listIterator(); it.hasNext();
-                        /* incrementing done in loop */) {
-                    int pos = it.next();
-                    int lines = opt[pos].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    // we have to compute metrics every time --
-                    // we can't really pre-compute this stuff and just deal with breaks
-                    // because of the way tab characters work, this makes it computationally
-                    // harder, but this way, we can still optimize while treating tab characters
-                    // correctly
-                    LineMetrics lineMetrics = computeMetrics(pos, i);
-                    if (lineMetrics.mPrintedWidth <= maxWidth) {
-                        float demerits = computeDemerits(maxWidth, lineMetrics.mPrintedWidth,
-                                finalBreak, p.penalty) + opt[pos].mDemerits;
-                        if (bestBreak == null || demerits < bestBreak.mDemerits) {
-                            if (bestBreak == null) {
-                                bestBreak = new Node(pos, opt[pos].mPrevCount + 1, demerits,
-                                        lineMetrics.mPrintedWidth, lineMetrics.mHasTabs);
-                            } else {
-                                bestBreak.mPrev = pos;
-                                bestBreak.mPrevCount = opt[pos].mPrevCount + 1;
-                                bestBreak.mDemerits = demerits;
-                                bestBreak.mWidth = lineMetrics.mPrintedWidth;
-                                bestBreak.mHasTabs = lineMetrics.mHasTabs;
-                            }
-                        }
-                    } else {
-                        it.remove();
-                    }
-                }
-                if (p.penalty == -PENALTY_INFINITY) {
-                    active.clear();
-                }
-                if (bestBreak != null) {
-                    opt[i] = bestBreak;
-                    active.add(i);
-                    lastBreak = i;
-                }
-                if (active.isEmpty()) {
-                    // we can't give up!
-                    LineMetrics lineMetrics = new LineMetrics();
-                    int lines = opt[lastBreak].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, lineMetrics);
-                    opt[breakIndex] = new Node(lastBreak, lines + 1, 0 /*doesn't matter*/,
-                            lineMetrics.mWidth, lineMetrics.mHasTabs);
-                    active.add(breakIndex);
-                    lastBreak = breakIndex;
-                    i = breakIndex; // incremented by i++
-                }
-            }
-        }
-
-        int idx = numBreaks - 1;
-        int count = opt[idx].mPrevCount;
-        resize(breakInfo, count);
-        while (opt[idx].mPrev != -1) {
-            count--;
-            assert count >=0;
-
-            breakInfo.breaks[count] = mPrimitives.get(idx).location;
-            breakInfo.widths[count] = opt[idx].mWidth;
-            breakInfo.flags [count] = opt[idx].mHasTabs ? TAB_MASK : 0;
-            idx = opt[idx].mPrev;
-        }
-    }
-
-    private static void resize(LineBreaks lineBreaks, int size) {
-        if (lineBreaks.breaks.length == size) {
-            return;
-        }
-        int[] breaks = new int[size];
-        float[] widths = new float[size];
-        int[] flags = new int[size];
-
-        int toCopy = Math.min(size, lineBreaks.breaks.length);
-        System.arraycopy(lineBreaks.breaks, 0, breaks, 0, toCopy);
-        System.arraycopy(lineBreaks.widths, 0, widths, 0, toCopy);
-        System.arraycopy(lineBreaks.flags, 0, flags, 0, toCopy);
-
-        lineBreaks.breaks = breaks;
-        lineBreaks.widths = widths;
-        lineBreaks.flags = flags;
-    }
-
-    @NonNull
-    private LineMetrics computeMetrics(int start, int end) {
-        boolean f = false;
-        float w = 0, pw = 0;
-        for (int i = start; i < end; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                f = true;
-            }
-        }
-        return new LineMetrics(w, pw, f);
-    }
-
-    private static float computeDemerits(float maxWidth, float width, boolean finalBreak,
-            float penalty) {
-        float deviation = finalBreak ? 0 : maxWidth - width;
-        return (deviation * deviation) + penalty;
-    }
-
-    /**
-     * @return the last break position or -1 if failed.
-     */
-    @SuppressWarnings("ConstantConditions")  // method too complex to be analyzed.
-    private int desperateBreak(int start, int limit, float maxWidth,
-            @NonNull LineMetrics lineMetrics) {
-        float w = 0, pw = 0;
-        boolean breakFound = false;
-        int breakIndex = 0, firstTabIndex = Integer.MAX_VALUE;
-        for (int i = start; i < limit; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            if (pw > maxWidth && breakFound) {
-                break;
-            }
-
-            // must make progress
-            if (i > start &&
-                    (p.type == PrimitiveType.PENALTY || p.type == PrimitiveType.WORD_BREAK)) {
-                breakFound = true;
-                breakIndex = i;
-            }
-        }
-
-        if (breakFound) {
-            lineMetrics.mWidth = w;
-            lineMetrics.mPrintedWidth = pw;
-            lineMetrics.mHasTabs = (start <= firstTabIndex && firstTabIndex < breakIndex);
-            return breakIndex;
-        } else {
-            return -1;
-        }
-    }
-
-    private static class LineMetrics {
-        /** Actual width of the line. */
-        float mWidth;
-        /** Width of the line minus trailing whitespace. */
-        float mPrintedWidth;
-        boolean mHasTabs;
-
-        public LineMetrics() {
-        }
-
-        public LineMetrics(float width, float printedWidth, boolean hasTabs) {
-            mWidth = width;
-            mPrintedWidth = printedWidth;
-            mHasTabs = hasTabs;
-        }
-    }
-
-    /**
-     * A struct to store the info about a break.
-     */
-    @SuppressWarnings("SpellCheckingInspection")  // For the word struct.
-    private static class Node {
-        // -1 for the first node.
-        int mPrev;
-        // number of breaks so far.
-        int mPrevCount;
-        float mDemerits;
-        float mWidth;
-        boolean mHasTabs;
-
-        public Node(int prev, int prevCount, float demerits, float width, boolean hasTabs) {
-            mPrev = prev;
-            mPrevCount = prevCount;
-            mDemerits = demerits;
-            mWidth = width;
-            mHasTabs = hasTabs;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Primitive.java b/tools/layoutlib/bridge/src/android/text/Primitive.java
deleted file mode 100644
index 37ed072..0000000
--- a/tools/layoutlib/bridge/src/android/text/Primitive.java
+++ /dev/null
@@ -1,92 +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 android.text;
-
-import android.annotation.NonNull;
-
-// Based on the native implementation of Primitive in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class Primitive {
-    public final @NonNull PrimitiveType type;
-    public final int location;
-    // The following fields don't make sense for all types.
-    // Box and Glue have width only.
-    // Penalty has both width and penalty.
-    // Word_break has penalty only.
-    public final float width;
-    public final float penalty;
-
-    /**
-     * Use {@code PrimitiveType#getNewPrimitive()}
-     */
-    private Primitive(@NonNull PrimitiveType type, int location, float width, float penalty) {
-        this.type = type;
-        this.location = location;
-        this.width = width;
-        this.penalty = penalty;
-    }
-
-    public static enum PrimitiveType {
-        /**
-         * Something with a constant width that is to be typeset - like a character.
-         */
-        BOX,
-        /**
-         * Blank space with fixed width.
-         */
-        GLUE,
-        /**
-         * Aesthetic cost indicating how desirable breaking at this point will be. A penalty of
-         * {@link #PENALTY_INFINITY} means a forced non-break, whereas a penalty of negative
-         * {@code #PENALTY_INFINITY} means a forced break.
-         * <p/>
-         * Currently, it only stores penalty with values 0 or -infinity.
-         */
-        PENALTY,
-        /**
-         * For tabs - variable width space.
-         */
-        VARIABLE,
-        /**
-         * Possible breakpoints within a word. Think of this as a high cost {@link #PENALTY}.
-         */
-        WORD_BREAK;
-
-        public Primitive getNewPrimitive(int location) {
-            assert this == VARIABLE;
-            return new Primitive(this, location, 0f, 0f);
-        }
-
-        public Primitive getNewPrimitive(int location, float value) {
-            assert this == BOX || this == GLUE || this == WORD_BREAK;
-            if (this == BOX || this == GLUE) {
-                return new Primitive(this, location, value, 0f);
-            } else {
-                return new Primitive(this, location, 0f, value);
-            }
-        }
-
-        public Primitive getNewPrimitive(int location, float width, float penalty) {
-            assert this == PENALTY;
-            return new Primitive(this, location, width, penalty);
-        }
-
-        // forced non-break, negative infinity is forced break.
-        public static final float PENALTY_INFINITY = 1e7f;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
deleted file mode 100644
index cc03143..0000000
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.BidiRenderer;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.RectF;
-import android.icu.text.BreakIterator;
-import android.icu.util.ULocale;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.text.Segment;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
- * <p/>
- * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class StaticLayout_Delegate {
-
-    private static final char CHAR_SPACE     = 0x20;
-    private static final char CHAR_TAB       = 0x09;
-    private static final char CHAR_NEWLINE   = 0x0A;
-    private static final char CHAR_ZWSP      = 0x200B;  // Zero width space.
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<Builder> sBuilderManager =
-        new DelegateManager<Builder>(Builder.class);
-
-    @LayoutlibDelegate
-    /*package*/ static long nNewBuilder() {
-        return sBuilderManager.addNewDelegate(new Builder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeBuilder(long nativeBuilder) {
-        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinishBuilder(long nativeBuilder) {
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nLoadHyphenator(ByteBuffer buf, int offset, int minPrefix,
-            int minSuffix) {
-        return Hyphenator_Delegate.loadHyphenator(buf, offset, minPrefix, minSuffix);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            builder.mLocale = locale;
-            builder.mNativeHyphenator = nativeHyphenator;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) {
-        // TODO.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
-            float firstWidth, int firstWidthLineCount, float restWidth,
-            int[] variableTabStops, int defaultTabStop, int breakStrategy,
-            int hyphenationFrequency, boolean isJustified) {
-        // TODO: implement justified alignment
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-
-        builder.mText = text;
-        builder.mWidths = new float[length];
-        builder.mLineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
-        builder.mTabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
-            int start, int end, boolean isRtl) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        return builder == null ? 0 :
-                measureText(nativePaint, builder.mText, start, end - start, builder.mWidths,
-                        bidiFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(widths, start, builder.mWidths, start, end - start);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-        builder.mWidths[start] = width;
-        Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nComputeLineBreaks(long nativeBuilder,
-            LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths,
-            int[] recycleFlags, int recycleLength) {
-
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return 0;
-        }
-
-        // compute all possible breakpoints.
-        int length = builder.mWidths.length;
-        BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
-        it.setText(new Segment(builder.mText, 0, length));
-
-        // average word length in english is 5. So, initialize the possible breaks with a guess.
-        List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
-        int loc;
-        it.first();
-        while ((loc = it.next()) != BreakIterator.DONE) {
-            breaks.add(loc);
-        }
-
-        List<Primitive> primitives =
-                computePrimitives(builder.mText, builder.mWidths, length, breaks);
-        switch (builder.mBreakStrategy) {
-            case Layout.BREAK_STRATEGY_SIMPLE:
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            case Layout.BREAK_STRATEGY_HIGH_QUALITY:
-                // TODO
-//                break;
-            case Layout.BREAK_STRATEGY_BALANCED:
-                builder.mLineBreaker = new OptimizingLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            default:
-                assert false : "Unknown break strategy: " + builder.mBreakStrategy;
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-        }
-        builder.mLineBreaker.computeBreaks(recycle);
-        return recycle.breaks.length;
-    }
-
-    /**
-     * Compute metadata each character - things which help in deciding if it's possible to break
-     * at a point or not.
-     */
-    @NonNull
-    private static List<Primitive> computePrimitives(@NonNull char[] text, @NonNull float[] widths,
-            int length, @NonNull List<Integer> breaks) {
-        // Initialize the list with a guess of the number of primitives:
-        // 2 Primitives per non-whitespace char and approx 5 chars per word (i.e. 83% chars)
-        List<Primitive> primitives = new ArrayList<Primitive>(((int) Math.ceil(length * 1.833)));
-        int breaksSize = breaks.size();
-        int breakIndex = 0;
-        for (int i = 0; i < length; i++) {
-            char c = text[i];
-            if (c == CHAR_SPACE || c == CHAR_ZWSP) {
-                primitives.add(PrimitiveType.GLUE.getNewPrimitive(i, widths[i]));
-            } else if (c == CHAR_TAB) {
-                primitives.add(PrimitiveType.VARIABLE.getNewPrimitive(i));
-            } else if (c != CHAR_NEWLINE) {
-                while (breakIndex < breaksSize && breaks.get(breakIndex) < i) {
-                    breakIndex++;
-                }
-                Primitive p;
-                if (widths[i] != 0) {
-                    if (breakIndex < breaksSize && breaks.get(breakIndex) == i) {
-                        p = PrimitiveType.PENALTY.getNewPrimitive(i, 0, 0);
-                    } else {
-                        p = PrimitiveType.WORD_BREAK.getNewPrimitive(i, 0);
-                    }
-                    primitives.add(p);
-                }
-
-                primitives.add(PrimitiveType.BOX.getNewPrimitive(i, widths[i]));
-            }
-        }
-        // final break at end of everything
-        primitives.add(
-                PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY));
-        return primitives;
-    }
-
-    private static float measureText(long nativePaint, char []text, int index, int count,
-            float[] widths, int bidiFlags) {
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-        RectF bounds = new BidiRenderer(null, paint, text)
-            .renderText(index, index + count, bidiFlags, widths, 0, false);
-        return bounds.right - bounds.left;
-    }
-
-    // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker.
-    /**
-     * Java representation of the native Builder class.
-     */
-    private static class Builder {
-        String mLocale;
-        char[] mText;
-        float[] mWidths;
-        LineBreaker mLineBreaker;
-        long mNativeHyphenator;
-        int mBreakStrategy;
-        LineWidth mLineWidth;
-        TabStops mTabStopCalculator;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/TabStops.java b/tools/layoutlib/bridge/src/android/text/TabStops.java
deleted file mode 100644
index 6c2f1e1..0000000
--- a/tools/layoutlib/bridge/src/android/text/TabStops.java
+++ /dev/null
@@ -1,44 +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 android.text;
-
-import android.annotation.Nullable;
-
-// Based on the native implementation of TabStops in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class TabStops {
-    @Nullable
-    private int[] mStops;
-    private final int mTabWidth;
-
-    public TabStops(@Nullable int[] stops, int defaultTabWidth) {
-        mTabWidth = defaultTabWidth;
-        mStops = stops;
-    }
-
-    public float width(float widthSoFar) {
-        if (mStops != null) {
-            for (int i : mStops) {
-                if (i > widthSoFar) {
-                    return i;
-                }
-            }
-        }
-        // find the next tabStop after widthSoFar.
-        return (int) ((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
deleted file mode 100644
index 1e4f213..0000000
--- a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
+++ /dev/null
@@ -1,42 +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.
- */
-
-package android.text.format;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link DateFormat}
- *
- * Through the layoutlib_create tool, the original  methods of DateFormat have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class DateFormat_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context) {
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context, int userHandle) {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
deleted file mode 100644
index 9fd1e15..0000000
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2008 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.util;
-
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-
-import java.util.Map;
-import java.util.function.Function;
-
-/**
- * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
- */
-public class BridgeXmlPullAttributes extends XmlPullAttributes {
-
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-    private final Function<String, Map<String, Integer>> mFrameworkEnumValueSupplier;
-    private final Function<String, Map<String, Integer>> mProjectEnumValueSupplier;
-
-    // VisibleForTesting
-    BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile,
-            @NonNull Function<String, Map<String, Integer>> frameworkEnumValueSupplier,
-            @NonNull Function<String, Map<String, Integer>> projectEnumValueSupplier) {
-        super(parser);
-        mContext = context;
-        mPlatformFile = platformFile;
-        mFrameworkEnumValueSupplier = frameworkEnumValueSupplier;
-        mProjectEnumValueSupplier = projectEnumValueSupplier;
-    }
-
-    public BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile) {
-        this(parser, context, platformFile, Bridge::getEnumValues, attrName -> {
-            // get the styleable matching the resolved name
-            RenderResources res = context.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, attrName);
-            return attr instanceof AttrResourceValue ?
-                    ((AttrResourceValue) attr).getAttributeValues() : null;
-        });
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
-     *
-     * This methods must return com.android.internal.R.attr.<name> matching
-     * the name of the attribute.
-     * It returns 0 if it doesn't find anything.
-     */
-    @Override
-    public int getAttributeNameResource(int index) {
-        // get the attribute name.
-        String name = getAttributeName(index);
-
-        // get the attribute namespace
-        String ns = mParser.getAttributeNamespace(index);
-
-        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
-            return Bridge.getResourceId(ResourceType.ATTR, name);
-
-        }
-
-        // this is not an attribute in the android namespace, we query the customviewloader, if
-        // the namespaces match.
-        if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
-            if (v != null) {
-                return v;
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToList(value, options, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value == null) {
-            return defaultValue;
-        }
-
-        ResourceValue r = getResourceValue(value);
-
-        if (r != null) {
-            value = r.getValue();
-        }
-
-        if (value.charAt(0) == '#') {
-            return ResourceHelper.getColor(value);
-        }
-
-        try {
-            return XmlUtils.convertValueToInt(value, defaultValue);
-        } catch (NumberFormatException e) {
-            // This is probably an enum
-            Map<String, Integer> enumValues = BridgeConstants.NS_RESOURCES.equals(namespace) ?
-                    mFrameworkEnumValueSupplier.apply(attribute) :
-                    mProjectEnumValueSupplier.apply(attribute);
-
-            Integer enumValue = enumValues != null ? enumValues.get(value) : null;
-            if (enumValue != null) {
-                return enumValue;
-            }
-
-            // We weren't able to find the enum int value
-            throw e;
-        }
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        String s = getAttributeValue(namespace, attribute);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        return XmlUtils.convertValueToList(
-            getAttributeValue(index), options, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return getAttributeIntValue(mParser.getAttributeNamespace(index),
-                getAttributeName(index)
-                , defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        String s = getAttributeValue(index);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    // -- private helper methods
-
-    /**
-     * Returns a resolved {@link ResourceValue} from a given value.
-     */
-    private ResourceValue getResourceValue(String value) {
-        // now look for this particular value
-        RenderResources resources = mContext.getRenderResources();
-        return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
-    }
-
-    /**
-     * Resolves and return a value to its associated integer.
-     */
-    private int resolveResourceValue(String value, int defaultValue) {
-        ResourceValue resource = getResourceValue(value);
-        if (resource != null) {
-            Integer id = null;
-            if (mPlatformFile || resource.isFramework()) {
-                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
-            } else {
-                id = mContext.getLayoutlibCallback().getResourceId(
-                        resource.getResourceType(), resource.getName());
-            }
-
-            if (id != null) {
-                return id;
-            }
-        }
-
-        return defaultValue;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java b/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
deleted file mode 100644
index 7f432ab..0000000
--- a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 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.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-class Log_Delegate {
-    // to replicate prefix visible when using 'adb logcat'
-    private static char priorityChar(int priority) {
-        switch (priority) {
-            case Log.VERBOSE:
-                return 'V';
-            case Log.DEBUG:
-                return 'D';
-            case Log.INFO:
-                return 'I';
-            case Log.WARN:
-                return 'W';
-            case Log.ERROR:
-                return 'E';
-            case Log.ASSERT:
-                return 'A';
-            default:
-                return '?';
-        }
-    }
-
-    @LayoutlibDelegate
-    static int println_native(int bufID, int priority, String tag, String msgs) {
-        String prefix = priorityChar(priority) + "/" + tag + ": ";
-        for (String msg: msgs.split("\n")) {
-            System.out.println(prefix + msg);
-        }
-        return 0;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/util/LruCache.java b/tools/layoutlib/bridge/src/android/util/LruCache.java
deleted file mode 100644
index 5208606..0000000
--- a/tools/layoutlib/bridge/src/android/util/LruCache.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2011 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.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * BEGIN LAYOUTLIB CHANGE
- * This is a custom version that doesn't use the non standard LinkedHashMap#eldest.
- * END LAYOUTLIB CHANGE
- *
- * A cache that holds strong references to a limited number of values. Each time
- * a value is accessed, it is moved to the head of a queue. When a value is
- * added to a full cache, the value at the end of that queue is evicted and may
- * become eligible for garbage collection.
- *
- * <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryRemoved}.
- *
- * <p>If a cache miss should be computed on demand for the corresponding keys,
- * override {@link #create}. This simplifies the calling code, allowing it to
- * assume a value will always be returned, even when there's a cache miss.
- *
- * <p>By default, the cache size is measured in the number of entries. Override
- * {@link #sizeOf} to size the cache in different units. For example, this cache
- * is limited to 4MiB of bitmaps:
- * <pre>   {@code
- *   int cacheSize = 4 * 1024 * 1024; // 4MiB
- *   LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
- *       protected int sizeOf(String key, Bitmap value) {
- *           return value.getByteCount();
- *       }
- *   }}</pre>
- *
- * <p>This class is thread-safe. Perform multiple cache operations atomically by
- * synchronizing on the cache: <pre>   {@code
- *   synchronized (cache) {
- *     if (cache.get(key) == null) {
- *         cache.put(key, value);
- *     }
- *   }}</pre>
- *
- * <p>This class does not allow null to be used as a key or value. A return
- * value of null from {@link #get}, {@link #put} or {@link #remove} is
- * unambiguous: the key was not in the cache.
- *
- * <p>This class appeared in Android 3.1 (Honeycomb MR1); it's available as part
- * of <a href="http://developer.android.com/sdk/compatibility-library.html">Android's
- * Support Package</a> for earlier releases.
- */
-public class LruCache<K, V> {
-    private final LinkedHashMap<K, V> map;
-
-    /** Size of this cache in units. Not necessarily the number of elements. */
-    private int size;
-    private int maxSize;
-
-    private int putCount;
-    private int createCount;
-    private int evictionCount;
-    private int hitCount;
-    private int missCount;
-
-    /**
-     * @param maxSize for caches that do not override {@link #sizeOf}, this is
-     *     the maximum number of entries in the cache. For all other caches,
-     *     this is the maximum sum of the sizes of the entries in this cache.
-     */
-    public LruCache(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-        this.maxSize = maxSize;
-        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
-    }
-
-    /**
-     * Sets the size of the cache.
-     * @param maxSize The new maximum size.
-     *
-     * @hide
-     */
-    public void resize(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-
-        synchronized (this) {
-            this.maxSize = maxSize;
-        }
-        trimToSize(maxSize);
-    }
-
-    /**
-     * Returns the value for {@code key} if it exists in the cache or can be
-     * created by {@code #create}. If a value was returned, it is moved to the
-     * head of the queue. This returns null if a value is not cached and cannot
-     * be created.
-     */
-    public final V get(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V mapValue;
-        synchronized (this) {
-            mapValue = map.get(key);
-            if (mapValue != null) {
-                hitCount++;
-                return mapValue;
-            }
-            missCount++;
-        }
-
-        /*
-         * Attempt to create a value. This may take a long time, and the map
-         * may be different when create() returns. If a conflicting value was
-         * added to the map while create() was working, we leave that value in
-         * the map and release the created value.
-         */
-
-        V createdValue = create(key);
-        if (createdValue == null) {
-            return null;
-        }
-
-        synchronized (this) {
-            createCount++;
-            mapValue = map.put(key, createdValue);
-
-            if (mapValue != null) {
-                // There was a conflict so undo that last put
-                map.put(key, mapValue);
-            } else {
-                size += safeSizeOf(key, createdValue);
-            }
-        }
-
-        if (mapValue != null) {
-            entryRemoved(false, key, createdValue, mapValue);
-            return mapValue;
-        } else {
-            trimToSize(maxSize);
-            return createdValue;
-        }
-    }
-
-    /**
-     * Caches {@code value} for {@code key}. The value is moved to the head of
-     * the queue.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V put(K key, V value) {
-        if (key == null || value == null) {
-            throw new NullPointerException("key == null || value == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            putCount++;
-            size += safeSizeOf(key, value);
-            previous = map.put(key, value);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, value);
-        }
-
-        trimToSize(maxSize);
-        return previous;
-    }
-
-    /**
-     * @param maxSize the maximum size of the cache before returning. May be -1
-     *     to evict even 0-sized elements.
-     */
-    private void trimToSize(int maxSize) {
-        while (true) {
-            K key;
-            V value;
-            synchronized (this) {
-                if (size < 0 || (map.isEmpty() && size != 0)) {
-                    throw new IllegalStateException(getClass().getName()
-                            + ".sizeOf() is reporting inconsistent results!");
-                }
-
-                if (size <= maxSize) {
-                    break;
-                }
-
-                // BEGIN LAYOUTLIB CHANGE
-                // get the last item in the linked list.
-                // This is not efficient, the goal here is to minimize the changes
-                // compared to the platform version.
-                Map.Entry<K, V> toEvict = null;
-                for (Map.Entry<K, V> entry : map.entrySet()) {
-                    toEvict = entry;
-                }
-                // END LAYOUTLIB CHANGE
-
-                if (toEvict == null) {
-                    break;
-                }
-
-                key = toEvict.getKey();
-                value = toEvict.getValue();
-                map.remove(key);
-                size -= safeSizeOf(key, value);
-                evictionCount++;
-            }
-
-            entryRemoved(true, key, value, null);
-        }
-    }
-
-    /**
-     * Removes the entry for {@code key} if it exists.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V remove(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            previous = map.remove(key);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, null);
-        }
-
-        return previous;
-    }
-
-    /**
-     * Called for entries that have been evicted or removed. This method is
-     * invoked when a value is evicted to make space, removed by a call to
-     * {@link #remove}, or replaced by a call to {@link #put}. The default
-     * implementation does nothing.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * @param evicted true if the entry is being removed to make space, false
-     *     if the removal was caused by a {@link #put} or {@link #remove}.
-     * @param newValue the new value for {@code key}, if it exists. If non-null,
-     *     this removal was caused by a {@link #put}. Otherwise it was caused by
-     *     an eviction or a {@link #remove}.
-     */
-    protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
-
-    /**
-     * Called after a cache miss to compute a value for the corresponding key.
-     * Returns the computed value or null if no value can be computed. The
-     * default implementation returns null.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * <p>If a value for {@code key} exists in the cache when this method
-     * returns, the created value will be released with {@link #entryRemoved}
-     * and discarded. This can occur when multiple threads request the same key
-     * at the same time (causing multiple values to be created), or when one
-     * thread calls {@link #put} while another is creating a value for the same
-     * key.
-     */
-    protected V create(K key) {
-        return null;
-    }
-
-    private int safeSizeOf(K key, V value) {
-        int result = sizeOf(key, value);
-        if (result < 0) {
-            throw new IllegalStateException("Negative size: " + key + "=" + value);
-        }
-        return result;
-    }
-
-    /**
-     * Returns the size of the entry for {@code key} and {@code value} in
-     * user-defined units.  The default implementation returns 1 so that size
-     * is the number of entries and max size is the maximum number of entries.
-     *
-     * <p>An entry's size must not change while it is in the cache.
-     */
-    protected int sizeOf(K key, V value) {
-        return 1;
-    }
-
-    /**
-     * Clear the cache, calling {@link #entryRemoved} on each removed entry.
-     */
-    public final void evictAll() {
-        trimToSize(-1); // -1 will evict 0-sized elements
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the number
-     * of entries in the cache. For all other caches, this returns the sum of
-     * the sizes of the entries in this cache.
-     */
-    public synchronized final int size() {
-        return size;
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the maximum
-     * number of entries in the cache. For all other caches, this returns the
-     * maximum sum of the sizes of the entries in this cache.
-     */
-    public synchronized final int maxSize() {
-        return maxSize;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned a value that was
-     * already present in the cache.
-     */
-    public synchronized final int hitCount() {
-        return hitCount;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned null or required a new
-     * value to be created.
-     */
-    public synchronized final int missCount() {
-        return missCount;
-    }
-
-    /**
-     * Returns the number of times {@link #create(Object)} returned a value.
-     */
-    public synchronized final int createCount() {
-        return createCount;
-    }
-
-    /**
-     * Returns the number of times {@link #put} was called.
-     */
-    public synchronized final int putCount() {
-        return putCount;
-    }
-
-    /**
-     * Returns the number of values that have been evicted.
-     */
-    public synchronized final int evictionCount() {
-        return evictionCount;
-    }
-
-    /**
-     * Returns a copy of the current contents of the cache, ordered from least
-     * recently accessed to most recently accessed.
-     */
-    public synchronized final Map<K, V> snapshot() {
-        return new LinkedHashMap<K, V>(map);
-    }
-
-    @Override public synchronized final String toString() {
-        int accesses = hitCount + missCount;
-        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;
-        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
-                maxSize, hitCount, missCount, hitPercent);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
deleted file mode 100644
index 7b69388..0000000
--- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path_Delegate;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.util.PathParser}
- * <p/>
- * Through the layoutlib_create tool, selected methods of PathParser have been replaced by calls to
- * methods of the same name in this delegate class.
- *
- * Most of the code has been taken from the implementation in
- * {@code tools/base/sdk-common/src/main/java/com/android/ide/common/vectordrawable/PathParser.java}
- * revision be6fe89a3b686db5a75e7e692a148699973957f3
- */
-public class PathParser_Delegate {
-
-    private static final Logger LOGGER = Logger.getLogger("PathParser");
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<PathParser_Delegate> sManager =
-            new DelegateManager<PathParser_Delegate>(PathParser_Delegate.class);
-
-    // ---- delegate data ----
-    @NonNull
-    private PathDataNode[] mPathDataNodes;
-
-    public static PathParser_Delegate getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    private PathParser_Delegate(@NonNull PathDataNode[] nodes) {
-        mPathDataNodes = nodes;
-    }
-
-    public PathDataNode[] getPathDataNodes() {
-        return mPathDataNodes;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nParseStringForPath(long pathPtr, @NonNull String pathString, int
-            stringLength) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(pathPtr);
-        if (path_delegate == null) {
-            return;
-        }
-        assert pathString.length() == stringLength;
-        PathDataNode.nodesToPath(createNodesFromPathData(pathString), path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCreatePathFromPathData(long outPathPtr, long pathData) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(outPathPtr);
-        PathParser_Delegate source = sManager.getDelegate(outPathPtr);
-        if (source == null || path_delegate == null) {
-            return;
-        }
-        PathDataNode.nodesToPath(source.mPathDataNodes, path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateEmptyPathData() {
-        PathParser_Delegate newDelegate = new PathParser_Delegate(new PathDataNode[0]);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathData(long nativePtr) {
-        PathParser_Delegate source = sManager.getDelegate(nativePtr);
-        if (source == null) {
-            return 0;
-        }
-        PathParser_Delegate dest = new PathParser_Delegate(deepCopyNodes(source.mPathDataNodes));
-        return sManager.addNewDelegate(dest);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataFromString(@NonNull String pathString,
-            int stringLength) {
-        assert pathString.length() == stringLength : "Inconsistent path string length.";
-        PathDataNode[] nodes = createNodesFromPathData(pathString);
-        PathParser_Delegate delegate = new PathParser_Delegate(nodes);
-        return sManager.addNewDelegate(delegate);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
-            long toDataPtr, float fraction) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        PathParser_Delegate to = sManager.getDelegate(toDataPtr);
-        if (out == null || from == null || to == null) {
-            return false;
-        }
-        int length = from.mPathDataNodes.length;
-        if (length != to.mPathDataNodes.length) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Cannot interpolate path data with different lengths (from " + length + " to " +
-                            to.mPathDataNodes.length + ").", null);
-            return false;
-        }
-        if (out.mPathDataNodes.length != length) {
-            out.mPathDataNodes = new PathDataNode[length];
-        }
-        for (int i = 0; i < length; i++) {
-            if (out.mPathDataNodes[i] == null) {
-                out.mPathDataNodes[i] = new PathDataNode(from.mPathDataNodes[i]);
-            }
-            out.mPathDataNodes[i].interpolatePathDataNode(from.mPathDataNodes[i],
-                        to.mPathDataNodes[i], fraction);
-        }
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nativePtr) {
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nCanMorph(long fromDataPtr, long toDataPtr) {
-        PathParser_Delegate fromPath = PathParser_Delegate.getDelegate(fromDataPtr);
-        PathParser_Delegate toPath = PathParser_Delegate.getDelegate(toDataPtr);
-        if (fromPath == null || toPath == null || fromPath.getPathDataNodes() == null || toPath
-                .getPathDataNodes() == null) {
-            return true;
-        }
-        return PathParser_Delegate.canMorph(fromPath.getPathDataNodes(), toPath.getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPathData(long outDataPtr, long fromDataPtr) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        if (from == null || out == null) {
-            return;
-        }
-        out.mPathDataNodes = deepCopyNodes(from.mPathDataNodes);
-    }
-
-    /**
-     * @param pathData The string representing a path, the same as "d" string in svg file.
-     *
-     * @return an array of the PathDataNode.
-     */
-    @NonNull
-    public static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
-        int start = 0;
-        int end = 1;
-
-        ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
-        while (end < pathData.length()) {
-            end = nextStart(pathData, end);
-            String s = pathData.substring(start, end).trim();
-            if (s.length() > 0) {
-                float[] val = getFloats(s);
-                addNode(list, s.charAt(0), val);
-            }
-
-            start = end;
-            end++;
-        }
-        if ((end - start) == 1 && start < pathData.length()) {
-            addNode(list, pathData.charAt(start), new float[0]);
-        }
-        return list.toArray(new PathDataNode[list.size()]);
-    }
-
-    /**
-     * @param source The array of PathDataNode to be duplicated.
-     *
-     * @return a deep copy of the <code>source</code>.
-     */
-    @NonNull
-    public static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
-        PathDataNode[] copy = new PathDataNode[source.length];
-        for (int i = 0; i < source.length; i++) {
-            copy[i] = new PathDataNode(source[i]);
-        }
-        return copy;
-    }
-
-    /**
-     * @param nodesFrom The source path represented in an array of PathDataNode
-     * @param nodesTo The target path represented in an array of PathDataNode
-     * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
-     */
-    public static boolean canMorph(PathDataNode[] nodesFrom, PathDataNode[] nodesTo) {
-        if (nodesFrom == null || nodesTo == null) {
-            return false;
-        }
-
-        if (nodesFrom.length != nodesTo.length) {
-            return false;
-        }
-
-        for (int i = 0; i < nodesFrom.length; i ++) {
-            if (nodesFrom[i].mType != nodesTo[i].mType
-                    || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Update the target's data to match the source.
-     * Before calling this, make sure canMorph(target, source) is true.
-     *
-     * @param target The target path represented in an array of PathDataNode
-     * @param source The source path represented in an array of PathDataNode
-     */
-    public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
-        for (int i = 0; i < source.length; i ++) {
-            target[i].mType = source[i].mType;
-            for (int j = 0; j < source[i].mParams.length; j ++) {
-                target[i].mParams[j] = source[i].mParams[j];
-            }
-        }
-    }
-
-    private static int nextStart(@NonNull String s, int end) {
-        char c;
-
-        while (end < s.length()) {
-            c = s.charAt(end);
-            // Note that 'e' or 'E' are not valid path commands, but could be
-            // used for floating point numbers' scientific notation.
-            // Therefore, when searching for next command, we should ignore 'e'
-            // and 'E'.
-            if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
-                    && c != 'e' && c != 'E') {
-                return end;
-            }
-            end++;
-        }
-        return end;
-    }
-
-    /**
-     * Calculate the position of the next comma or space or negative sign
-     *
-     * @param s the string to search
-     * @param start the position to start searching
-     * @param result the result of the extraction, including the position of the the starting
-     * position of next number, whether it is ending with a '-'.
-     */
-    private static void extract(@NonNull String s, int start, @NonNull ExtractFloatResult result) {
-        // Now looking for ' ', ',', '.' or '-' from the start.
-        int currentIndex = start;
-        boolean foundSeparator = false;
-        result.mEndWithNegOrDot = false;
-        boolean secondDot = false;
-        boolean isExponential = false;
-        for (; currentIndex < s.length(); currentIndex++) {
-            boolean isPrevExponential = isExponential;
-            isExponential = false;
-            char currentChar = s.charAt(currentIndex);
-            switch (currentChar) {
-                case ' ':
-                case ',':
-                    foundSeparator = true;
-                    break;
-                case '-':
-                    // The negative sign following a 'e' or 'E' is not a separator.
-                    if (currentIndex != start && !isPrevExponential) {
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case '.':
-                    if (!secondDot) {
-                        secondDot = true;
-                    } else {
-                        // This is the second dot, and it is considered as a separator.
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case 'e':
-                case 'E':
-                    isExponential = true;
-                    break;
-            }
-            if (foundSeparator) {
-                break;
-            }
-        }
-        // When there is nothing found, then we put the end position to the end
-        // of the string.
-        result.mEndPosition = currentIndex;
-    }
-
-    /**
-     * Parse the floats in the string. This is an optimized version of
-     * parseFloat(s.split(",|\\s"));
-     *
-     * @param s the string containing a command and list of floats
-     *
-     * @return array of floats
-     */
-    @NonNull
-    private static float[] getFloats(@NonNull String s) {
-        if (s.charAt(0) == 'z' || s.charAt(0) == 'Z') {
-            return new float[0];
-        }
-        try {
-            float[] results = new float[s.length()];
-            int count = 0;
-            int startPosition = 1;
-            int endPosition;
-
-            ExtractFloatResult result = new ExtractFloatResult();
-            int totalLength = s.length();
-
-            // The startPosition should always be the first character of the
-            // current number, and endPosition is the character after the current
-            // number.
-            while (startPosition < totalLength) {
-                extract(s, startPosition, result);
-                endPosition = result.mEndPosition;
-
-                if (startPosition < endPosition) {
-                    results[count++] = Float.parseFloat(
-                            s.substring(startPosition, endPosition));
-                }
-
-                if (result.mEndWithNegOrDot) {
-                    // Keep the '-' or '.' sign with next number.
-                    startPosition = endPosition;
-                } else {
-                    startPosition = endPosition + 1;
-                }
-            }
-            return Arrays.copyOf(results, count);
-        } catch (NumberFormatException e) {
-            assert false : "error in parsing \"" + s + "\"" + e;
-            return new float[0];
-        }
-    }
-
-
-    private static void addNode(@NonNull ArrayList<PathDataNode> list, char cmd,
-            @NonNull float[] val) {
-        list.add(new PathDataNode(cmd, val));
-    }
-
-    private static class ExtractFloatResult {
-        // We need to return the position of the next separator and whether the
-        // next float starts with a '-' or a '.'.
-        private int mEndPosition;
-        private boolean mEndWithNegOrDot;
-    }
-
-    /**
-     * Each PathDataNode represents one command in the "d" attribute of the svg file. An array of
-     * PathDataNode can represent the whole "d" attribute.
-     */
-    public static class PathDataNode {
-        private char mType;
-        @NonNull
-        private float[] mParams;
-
-        private PathDataNode(char type, @NonNull float[] params) {
-            mType = type;
-            mParams = params;
-        }
-
-        public char getType() {
-            return mType;
-        }
-
-        @NonNull
-        public float[] getParams() {
-            return mParams;
-        }
-
-        private PathDataNode(@NonNull PathDataNode n) {
-            mType = n.mType;
-            mParams = Arrays.copyOf(n.mParams, n.mParams.length);
-        }
-
-        /**
-         * Convert an array of PathDataNode to Path. Reset the passed path as needed before
-         * calling this method.
-         *
-         * @param node The source array of PathDataNode.
-         * @param path The target Path object.
-         */
-        public static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path_Delegate path) {
-            float[] current = new float[6];
-            char previousCommand = 'm';
-            //noinspection ForLoopReplaceableByForEach
-            for (int i = 0; i < node.length; i++) {
-                addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
-                previousCommand = node[i].mType;
-            }
-        }
-
-        /**
-         * The current PathDataNode will be interpolated between the <code>nodeFrom</code> and
-         * <code>nodeTo</code> according to the <code>fraction</code>.
-         *
-         * @param nodeFrom The start value as a PathDataNode.
-         * @param nodeTo The end value as a PathDataNode
-         * @param fraction The fraction to interpolate.
-         */
-        private void interpolatePathDataNode(@NonNull PathDataNode nodeFrom,
-                @NonNull PathDataNode nodeTo, float fraction) {
-            for (int i = 0; i < nodeFrom.mParams.length; i++) {
-                mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
-                        + nodeTo.mParams[i] * fraction;
-            }
-        }
-
-        @SuppressWarnings("PointlessArithmeticExpression")
-        private static void addCommand(@NonNull Path_Delegate path, float[] current,
-                char previousCmd, char cmd, @NonNull float[] val) {
-
-            int incr = 2;
-            float currentX = current[0];
-            float currentY = current[1];
-            float ctrlPointX = current[2];
-            float ctrlPointY = current[3];
-            float currentSegmentStartX = current[4];
-            float currentSegmentStartY = current[5];
-            float reflectiveCtrlPointX;
-            float reflectiveCtrlPointY;
-
-            switch (cmd) {
-                case 'z':
-                case 'Z':
-                    path.close();
-                    // Path is closed here, but we need to move the pen to the
-                    // closed position. So we cache the segment's starting position,
-                    // and restore it here.
-                    currentX = currentSegmentStartX;
-                    currentY = currentSegmentStartY;
-                    ctrlPointX = currentSegmentStartX;
-                    ctrlPointY = currentSegmentStartY;
-                    path.moveTo(currentX, currentY);
-                    break;
-                case 'm':
-                case 'M':
-                case 'l':
-                case 'L':
-                case 't':
-                case 'T':
-                    incr = 2;
-                    break;
-                case 'h':
-                case 'H':
-                case 'v':
-                case 'V':
-                    incr = 1;
-                    break;
-                case 'c':
-                case 'C':
-                    incr = 6;
-                    break;
-                case 's':
-                case 'S':
-                case 'q':
-                case 'Q':
-                    incr = 4;
-                    break;
-                case 'a':
-                case 'A':
-                    incr = 7;
-                    break;
-            }
-
-            for (int k = 0; k < val.length; k += incr) {
-                switch (cmd) {
-                    case 'm': // moveto - Start a new sub-path (relative)
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.rLineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.rMoveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'M': // moveto - Start a new sub-path
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.lineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.moveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'l': // lineto - Draw a line from the current point (relative)
-                        path.rLineTo(val[k + 0], val[k + 1]);
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'L': // lineto - Draw a line from the current point
-                        path.lineTo(val[k + 0], val[k + 1]);
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'h': // horizontal lineto - Draws a horizontal line (relative)
-                        path.rLineTo(val[k + 0], 0);
-                        currentX += val[k + 0];
-                        break;
-                    case 'H': // horizontal lineto - Draws a horizontal line
-                        path.lineTo(val[k + 0], currentY);
-                        currentX = val[k + 0];
-                        break;
-                    case 'v': // vertical lineto - Draws a vertical line from the current point (r)
-                        path.rLineTo(0, val[k + 0]);
-                        currentY += val[k + 0];
-                        break;
-                    case 'V': // vertical lineto - Draws a vertical line from the current point
-                        path.lineTo(currentX, val[k + 0]);
-                        currentY = val[k + 0];
-                        break;
-                    case 'c': // curveto - Draws a cubic Bézier curve (relative)
-                        path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-
-                        ctrlPointX = currentX + val[k + 2];
-                        ctrlPointY = currentY + val[k + 3];
-                        currentX += val[k + 4];
-                        currentY += val[k + 5];
-
-                        break;
-                    case 'C': // curveto - Draws a cubic Bézier curve
-                        path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-                        currentX = val[k + 4];
-                        currentY = val[k + 5];
-                        ctrlPointX = val[k + 2];
-                        ctrlPointY = val[k + 3];
-                        break;
-                    case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1],
-                                val[k + 2], val[k + 3]);
-
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 'q': // Draws a quadratic Bézier (relative)
-                        path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'Q': // Draws a quadratic Bézier
-                        path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = currentX + reflectiveCtrlPointX;
-                        ctrlPointY = currentY + reflectiveCtrlPointY;
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'T': // Draws a quadratic Bézier curve (reflective control point)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = reflectiveCtrlPointX;
-                        ctrlPointY = reflectiveCtrlPointY;
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'a': // Draws an elliptical arc
-                        // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5] + currentX,
-                                val[k + 6] + currentY,
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX += val[k + 5];
-                        currentY += val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                    case 'A': // Draws an elliptical arc
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5],
-                                val[k + 6],
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX = val[k + 5];
-                        currentY = val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                }
-                previousCmd = cmd;
-            }
-            current[0] = currentX;
-            current[1] = currentY;
-            current[2] = ctrlPointX;
-            current[3] = ctrlPointY;
-            current[4] = currentSegmentStartX;
-            current[5] = currentSegmentStartY;
-        }
-
-        private static void drawArc(@NonNull Path_Delegate p, float x0, float y0, float x1,
-                float y1, float a, float b, float theta, boolean isMoreThanHalf,
-                boolean isPositiveArc) {
-
-            LOGGER.log(Level.FINE, "(" + x0 + "," + y0 + ")-(" + x1 + "," + y1
-                    + ") {" + a + " " + b + "}");
-        /* Convert rotation angle from degrees to radians */
-            double thetaD = theta * Math.PI / 180.0f;
-        /* Pre-compute rotation matrix entries */
-            double cosTheta = Math.cos(thetaD);
-            double sinTheta = Math.sin(thetaD);
-        /* Transform (x0, y0) and (x1, y1) into unit space */
-        /* using (inverse) rotation, followed by (inverse) scale */
-            double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
-            double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
-            double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
-            double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
-            LOGGER.log(Level.FINE, "unit space (" + x0p + "," + y0p + ")-(" + x1p
-                    + "," + y1p + ")");
-        /* Compute differences and averages */
-            double dx = x0p - x1p;
-            double dy = y0p - y1p;
-            double xm = (x0p + x1p) / 2;
-            double ym = (y0p + y1p) / 2;
-        /* Solve for intersecting unit circles */
-            double dsq = dx * dx + dy * dy;
-            if (dsq == 0.0) {
-                LOGGER.log(Level.FINE, " Points are coincident");
-                return; /* Points are coincident */
-            }
-            double disc = 1.0 / dsq - 1.0 / 4.0;
-            if (disc < 0.0) {
-                LOGGER.log(Level.FINE, "Points are too far apart " + dsq);
-                float adjust = (float) (Math.sqrt(dsq) / 1.99999);
-                drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta,
-                        isMoreThanHalf, isPositiveArc);
-                return; /* Points are too far apart */
-            }
-            double s = Math.sqrt(disc);
-            double sdx = s * dx;
-            double sdy = s * dy;
-            double cx;
-            double cy;
-            if (isMoreThanHalf == isPositiveArc) {
-                cx = xm - sdy;
-                cy = ym + sdx;
-            } else {
-                cx = xm + sdy;
-                cy = ym - sdx;
-            }
-
-            double eta0 = Math.atan2((y0p - cy), (x0p - cx));
-            LOGGER.log(Level.FINE, "eta0 = Math.atan2( " + (y0p - cy) + " , "
-                    + (x0p - cx) + ") = " + Math.toDegrees(eta0));
-
-            double eta1 = Math.atan2((y1p - cy), (x1p - cx));
-            LOGGER.log(Level.FINE, "eta1 = Math.atan2( " + (y1p - cy) + " , "
-                    + (x1p - cx) + ") = " + Math.toDegrees(eta1));
-            double sweep = (eta1 - eta0);
-            if (isPositiveArc != (sweep >= 0)) {
-                if (sweep > 0) {
-                    sweep -= 2 * Math.PI;
-                } else {
-                    sweep += 2 * Math.PI;
-                }
-            }
-
-            cx *= a;
-            cy *= b;
-            double tcx = cx;
-            cx = cx * cosTheta - cy * sinTheta;
-            cy = tcx * sinTheta + cy * cosTheta;
-            LOGGER.log(
-                    Level.FINE,
-                    "cx, cy, a, b, x0, y0, thetaD, eta0, sweep = " + cx + " , "
-                            + cy + " , " + a + " , " + b + " , " + x0 + " , " + y0
-                            + " , " + Math.toDegrees(thetaD) + " , "
-                            + Math.toDegrees(eta0) + " , " + Math.toDegrees(sweep));
-
-            arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
-        }
-
-        /**
-         * Converts an arc to cubic Bezier segments and records them in p.
-         *
-         * @param p The target for the cubic Bezier segments
-         * @param cx The x coordinate center of the ellipse
-         * @param cy The y coordinate center of the ellipse
-         * @param a The radius of the ellipse in the horizontal direction
-         * @param b The radius of the ellipse in the vertical direction
-         * @param e1x E(eta1) x coordinate of the starting point of the arc
-         * @param e1y E(eta2) y coordinate of the starting point of the arc
-         * @param theta The angle that the ellipse bounding rectangle makes with the horizontal
-         * plane
-         * @param start The start angle of the arc on the ellipse
-         * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
-         */
-        private static void arcToBezier(@NonNull Path_Delegate p, double cx, double cy, double a,
-                double b, double e1x, double e1y, double theta, double start,
-                double sweep) {
-            // Taken from equations at:
-            // http://spaceroots.org/documents/ellipse/node8.html
-            // and http://www.spaceroots.org/documents/ellipse/node22.html
-            // Maximum of 45 degrees per cubic Bezier segment
-            int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
-
-
-            double eta1 = start;
-            double cosTheta = Math.cos(theta);
-            double sinTheta = Math.sin(theta);
-            double cosEta1 = Math.cos(eta1);
-            double sinEta1 = Math.sin(eta1);
-            double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
-            double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
-
-            double anglePerSegment = sweep / numSegments;
-            for (int i = 0; i < numSegments; i++) {
-                double eta2 = eta1 + anglePerSegment;
-                double sinEta2 = Math.sin(eta2);
-                double cosEta2 = Math.cos(eta2);
-                double e2x = cx + (a * cosTheta * cosEta2)
-                        - (b * sinTheta * sinEta2);
-                double e2y = cy + (a * sinTheta * cosEta2)
-                        + (b * cosTheta * sinEta2);
-                double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
-                double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
-                double tanDiff2 = Math.tan((eta2 - eta1) / 2);
-                double alpha = Math.sin(eta2 - eta1)
-                        * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
-                double q1x = e1x + alpha * ep1x;
-                double q1y = e1y + alpha * ep1y;
-                double q2x = e2x - alpha * ep2x;
-                double q2y = e2y - alpha * ep2y;
-
-                p.cubicTo((float) q1x,
-                        (float) q1y,
-                        (float) q2x,
-                        (float) q2y,
-                        (float) e2x,
-                        (float) e2y);
-                eta1 = eta2;
-                e1x = e2x;
-                e1y = e2y;
-                ep1x = ep2x;
-                ep1y = ep2y;
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java b/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
deleted file mode 100644
index 213e848..0000000
--- a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
+++ /dev/null
@@ -1,45 +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 android.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * Delegate overriding some methods of android.util.Xml
- *
- * Through the layoutlib_create tool, the original methods of Xml have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class Xml_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static XmlPullParser newPullParser() {
-        try {
-            return ParserFactory.instantiateParser(null);
-        } catch (XmlPullParserException e) {
-            throw new AssertionError();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
deleted file mode 100644
index 4445a22..0000000
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeWindow;
-import com.android.layoutlib.bridge.android.BridgeWindowSession;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.View.AttachInfo;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class AttachInfo_Accessor {
-
-    public static void setAttachInfo(View view) {
-        Context context = view.getContext();
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
-        ViewRootImpl root = new ViewRootImpl(context, display);
-        AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
-                display, root, new Handler(), null, context);
-        info.mHasWindowFocus = true;
-        info.mWindowVisibility = View.VISIBLE;
-        info.mInTouchMode = false; // this is so that we can display selections.
-        info.mHardwareAccelerated = false;
-        view.dispatchAttachedToWindow(info, 0);
-    }
-
-    public static void dispatchOnPreDraw(View view) {
-        view.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
-    }
-
-    public static void detachFromWindow(View view) {
-        if (view != null) {
-            view.dispatchDetachedFromWindow();
-        }
-    }
-
-    public static ViewRootImpl getRootView(View view) {
-        return view.mAttachInfo != null ? view.mAttachInfo.mViewRootImpl : null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
deleted file mode 100644
index b6e6ec0..0000000
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.MergeCookie;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
-import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-import android.widget.NumberPicker;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static com.android.SdkConstants.AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.BUTTON;
-import static com.android.SdkConstants.CHECKED_TEXT_VIEW;
-import static com.android.SdkConstants.CHECK_BOX;
-import static com.android.SdkConstants.EDIT_TEXT;
-import static com.android.SdkConstants.IMAGE_BUTTON;
-import static com.android.SdkConstants.IMAGE_VIEW;
-import static com.android.SdkConstants.MULTI_AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.RADIO_BUTTON;
-import static com.android.SdkConstants.SEEK_BAR;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TEXT_VIEW;
-import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
-
-/**
- * Custom implementation of {@link LayoutInflater} to handle custom views.
- */
-public final class BridgeInflater extends LayoutInflater {
-
-    private final LayoutlibCallback mLayoutlibCallback;
-    /**
-     * If true, the inflater will try to replace the framework widgets with the AppCompat versions.
-     * Ideally, this should be based on the activity being an AppCompat activity but since that is
-     * not trivial to check from layoutlib, we currently base the decision on the current theme
-     * being an AppCompat theme.
-     */
-    private boolean mLoadAppCompatViews;
-    /**
-     * This set contains the framework views that have an AppCompat version but failed to load.
-     * This might happen because not all widgets are contained in all versions of the support
-     * library.
-     * This will help us to avoid trying to load the AppCompat version multiple times if it
-     * doesn't exist.
-     */
-    private Set<String> mFailedAppCompatViews = new HashSet<>();
-    private boolean mIsInMerge = false;
-    private ResourceReference mResourceReference;
-    private Map<View, String> mOpenDrawerLayouts;
-
-    // Keep in sync with the same value in LayoutInflater.
-    private static final int[] ATTRS_THEME = new int[] {com.android.internal.R.attr.theme };
-
-    private static final String APPCOMPAT_WIDGET_PREFIX = "android.support.v7.widget.AppCompat";
-    /** List of platform widgets that have an AppCompat version */
-    private static final Set<String> APPCOMPAT_VIEWS = Collections.unmodifiableSet(
-            new HashSet<>(
-                    Arrays.asList(TEXT_VIEW, IMAGE_VIEW, BUTTON, EDIT_TEXT, SPINNER,
-                            IMAGE_BUTTON, CHECK_BOX, RADIO_BUTTON, CHECKED_TEXT_VIEW,
-                            AUTO_COMPLETE_TEXT_VIEW, MULTI_AUTO_COMPLETE_TEXT_VIEW, "RatingBar",
-                            SEEK_BAR)));
-
-    /**
-     * List of class prefixes which are tried first by default.
-     * <p/>
-     * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
-     */
-    private static final String[] sClassPrefixList = {
-        "android.widget.",
-        "android.webkit.",
-        "android.app."
-    };
-
-    public static String[] getClassPrefixList() {
-        return sClassPrefixList;
-    }
-
-    private BridgeInflater(LayoutInflater original, Context newContext) {
-        super(original, newContext);
-        newContext = getBaseContext(newContext);
-        if (newContext instanceof BridgeContext) {
-            mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
-            mLoadAppCompatViews = ((BridgeContext) newContext).isAppCompatTheme();
-        } else {
-            mLayoutlibCallback = null;
-            mLoadAppCompatViews = false;
-        }
-    }
-
-    /**
-     * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
-     *
-     * @param context The Android application context.
-     * @param layoutlibCallback the {@link LayoutlibCallback} object.
-     */
-    public BridgeInflater(BridgeContext context, LayoutlibCallback layoutlibCallback) {
-        super(context);
-        mLayoutlibCallback = layoutlibCallback;
-        mConstructorArgs[0] = context;
-        mLoadAppCompatViews = context.isAppCompatTheme();
-    }
-
-    @Override
-    public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
-        View view = null;
-
-        try {
-            if (mLoadAppCompatViews
-                    && APPCOMPAT_VIEWS.contains(name)
-                    && !mFailedAppCompatViews.contains(name)) {
-                // We are using an AppCompat theme so try to load the appcompat views
-                view = loadCustomView(APPCOMPAT_WIDGET_PREFIX + name, attrs, true);
-
-                if (view == null) {
-                    mFailedAppCompatViews.add(name); // Do not try this one anymore
-                }
-            }
-
-            if (view == null) {
-                // First try to find a class using the default Android prefixes
-                for (String prefix : sClassPrefixList) {
-                    try {
-                        view = createView(name, prefix, attrs);
-                        if (view != null) {
-                            break;
-                        }
-                    } catch (ClassNotFoundException e) {
-                        // Ignore. We'll try again using the base class below.
-                    }
-                }
-
-                // Next try using the parent loader. This will most likely only work for
-                // fully-qualified class names.
-                try {
-                    if (view == null) {
-                        view = super.onCreateView(name, attrs);
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore. We'll try again using the custom view loader below.
-                }
-            }
-
-            // Finally try again using the custom view loader
-            if (view == null) {
-                view = loadCustomView(name, attrs);
-            }
-        } catch (InflateException e) {
-            // Don't catch the InflateException below as that results in hiding the real cause.
-            throw e;
-        } catch (Exception e) {
-            // Wrap the real exception in a ClassNotFoundException, so that the calling method
-            // can deal with it.
-            throw new ClassNotFoundException("onCreateView", e);
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
-            boolean ignoreThemeAttr) {
-        View view = null;
-        if (name.equals("view")) {
-            // This is usually done by the superclass but this allows us catching the error and
-            // reporting something useful.
-            name = attrs.getAttributeValue(null, "class");
-
-            if (name == null) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to inflate view tag without " +
-                  "class attribute", null);
-                // We weren't able to resolve the view so we just pass a mock View to be able to
-                // continue rendering.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText("view");
-            }
-        }
-
-        try {
-            if (view == null) {
-                view = super.createViewFromTag(parent, name, context, attrs, ignoreThemeAttr);
-            }
-        } catch (InflateException e) {
-            // Creation of ContextThemeWrapper code is same as in the super method.
-            // Apply a theme wrapper, if allowed and one is specified.
-            if (!ignoreThemeAttr) {
-                final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-                final int themeResId = ta.getResourceId(0, 0);
-                if (themeResId != 0) {
-                    context = new ContextThemeWrapper(context, themeResId);
-                }
-                ta.recycle();
-            }
-            if (!(e.getCause() instanceof ClassNotFoundException)) {
-                // There is some unknown inflation exception in inflating a View that was found.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText(name);
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null);
-            } else {
-                final Object lastContext = mConstructorArgs[0];
-                mConstructorArgs[0] = context;
-                // try to load the class from using the custom view loader
-                try {
-                    view = loadCustomView(name, attrs);
-                } catch (Exception e2) {
-                    // Wrap the real exception in an InflateException so that the calling
-                    // method can deal with it.
-                    InflateException exception = new InflateException();
-                    if (!e2.getClass().equals(ClassNotFoundException.class)) {
-                        exception.initCause(e2);
-                    } else {
-                        exception.initCause(e);
-                    }
-                    throw exception;
-                } finally {
-                    mConstructorArgs[0] = lastContext;
-                }
-            }
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View inflate(int resource, ViewGroup root) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bridgeContext = (BridgeContext)context;
-
-            ResourceValue value = null;
-
-            @SuppressWarnings("deprecation")
-            Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
-            if (layoutInfo != null) {
-                value = bridgeContext.getRenderResources().getFrameworkResource(
-                        ResourceType.LAYOUT, layoutInfo.getSecond());
-            } else {
-                layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
-
-                if (layoutInfo != null) {
-                    value = bridgeContext.getRenderResources().getProjectResource(
-                            ResourceType.LAYOUT, layoutInfo.getSecond());
-                }
-            }
-
-            if (value != null) {
-                File f = new File(value.getValue());
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f, true);
-
-                        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
-                                parser, bridgeContext, value.isFramework());
-
-                        return inflate(bridgeParser, root);
-                    } catch (Exception e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                                "Failed to parse file " + f.getAbsolutePath(), e, null);
-
-                        return null;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Instantiates the given view name and returns the instance. If the view doesn't exist, a
-     * MockView or null might be returned.
-     * @param name the custom view name
-     * @param attrs the {@link AttributeSet} to be passed to the view constructor
-     * @param silent if true, errors while loading the view won't be reported and, if the view
-     * doesn't exist, null will be returned.
-     */
-    private View loadCustomView(String name, AttributeSet attrs, boolean silent) throws Exception {
-        if (mLayoutlibCallback != null) {
-            // first get the classname in case it's not the node name
-            if (name.equals("view")) {
-                name = attrs.getAttributeValue(null, "class");
-                if (name == null) {
-                    return null;
-                }
-            }
-
-            mConstructorArgs[1] = attrs;
-
-            Object customView = silent ?
-                    mLayoutlibCallback.loadClass(name, mConstructorSignature, mConstructorArgs)
-                    : mLayoutlibCallback.loadView(name, mConstructorSignature, mConstructorArgs);
-
-            if (customView instanceof View) {
-                return (View)customView;
-            }
-        }
-
-        return null;
-    }
-
-    private View loadCustomView(String name, AttributeSet attrs) throws Exception {
-        return loadCustomView(name, attrs, false);
-    }
-
-    private void setupViewInContext(View view, AttributeSet attrs) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bc = (BridgeContext) context;
-            // get the view key
-            Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge);
-            if (viewKey != null) {
-                bc.addViewKey(view, viewKey);
-            }
-            String scrollPosX = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollX");
-            if (scrollPosX != null && scrollPosX.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosX.substring(0, scrollPosX.length() - 2));
-                bc.setScrollXPos(view, value);
-            }
-            String scrollPosY = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY");
-            if (scrollPosY != null && scrollPosY.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosY.substring(0, scrollPosY.length() - 2));
-                bc.setScrollYPos(view, value);
-            }
-            if (ReflectionUtils.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) {
-                Integer resourceId = null;
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_LIST_ITEM);
-                if (attrVal != null && !attrVal.isEmpty()) {
-                    ResourceValue resValue = bc.getRenderResources().findResValue(attrVal, false);
-                    if (resValue.isFramework()) {
-                        resourceId = Bridge.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    } else {
-                        resourceId = mLayoutlibCallback.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    }
-                }
-                if (resourceId == null) {
-                    resourceId = 0;
-                }
-                RecyclerViewUtil.setAdapter(view, bc, mLayoutlibCallback, resourceId);
-            } else if (ReflectionUtils.isInstanceOf(view, DrawerLayoutUtil.CN_DRAWER_LAYOUT)) {
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_OPEN_DRAWER);
-                if (attrVal != null) {
-                    getDrawerLayoutMap().put(view, attrVal);
-                }
-            }
-            else if (view instanceof NumberPicker) {
-                NumberPicker numberPicker = (NumberPicker) view;
-                String minValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "minValue");
-                if (minValue != null) {
-                    numberPicker.setMinValue(Integer.parseInt(minValue));
-                }
-                String maxValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "maxValue");
-                if (maxValue != null) {
-                    numberPicker.setMaxValue(Integer.parseInt(maxValue));
-                }
-            }
-            else if (view instanceof ImageView) {
-                ImageView img = (ImageView) view;
-                Drawable drawable = img.getDrawable();
-                if (drawable instanceof Animatable) {
-                    if (!((Animatable) drawable).isRunning()) {
-                        ((Animatable) drawable).start();
-                    }
-                }
-            }
-
-        }
-    }
-
-    public void setIsInMerge(boolean isInMerge) {
-        mIsInMerge = isInMerge;
-    }
-
-    public void setResourceReference(ResourceReference reference) {
-        mResourceReference = reference;
-    }
-
-    @Override
-    public LayoutInflater cloneInContext(Context newContext) {
-        return new BridgeInflater(this, newContext);
-    }
-
-    /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc,
-            ResourceReference resourceReference, boolean isInMerge) {
-
-        if (!(attrs instanceof BridgeXmlBlockParser)) {
-            return null;
-        }
-        BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs);
-
-        // get the view key
-        Object viewKey = parser.getViewCookie();
-
-        if (viewKey == null) {
-            int currentDepth = parser.getDepth();
-
-            // test whether we are in an included file or in a adapter binding view.
-            BridgeXmlBlockParser previousParser = bc.getPreviousParser();
-            if (previousParser != null) {
-                // looks like we are inside an embedded layout.
-                // only apply the cookie of the calling node (<include>) if we are at the
-                // top level of the embedded layout. If there is a merge tag, then
-                // skip it and look for the 2nd level
-                int testDepth = isInMerge ? 2 : 1;
-                if (currentDepth == testDepth) {
-                    viewKey = previousParser.getViewCookie();
-                    // if we are in a merge, wrap the cookie in a MergeCookie.
-                    if (viewKey != null && isInMerge) {
-                        viewKey = new MergeCookie(viewKey);
-                    }
-                }
-            } else if (resourceReference != null && currentDepth == 1) {
-                // else if there's a resource reference, this means we are in an adapter
-                // binding case. Set the resource ref as the view cookie only for the top
-                // level view.
-                viewKey = resourceReference;
-            }
-        }
-
-        return viewKey;
-    }
-
-    public void postInflateProcess(View view) {
-        if (mOpenDrawerLayouts != null) {
-            String gravity = mOpenDrawerLayouts.get(view);
-            if (gravity != null) {
-                DrawerLayoutUtil.openDrawer(view, gravity);
-            }
-            mOpenDrawerLayouts.remove(view);
-        }
-    }
-
-    @NonNull
-    private Map<View, String> getDrawerLayoutMap() {
-        if (mOpenDrawerLayouts == null) {
-            mOpenDrawerLayouts = new HashMap<View, String>(4);
-        }
-        return mOpenDrawerLayouts;
-    }
-
-    public void onDoneInflation() {
-        if (mOpenDrawerLayouts != null) {
-            mOpenDrawerLayouts.clear();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
deleted file mode 100644
index 494ffa1..0000000
--- a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
- *
- * Through the layoutlib_create tool, the original  methods of Choreographer have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class Choreographer_Delegate {
-    static final AtomicReference<Choreographer> mInstance = new AtomicReference<Choreographer>();
-
-    @LayoutlibDelegate
-    public static Choreographer getInstance() {
-        if (mInstance.get() == null) {
-            mInstance.compareAndSet(null, Choreographer.getInstance_Original());
-        }
-
-        return mInstance.get();
-    }
-
-    @LayoutlibDelegate
-    public static float getRefreshRate() {
-        return 60.f;
-    }
-
-    @LayoutlibDelegate
-    static void scheduleVsyncLocked(Choreographer thisChoreographer) {
-        // do nothing
-    }
-
-    public static void doFrame(long frameTimeNanos) {
-        Choreographer thisChoreographer = Choreographer.getInstance();
-
-        thisChoreographer.mLastFrameTimeNanos = frameTimeNanos - thisChoreographer
-                .getFrameIntervalNanos();
-        thisChoreographer.mFrameInfo.markInputHandlingStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markAnimationsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markPerformTraversalsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
-
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
-    }
-
-    public static void dispose() {
-        try {
-            Field threadInstanceField = Choreographer.class.getDeclaredField("sThreadInstance");
-            threadInstanceField.setAccessible(true);
-            @SuppressWarnings("unchecked") ThreadLocal<Choreographer> threadInstance =
-                    (ThreadLocal<Choreographer>) threadInstanceField.get(null);
-            threadInstance.remove();
-        } catch (ReflectiveOperationException e) {
-            assert false;
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to clear Choreographer memory.", e, null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
deleted file mode 100644
index 53dc821..0000000
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Display}
- *
- * Through the layoutlib_create tool, the original  methods of Display have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Display_Delegate {
-
-    @LayoutlibDelegate
-    static void updateDisplayInfoLocked(Display theDisplay) {
-        // do nothing
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java b/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
deleted file mode 100644
index e580ed0..0000000
--- a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
+++ /dev/null
@@ -1,37 +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 android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link HandlerActionQueue}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl.RunQueue have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class HandlerActionQueue_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void postDelayed(HandlerActionQueue thisQueue, Runnable action, long
-            delayMillis) {
-        // The actual HandlerActionQueue is never run and therefore never cleared. This method
-        // avoids runnables to be added to the RunQueue so they do not leak resources.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
deleted file mode 100644
index deb0e09..0000000
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-
-import com.android.internal.app.IAssistScreenshotReceiver;
-import com.android.internal.os.IResultReceiver;
-import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.policy.IShortcutService;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
-/**
- * Basic implementation of {@link IWindowManager} so that {@link Display} (and
- * {@link Display_Delegate}) can return a valid instance.
- */
-public class IWindowManagerImpl implements IWindowManager {
-
-    private final Configuration mConfig;
-    private final DisplayMetrics mMetrics;
-    private final int mRotation;
-    private final boolean mHasNavigationBar;
-
-    public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
-            boolean hasNavigationBar) {
-        mConfig = config;
-        mMetrics = metrics;
-        mRotation = rotation;
-        mHasNavigationBar = hasNavigationBar;
-    }
-
-    // custom API.
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    // ---- implementation of IWindowManager that we care about ----
-
-    @Override
-    public int getDefaultDisplayRotation() throws RemoteException {
-        return mRotation;
-    }
-
-    @Override
-    public boolean hasNavigationBar() {
-        return mHasNavigationBar;
-    }
-
-    // ---- unused implementation of IWindowManager ----
-
-    @Override
-    public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearForcedDisplaySize(int displayId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void clearForcedDisplayDensityForUser(int displayId, int userId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setOverscan(int displayId, int left, int top, int right, int bottom)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void closeSystemDialogs(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startFreezingScreen(int exitAnim, int enterAnim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void stopFreezingScreen() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void executeAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void exitKeyguardSecurely(IOnKeyguardExitResult arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void freezeRotation(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getAnimationScale(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public float[] getAnimationScales() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPendingAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean inKeyguardRestrictedInputMode() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardLocked() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardSecure() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isViewServerRunning() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public IWindowSession openSession(IWindowSessionCallback argn1, IInputMethodClient arg0,
-            IInputContext arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void overridePendingAppTransition(String arg0, int arg1, int arg2,
-            IRemoteCallback startedCallback) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
-            int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionClipReveal(int startX, int startY,
-            int startWidth, int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
-            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
-            boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionInPlace(String packageName, int anim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumbFuture(
-            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
-            boolean scaleUp) throws RemoteException {
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
-            IRemoteCallback callback0, IRemoteCallback callback1, boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void reenableKeyguard(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setAnimationScale(int arg0, float arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAnimationScales(float[] arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getCurrentAnimatorScale() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setEventDispatching(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setFocusedApp(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getInitialDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getBaseDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplaySize(int displayId, int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int getInitialDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public int getBaseDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public void setForcedDisplayDensityForUser(int displayId, int density, int userId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplayScalingMode(int displayId, int mode) {
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int[] setNewDisplayOverrideConfiguration(Configuration arg0, int displayId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setScreenCaptureDisabled(int userId, boolean disabled) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setStrictModeVisualIndicatorPreference(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void showStrictModeViolation(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean startViewServer(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void statusBarVisibilityChanged(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setRecentsVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setPipVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean stopViewServer() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void thawRotation() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int watchRotation(IRotationWatcher arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void removeRotationWatcher(IRotationWatcher arg0) throws RemoteException {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPreferredOptionsPanelGravity() throws RemoteException {
-        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    }
-
-    @Override
-    public void dismissKeyguard(IKeyguardDismissCallback callback) throws RemoteException {
-    }
-
-    @Override
-    public void setSwitchingUser(boolean switching) throws RemoteException {
-    }
-
-    @Override
-    public void lockNow(Bundle options) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean isSafeModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public boolean isRotationFrozen() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void enableScreenIfNeeded() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean clearWindowContentFrameStats(IBinder token) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public WindowContentFrameStats getWindowContentFrameStats(IBinder token)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getDockedStackSide() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setDockedStackResizing(boolean resizing) throws RemoteException {
-    }
-
-    @Override
-    public void endProlongedAnimations() {
-    }
-
-    @Override
-    public void registerDockedStackListener(IDockedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void setResizeDimLayer(boolean visible, int targetStackId, float alpha)
-            throws RemoteException {
-    }
-
-    @Override
-    public void setDockedStackDividerTouchRegion(Rect touchableRegion) throws RemoteException {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
-    }
-
-    @Override
-    public void registerShortcutKey(long shortcutCode, IShortcutService service)
-        throws RemoteException {}
-
-    @Override
-    public void createInputConsumer(String name, InputChannel inputChannel)
-            throws RemoteException {}
-
-    @Override
-    public boolean destroyInputConsumer(String name) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public Bitmap screenshotWallpaper() throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public void enableSurfaceTrace(ParcelFileDescriptor fd) throws RemoteException {
-    }
-
-    @Override
-    public void disableSurfaceTrace() throws RemoteException {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
deleted file mode 100644
index cec6bb3..0000000
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.util.Xml;
-
-import java.io.IOException;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
- *
- * Through the layoutlib_create tool, the original  methods of LayoutInflater have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class LayoutInflater_Delegate {
-    private static final String TAG_MERGE = "merge";
-
-    private static final String ATTR_LAYOUT = "layout";
-
-    private static final int[] ATTRS_THEME = new int[] {
-            com.android.internal.R.attr.theme };
-
-    public static boolean sIsInInclude = false;
-
-    /**
-     * Recursive method used to descend down the xml hierarchy and instantiate
-     * views, instantiate their children, and then call onFinishInflate().
-     *
-     * This implementation just records the merge status before calling the default implementation.
-     */
-    @LayoutlibDelegate
-    /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
-            View parent, Context context, AttributeSet attrs, boolean finishInflate)
-            throws XmlPullParserException, IOException {
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(true);
-            }
-        }
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        thisInflater.rInflate_Original(parser, parent, context, attrs, finishInflate);
-
-        // ---- END DEFAULT IMPLEMENTATION.
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(false);
-            }
-        }
-    }
-
-    @LayoutlibDelegate
-    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser,
-            Context context, View parent, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-        int type;
-
-        if (parent instanceof ViewGroup) {
-            // Apply a theme wrapper, if requested. This is sort of a weird
-            // edge case, since developers think the <include> overwrites
-            // values in the AttributeSet of the included View. So, if the
-            // included View has a theme attribute, we'll need to ignore it.
-            final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-            final int themeResId = ta.getResourceId(0, 0);
-            final boolean hasThemeOverride = themeResId != 0;
-            if (hasThemeOverride) {
-                context = new ContextThemeWrapper(context, themeResId);
-            }
-            ta.recycle();
-
-            // If the layout is pointing to a theme attribute, we have to
-            // massage the value to get a resource identifier out of it.
-            int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null || value.length() <= 0) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                    LayoutInflater.consumeChildElements(parser);
-                    return;
-                }
-
-                // Attempt to resolve the "?attr/name" string to an identifier.
-                layout = context.getResources().getIdentifier(value.substring(1), null, null);
-            }
-
-            // The layout might be referencing a theme attribute.
-            // ---- START CHANGES
-            if (layout != 0) {
-                final TypedValue tempValue = new TypedValue();
-                if (context.getTheme().resolveAttribute(layout, tempValue, true)) {
-                    layout = tempValue.resourceId;
-                }
-            }
-            // ---- END CHANGES
-
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout "
-                            + "reference. The layout ID " + value + " is not valid.", null);
-                }
-            } else {
-                final XmlResourceParser childParser =
-                    thisInflater.getContext().getResources().getLayout(layout);
-
-                try {
-                    final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
-
-                    while ((type = childParser.next()) != XmlPullParser.START_TAG &&
-                            type != XmlPullParser.END_DOCUMENT) {
-                        // Empty.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                                childParser.getPositionDescription() + ": No start tag found!",
-                                null);
-                        LayoutInflater.consumeChildElements(parser);
-                        return;
-                    }
-
-                    final String childName = childParser.getName();
-
-                    if (TAG_MERGE.equals(childName)) {
-                        // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, context, childAttrs, false);
-                    } else {
-                        final View view = thisInflater.createViewFromTag(parent, childName,
-                                context, childAttrs, hasThemeOverride);
-                        final ViewGroup group = (ViewGroup) parent;
-
-                        final TypedArray a = context.obtainStyledAttributes(
-                                attrs, com.android.internal.R.styleable.Include);
-                        final int id = a.getResourceId(
-                                com.android.internal.R.styleable.Include_id, View.NO_ID);
-                        final int visibility = a.getInt(
-                                com.android.internal.R.styleable.Include_visibility, -1);
-                        a.recycle();
-
-                        // We try to load the layout params set in the <include /> tag. If
-                        // they don't exist, we will rely on the layout params set in the
-                        // included XML file.
-                        // During a layoutparams generation, a runtime exception is thrown
-                        // if either layout_width or layout_height is missing. We catch
-                        // this exception and set localParams accordingly: true means we
-                        // successfully loaded layout params from the <include /> tag,
-                        // false means we need to rely on the included layout params.
-                        ViewGroup.LayoutParams params = null;
-                        try {
-                            // ---- START CHANGES
-                            sIsInInclude = true;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(attrs);
-                        } catch (RuntimeException ignored) {
-                            // Ignore, just fail over to child attrs.
-                        } finally {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-                        }
-                        if (params == null) {
-                            params = group.generateLayoutParams(childAttrs);
-                        }
-                        view.setLayoutParams(params);
-
-                        // Inflate all children.
-                        thisInflater.rInflateChildren(childParser, view, childAttrs, true);
-
-                        if (id != View.NO_ID) {
-                            view.setId(id);
-                        }
-
-                        switch (visibility) {
-                            case 0:
-                                view.setVisibility(View.VISIBLE);
-                                break;
-                            case 1:
-                                view.setVisibility(View.INVISIBLE);
-                                break;
-                            case 2:
-                                view.setVisibility(View.GONE);
-                                break;
-                        }
-
-                        group.addView(view);
-                    }
-                } finally {
-                    childParser.close();
-                }
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "<include /> can only be used inside of a ViewGroup",
-                    null);
-        }
-
-        LayoutInflater.consumeChildElements(parser);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
deleted file mode 100644
index 08a97d6..0000000
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ /dev/null
@@ -1,72 +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 android.view;
-
-import android.content.Context;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.AttributeSet;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuInflater}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of MenuInflater have been
- * replaced by calls to methods of the same name in this delegate class.
- * <p/>
- * The main purpose of the class is to get the view key from the menu xml parser and add it to
- * the menu item. The view key is used by the IDE to match the individual view elements to the
- * corresponding xml tag in the menu/layout file.
- * <p/>
- * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the
- * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link
- * ViewInfo}, we check the corresponding view key in the menu item for the view and add it
- */
-public class MenuInflater_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem,
-            AttributeSet attrs) {
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            Context context = thisInflater.getContext();
-            context = BridgeContext.getBaseContext(context);
-            if (context instanceof BridgeContext) {
-                Object viewKey = BridgeInflater.getViewKeyFromParser(
-                        attrs, ((BridgeContext) context), null, false);
-                ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey);
-                return;
-            }
-        }
-        // This means that Bridge did not take over the instantiation of some object properly.
-        // This is most likely a bug in the LayoutLib code.
-        Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                "Action Bar Menu rendering may be incorrect.", null);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu,
-            AttributeSet parser) {
-        registerMenu(thisInflater, subMenu.getItem(), parser);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java b/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
deleted file mode 100644
index 4a5ea9b..0000000
--- a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
+++ /dev/null
@@ -1,33 +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 android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-public class PointerIcon_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void loadResource(PointerIcon icon, Context context, Resources resources,
-            int resourceId) {
-        // HACK: This bypasses the problem of having an enum resolved as a resourceId.
-        // PointerIcon would not be displayed by layoutlib anyway, so we always return the null
-        // icon.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
deleted file mode 100644
index 8ae212c..0000000
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2015, 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.view;
-
-import android.annotation.NonNull;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import com.android.layoutlib.bridge.shadowutil.SpotShadow;
-import com.android.layoutlib.bridge.shadowutil.ShadowBuffer;
-
-public class RectShadowPainter {
-
-    private static final float SHADOW_STRENGTH = 0.1f;
-    private static final int LIGHT_POINTS = 8;
-
-    private static final int QUADRANT_DIVIDED_COUNT = 8;
-
-    private static final int RAY_TRACING_RAYS = 180;
-    private static final int RAY_TRACING_LAYERS = 10;
-
-    public static void paintShadow(@NonNull Outline viewOutline, float elevation,
-            @NonNull Canvas canvas) {
-        Rect outline = new Rect();
-        if (!viewOutline.getRect(outline)) {
-            assert false : "Outline is not a rect shadow";
-            return;
-        }
-
-        Rect originCanvasRect = canvas.getClipBounds();
-        int saved = modifyCanvas(canvas);
-        if (saved == -1) {
-            return;
-        }
-        try {
-            float radius = viewOutline.getRadius();
-            if (radius <= 0) {
-                // We can not paint a shadow with radius 0
-                return;
-            }
-
-            // view's absolute position in this canvas.
-            int viewLeft = -originCanvasRect.left + outline.left;
-            int viewTop = -originCanvasRect.top + outline.top;
-            int viewRight = viewLeft + outline.width();
-            int viewBottom = viewTop + outline.height();
-
-            float[][] rectangleCoordinators = generateRectangleCoordinates(viewLeft, viewTop,
-                    viewRight, viewBottom, radius, elevation);
-
-            // TODO: get these values from resources.
-            float lightPosX = canvas.getWidth() / 2;
-            float lightPosY = 0;
-            float lightHeight = 1800;
-            float lightSize = 200;
-
-            paintGeometricShadow(rectangleCoordinators, lightPosX, lightPosY, lightHeight,
-                    lightSize, canvas);
-        } finally {
-            canvas.restoreToCount(saved);
-        }
-    }
-
-    private static int modifyCanvas(@NonNull Canvas canvas) {
-        Rect rect = canvas.getClipBounds();
-        canvas.translate(rect.left, rect.top);
-        return canvas.save();
-    }
-
-    @NonNull
-    private static float[][] generateRectangleCoordinates(float left, float top, float right,
-            float bottom, float radius, float elevation) {
-        left = left + radius;
-        top = top + radius;
-        right = right - radius;
-        bottom = bottom - radius;
-
-        final double RADIANS_STEP = 2 * Math.PI / 4 / QUADRANT_DIVIDED_COUNT;
-
-        float[][] ret = new float[QUADRANT_DIVIDED_COUNT * 4][3];
-
-        int points = 0;
-        // left-bottom points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // left-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-bottom point
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-
-        return ret;
-    }
-
-    private static void paintGeometricShadow(@NonNull float[][] coordinates, float lightPosX,
-            float lightPosY, float lightHeight, float lightSize, Canvas canvas) {
-        if (canvas == null || canvas.getWidth() == 0 || canvas.getHeight() == 0) {
-            return;
-        }
-
-        // The polygon of shadow (same as the original item)
-        float[] shadowPoly = new float[coordinates.length * 3];
-        for (int i = 0; i < coordinates.length; i++) {
-            shadowPoly[i * 3 + 0] = coordinates[i][0];
-            shadowPoly[i * 3 + 1] = coordinates[i][1];
-            shadowPoly[i * 3 + 2] = coordinates[i][2];
-        }
-
-        // TODO: calculate the ambient shadow and mix with Spot shadow.
-
-        // Calculate the shadow of SpotLight
-        float[] light = SpotShadow.calculateLight(lightSize, LIGHT_POINTS, lightPosX,
-                lightPosY, lightHeight);
-
-        int stripSize = 3 * SpotShadow.getStripSize(RAY_TRACING_RAYS, RAY_TRACING_LAYERS);
-        if (stripSize < 9) {
-            return;
-        }
-        float[] strip = new float[stripSize];
-        SpotShadow.calcShadow(light, LIGHT_POINTS, shadowPoly, coordinates.length, RAY_TRACING_RAYS,
-                RAY_TRACING_LAYERS, 1f, strip);
-
-        ShadowBuffer buff = new ShadowBuffer(canvas.getWidth(), canvas.getHeight());
-        buff.generateTriangles(strip, SHADOW_STRENGTH);
-        buff.draw(canvas);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
deleted file mode 100644
index 152878b..0000000
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ /dev/null
@@ -1,335 +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 android.view;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of {@link RenderNode}
- * <p/>
- * Through the layoutlib_create tool, some native methods of RenderNode have been replaced by calls
- * to methods of the same name in this delegate class.
- *
- * @see DelegateManager
- */
-public class RenderNode_Delegate {
-
-
-    // ---- delegate manager ----
-    private static final DelegateManager<RenderNode_Delegate> sManager =
-            new DelegateManager<RenderNode_Delegate>(RenderNode_Delegate.class);
-    private static long sFinalizer = -1;
-
-    private float mLift;
-    private float mTranslationX;
-    private float mTranslationY;
-    private float mTranslationZ;
-    private float mRotation;
-    private float mScaleX = 1;
-    private float mScaleY = 1;
-    private float mPivotX;
-    private float mPivotY;
-    private boolean mPivotExplicitlySet;
-    private int mLeft;
-    private int mRight;
-    private int mTop;
-    private int mBottom;
-    @SuppressWarnings("UnusedDeclaration")
-    private String mName;
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(String name) {
-        RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
-        renderNodeDelegate.mName = name;
-        return sManager.addNewDelegate(renderNodeDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (RenderNode_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetElevation(long renderNode, float lift) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLift != lift) {
-            delegate.mLift = lift;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetElevation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mLift;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationX != translationX) {
-            delegate.mTranslationX = translationX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationY != translationY) {
-            delegate.mTranslationY = translationY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationY;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationZ != translationZ) {
-            delegate.mTranslationZ = translationZ;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationZ(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationZ;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRotation != rotation) {
-            delegate.mRotation = rotation;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRotation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mRotation;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
-        outMatrix.reset();
-        if (renderNode != null) {
-            float rotation = renderNode.getRotation();
-            float translationX = renderNode.getTranslationX();
-            float translationY = renderNode.getTranslationY();
-            float pivotX = renderNode.getPivotX();
-            float pivotY = renderNode.getPivotY();
-            float scaleX = renderNode.getScaleX();
-            float scaleY = renderNode.getScaleY();
-
-            outMatrix.setTranslate(translationX, translationY);
-            outMatrix.preRotate(rotation, pivotX, pivotY);
-            outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeft(long renderNode, int left) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLeft != left) {
-            delegate.mLeft = left;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTop(long renderNode, int top) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTop != top) {
-            delegate.mTop = top;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRight(long renderNode, int right) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRight != right) {
-            delegate.mRight = right;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mBottom != bottom) {
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
-            int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
-                .mRight != right || delegate.mBottom != bottom)) {
-            delegate.mLeft = left;
-            delegate.mTop = top;
-            delegate.mRight = right;
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        return delegate != null && delegate.mPivotExplicitlySet;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotX = pivotX;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotX;
-            } else {
-                return (delegate.mRight - delegate.mLeft) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotY = pivotY;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotY;
-            } else {
-                return (delegate.mBottom - delegate.mTop) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleX != scaleX) {
-            delegate.mScaleX = scaleX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleY != scaleY) {
-            delegate.mScaleY = scaleY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleY;
-        }
-        return 0f;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java b/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
deleted file mode 100644
index f09fffd..0000000
--- a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
+++ /dev/null
@@ -1,422 +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 android.view;
-
-import android.annotation.NonNull;
-
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-public class ShadowPainter {
-
-    /**
-     * Adds a drop shadow to a semi-transparent image (of an arbitrary shape) and returns it as a
-     * new image. This method attempts to mimic the same visual characteristics as the rectangular
-     * shadow painting methods in this class, {@link #createRectangularDropShadow(java.awt.image.BufferedImage)}
-     * and {@link #createSmallRectangularDropShadow(java.awt.image.BufferedImage)}.
-     * <p/>
-     * If shadowSize is less or equals to 1, no shadow will be painted and the source image will be
-     * returned instead.
-     *
-     * @param source the source image
-     * @param shadowSize the size of the shadow, normally {@link #SHADOW_SIZE or {@link
-     * #SMALL_SHADOW_SIZE}}
-     *
-     * @return an image with the shadow painted in or the source image if shadowSize <= 1
-     */
-    @NonNull
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize) {
-        shadowSize /= 2; // make shadow size have the same meaning as in the other shadow paint methods in this class
-
-        return createDropShadow(source, shadowSize, 0.7f, 0);
-    }
-
-    /**
-     * Creates a drop shadow of a given image and returns a new image which shows the input image on
-     * top of its drop shadow.
-     * <p/>
-     * <b>NOTE: If the shape is rectangular and opaque, consider using {@link
-     * #drawRectangleShadow(Graphics2D, int, int, int, int)} instead.</b>
-     *
-     * @param source the source image to be shadowed
-     * @param shadowSize the size of the shadow in pixels
-     * @param shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque
-     * @param shadowRgb the RGB int to use for the shadow color
-     *
-     * @return a new image with the source image on top of its shadow when shadowSize > 0 or the
-     * source image otherwise
-     */
-    @SuppressWarnings({"SuspiciousNameCombination", "UnnecessaryLocalVariable"})  // Imported code
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize,
-            float shadowOpacity, int shadowRgb) {
-        if (shadowSize <= 0) {
-            return source;
-        }
-
-        // This code is based on
-        //      http://www.jroller.com/gfx/entry/non_rectangular_shadow
-
-        BufferedImage image;
-        int width = source.getWidth();
-        int height = source.getHeight();
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE,
-                BufferedImage.TYPE_INT_ARGB);
-
-        Graphics2D g2 = image.createGraphics();
-        g2.drawImage(image, shadowSize, shadowSize, null);
-
-        int dstWidth = image.getWidth();
-        int dstHeight = image.getHeight();
-
-        int left = (shadowSize - 1) >> 1;
-        int right = shadowSize - left;
-        int xStart = left;
-        int xStop = dstWidth - right;
-        int yStart = left;
-        int yStop = dstHeight - right;
-
-        shadowRgb &= 0x00FFFFFF;
-
-        int[] aHistory = new int[shadowSize];
-        int historyIdx;
-
-        int aSum;
-
-        int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
-        int lastPixelOffset = right * dstWidth;
-        float sumDivider = shadowOpacity / shadowSize;
-
-        // horizontal pass
-        for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int x = 0; x < shadowSize; x++, bufferOffset++) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[x] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= right;
-
-            for (int x = xStart; x < xStop; x++, bufferOffset++) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + right] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-        // vertical pass
-        for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[y] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= lastPixelOffset;
-
-            for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-
-        g2.drawImage(source, null, 0, 0);
-        g2.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a rectangular drop shadow (of size {@link #SHADOW_SIZE} by {@link #SHADOW_SIZE} around
-     * the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-        BufferedImage image;
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE, type);
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a small rectangular drop shadow (of size {@link #SMALL_SHADOW_SIZE} by {@link
-     * #SMALL_SHADOW_SIZE} around the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createSmallRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-
-        BufferedImage image;
-        image = new BufferedImage(width + SMALL_SHADOW_SIZE, height + SMALL_SHADOW_SIZE, type);
-
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawSmallRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics. The size of the shadow is {@link #SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics. The size of the shadow is {@link #SMALL_SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawSmallRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SHADOW_SIZE = 20; // DO NOT EDIT. This corresponds to bitmap graphics
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawSmallRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SMALL_SHADOW_SIZE = 10; // DO NOT EDIT. Corresponds to bitmap graphics
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics.
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(Graphics2D gc, int x, int y, int width, int height) {
-        assert ShadowBottomLeft != null;
-        assert ShadowBottomRight.getWidth(null) == SHADOW_SIZE;
-        assert ShadowBottomRight.getHeight(null) == SHADOW_SIZE;
-
-        int blWidth = ShadowBottomLeft.getWidth(null);
-        int trHeight = ShadowTopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(ShadowBottomLeft, x - ShadowBottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(ShadowBottomRight, x + width, y + height, null);
-        gc.drawImage(ShadowTopRight, x + width, y, null);
-        gc.drawImage(ShadowTopLeft, x - ShadowTopLeft.getWidth(null), y, null);
-        gc.drawImage(ShadowBottom,
-                x, y + height, x + width, y + height + ShadowBottom.getHeight(null),
-                0, 0, ShadowBottom.getWidth(null), ShadowBottom.getHeight(null), null);
-        gc.drawImage(ShadowRight,
-                x + width, y + ShadowTopRight.getHeight(null), x + width + ShadowRight.getWidth(null), y + height,
-                0, 0, ShadowRight.getWidth(null), ShadowRight.getHeight(null), null);
-        gc.drawImage(ShadowLeft,
-                x - ShadowLeft.getWidth(null), y + ShadowTopLeft.getHeight(null), x, y + height,
-                0, 0, ShadowLeft.getWidth(null), ShadowLeft.getHeight(null), null);
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics.
-     * <p/>
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(Graphics2D gc, int x, int y, int width,
-            int height) {
-        assert Shadow2BottomLeft != null;
-        assert Shadow2TopRight != null;
-        assert Shadow2BottomRight.getWidth(null) == SMALL_SHADOW_SIZE;
-        assert Shadow2BottomRight.getHeight(null) == SMALL_SHADOW_SIZE;
-
-        int blWidth = Shadow2BottomLeft.getWidth(null);
-        int trHeight = Shadow2TopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(Shadow2BottomLeft, x - Shadow2BottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(Shadow2BottomRight, x + width, y + height, null);
-        gc.drawImage(Shadow2TopRight, x + width, y, null);
-        gc.drawImage(Shadow2TopLeft, x - Shadow2TopLeft.getWidth(null), y, null);
-        gc.drawImage(Shadow2Bottom,
-                x, y + height, x + width, y + height + Shadow2Bottom.getHeight(null),
-                0, 0, Shadow2Bottom.getWidth(null), Shadow2Bottom.getHeight(null), null);
-        gc.drawImage(Shadow2Right,
-                x + width, y + Shadow2TopRight.getHeight(null), x + width + Shadow2Right.getWidth(null), y + height,
-                0, 0, Shadow2Right.getWidth(null), Shadow2Right.getHeight(null), null);
-        gc.drawImage(Shadow2Left,
-                x - Shadow2Left.getWidth(null), y + Shadow2TopLeft.getHeight(null), x, y + height,
-                0, 0, Shadow2Left.getWidth(null), Shadow2Left.getHeight(null), null);
-    }
-
-    private static Image loadIcon(String name) {
-        InputStream inputStream = ShadowPainter.class.getResourceAsStream(name);
-        if (inputStream == null) {
-            throw new RuntimeException("Unable to load image for shadow: " + name);
-        }
-        try {
-            return ImageIO.read(inputStream);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to load image for shadow:" + name, e);
-        } finally {
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-                // ignore.
-            }
-        }
-    }
-
-    // Shadow graphics. This was generated by creating a drop shadow in
-    // Gimp, using the parameters x offset=10, y offset=10, blur radius=10,
-    // (for the small drop shadows x offset=10, y offset=10, blur radius=10)
-    // color=black, and opacity=51. These values attempt to make a shadow
-    // that is legible both for dark and light themes, on top of the
-    // canvas background (rgb(150,150,150). Darker shadows would tend to
-    // blend into the foreground for a dark holo screen, and lighter shadows
-    // would be hard to spot on the canvas background. If you make adjustments,
-    // make sure to check the shadow with both dark and light themes.
-    //
-    // After making the graphics, I cut out the top right, bottom left
-    // and bottom right corners as 20x20 images, and these are reproduced by
-    // painting them in the corresponding places in the target graphics context.
-    // I then grabbed a single horizontal gradient line from the middle of the
-    // right edge,and a single vertical gradient line from the bottom. These
-    // are then painted scaled/stretched in the target to fill the gaps between
-    // the three corner images.
-    //
-    // Filenames: bl=bottom left, b=bottom, br=bottom right, r=right, tr=top right
-
-    // Normal Drop Shadow
-    private static final Image ShadowBottom = loadIcon("/icons/shadow-b.png");
-    private static final Image ShadowBottomLeft = loadIcon("/icons/shadow-bl.png");
-    private static final Image ShadowBottomRight = loadIcon("/icons/shadow-br.png");
-    private static final Image ShadowRight = loadIcon("/icons/shadow-r.png");
-    private static final Image ShadowTopRight = loadIcon("/icons/shadow-tr.png");
-    private static final Image ShadowTopLeft = loadIcon("/icons/shadow-tl.png");
-    private static final Image ShadowLeft = loadIcon("/icons/shadow-l.png");
-
-    // Small Drop Shadow
-    private static final Image Shadow2Bottom = loadIcon("/icons/shadow2-b.png");
-    private static final Image Shadow2BottomLeft = loadIcon("/icons/shadow2-bl.png");
-    private static final Image Shadow2BottomRight = loadIcon("/icons/shadow2-br.png");
-    private static final Image Shadow2Right = loadIcon("/icons/shadow2-r.png");
-    private static final Image Shadow2TopRight = loadIcon("/icons/shadow2-tr.png");
-    private static final Image Shadow2TopLeft = loadIcon("/icons/shadow2-tl.png");
-    private static final Image Shadow2Left = loadIcon("/icons/shadow2-l.png");
-}
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
deleted file mode 100644
index ebb2af4..0000000
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.util.AttributeSet;
-
-/**
- * Mock version of the SurfaceView.
- * Only non override public methods from the real SurfaceView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- *
- * TODO: generate automatically.
- *
- */
-public class SurfaceView extends MockView {
-
-    public SurfaceView(Context context) {
-        this(context, null);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs , 0);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public boolean gatherTransparentRegion(Region region) {
-      return false;
-    }
-
-    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-    }
-
-    public void setZOrderOnTop(boolean onTop) {
-    }
-
-    public void setSecure(boolean isSecure) {
-    }
-
-    public SurfaceHolder getHolder() {
-        return mSurfaceHolder;
-    }
-
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-
-        @Override
-        public boolean isCreating() {
-            return false;
-        }
-
-        @Override
-        public void addCallback(Callback callback) {
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-        }
-
-        @Override
-        public void setFixedSize(int width, int height) {
-        }
-
-        @Override
-        public void setSizeFromLayout() {
-        }
-
-        @Override
-        public void setFormat(int format) {
-        }
-
-        @Override
-        public void setType(int type) {
-        }
-
-        @Override
-        public void setKeepScreenOn(boolean screenOn) {
-        }
-
-        @Override
-        public Canvas lockCanvas() {
-            return null;
-        }
-
-        @Override
-        public Canvas lockCanvas(Rect dirty) {
-            return null;
-        }
-
-        @Override
-        public void unlockCanvasAndPost(Canvas canvas) {
-        }
-
-        @Override
-        public Surface getSurface() {
-            return null;
-        }
-
-        @Override
-        public Rect getSurfaceFrame() {
-            return null;
-        }
-    };
-}
-
diff --git a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
deleted file mode 100644
index c3533e0..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class ViewConfiguration_Accessor {
-
-    public static void clearConfigurations() {
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration.sConfigurations.clear();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
deleted file mode 100644
index 4b760a7..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ /dev/null
@@ -1,158 +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 android.view;
-
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.view.animation.Transformation;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewGroup}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of ViewGroup have been replaced by calls
- * to methods of the same name in this delegate class.
- */
-public class ViewGroup_Delegate {
-
-    /**
-     * Overrides the original drawChild call in ViewGroup to draw the shadow.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean drawChild(ViewGroup thisVG, Canvas canvas, View child,
-            long drawingTime) {
-        if (child.getZ() > thisVG.getZ()) {
-            // The background's bounds are set lazily. Make sure they are set correctly so that
-            // the outline obtained is correct.
-            child.setBackgroundBounds();
-            ViewOutlineProvider outlineProvider = child.getOutlineProvider();
-            if (outlineProvider != null) {
-                Outline outline = child.mAttachInfo.mTmpOutline;
-                outlineProvider.getOutline(child, outline);
-                if (outline.mPath != null || (outline.mRect != null && !outline.mRect.isEmpty())) {
-                    int restoreTo = transformCanvas(thisVG, canvas, child);
-                    drawShadow(thisVG, canvas, child, outline);
-                    canvas.restoreToCount(restoreTo);
-                }
-            }
-        }
-        return thisVG.drawChild_Original(canvas, child, drawingTime);
-    }
-
-    private static void drawShadow(ViewGroup parent, Canvas canvas, View child,
-            Outline outline) {
-        float elevation = getElevation(child, parent);
-        if(outline.mMode == Outline.MODE_ROUND_RECT && outline.mRect != null) {
-            RectShadowPainter.paintShadow(outline, elevation, canvas);
-            return;
-        }
-        BufferedImage shadow = null;
-        if (outline.mPath != null) {
-            shadow = getPathShadow(outline, canvas, elevation);
-        }
-        if (shadow == null) {
-            return;
-        }
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(shadow, false,
-                Density.getEnum(canvas.getDensity()));
-        Rect clipBounds = canvas.getClipBounds();
-        Rect newBounds = new Rect(clipBounds);
-        newBounds.inset((int)-elevation, (int)-elevation);
-        canvas.clipRect(newBounds, Op.REPLACE);
-        canvas.drawBitmap(bitmap, 0, 0, null);
-        canvas.clipRect(clipBounds, Op.REPLACE);
-    }
-
-    private static float getElevation(View child, ViewGroup parent) {
-        return child.getZ() - parent.getZ();
-    }
-
-    private static BufferedImage getPathShadow(Outline outline, Canvas canvas, float elevation) {
-        Rect clipBounds = canvas.getClipBounds();
-        if (clipBounds.isEmpty()) {
-          return null;
-        }
-        BufferedImage image = new BufferedImage(clipBounds.width(), clipBounds.height(),
-                BufferedImage.TYPE_INT_ARGB);
-        Graphics2D graphics = image.createGraphics();
-        graphics.draw(Path_Delegate.getDelegate(outline.mPath.mNativePath).getJavaShape());
-        graphics.dispose();
-        return ShadowPainter.createDropShadow(image, (int) elevation);
-    }
-
-    // Copied from android.view.View#draw(Canvas, ViewGroup, long) and removed code paths
-    // which were never taken. Ideally, we should hook up the shadow code in the same method so
-    // that we don't have to transform the canvas twice.
-    private static int transformCanvas(ViewGroup thisVG, Canvas canvas, View child) {
-        final int restoreTo = canvas.save();
-        final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
-        int flags = thisVG.mGroupFlags;
-        Transformation transformToApply = null;
-        boolean concatMatrix = false;
-        if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
-            final Transformation t = thisVG.getChildTransformation();
-            final boolean hasTransform = thisVG.getChildStaticTransformation(child, t);
-            if (hasTransform) {
-                final int transformType = t.getTransformationType();
-                transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
-                concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
-            }
-        }
-        concatMatrix |= childHasIdentityMatrix;
-
-        child.computeScroll();
-        int sx = child.mScrollX;
-        int sy = child.mScrollY;
-
-        canvas.translate(child.mLeft - sx, child.mTop - sy);
-        float alpha = child.getAlpha() * child.getTransitionAlpha();
-
-        if (transformToApply != null || alpha < 1 || !childHasIdentityMatrix) {
-            if (transformToApply != null || !childHasIdentityMatrix) {
-                int transX = -sx;
-                int transY = -sy;
-
-                if (transformToApply != null) {
-                    if (concatMatrix) {
-                        // Undo the scroll translation, apply the transformation matrix,
-                        // then redo the scroll translate to get the correct result.
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(transformToApply.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                    if (!childHasIdentityMatrix) {
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(child.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                }
-
-            }
-        }
-        return restoreTo;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
deleted file mode 100644
index 0e15b97..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
+++ /dev/null
@@ -1,26 +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 android.view;
-
-/**
- * Accessor to allow layoutlib to call {@link ViewRootImpl#dispatchApplyInsets} directly.
- */
-public class ViewRootImpl_Accessor {
-    public static void dispatchApplyInsets(ViewRootImpl viewRoot, View host) {
-        viewRoot.dispatchApplyInsets(host);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
deleted file mode 100644
index 14b84ef..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ViewRootImpl_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInTouchMode() {
-        return false; // this allows displaying selection.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
deleted file mode 100644
index 408ec54..0000000
--- a/tools/layoutlib/bridge/src/android/view/View_Delegate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.IBinder;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link View}
- *
- * Through the layoutlib_create tool, the original  methods of View have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class View_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInEditMode(View thisView) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static IBinder getWindowToken(View thisView) {
-        Context baseContext = BridgeContext.getBaseContext(thisView.getContext());
-        if (baseContext instanceof BridgeContext) {
-            return ((BridgeContext) baseContext).getBinder();
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
deleted file mode 100644
index 1ea8a9f..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ /dev/null
@@ -1,144 +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 android.view;
-
-import android.annotation.Nullable;
-import android.view.ActionMode.Callback;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-
-import java.util.List;
-
-/**
- * An empty implementation of {@link Window.Callback} that always returns null/false.
- */
-public class WindowCallback implements Window.Callback {
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTrackballEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchGenericMotionEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        return false;
-    }
-
-    @Override
-    public View onCreatePanelView(int featureId) {
-        return null;
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onPreparePanel(int featureId, View view, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        return false;
-    }
-
-    @Override
-    public void onWindowAttributesChanged(LayoutParams attrs) {
-
-    }
-
-    @Override
-    public void onContentChanged() {
-
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-
-    }
-
-    @Override
-    public void onPanelClosed(int featureId, Menu menu) {
-
-    }
-
-    @Override
-    public boolean onSearchRequested(SearchEvent searchEvent) {
-        return onSearchRequested();
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        return false;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback) {
-        return null;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback, int type) {
-        return null;
-    }
-
-    @Override
-    public void onActionModeStarted(ActionMode mode) {
-
-    }
-
-    @Override
-    public void onActionModeFinished(ActionMode mode) {
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
deleted file mode 100644
index 2606e55..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link WindowManagerGlobal}
- *
- * Through the layoutlib_create tool, the original  methods of WindowManagerGlobal have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class WindowManagerGlobal_Delegate {
-
-    private static IWindowManager sService;
-
-    @LayoutlibDelegate
-    public static IWindowManager getWindowManagerService() {
-        return sService;
-    }
-
-    // ---- internal implementation stuff ----
-
-    public static void setWindowManagerService(IWindowManager service) {
-        sService = service;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
deleted file mode 100644
index 672ff6d..0000000
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.view.IWindow;
-import android.view.View;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
- * Such events are generated when something notable happens in the user interface,
- * for example an {@link android.app.Activity} starts, the focus or selection of a
- * {@link android.view.View} changes etc. Parties interested in handling accessibility
- * events implement and register an accessibility service which extends
- * {@code android.accessibilityservice.AccessibilityService}.
- *
- * @see AccessibilityEvent
- * @see android.content.Context#getSystemService
- */
-@SuppressWarnings("UnusedDeclaration")
-public final class AccessibilityManager {
-
-    private static AccessibilityManager sInstance = new AccessibilityManager(null, null, 0);
-
-
-    /**
-     * Listener for the accessibility state.
-     */
-    public interface AccessibilityStateChangeListener {
-
-        /**
-         * Called back on change in the accessibility state.
-         *
-         * @param enabled Whether accessibility is enabled.
-         */
-        public void onAccessibilityStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system touch exploration state. To listen for changes to
-     * the touch exploration state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addTouchExplorationStateChangeListener}.
-     */
-    public interface TouchExplorationStateChangeListener {
-
-        /**
-         * Called when the touch exploration enabled state changes.
-         *
-         * @param enabled Whether touch exploration is enabled.
-         */
-        public void onTouchExplorationStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system high text contrast state. To listen for changes to
-     * the high text contrast state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addHighTextContrastStateChangeListener}.
-     */
-    public interface HighTextContrastChangeListener {
-
-        /**
-         * Called when the high text contrast enabled state changes.
-         *
-         * @param enabled Whether high text contrast is enabled.
-         */
-        public void onHighTextContrastStateChanged(boolean enabled);
-    }
-
-    private final IAccessibilityManagerClient.Stub mClient =
-            new IAccessibilityManagerClient.Stub() {
-                public void setState(int state) {
-                }
-
-                public void notifyServicesStateChanged() {
-                }
-
-                public void setRelevantEventTypes(int eventTypes) {
-                }
-            };
-
-    /**
-     * Get an AccessibilityManager instance (create one if necessary).
-     *
-     */
-    public static AccessibilityManager getInstance(Context context) {
-        return sInstance;
-    }
-
-    /**
-     * Create an instance.
-     *
-     * @param context A {@link Context}.
-     */
-    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
-    }
-
-    public IAccessibilityManagerClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns if the {@link AccessibilityManager} is enabled.
-     *
-     * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
-     */
-    public boolean isEnabled() {
-        return false;
-    }
-
-    /**
-     * Returns if the touch exploration in the system is enabled.
-     *
-     * @return True if touch exploration is enabled, false otherwise.
-     */
-    public boolean isTouchExplorationEnabled() {
-        return true;
-    }
-
-    /**
-     * Returns if the high text contrast in the system is enabled.
-     * <p>
-     * <strong>Note:</strong> You need to query this only if you application is
-     * doing its own rendering and does not rely on the platform rendering pipeline.
-     * </p>
-     *
-     */
-    public boolean isHighTextContrastEnabled() {
-        return false;
-    }
-
-    /**
-     * Sends an {@link AccessibilityEvent}.
-     */
-    public void sendAccessibilityEvent(AccessibilityEvent event) {
-    }
-
-    /**
-     * Requests interruption of the accessibility feedback from all accessibility services.
-     */
-    public void interrupt() {
-    }
-
-    /**
-     * Returns the {@link ServiceInfo}s of the installed accessibility services.
-     *
-     * @return An unmodifiable list with {@link ServiceInfo}s.
-     */
-    @Deprecated
-    public List<ServiceInfo> getAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
-     * for a given feedback type.
-     *
-     * @param feedbackTypeFlags The feedback type flags.
-     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
-     *
-     * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
-     * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
-     * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
-     * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
-     * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
-     */
-    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
-            int feedbackTypeFlags) {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Registers an {@link AccessibilityStateChangeListener} for changes in
-     * the global accessibility state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    public boolean removeAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link TouchExplorationStateChangeListener} for changes in
-     * the global touch exploration state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Unregisters a {@link TouchExplorationStateChangeListener}.
-     *
-     * @param listener The listener.
-     * @return True if successfully unregistered.
-     */
-    public boolean removeTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link HighTextContrastChangeListener} for changes in
-     * the global high text contrast state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     *
-     */
-    public boolean addHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Unregisters a {@link HighTextContrastChangeListener}.
-     *
-     * @param listener The listener.
-     * @return True if successfully unregistered.
-     *
-     */
-    public boolean removeHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Sets the current state and notifies listeners, if necessary.
-     *
-     * @param stateFlags The state flags.
-     */
-    private void setStateLocked(int stateFlags) {
-    }
-
-    public int addAccessibilityInteractionConnection(IWindow windowToken,
-            IAccessibilityInteractionConnection connection) {
-        return View.NO_ID;
-    }
-
-    public void removeAccessibilityInteractionConnection(IWindow windowToken) {
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
deleted file mode 100644
index dc4f9c8..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inputmethod;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class InputMethodManager_Accessor {
-
-    public static void resetInstance() {
-        InputMethodManager.sInstance = null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
deleted file mode 100644
index 7c98847..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inputmethod;
-
-import com.android.layoutlib.bridge.android.BridgeIInputMethodManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Looper;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link InputMethodManager}
- *
- * Through the layoutlib_create tool, the original  methods of InputMethodManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class InputMethodManager_Delegate {
-
-    // ---- Overridden methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static InputMethodManager getInstance() {
-        synchronized (InputMethodManager.class) {
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm == null) {
-                imm = new InputMethodManager(
-                        new BridgeIInputMethodManager(), Looper.getMainLooper());
-                InputMethodManager.sInstance = imm;
-            }
-            return imm;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java b/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
deleted file mode 100644
index 8e1f218..0000000
--- a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
+++ /dev/null
@@ -1,72 +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 android.view.textservice;
-
-import android.os.Bundle;
-import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
-
-import java.util.Locale;
-
-/**
- * A stub class of TextServicesManager for Layout-Lib.
- */
-public final class TextServicesManager {
-    private static final TextServicesManager sInstance = new TextServicesManager();
-    private static final SpellCheckerInfo[] EMPTY_SPELL_CHECKER_INFO = new SpellCheckerInfo[0];
-
-    /**
-     * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
-     * @hide
-     */
-    public static TextServicesManager getInstance() {
-        return sInstance;
-    }
-
-    public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
-            SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo[] getEnabledSpellCheckers() {
-        return EMPTY_SPELL_CHECKER_INFO;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo getCurrentSpellChecker() {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
-            boolean allowImplicitlySelectedSubtype) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean isSpellCheckerEnabled() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
deleted file mode 100644
index 202f204..0000000
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.os.Bundle;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the WebView.
- * Only non override public methods from the real WebView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class WebView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public WebView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public WebView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.webViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void setHorizontalScrollbarOverlay(boolean overlay) {
-    }
-
-    public void setVerticalScrollbarOverlay(boolean overlay) {
-    }
-
-    public boolean overlayHorizontalScrollbar() {
-        return false;
-    }
-
-    public boolean overlayVerticalScrollbar() {
-        return false;
-    }
-
-    public void savePassword(String host, String username, String password) {
-    }
-
-    public void setHttpAuthUsernamePassword(String host, String realm,
-            String username, String password) {
-    }
-
-    public String[] getHttpAuthUsernamePassword(String host, String realm) {
-        return null;
-    }
-
-    public void destroy() {
-    }
-
-    public static void enablePlatformNotifications() {
-    }
-
-    public static void disablePlatformNotifications() {
-    }
-
-    public void loadUrl(String url) {
-    }
-
-    public void loadData(String data, String mimeType, String encoding) {
-    }
-
-    public void loadDataWithBaseURL(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl) {
-    }
-
-    public void stopLoading() {
-    }
-
-    public void reload() {
-    }
-
-    public boolean canGoBack() {
-        return false;
-    }
-
-    public void goBack() {
-    }
-
-    public boolean canGoForward() {
-        return false;
-    }
-
-    public void goForward() {
-    }
-
-    public boolean canGoBackOrForward(int steps) {
-        return false;
-    }
-
-    public void goBackOrForward(int steps) {
-    }
-
-    public boolean pageUp(boolean top) {
-        return false;
-    }
-    
-    public boolean pageDown(boolean bottom) {
-        return false;
-    }
-
-    public void clearView() {
-    }
-    
-    public Picture capturePicture() {
-        return null;
-    }
-
-    public float getScale() {
-        return 0;
-    }
-
-    public void setInitialScale(int scaleInPercent) {
-    }
-
-    public void invokeZoomPicker() {
-    }
-
-    public void requestFocusNodeHref(Message hrefMsg) {
-    }
-
-    public void requestImageRef(Message msg) {
-    }
-
-    public String getUrl() {
-        return null;
-    }
-
-    public String getTitle() {
-        return null;
-    }
-
-    public Bitmap getFavicon() {
-        return null;
-    }
-
-    public int getProgress() {
-        return 0;
-    }
-    
-    public int getContentHeight() {
-        return 0;
-    }
-
-    public void pauseTimers() {
-    }
-
-    public void resumeTimers() {
-    }
-
-    public void clearCache() {
-    }
-
-    public void clearFormData() {
-    }
-
-    public void clearHistory() {
-    }
-
-    public void clearSslPreferences() {
-    }
-
-    public static String findAddress(String addr) {
-        return null;
-    }
-
-    public void documentHasImages(Message response) {
-    }
-
-    public void setWebViewClient(WebViewClient client) {
-    }
-
-    public void setDownloadListener(DownloadListener listener) {
-    }
-
-    public void setWebChromeClient(WebChromeClient client) {
-    }
-
-    public void addJavascriptInterface(Object obj, String interfaceName) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-
-    public boolean zoomIn() {
-        return false;
-    }
-
-    public boolean zoomOut() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
deleted file mode 100644
index fdd1779..0000000
--- a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
+++ /dev/null
@@ -1,32 +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 android.widget;
-
-import android.content.Context;
-
-/**
- * To access non public members of classes in {@link Toolbar}
- */
-public class Toolbar_Accessor {
-    public static ActionMenuPresenter getActionMenuPresenter(Toolbar toolbar) {
-        return toolbar.getOuterActionMenuPresenter();
-    }
-
-    public static Context getPopupContext(Toolbar toolbar) {
-        return toolbar.getPopupContext();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
deleted file mode 100644
index 01fe45d..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
+++ /dev/null
@@ -1,53 +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.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.LongSparseLongArray;
-
-/**
- * Delegate used to provide new implementation the native methods of {@link VirtualRefBasePtr}
- *
- * Through the layoutlib_create tool, the original native  methods of VirtualRefBasePtr have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-@SuppressWarnings("unused")
-public class VirtualRefBasePtr_Delegate {
-    private static final DelegateManager<Object> sManager = new DelegateManager<>(Object.class);
-    private static final LongSparseLongArray sRefCount = new LongSparseLongArray();
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nIncStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-        sRefCount.put(ptr, ++counter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nDecStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-
-        if (counter > 1) {
-            sRefCount.put(ptr, --counter);
-        } else {
-            sRefCount.delete(ptr);
-            sManager.removeJavaReferenceFor(ptr);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
deleted file mode 100644
index bf998b8..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
- *
- * Through the layoutlib_create tool, the original  methods of XmlUtils have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class XmlUtils_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
-        if (null == charSeq)
-            return defaultValue;
-
-        String nm = charSeq.toString();
-
-        // This code is copied from the original implementation. The issue is that
-        // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
-        // is > 80000000 but the Java VM cannot.
-
-        int sign = 1;
-        int index = 0;
-        int len = nm.length();
-        int base = 10;
-
-        if ('-' == nm.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == nm.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = nm.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                base = 8;
-            }
-        }
-        else if ('#' == nm.charAt(index)) {
-            index++;
-            base = 16;
-        }
-
-        return ((int)Long.parseLong(nm.substring(index), base)) * sign;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
deleted file mode 100644
index da1ab27..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
+++ /dev/null
@@ -1,140 +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.view.animation;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.util.MathUtils;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnticipateInterpolator;
-import android.view.animation.AnticipateOvershootInterpolator;
-import android.view.animation.BaseInterpolator;
-import android.view.animation.BounceInterpolator;
-import android.view.animation.CycleInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.OvershootInterpolator;
-import android.view.animation.PathInterpolator;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * NativeInterpolatorFactoryHelper}
- * <p>
- * Through the layoutlib_create tool, the original  methods of NativeInterpolatorFactoryHelper have
- * been replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class NativeInterpolatorFactoryHelper_Delegate {
-    private static final DelegateManager<Interpolator> sManager = new DelegateManager<>
-            (Interpolator.class);
-
-    public static Interpolator getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateDecelerateInterpolator() {
-        return sManager.addNewDelegate(new AccelerateDecelerateInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new AccelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateOvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createBounceInterpolator() {
-        return sManager.addNewDelegate(new BounceInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createCycleInterpolator(float cycles) {
-        return sManager.addNewDelegate(new CycleInterpolator(cycles));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createDecelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new DecelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLinearInterpolator() {
-        return sManager.addNewDelegate(new LinearInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new OvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createPathInterpolator(float[] x, float[] y) {
-        Path path = new Path();
-        path.moveTo(x[0], y[0]);
-        for (int i = 1; i < x.length; i++) {
-            path.lineTo(x[i], y[i]);
-        }
-        return sManager.addNewDelegate(new PathInterpolator(path));
-    }
-
-    private static class LutInterpolator extends BaseInterpolator {
-        private final float[] mValues;
-        private final int mSize;
-
-        private LutInterpolator(float[] values) {
-            mValues = values;
-            mSize = mValues.length;
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            float lutpos = input * (mSize - 1);
-            if (lutpos >= (mSize - 1)) {
-                return mValues[mSize - 1];
-            }
-
-            int ipart = (int) lutpos;
-            float weight = lutpos - ipart;
-
-            int i1 = ipart;
-            int i2 = Math.min(i1 + 1, mSize - 1);
-
-            assert i1 >= 0 && i2 >= 0 : "Negatives in the interpolation";
-
-            return MathUtils.lerp(mValues[i1], mValues[i2], weight);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLutInterpolator(float[] values) {
-        return sManager.addNewDelegate(new LutInterpolator(values));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
deleted file mode 100644
index bb95c4e..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
+++ /dev/null
@@ -1,65 +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.android.internal.view.menu;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.content.Context;
-import android.view.View;
-
-/**
- * An extension of the {@link MenuItemImpl} to store the view cookie also.
- */
-public class BridgeMenuItemImpl extends MenuItemImpl {
-
-    /**
-     * An object returned by the IDE that helps mapping each View to the corresponding XML tag in
-     * the layout. For Menus, we store this cookie here and attach it to the corresponding view
-     * at the time of rendering.
-     */
-    private Object viewCookie;
-    private BridgeContext mContext;
-
-    /**
-     * Instantiates this menu item.
-     */
-    BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
-            CharSequence title, int showAsAction) {
-        super(menu, group, id, categoryOrder, ordering, title, showAsAction);
-        Context context = menu.getContext();
-        context = BridgeContext.getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            mContext = ((BridgeContext) context);
-        }
-    }
-
-    public Object getViewCookie() {
-        return viewCookie;
-    }
-
-    public void setViewCookie(Object viewCookie) {
-        // If the menu item has an associated action provider view,
-        // directly set the cookie in the view to cookie map stored in BridgeContext.
-        View actionView = getActionView();
-        if (actionView != null && mContext != null) {
-            mContext.addViewKey(actionView, viewCookie);
-            // We don't need to add the view cookie to the this item now. But there's no harm in
-            // storing it, in case we need it in the future.
-        }
-        this.viewCookie = viewCookie;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
deleted file mode 100644
index 505fb81..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
+++ /dev/null
@@ -1,38 +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.android.internal.view.menu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuBuilder}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of {@code MenuBuilder} have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class MenuBuilder_Delegate {
-    /**
-     * The method overrides the instantiation of the {@link MenuItemImpl} with an instance of
-     * {@link BridgeMenuItemImpl} so that view cookies may be stored.
-     */
-    @LayoutlibDelegate
-    /*package*/ static MenuItemImpl createNewMenuItem(MenuBuilder thisMenu, int group, int id,
-            int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) {
-        return new BridgeMenuItemImpl(thisMenu, group, id, categoryOrder, ordering, title,
-                defaultShowAsAction);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java b/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
deleted file mode 100644
index 40b6220..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
+++ /dev/null
@@ -1,32 +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.android.internal.widget;
-
-import android.widget.ActionMenuPresenter;
-
-/**
- * To access non public members of AbsActionBarView
- */
-public class ActionBarAccessor {
-
-    /**
-     * Returns the {@link ActionMenuPresenter} associated with the {@link AbsActionBarView}
-     */
-    public static ActionMenuPresenter getActionMenuPresenter(AbsActionBarView view) {
-        return view.mActionMenuPresenter;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 2e14974..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Capability;
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.Features;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderDrawable;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.layoutlib.bridge.util.DynamicIdMap;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.create.MethodAdapter;
-import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.content.res.BridgeAssetManager;
-import android.graphics.Bitmap;
-import android.graphics.FontFamily_Delegate;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Delegate;
-import android.icu.util.ULocale;
-import android.os.Looper;
-import android.os.Looper_Accessor;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import java.io.File;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-import libcore.io.MemoryMappedFile_Delegate;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-/**
- * Main entry point of the LayoutLib Bridge.
- * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #createSession(SessionParams)}
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-
-    private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
-
-    public static class StaticMethodNotImplementedException extends RuntimeException {
-        private static final long serialVersionUID = 1L;
-
-        public StaticMethodNotImplementedException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Lock to ensure only one rendering/inflating happens at a time.
-     * This is due to some singleton in the Android framework.
-     */
-    private final static ReentrantLock sLock = new ReentrantLock();
-
-    /**
-     * Maps from id to resource type/name. This is for com.android.internal.R
-     */
-    private final static Map<Integer, Pair<ResourceType, String>> sRMap =
-        new HashMap<Integer, Pair<ResourceType, String>>();
-
-    /**
-     * Same as sRMap except for int[] instead of int resources. This is for android.R only.
-     */
-    private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(384);
-    /**
-     * Reverse map compared to sRMap, resource type -> (resource name -> id).
-     * This is for com.android.internal.R.
-     */
-    private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
-        new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
-
-    // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
-    // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
-    // collision which should be fine.
-    private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
-    private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
-
-    private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
-        new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
-    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
-        new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
-
-    private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
-        new HashMap<String, SoftReference<Bitmap>>();
-    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
-        new HashMap<String, SoftReference<NinePatchChunk>>();
-
-    private static Map<String, Map<String, Integer>> sEnumValueMap;
-    private static Map<String, String> sPlatformProperties;
-
-    /**
-     * int[] wrapper to use as keys in maps.
-     */
-    private final static class IntArray {
-        private int[] mArray;
-
-        private IntArray() {
-            // do nothing
-        }
-
-        private IntArray(int[] a) {
-            mArray = a;
-        }
-
-        private void set(int[] a) {
-            mArray = a;
-        }
-
-        @Override
-        public int hashCode() {
-            return Arrays.hashCode(mArray);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            if (obj == null) return false;
-            if (getClass() != obj.getClass()) return false;
-
-            IntArray other = (IntArray) obj;
-            return Arrays.equals(mArray, other.mArray);
-        }
-    }
-
-    /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
-    private final static IntArray sIntArrayWrapper = new IntArray();
-
-    /**
-     * A default log than prints to stdout/stderr.
-     */
-    private final static LayoutLog sDefaultLog = new LayoutLog() {
-        @Override
-        public void error(String tag, String message, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void error(String tag, String message, Throwable throwable, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void warning(String tag, String message, Object data) {
-            System.out.println(message);
-        }
-    };
-
-    /**
-     * Current log.
-     */
-    private static LayoutLog sCurrentLog = sDefaultLog;
-
-    private static final int LAST_SUPPORTED_FEATURE = Features.THEME_PREVIEW_NAVIGATION_BAR;
-
-    @Override
-    public int getApiLevel() {
-        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
-    }
-
-    @Override
-    @Deprecated
-    public EnumSet<Capability> getCapabilities() {
-        // The Capability class is deprecated and frozen. All Capabilities enumerated there are
-        // supported by this version of LayoutLibrary. So, it's safe to use EnumSet.allOf()
-        return EnumSet.allOf(Capability.class);
-    }
-
-    @Override
-    public boolean supports(int feature) {
-        return feature <= LAST_SUPPORTED_FEATURE;
-    }
-
-    @Override
-    public boolean init(Map<String,String> platformProperties,
-            File fontLocation,
-            Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
-        sPlatformProperties = platformProperties;
-        sEnumValueMap = enumValueMap;
-
-        BridgeAssetManager.initSystem();
-
-        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
-        // on static (native) methods which prints the signature on the console and
-        // throws an exception.
-        // This is useful when testing the rendering in ADT to identify static native
-        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
-        // which is generally OK yet might be a problem, so this is how you'd find out.
-        //
-        // Currently layoutlib_create only overrides static native method.
-        // Static non-natives are not overridden and thus do not get here.
-        final String debug = System.getenv("DEBUG_LAYOUT");
-        if (debug != null && !debug.equals("0") && !debug.equals("false")) {
-
-            OverrideMethod.setDefaultListener(new MethodAdapter() {
-                @Override
-                public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    sDefaultLog.error(null, "Missing Stub: " + signature +
-                            (isNative ? " (native)" : ""), null /*data*/);
-
-                    if (debug.equalsIgnoreCase("throw")) {
-                        // Throwing this exception doesn't seem that useful. It breaks
-                        // the layout editor yet doesn't display anything meaningful to the
-                        // user. Having the error in the console is just as useful. We'll
-                        // throw it only if the environment variable is "throw" or "THROW".
-                        throw new StaticMethodNotImplementedException(signature);
-                    }
-                }
-            });
-        }
-
-        // load the fonts.
-        FontFamily_Delegate.setFontLocation(fontLocation.getAbsolutePath());
-        MemoryMappedFile_Delegate.setDataDir(fontLocation.getAbsoluteFile().getParentFile());
-
-        // now parse com.android.internal.R (and only this one as android.R is a subset of
-        // the internal version), and put the content in the maps.
-        try {
-            Class<?> r = com.android.internal.R.class;
-            // Parse the styleable class first, since it may contribute to attr values.
-            parseStyleable();
-
-            for (Class<?> inner : r.getDeclaredClasses()) {
-                if (inner == com.android.internal.R.styleable.class) {
-                    // Already handled the styleable case. Not skipping attr, as there may be attrs
-                    // that are not referenced from styleables.
-                    continue;
-                }
-                String resTypeName = inner.getSimpleName();
-                ResourceType resType = ResourceType.getEnum(resTypeName);
-                if (resType != null) {
-                    Map<String, Integer> fullMap = null;
-                    switch (resType) {
-                        case ATTR:
-                            fullMap = sRevRMap.get(ResourceType.ATTR);
-                            break;
-                        case STRING:
-                        case STYLE:
-                            // Slightly less than thousand entries in each.
-                            fullMap = new HashMap<String, Integer>(1280);
-                            // no break.
-                        default:
-                            if (fullMap == null) {
-                                fullMap = new HashMap<String, Integer>();
-                            }
-                            sRevRMap.put(resType, fullMap);
-                    }
-
-                    for (Field f : inner.getDeclaredFields()) {
-                        // only process static final fields. Since the final attribute may have
-                        // been altered by layoutlib_create, we only check static
-                        if (!isValidRField(f)) {
-                            continue;
-                        }
-                        Class<?> type = f.getType();
-                        if (type.isArray()) {
-                            // if the object is an int[] we put it in sRArrayMap using an IntArray
-                            // wrapper that properly implements equals and hashcode for the array
-                            // objects, as required by the map contract.
-                            sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
-                        } else {
-                            Integer value = (Integer) f.get(null);
-                            sRMap.put(value, Pair.of(resType, f.getName()));
-                            fullMap.put(f.getName(), value);
-                        }
-                    }
-                }
-            }
-        } catch (Exception throwable) {
-            if (log != null) {
-                log.error(LayoutLog.TAG_BROKEN,
-                        "Failed to load com.android.internal.R from the layout library jar",
-                        throwable, null);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Tests if the field is pubic, static and one of int or int[].
-     */
-    private static boolean isValidRField(Field field) {
-        int modifiers = field.getModifiers();
-        boolean isAcceptable = Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
-        Class<?> type = field.getType();
-        return isAcceptable && type == int.class ||
-                (type.isArray() && type.getComponentType() == int.class);
-
-    }
-
-    private static void parseStyleable() throws Exception {
-        // R.attr doesn't contain all the needed values. There are too many resources in the
-        // framework for all to be in the R class. Only the ones specified manually in
-        // res/values/symbols.xml are put in R class. Since, we need to create a map of all attr
-        // values, we try and find them from the styleables.
-
-        // There were 1500 elements in this map at M timeframe.
-        Map<String, Integer> revRAttrMap = new HashMap<String, Integer>(2048);
-        sRevRMap.put(ResourceType.ATTR, revRAttrMap);
-        // There were 2000 elements in this map at M timeframe.
-        Map<String, Integer> revRStyleableMap = new HashMap<String, Integer>(3072);
-        sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap);
-        Class<?> c = com.android.internal.R.styleable.class;
-        Field[] fields = c.getDeclaredFields();
-        // Sort the fields to bring all arrays to the beginning, so that indices into the array are
-        // able to refer back to the arrays (i.e. no forward references).
-        Arrays.sort(fields, new Comparator<Field>() {
-            @Override
-            public int compare(Field o1, Field o2) {
-                if (o1 == o2) {
-                    return 0;
-                }
-                Class<?> t1 = o1.getType();
-                Class<?> t2 = o2.getType();
-                if (t1.isArray() && !t2.isArray()) {
-                    return -1;
-                } else if (t2.isArray() && !t1.isArray()) {
-                    return 1;
-                }
-                return o1.getName().compareTo(o2.getName());
-            }
-        });
-        Map<String, int[]> styleables = new HashMap<String, int[]>();
-        for (Field field : fields) {
-            if (!isValidRField(field)) {
-                // Only consider public static fields that are int or int[].
-                // Don't check the final flag as it may have been modified by layoutlib_create.
-                continue;
-            }
-            String name = field.getName();
-            if (field.getType().isArray()) {
-                int[] styleableValue = (int[]) field.get(null);
-                sRArrayMap.put(new IntArray(styleableValue), name);
-                styleables.put(name, styleableValue);
-                continue;
-            }
-            // Not an array.
-            String arrayName = name;
-            int[] arrayValue = null;
-            int index;
-            while ((index = arrayName.lastIndexOf('_')) >= 0) {
-                // Find the name of the corresponding styleable.
-                // Search in reverse order so that attrs like LinearLayout_Layout_layout_gravity
-                // are mapped to LinearLayout_Layout and not to LinearLayout.
-                arrayName = arrayName.substring(0, index);
-                arrayValue = styleables.get(arrayName);
-                if (arrayValue != null) {
-                    break;
-                }
-            }
-            index = (Integer) field.get(null);
-            if (arrayValue != null) {
-                String attrName = name.substring(arrayName.length() + 1);
-                int attrValue = arrayValue[index];
-                sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName));
-                revRAttrMap.put(attrName, attrValue);
-            }
-            sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name));
-            revRStyleableMap.put(name, index);
-        }
-    }
-
-    @Override
-    public boolean dispose() {
-        BridgeAssetManager.clearSystem();
-
-        // dispose of the default typeface.
-        Typeface_Delegate.resetDefaults();
-        Typeface.sDynamicTypefaceCache.evictAll();
-
-        return true;
-    }
-
-    /**
-     * Starts a layout session by inflating and rendering it. The method returns a
-     * {@link RenderSession} on which further actions can be taken.
-     * <p/>
-     * If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE},
-     * this method will only inflate the layout but will NOT render it.
-     * @param params the {@link SessionParams} object with all the information necessary to create
-     *           the scene.
-     * @return a new {@link RenderSession} object that contains the result of the layout.
-     * @since 5
-     */
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderSessionImpl scene = new RenderSessionImpl(params);
-            try {
-                prepareThread();
-                lastResult = scene.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = scene.inflate();
-
-                    boolean doNotRenderOnCreate = Boolean.TRUE.equals(
-                            params.getFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE));
-                    if (lastResult.isSuccess() && !doNotRenderOnCreate) {
-                        lastResult = scene.render(true /*freshRender*/);
-                    }
-                }
-            } finally {
-                scene.release();
-                cleanupThread();
-            }
-
-            return new BridgeRenderSession(scene, lastResult);
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return new BridgeRenderSession(null,
-                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
-        }
-    }
-
-    @Override
-    public Result renderDrawable(DrawableParams params) {
-        try {
-            Result lastResult = SUCCESS.createResult();
-            RenderDrawable action = new RenderDrawable(params);
-            try {
-                prepareThread();
-                lastResult = action.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = action.render();
-                }
-            } finally {
-                action.release();
-                cleanupThread();
-            }
-
-            return lastResult;
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
-        }
-    }
-
-    @Override
-    public void clearCaches(Object projectKey) {
-        if (projectKey != null) {
-            sProjectBitmapCache.remove(projectKey);
-            sProject9PatchCache.remove(projectKey);
-        }
-    }
-
-    @Override
-    public Result getViewParent(Object viewObject) {
-        if (viewObject instanceof View) {
-            return Status.SUCCESS.createResult(((View)viewObject).getParent());
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public Result getViewIndex(Object viewObject) {
-        if (viewObject instanceof View) {
-            View view = (View) viewObject;
-            ViewParent parentView = view.getParent();
-
-            if (parentView instanceof ViewGroup) {
-                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
-            }
-
-            return Status.SUCCESS.createResult();
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public boolean isRtl(String locale) {
-        return isLocaleRtl(locale);
-    }
-
-    public static boolean isLocaleRtl(String locale) {
-        if (locale == null) {
-            locale = "";
-        }
-        ULocale uLocale = new ULocale(locale);
-        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL);
-    }
-
-    /**
-     * Returns the lock for the bridge
-     */
-    public static ReentrantLock getLock() {
-        return sLock;
-    }
-
-    /**
-     * Prepares the current thread for rendering.
-     *
-     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
-     * will do the clean-up, and make the thread unable to do further scene actions.
-     */
-    public synchronized static void prepareThread() {
-        // we need to make sure the Looper has been initialized for this thread.
-        // this is required for View that creates Handler objects.
-        if (Looper.myLooper() == null) {
-            Looper.prepareMainLooper();
-        }
-    }
-
-    /**
-     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
-     * <p>
-     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
-     * call to this will prevent the thread from doing further scene actions
-     */
-    public synchronized static void cleanupThread() {
-        // clean up the looper
-        Looper_Accessor.cleanupThread();
-    }
-
-    public static LayoutLog getLog() {
-        return sCurrentLog;
-    }
-
-    public static void setLog(LayoutLog log) {
-        // check only the thread currently owning the lock can do this.
-        if (!sLock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-
-        if (log != null) {
-            sCurrentLog = log;
-        } else {
-            sCurrentLog = sDefaultLog;
-        }
-    }
-
-    /**
-     * Returns details of a framework resource from its integer value.
-     * @param value the integer value
-     * @return a Pair containing the resource type and name, or null if the id
-     *     does not match any resource.
-     */
-    public static Pair<ResourceType, String> resolveResourceId(int value) {
-        Pair<ResourceType, String> pair = sRMap.get(value);
-        if (pair == null) {
-            pair = sDynamicIds.resolveId(value);
-            if (pair == null) {
-                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
-            }
-        }
-        return pair;
-    }
-
-    /**
-     * Returns the name of a framework resource whose value is an int array.
-     */
-    public static String resolveResourceId(int[] array) {
-        sIntArrayWrapper.set(array);
-        return sRArrayMap.get(sIntArrayWrapper);
-    }
-
-    /**
-     * Returns the integer id of a framework resource, from a given resource type and resource name.
-     * <p/>
-     * If no resource is found, it creates a dynamic id for the resource.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource.
-     *
-     * @return an {@link Integer} containing the resource id.
-     */
-    @NonNull
-    public static Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> map = sRevRMap.get(type);
-        Integer value = null;
-        if (map != null) {
-            value = map.get(name);
-        }
-
-        return value == null ? sDynamicIds.getId(type, name) : value;
-
-    }
-
-    /**
-     * Returns the list of possible enums for a given attribute name.
-     */
-    public static Map<String, Integer> getEnumValues(String attributeName) {
-        if (sEnumValueMap != null) {
-            return sEnumValueMap.get(attributeName);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the platform build properties.
-     */
-    public static Map<String, String> getPlatformProperties() {
-        return sPlatformProperties;
-    }
-
-    /**
-     * Returns the bitmap for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the bitmap
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached Bitmap or null if not found.
-     */
-    public static Bitmap getCachedBitmap(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-            if (map != null) {
-                SoftReference<Bitmap> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a bitmap in a project cache or in the framework cache.
-     * @param value the path of the bitmap
-     * @param bmp the Bitmap object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<Bitmap>>();
-                sProjectBitmapCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<Bitmap>(bmp));
-        } else {
-            sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
-        }
-    }
-
-    /**
-     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the 9 patch
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached 9 patch or null if not found.
-     */
-    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map != null) {
-                SoftReference<NinePatchChunk> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a 9 patch chunk in a project cache or in the framework cache.
-     * @param value the path of the 9 patch
-     * @param ninePatch the 9 patch object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<NinePatchChunk>>();
-                sProject9PatchCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        } else {
-            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
deleted file mode 100644
index 6228766..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>NS_</code> Namespace constant.</li>
- * <li><code>CLASS_</code> Fully qualified class name.</li>
- * </ul>
- *
- */
-public class BridgeConstants {
-
-    /** Namespace for the resource XML */
-    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
-
-    /** App auto namespace */
-    public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
-    public final static String NS_TOOLS_URI = "http://schemas.android.com/tools";
-
-    public final static String R = "com.android.internal.R";
-
-
-    public final static String MATCH_PARENT = "match_parent";
-    public final static String FILL_PARENT = "fill_parent";
-    public final static String WRAP_CONTENT = "wrap_content";
-
-    // Should be kept in sync with LayoutMetadata.KEY_LV_ITEM in tools/adt/idea
-    /** Attribute in the tools namespace used to specify layout manager for RecyclerView. */
-    @SuppressWarnings("SpellCheckingInspection")
-    public static final String ATTR_LIST_ITEM = "listitem";
-    public static final String ATTR_OPEN_DRAWER = "openDrawer";
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
deleted file mode 100644
index fdf6d63..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.PropertiesMap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.awt.image.BufferedImage;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link RenderSession}.
- *
- * This is a pretty basic class that does almost nothing. All of the work is done in
- * {@link RenderSessionImpl}.
- *
- */
-public class BridgeRenderSession extends RenderSession {
-
-    @Nullable
-    private final RenderSessionImpl mSession;
-    @NonNull
-    private Result mLastResult;
-
-    @Override
-    public Result getResult() {
-        return mLastResult;
-    }
-
-    @Override
-    public BufferedImage getImage() {
-        return mSession != null ? mSession.getImage() :
-                new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
-    }
-
-    @Override
-    public boolean isAlphaChannelImage() {
-        return mSession != null && mSession.isAlphaChannelImage();
-    }
-
-    @Override
-    public List<ViewInfo> getRootViews() {
-        return mSession != null ? mSession.getViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public List<ViewInfo> getSystemRootViews() {
-        return mSession != null ? mSession.getSystemViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mSession != null ? mSession.getDefaultProperties() : Collections.emptyMap();
-    }
-
-    @Override
-    public Result measure(long timeout) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    mSession.invalidateRenderingSize();
-                    mLastResult = mSession.measure();
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result render(long timeout, boolean forceMeasure) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    if (forceMeasure) {
-                        mSession.invalidateRenderingSize();
-                    }
-                    mLastResult = mSession.render(false /*freshRender*/);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
-                            listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
-            IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult =
-                            mSession.insertChild((ViewGroup) parentView, childXml, index, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-
-    @Override
-    public Result moveChild(Object parentView, Object childView, int index,
-            Map<String, String> layoutParams, IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
-                            layoutParams, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result removeChild(Object childView, IAnimationListener listener) {
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.removeChild((View) childView, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public void setSystemTimeNanos(long nanos) {
-        System_Delegate.setNanosTime(nanos);
-    }
-
-    @Override
-    public void setSystemBootTimeNanos(long nanos) {
-        System_Delegate.setBootTimeNanos(nanos);
-    }
-
-    @Override
-    public void setElapsedFrameTimeNanos(long nanos) {
-        if (mSession != null) {
-            mSession.setElapsedFrameTimeNanos(nanos);
-        }
-    }
-
-    @Override
-    public void dispose() {
-        if (mSession != null) {
-            mSession.dispose();
-        }
-    }
-
-    /*package*/ BridgeRenderSession(@Nullable RenderSessionImpl scene, @NonNull Result lastResult) {
-        mSession = scene;
-        if (scene != null) {
-            mSession.setScene(this);
-        }
-        mLastResult = lastResult;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
deleted file mode 100644
index e10f20d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-/**
- * Base class for mocked views.
- * <p/>
- * FrameLayout with a single TextView. Doesn't allow adding any other views to itself.
- */
-public class MockView extends FrameLayout {
-
-    private final TextView mView;
-
-    public MockView(Context context) {
-        this(context, null);
-    }
-
-    public MockView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mView = new TextView(context, attrs);
-        mView.setTextColor(0xFF000000);
-        setGravity(Gravity.CENTER);
-        setText(getClass().getSimpleName());
-        addView(mView);
-        setBackgroundColor(0xFF7F7F7F);
-    }
-
-    // Only allow adding one TextView.
-    @Override
-    public void addView(View child) {
-        if (child == mView) {
-            super.addView(child);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index) {
-        if (child == mView) {
-            super.addView(child, index);
-        }
-    }
-
-    @Override
-    public void addView(View child, int width, int height) {
-        if (child == mView) {
-            super.addView(child, width, height);
-        }
-    }
-
-    @Override
-    public void addView(View child, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, params);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, index, params);
-        }
-    }
-
-    // The following methods are called by the IDE via reflection, and should be considered part
-    // of the API.
-    // Historically, MockView used to be a textView and had these methods. Now, we simply delegate
-    // them to the contained textView.
-
-    public void setText(CharSequence text) {
-        mView.setText(text);
-    }
-
-    @SuppressWarnings("WeakerAccess") // This method is used from Studio
-    public void setGravity(int gravity) {
-        mView.setGravity(gravity);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
deleted file mode 100644
index faaf105..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ /dev/null
@@ -1,72 +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.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.RenderAction;
-
-import android.icu.util.ULocale;
-
-import java.util.Locale;
-
-/**
- * This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag}
- * which is only available after Java 6.
- *
- * The create tool re-writes references to the above mentioned method to this one. Hence it's
- * imperative that this class is not deleted unless the create tool is modified.
- */
-@SuppressWarnings("UnusedDeclaration")
-public class AndroidLocale {
-
-    public static String toLanguageTag(Locale locale)  {
-        return ULocale.forLocale(locale).toLanguageTag();
-    }
-
-    public static String adjustLanguageCode(String languageCode) {
-        String adjusted = languageCode.toLowerCase(Locale.US);
-        // Map new language codes to the obsolete language
-        // codes so the correct resource bundles will be used.
-        if (languageCode.equals("he")) {
-            adjusted = "iw";
-        } else if (languageCode.equals("id")) {
-            adjusted = "in";
-        } else if (languageCode.equals("yi")) {
-            adjusted = "ji";
-        }
-
-        return adjusted;
-    }
-
-    public static Locale forLanguageTag(String tag) {
-        return ULocale.forLanguageTag(tag).toLocale();
-    }
-
-    public static String getScript(Locale locale) {
-        return ULocale.forLocale(locale).getScript();
-    }
-
-    public static Locale getDefault() {
-        BridgeContext context = RenderAction.getCurrentContext();
-        if (context != null) {
-            Locale locale = context.getConfiguration().locale;
-            if (locale != null) {
-                return locale;
-            }
-        }
-        return Locale.getDefault();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
deleted file mode 100644
index c827f17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentValues;
-import android.content.IContentProvider;
-import android.content.OperationApplicationException;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-
-/**
- * Mock implementation of {@link IContentProvider}.
- *
- * TODO: never return null when the method is not supposed to. Return fake data instead.
- */
-public final class BridgeContentProvider implements IContentProvider {
-    @Override
-    public ContentProviderResult[] applyBatch(String callingPackage,
-            ArrayList<ContentProviderOperation> arg0)
-            throws RemoteException, OperationApplicationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int bulkInsert(String callingPackage, Uri arg0, ContentValues[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Bundle call(String callingPackage, String arg0, String arg1, Bundle arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int delete(String callingPackage, Uri arg0, String arg1, String[] arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public String getType(Uri arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Uri insert(String callingPackage, Uri arg0, ContentValues arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openAssetFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Cursor query(String callingPackage, Uri arg0, String[] arg1,
-            Bundle arg3, ICancellationSignal arg4) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int update(String callingPackage, Uri arg0, ContentValues arg1, String arg2,
-            String[] arg3) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
-            Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ICancellationSignal createCancellationSignal() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-
-    @Override
-    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public boolean refresh(String callingPkg, Uri url, Bundle args,
-                    ICancellationSignal cancellationSignal) throws RemoteException {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
deleted file mode 100644
index 8d259d7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 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.layoutlib.bridge.android;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * A mock content resolver for the LayoutLib Bridge.
- * <p/>
- * It won't serve any actual data but it's good enough for all
- * the widgets which expect to have a content resolver available via
- * {@link BridgeContext#getContentResolver()}.
- */
-public class BridgeContentResolver extends ContentResolver {
-
-    private BridgeContentProvider mProvider = null;
-
-    public BridgeContentResolver(Context context) {
-        super(context);
-    }
-
-    @Override
-    public IContentProvider acquireProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public IContentProvider acquireExistingProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public boolean releaseProvider(IContentProvider icp) {
-        // ignore
-        return false;
-    }
-
-    @Override
-    protected IContentProvider acquireUnstableProvider(Context c, String name) {
-        return acquireProvider(c, name);
-    }
-
-    @Override
-    public boolean releaseUnstableProvider(IContentProvider icp) {
-        return releaseProvider(icp);
-    }
-
-    /** @hide */
-    @Override
-    public void unstableProviderDied(IContentProvider icp) {
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void startSync(Uri uri, Bundle extras) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void cancelSync(Uri uri) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
deleted file mode 100644
index 1fc5d72..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ /dev/null
@@ -1,2064 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge.android;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.Stack;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-import com.android.util.PropertiesMap.Property;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.SystemServiceRegistry_Accessor;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.content.res.BridgeTypedArray;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources_Delegate;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.view.textservice.TextServicesManager;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
-
-/**
- * Custom implementation of Context/Activity to handle non compiled resources.
- */
-@SuppressWarnings("deprecation")  // For use of Pair.
-public class BridgeContext extends Context {
-    private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
-
-    private static final Map<String, ResourceValue> FRAMEWORK_PATCHED_VALUES = new HashMap<>(2);
-    private static final Map<String, ResourceValue> FRAMEWORK_REPLACE_VALUES = new HashMap<>(3);
-
-    static {
-        FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue(
-                ResourceType.BOOL, "animateFirstView", "false", false));
-        FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
-                new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false));
-
-
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout",
-                        "text_edit_suggestion_item", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout",
-                        "text_edit_suggestion_container", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
-                new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle",
-                        "TextAppearance.Holo.SuggestionHighlight", true));
-
-    }
-
-    /** The map adds cookies to each view so that IDE can link xml tags to views. */
-    private final HashMap<View, Object> mViewKeyMap = new HashMap<>();
-    /**
-     * In some cases, when inflating an xml, some objects are created. Then later, the objects are
-     * converted to views. This map stores the mapping from objects to cookies which can then be
-     * used to populate the mViewKeyMap.
-     */
-    private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>();
-    private final BridgeAssetManager mAssets;
-    private Resources mSystemResources;
-    private final Object mProjectKey;
-    private final DisplayMetrics mMetrics;
-    private final RenderResources mRenderResources;
-    private final Configuration mConfig;
-    private final ApplicationInfo mApplicationInfo;
-    private final LayoutlibCallback mLayoutlibCallback;
-    private final WindowManager mWindowManager;
-    private final DisplayManager mDisplayManager;
-    private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
-    private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
-
-    private Resources.Theme mTheme;
-
-    private final Map<Object, PropertiesMap> mDefaultPropMaps = new IdentityHashMap<>();
-
-    // maps for dynamically generated id representing style objects (StyleResourceValue)
-    @Nullable
-    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
-    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
-    private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
-
-    // cache for TypedArray generated from StyleResourceValue object
-    private TypedArrayCache mTypedArrayCache;
-    private BridgeInflater mBridgeInflater;
-
-    private BridgeContentResolver mContentResolver;
-
-    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>();
-    private SharedPreferences mSharedPreferences;
-    private ClassLoader mClassLoader;
-    private IBinder mBinder;
-    private PackageManager mPackageManager;
-    private Boolean mIsThemeAppCompat;
-
-    /**
-     * Some applications that target both pre API 17 and post API 17, set the newer attrs to
-     * reference the older ones. For example, android:paddingStart will resolve to
-     * android:paddingLeft. This way the apps need to only define paddingLeft at any other place.
-     * This a map from value to attribute name. Warning for missing references shouldn't be logged
-     * if value and attr name pair is the same as an entry in this map.
-     */
-    private static Map<String, String> RTL_ATTRS = new HashMap<>(10);
-
-    static {
-        RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
-        RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
-        RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
-        RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
-        RTL_ATTRS.put("?android:attr/layout_toLeftOf", "layout_toStartOf");
-        RTL_ATTRS.put("?android:attr/layout_toRightOf", "layout_toEndOf");
-        RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
-        RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
-        RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");
-        RTL_ATTRS.put("?android:attr/drawableRight", "drawableEnd");
-    }
-
-    /**
-     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
-     * @param metrics the {@link DisplayMetrics}.
-     * @param renderResources the configured resources (both framework and projects) for this
-     * render.
-     * @param config the Configuration object for this render.
-     * @param targetSdkVersion the targetSdkVersion of the application.
-     */
-    public BridgeContext(Object projectKey, DisplayMetrics metrics,
-            RenderResources renderResources,
-            AssetRepository assets,
-            LayoutlibCallback layoutlibCallback,
-            Configuration config,
-            int targetSdkVersion,
-            boolean hasRtlSupport) {
-        mProjectKey = projectKey;
-        mMetrics = metrics;
-        mLayoutlibCallback = layoutlibCallback;
-
-        mRenderResources = renderResources;
-        mConfig = config;
-        AssetManager systemAssetManager = AssetManager.getSystem();
-        if (systemAssetManager instanceof BridgeAssetManager) {
-            mAssets = (BridgeAssetManager) systemAssetManager;
-        } else {
-            throw new AssertionError("Creating BridgeContext without initializing Bridge");
-        }
-        mAssets.setAssetRepository(assets);
-
-        mApplicationInfo = new ApplicationInfo();
-        mApplicationInfo.targetSdkVersion = targetSdkVersion;
-        if (hasRtlSupport) {
-            mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
-        }
-
-        mWindowManager = new WindowManagerImpl(mMetrics);
-        mDisplayManager = new DisplayManager(this);
-    }
-
-    /**
-     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
-     * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
-     *
-     * @see #disposeResources()
-     */
-    public void initResources() {
-        AssetManager assetManager = AssetManager.getSystem();
-
-        mSystemResources = Resources_Delegate.initSystem(
-                this,
-                assetManager,
-                mMetrics,
-                mConfig,
-                mLayoutlibCallback);
-        mTheme = mSystemResources.newTheme();
-    }
-
-    /**
-     * Disposes the {@link Resources} singleton.
-     */
-    public void disposeResources() {
-        Resources_Delegate.disposeSystem();
-    }
-
-    public void setBridgeInflater(BridgeInflater inflater) {
-        mBridgeInflater = inflater;
-    }
-
-    public void addViewKey(View view, Object viewKey) {
-        mViewKeyMap.put(view, viewKey);
-    }
-
-    public Object getViewKey(View view) {
-        return mViewKeyMap.get(view);
-    }
-
-    public void addCookie(Object o, Object cookie) {
-        mViewKeyHelpMap.put(o, cookie);
-    }
-
-    public Object getCookie(Object o) {
-        return mViewKeyHelpMap.get(o);
-    }
-
-    public Object getProjectKey() {
-        return mProjectKey;
-    }
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    public LayoutlibCallback getLayoutlibCallback() {
-        return mLayoutlibCallback;
-    }
-
-    public RenderResources getRenderResources() {
-        return mRenderResources;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mDefaultPropMaps;
-    }
-
-    public Configuration getConfiguration() {
-        return mConfig;
-    }
-
-    /**
-     * Adds a parser to the stack.
-     * @param parser the parser to add.
-     */
-    public void pushParser(BridgeXmlBlockParser parser) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("PUSH " + parser.getParser().toString());
-        }
-        mParserStack.push(parser);
-    }
-
-    /**
-     * Removes the parser at the top of the stack
-     */
-    public void popParser() {
-        BridgeXmlBlockParser parser = mParserStack.pop();
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("POPD " + parser.getParser().toString());
-        }
-    }
-
-    /**
-     * Returns the current parser at the top the of the stack.
-     * @return a parser or null.
-     */
-    private BridgeXmlBlockParser getCurrentParser() {
-        return mParserStack.peek();
-    }
-
-    /**
-     * Returns the previous parser.
-     * @return a parser or null if there isn't any previous parser
-     */
-    public BridgeXmlBlockParser getPreviousParser() {
-        if (mParserStack.size() < 2) {
-            return null;
-        }
-        return mParserStack.get(mParserStack.size() - 2);
-    }
-
-    public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) {
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resId);
-        boolean isFrameworkRes = true;
-        if (resourceInfo == null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(resId);
-            isFrameworkRes = false;
-        }
-
-        if (resourceInfo == null) {
-            return false;
-        }
-
-        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
-                isFrameworkRes);
-        if (resolveRefs) {
-            value = mRenderResources.resolveResValue(value);
-        }
-
-        if (value == null) {
-            // unable to find the attribute.
-            return false;
-        }
-
-        // check if this is a style resource
-        if (value instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
-            return true;
-        }
-
-        String stringValue = value.getValue();
-        if (!stringValue.isEmpty()) {
-            if (stringValue.charAt(0) == '#') {
-                outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
-                outValue.data = Color.parseColor(value.getValue());
-            }
-            else if (stringValue.charAt(0) == '@') {
-                outValue.type = TypedValue.TYPE_REFERENCE;
-            }
-
-        }
-
-        int a;
-        // if this is a framework value.
-        if (value.isFramework()) {
-            // look for idName in the android R classes.
-            // use 0 a default res value as it's not a valid id value.
-            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        } else {
-            // look for idName in the project R class.
-            // use 0 a default res value as it's not a valid id value.
-            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        }
-
-        if (a != 0) {
-            outValue.resourceId = a;
-            return true;
-        }
-
-        // If the value is not a valid reference, fallback to pass the value as a string.
-        outValue.string = stringValue;
-        return true;
-    }
-
-
-    public ResourceReference resolveId(int id) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        if (resourceInfo != null) {
-            return new ResourceReference(resourceInfo.getSecond(), true);
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (mLayoutlibCallback != null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                return new ResourceReference(resourceInfo.getSecond(), false);
-            }
-        }
-
-        // The base value for R.style is 0x01030000 and the custom style is 0x02030000.
-        // So, if the second byte is 03, it's probably a style.
-        if ((id >> 16 & 0xFF) == 0x03) {
-            return getStyleByDynamicId(id);
-        }
-        return null;
-    }
-
-    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
-            @SuppressWarnings("SameParameterValue") boolean attachToRoot,
-            boolean skipCallbackParser) {
-        boolean isPlatformLayout = resource.isFramework();
-
-        if (!isPlatformLayout && !skipCallbackParser) {
-            // check if the project callback can provide us with a custom parser.
-            ILayoutPullParser parser = getParser(resource);
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                        this, resource.isFramework());
-                try {
-                    pushParser(blockParser);
-                    return Pair.of(
-                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                            Boolean.TRUE);
-                } finally {
-                    popParser();
-                }
-            }
-        }
-
-        ResourceValue resValue;
-        if (resource instanceof ResourceValue) {
-            resValue = (ResourceValue) resource;
-        } else {
-            if (isPlatformLayout) {
-                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
-                        resource.getName());
-            } else {
-                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
-                        resource.getName());
-            }
-        }
-
-        if (resValue != null) {
-
-            File xml = new File(resValue.getValue());
-            if (xml.isFile()) {
-                // we need to create a pull parser around the layout XML file, and then
-                // give that to our XmlBlockParser
-                try {
-                    XmlPullParser parser = ParserFactory.create(xml, true);
-
-                    // set the resource ref to have correct view cookies
-                    mBridgeInflater.setResourceReference(resource);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                            this, resource.isFramework());
-                    try {
-                        pushParser(blockParser);
-                        return Pair.of(
-                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                                Boolean.FALSE);
-                    } finally {
-                        popParser();
-                    }
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Failed to configure parser for " + xml, e, null /*data*/);
-                    // we'll return null below.
-                } catch (FileNotFoundException e) {
-                    // this shouldn't happen since we check above.
-                } finally {
-                    mBridgeInflater.setResourceReference(null);
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s is missing!", xml), null);
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
-                            resource.getName()), null);
-        }
-
-        return Pair.of(null, Boolean.FALSE);
-    }
-
-    /**
-     * Returns whether the current selected theme is based on AppCompat
-     */
-    public boolean isAppCompatTheme() {
-        // If a cached value exists, return it.
-        if (mIsThemeAppCompat != null) {
-            return mIsThemeAppCompat;
-        }
-        // Ideally, we should check if the corresponding activity extends
-        // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
-        StyleResourceValue defaultTheme = mRenderResources.getDefaultTheme();
-        // We can't simply check for parent using resources.themeIsParentOf() since the
-        // inheritance structure isn't really what one would expect. The first common parent
-        // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
-        boolean isThemeAppCompat = false;
-        for (int i = 0; i < 50; i++) {
-            if (defaultTheme == null) {
-                break;
-            }
-            // for loop ensures that we don't run into cyclic theme inheritance.
-            if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) {
-                isThemeAppCompat = true;
-                break;
-            }
-            defaultTheme = mRenderResources.getParent(defaultTheme);
-        }
-        mIsThemeAppCompat = isThemeAppCompat;
-        return isThemeAppCompat;
-    }
-
-    @SuppressWarnings("deprecation")
-    private ILayoutPullParser getParser(ResourceReference resource) {
-        ILayoutPullParser parser;
-        if (resource instanceof ResourceValue) {
-            parser = mLayoutlibCallback.getParser((ResourceValue) resource);
-        } else {
-            parser = mLayoutlibCallback.getParser(resource.getName());
-        }
-        return parser;
-    }
-
-    // ------------ Context methods
-
-    @Override
-    public Resources getResources() {
-        return mSystemResources;
-    }
-
-    @Override
-    public Theme getTheme() {
-        return mTheme;
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        // The documentation for this method states that it should return a class loader one can
-        // use to retrieve classes in this package. However, when called by LayoutInflater, we do
-        // not want the class loader to return app's custom views.
-        // This is so that the IDE can instantiate the custom views and also generate proper error
-        // messages in case of failure. This also enables the IDE to fallback to MockView in case
-        // there's an exception thrown when trying to inflate the custom view.
-        // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to
-        // replace invocations of this method to a new method: getFrameworkClassLoader(). Also,
-        // the method is injected into Context. The implementation of getFrameworkClassLoader() is:
-        // "return getClass().getClassLoader();". This means that when LayoutInflater asks for
-        // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have
-        // access to the apps's custom views.
-        // This method can now return the right ClassLoader, which CustomViews can use to do the
-        // right thing.
-        if (mClassLoader == null) {
-            mClassLoader = new ClassLoader(getClass().getClassLoader()) {
-                @Override
-                protected Class<?> findClass(String name) throws ClassNotFoundException {
-                    for (String prefix : BridgeInflater.getClassPrefixList()) {
-                        if (name.startsWith(prefix)) {
-                            // These are framework classes and should not be loaded from the app.
-                            throw new ClassNotFoundException(name + " not found");
-                        }
-                    }
-                    return BridgeContext.this.mLayoutlibCallback.findClass(name);
-                }
-            };
-        }
-        return mClassLoader;
-    }
-
-    @Override
-    public Object getSystemService(String service) {
-        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
-            return mBridgeInflater;
-        }
-
-        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
-            // we need to return a valid service to avoid NPE
-            return TextServicesManager.getInstance();
-        }
-
-        if (WINDOW_SERVICE.equals(service)) {
-            return mWindowManager;
-        }
-
-        // needed by SearchView
-        if (INPUT_METHOD_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (POWER_SERVICE.equals(service)) {
-            return new PowerManager(this, new BridgePowerManager(), new Handler());
-        }
-
-        if (DISPLAY_SERVICE.equals(service)) {
-            return mDisplayManager;
-        }
-
-        if (ACCESSIBILITY_SERVICE.equals(service)) {
-            return AccessibilityManager.getInstance(this);
-        }
-
-        if (AUTOFILL_MANAGER_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (AUDIO_SERVICE.equals(service)) {
-            return null;
-        }
-
-        assert false : "Unsupported Service: " + service;
-        return null;
-    }
-
-    @Override
-    public String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry_Accessor.getSystemServiceName(serviceClass);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
-        return obtainStyledAttributes(0, attrs);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int resId, int[] attrs)
-            throws Resources.NotFoundException {
-        StyleResourceValue style = null;
-        // get the StyleResourceValue based on the resId;
-        if (resId != 0) {
-            style = getStyleByDynamicId(resId);
-
-            if (style == null) {
-                // In some cases, style may not be a dynamic id, so we do a full search.
-                ResourceReference ref = resolveId(resId);
-                if (ref != null) {
-                    style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
-                }
-            }
-
-            if (style == null) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find style with " + resId, null);
-                return null;
-            }
-        }
-
-        if (mTypedArrayCache == null) {
-            mTypedArrayCache = new TypedArrayCache();
-        }
-
-        List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
-
-        Pair<BridgeTypedArray, PropertiesMap> typeArrayAndPropertiesPair =
-                mTypedArrayCache.get(attrs, currentThemes, resId);
-
-        if (typeArrayAndPropertiesPair == null) {
-            typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs);
-            mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair);
-        }
-        // Add value to defaultPropsMap if needed
-        if (typeArrayAndPropertiesPair.getSecond() != null) {
-            BridgeXmlBlockParser parser = getCurrentParser();
-            Object key = parser != null ? parser.getViewCookie() : null;
-            if (key != null) {
-                PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
-                if (defaultPropMap == null) {
-                    defaultPropMap = typeArrayAndPropertiesPair.getSecond();
-                    mDefaultPropMaps.put(key, defaultPropMap);
-                } else {
-                    defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond());
-                }
-            }
-        }
-        return typeArrayAndPropertiesPair.getFirst();
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
-        return obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    @Override
-    public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
-            int defStyleAttr, int defStyleRes) {
-
-        PropertiesMap defaultPropMap = null;
-        boolean isPlatformFile = true;
-
-        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
-        if (set instanceof BridgeXmlBlockParser) {
-            BridgeXmlBlockParser parser;
-            parser = (BridgeXmlBlockParser)set;
-
-            isPlatformFile = parser.isPlatformFile();
-
-            Object key = parser.getViewCookie();
-            if (key != null) {
-                defaultPropMap = mDefaultPropMaps.computeIfAbsent(key, k -> new PropertiesMap());
-            }
-
-        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
-            // this is only for temp layout params generated dynamically, so this is never
-            // platform content.
-            isPlatformFile = false;
-        } else if (set != null) { // null parser is ok
-            // really this should not be happening since its instantiated in Bridge
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Parser is not a BridgeXmlBlockParser!", null);
-            return null;
-        }
-
-        List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, isPlatformFile);
-
-        // look for a custom style.
-        String customStyle = null;
-        if (set != null) {
-            customStyle = set.getAttributeValue(null, "style");
-        }
-
-        StyleResourceValue customStyleValues = null;
-        if (customStyle != null) {
-            ResourceValue item = mRenderResources.findResValue(customStyle,
-                    isPlatformFile /*forceFrameworkOnly*/);
-
-            // resolve it in case it links to something else
-            item = mRenderResources.resolveResValue(item);
-
-            if (item instanceof StyleResourceValue) {
-                customStyleValues = (StyleResourceValue)item;
-            }
-        }
-
-        // resolve the defStyleAttr value into a IStyleResourceValue
-        StyleResourceValue defStyleValues = null;
-
-        if (defStyleAttr != 0) {
-            // get the name from the int.
-            Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
-
-            if (defStyleAttribute == null) {
-                // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
-                // This will happen if the user explicitly used a non existing int value for
-                // defStyleAttr or there's something wrong with the project structure/build.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find the style corresponding to the id " + defStyleAttr, null);
-            } else {
-                String defStyleName = defStyleAttribute.getFirst();
-
-                // look for the style in the current theme, and its parent:
-                ResourceValue item = mRenderResources.findItemInTheme(defStyleName,
-                        defStyleAttribute.getSecond());
-
-                if (item != null) {
-                    // item is a reference to a style entry. Search for it.
-                    item = mRenderResources.findResValue(item.getValue(), item.isFramework());
-                    item = mRenderResources.resolveResValue(item);
-                    if (item instanceof StyleResourceValue) {
-                        defStyleValues = (StyleResourceValue) item;
-                    }
-                    if (defaultPropMap != null) {
-                        if (defStyleAttribute.getSecond()) {
-                            defStyleName = "android:" + defStyleName;
-                        }
-                        defaultPropMap.put("style", new Property(defStyleName, item.getValue()));
-                    }
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                            String.format(
-                                    "Failed to find style '%s' in current theme",
-                                    defStyleAttribute.getFirst()),
-                            null);
-                }
-            }
-        } else if (defStyleRes != 0) {
-            StyleResourceValue item = getStyleByDynamicId(defStyleRes);
-            if (item != null) {
-                defStyleValues = item;
-            } else {
-                boolean isFrameworkRes = true;
-                Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
-                if (value == null) {
-                    value = mLayoutlibCallback.resolveResourceId(defStyleRes);
-                    isFrameworkRes = false;
-                }
-
-                if (value != null) {
-                    if ((value.getFirst() == ResourceType.STYLE)) {
-                        // look for the style in all resources:
-                        item = mRenderResources.getStyle(value.getSecond(), isFrameworkRes);
-                        if (item != null) {
-                            if (defaultPropMap != null) {
-                                String name = item.getName();
-                                defaultPropMap.put("style", new Property(name, name));
-                            }
-
-                            defStyleValues = item;
-                        } else {
-                            Bridge.getLog().error(null,
-                                    String.format(
-                                            "Style with id 0x%x (resolved to '%s') does not exist.",
-                                            defStyleRes, value.getSecond()),
-                                    null);
-                        }
-                    } else {
-                        Bridge.getLog().error(null,
-                                String.format(
-                                        "Resource id 0x%x is not of type STYLE (instead %s)",
-                                        defStyleRes, value.getFirst().toString()),
-                                null);
-                    }
-                } else {
-                    Bridge.getLog().error(null,
-                            String.format(
-                                    "Failed to find style with id 0x%x in current theme",
-                                    defStyleRes),
-                            null);
-                }
-            }
-        }
-
-        String appNamespace = mLayoutlibCallback.getNamespace();
-
-        if (attributeList != null) {
-            for (int index = 0 ; index < attributeList.size() ; index++) {
-                Pair<String, Boolean> attribute = attributeList.get(index);
-
-                if (attribute == null) {
-                    continue;
-                }
-
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                String value = null;
-                if (set != null) {
-                    value = set.getAttributeValue(
-                            frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
-                                    attrName);
-
-                    // if this is an app attribute, and the first get fails, try with the
-                    // new res-auto namespace as well
-                    if (!frameworkAttr && value == null) {
-                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
-                    }
-                }
-
-                // Calculate the default value from the Theme in two cases:
-                //   - If defaultPropMap is not null, get the default value to add it to the list
-                //   of default values of properties.
-                //   - If value is null, it means that the attribute is not directly set as an
-                //   attribute in the XML so try to get the default value.
-                ResourceValue defaultValue = null;
-                if (defaultPropMap != null || value == null) {
-                    // look for the value in the custom style first (and its parent if needed)
-                    if (customStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(customStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // then look for the value in the default Style (and its parent if needed)
-                    if (defaultValue == null && defStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(defStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // if the item is not present in the defStyle, we look in the main theme (and
-                    // its parent themes)
-                    if (defaultValue == null) {
-                        defaultValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        String preResolve = defaultValue.getValue();
-                        defaultValue = mRenderResources.resolveResValue(defaultValue);
-
-                        if (defaultPropMap != null) {
-                            defaultPropMap.put(
-                                    frameworkAttr ? SdkConstants.PREFIX_ANDROID + attrName :
-                                            attrName, new Property(preResolve, defaultValue.getValue()));
-                        }
-                    }
-                }
-                // Done calculating the defaultValue
-
-                // if there's no direct value for this attribute in the XML, we look for default
-                // values in the widget defStyle, and then in the theme.
-                if (value == null) {
-                    if (frameworkAttr) {
-                        // For some framework values, layoutlib patches the actual value in the
-                        // theme when it helps to improve the final preview. In most cases
-                        // we just disable animations.
-                        ResourceValue patchedValue = FRAMEWORK_PATCHED_VALUES.get(attrName);
-                        if (patchedValue != null) {
-                            defaultValue = patchedValue;
-                        }
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        // If the value is a reference to another theme attribute that doesn't
-                        // exist, we should log a warning and omit it.
-                        String val = defaultValue.getValue();
-                        if (val != null && val.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                            // Because we always use the latest framework code, some resources might
-                            // fail to resolve when using old themes (they haven't been backported).
-                            // Since this is an artifact caused by us using always the latest
-                            // code, we check for some of those values and replace them here.
-                            defaultValue = FRAMEWORK_REPLACE_VALUES.get(attrName);
-
-                            if (defaultValue == null &&
-                                    (getApplicationInfo().targetSdkVersion < JELLY_BEAN_MR1 ||
-                                    !attrName.equals(RTL_ATTRS.get(val)))) {
-                                // Only log a warning if the referenced value isn't one of the RTL
-                                // attributes, or the app targets old API.
-                                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                                        String.format("Failed to find '%s' in current theme.", val),
-                                        val);
-                            }
-                        }
-                    }
-
-                    ta.bridgeSetValue(index, attrName, frameworkAttr, defaultValue);
-                } else {
-                    // there is a value in the XML, but we need to resolve it in case it's
-                    // referencing another resource or a theme value.
-                    ta.bridgeSetValue(index, attrName, frameworkAttr,
-                            mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return Looper.myLooper();
-    }
-
-
-    @Override
-    public String getPackageName() {
-        if (mApplicationInfo.packageName == null) {
-            mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
-        }
-        return mApplicationInfo.packageName;
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        if (mPackageManager == null) {
-            mPackageManager = new BridgePackageManager();
-        }
-        return mPackageManager;
-    }
-
-    // ------------- private new methods
-
-    /**
-     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
-     * values found in the given style. If no style is specified, the default theme, along with the
-     * styles applied to it are used.
-     *
-     * @see #obtainStyledAttributes(int, int[])
-     */
-    private Pair<BridgeTypedArray, PropertiesMap> createStyleBasedTypedArray(
-            @Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
-        List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
-
-        PropertiesMap defaultPropMap = new PropertiesMap();
-        // for each attribute, get its name so that we can search it in the style
-        for (int i = 0; i < attrs.length; i++) {
-            Pair<String, Boolean> attribute = attributes.get(i);
-
-            if (attribute != null) {
-                // look for the value in the given style
-                ResourceValue resValue;
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                if (style != null) {
-                    resValue = mRenderResources.findItemInStyle(style, attrName, frameworkAttr);
-                } else {
-                    resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                }
-
-                if (resValue != null) {
-                    // Add it to defaultPropMap before resolving
-                    String preResolve = resValue.getValue();
-                    // resolve it to make sure there are no references left.
-                    resValue = mRenderResources.resolveResValue(resValue);
-                    ta.bridgeSetValue(i, attrName, frameworkAttr, resValue);
-                    defaultPropMap.put(
-                            frameworkAttr ? SdkConstants.ANDROID_PREFIX + attrName : attrName,
-                            new Property(preResolve, resValue.getValue()));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return Pair.of(ta, defaultPropMap);
-    }
-
-    /**
-     * The input int[] attrs is a list of attributes. The returns a list of information about
-     * each attributes. The information is (name, isFramework)
-     * <p/>
-     *
-     * @param attrs An attribute array reference given to obtainStyledAttributes.
-     * @return List of attribute information.
-     */
-    private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
-        List<Pair<String, Boolean>> results = new ArrayList<>(attrs.length);
-
-        // for each attribute, get its name so that we can search it in the style
-        for (int attr : attrs) {
-            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
-            boolean isFramework = false;
-            if (resolvedResource != null) {
-                isFramework = true;
-            } else {
-                resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
-            }
-
-            if (resolvedResource != null) {
-                results.add(Pair.of(resolvedResource.getSecond(), isFramework));
-            } else {
-                results.add(null);
-            }
-        }
-
-        return results;
-    }
-
-    /**
-     * Searches for the attribute referenced by its internal id.
-     *
-     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
-     * @return A (name, isFramework) pair describing the attribute if found. Returns null
-     *         if nothing is found.
-     */
-    private Pair<String, Boolean> searchAttr(int attr) {
-        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.TRUE);
-        }
-
-        info = mLayoutlibCallback.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.FALSE);
-        }
-
-        return null;
-    }
-
-    public int getDynamicIdByStyle(StyleResourceValue resValue) {
-        if (mDynamicIdToStyleMap == null) {
-            // create the maps.
-            mDynamicIdToStyleMap = new HashMap<>();
-            mStyleToDynamicIdMap = new HashMap<>();
-        }
-
-        // look for an existing id
-        Integer id = mStyleToDynamicIdMap.get(resValue);
-
-        if (id == null) {
-            // generate a new id
-            id = ++mDynamicIdGenerator;
-
-            // and add it to the maps.
-            mDynamicIdToStyleMap.put(id, resValue);
-            mStyleToDynamicIdMap.put(resValue, id);
-        }
-
-        return id;
-    }
-
-    private StyleResourceValue getStyleByDynamicId(int i) {
-        if (mDynamicIdToStyleMap != null) {
-            return mDynamicIdToStyleMap.get(i);
-        }
-
-        return null;
-    }
-
-    public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
-        if (getRenderResources().getFrameworkResource(resType, resName) != null) {
-            // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
-            // we check for the existence of the resource before calling it.
-            return Bridge.getResourceId(resType, resName);
-        }
-
-        return defValue;
-    }
-
-    public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
-        // getResourceId creates a new resource id if an existing resource id isn't found. So, we
-        // check for the existence of the resource before calling it.
-        if (getRenderResources().getProjectResource(resType, resName) != null) {
-            if (mLayoutlibCallback != null) {
-                Integer value = mLayoutlibCallback.getResourceId(resType, resName);
-                if (value != null) {
-                    return value;
-                }
-            }
-        }
-
-        return defValue;
-    }
-
-    public static Context getBaseContext(Context context) {
-        while (context instanceof ContextWrapper) {
-            context = ((ContextWrapper) context).getBaseContext();
-        }
-        return context;
-    }
-
-    public IBinder getBinder() {
-        if (mBinder == null) {
-            // create a dummy binder. We only need it be not null.
-            mBinder = new IBinder() {
-                @Override
-                public String getInterfaceDescriptor() throws RemoteException {
-                    return null;
-                }
-
-                @Override
-                public boolean pingBinder() {
-                    return false;
-                }
-
-                @Override
-                public boolean isBinderAlive() {
-                    return false;
-                }
-
-                @Override
-                public IInterface queryLocalInterface(String descriptor) {
-                    return null;
-                }
-
-                @Override
-                public void dump(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public boolean transact(int code, Parcel data, Parcel reply, int flags)
-                        throws RemoteException {
-                    return false;
-                }
-
-                @Override
-                public void linkToDeath(DeathRecipient recipient, int flags)
-                        throws RemoteException {
-
-                }
-
-                @Override
-                public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
-                    return false;
-                }
-
-                @Override
-                public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-                  String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver) {
-                }
-            };
-        }
-        return mBinder;
-    }
-
-    //------------ NOT OVERRIDEN --------------------
-
-    @Override
-    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public int checkCallingOrSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
-            int arg4, int arg5) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public void clearWallpaper() {
-        // pass
-
-    }
-
-    @Override
-    public Context createPackageContext(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createConfigurationContext(Configuration overrideConfiguration) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createDisplayContext(Display display) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createContextForSplit(String splitName) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String[] databaseList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createApplicationContext(ApplicationInfo application, int flags)
-            throws PackageManager.NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean moveDatabaseFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteDatabase(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteFile(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
-            String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
-            String arg4) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
-            int arg3, int arg4, int arg5, String arg6) {
-        // pass
-
-    }
-
-    @Override
-    public String[] fileList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public BridgeAssetManager getAssets() {
-        return mAssets;
-    }
-
-    @Override
-    public File getCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getCodeCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getPreloadsFileCache() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        if (mContentResolver == null) {
-            mContentResolver = new BridgeContentResolver(this);
-        }
-        return mContentResolver;
-    }
-
-    @Override
-    public File getDatabasePath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDir(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFileStreamPath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getSharedPreferencesPath(String name) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDataDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getNoBackupFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalFilesDir(String type) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getPackageCodePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getBasePackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getOpPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo() {
-        return mApplicationInfo;
-    }
-
-    @Override
-    public String getPackageResourcePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(File arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteSharedPreferences(String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public Drawable getWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        return -1;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        return -1;
-    }
-
-    @Override
-    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
-            CursorFactory arg2, DatabaseErrorHandler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Drawable peekWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, int arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3, int arg4) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
-            IntentFilter arg1, String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void removeStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(Uri arg0, int arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
-            String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, Bundle options) {
-        // pass
-    }
-
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcast(Intent intent,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
-           Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcastAsUser(Intent intent,
-            UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void setTheme(int arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(Bitmap arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(InputStream arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void startActivity(Intent arg0) {
-        // pass
-    }
-
-    @Override
-    public void startActivity(Intent arg0, Bundle arg1) {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
-            Bundle options) throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public boolean startInstrumentation(ComponentName arg0, String arg1,
-            Bundle arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startService(Intent arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundService(Intent service) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopService(Intent arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void unbindService(ServiceConnection arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void unregisterReceiver(BroadcastReceiver arg0) {
-        // pass
-
-    }
-
-    @Override
-    public Context getApplicationContext() {
-        return this;
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0, Bundle arg1) {
-        // pass
-
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return false;
-    }
-
-    @Override
-    public File getObbDir() {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
-        return null;
-    }
-
-    @Override
-    public DisplayAdjustments getDisplayAdjustments(int displayId) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Display getDisplay() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void updateDisplay(int displayId) {
-        // pass
-    }
-
-    @Override
-    public int getUserId() {
-        return 0; // not used
-    }
-
-    @Override
-    public File[] getExternalFilesDirs(String type) {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getObbDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalCacheDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalMediaDirs() {
-        // pass
-        return new File[0];
-    }
-
-    public void setScrollYPos(@NonNull View view, int scrollPos) {
-        mScrollYPos.put(view, scrollPos);
-    }
-
-    public int getScrollYPos(@NonNull View view) {
-        Integer pos = mScrollYPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    public void setScrollXPos(@NonNull View view, int scrollPos) {
-        mScrollXPos.put(view, scrollPos);
-    }
-
-    public int getScrollXPos(@NonNull View view) {
-        Integer pos = mScrollXPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    @Override
-    public Context createDeviceProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createCredentialProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean isDeviceProtectedStorage() {
-        return false;
-    }
-
-    @Override
-    public boolean isCredentialProtectedStorage() {
-        return false;
-    }
-
-    @Override
-    public boolean canLoadUnsafeResources() {
-        return false;
-    }
-
-    /**
-     * The cached value depends on
-     * <ol>
-     * <li>{@code int[]}: the attributes for which TypedArray is created </li>
-     * <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of
-     * creation of the TypedArray</li>
-     * <li>{@code Integer}: the default style used at the time of creation</li>
-     * </ol>
-     *
-     * The class is created by using nested maps resolving one dependency at a time.
-     * <p/>
-     * The final value of the nested maps is a pair of the typed array and a map of properties
-     * that should be added to {@link #mDefaultPropMaps}, if needed.
-     */
-    private static class TypedArrayCache {
-
-        private Map<int[],
-                Map<List<StyleResourceValue>,
-                        Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>> mCache;
-
-        private TypedArrayCache() {
-            mCache = new IdentityHashMap<>();
-        }
-
-        public Pair<BridgeTypedArray, PropertiesMap> get(int[] attrs,
-                List<StyleResourceValue> themes, int resId) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.get(attrs);
-            if (cacheFromThemes != null) {
-                Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                        cacheFromThemes.get(themes);
-                if (cacheFromResId != null) {
-                    return cacheFromResId.get(resId);
-                }
-            }
-            return null;
-        }
-
-        public void put(int[] attrs, List<StyleResourceValue> themes, int resId,
-                Pair<BridgeTypedArray, PropertiesMap> value) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.computeIfAbsent(attrs, k -> new HashMap<>());
-            Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                    cacheFromThemes.computeIfAbsent(themes, k -> new HashMap<>());
-            cacheFromResId.put(resId, value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
deleted file mode 100644
index 4805ed1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.android;
-
-import com.android.internal.inputmethod.IInputContentUriToken;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.InputBindResult;
-
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.text.style.SuggestionSpan;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSubtype;
-
-import java.util.List;
-
-/**
- * Basic implementation of IInputMethodManager that does nothing.
- *
- */
-public class BridgeIInputMethodManager implements IInputMethodManager {
-
-    @Override
-    public void addClient(IInputMethodClient arg0, IInputContext arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void finishInput(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public InputMethodSubtype getCurrentInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getEnabledInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
-            boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public InputMethodSubtype getLastInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List getShortcutInputMethodsAndSubtypes() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void hideMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean hideSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean notifySuggestionPicked(SuggestionSpan arg0, String arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void registerSuggestionSpansForNotification(SuggestionSpan[] arg0)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeClient(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setImeWindowStatus(IBinder arg0, IBinder arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setInputMethod(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setInputMethodAndSubtype(IBinder arg0, String arg1, InputMethodSubtype arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean setInputMethodEnabled(String arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient arg0, String arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showInputMethodPickerFromClient(IInputMethodClient arg0,
-            int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean showSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToLastInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-     public int getInputMethodWindowVisibleHeight() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void notifyUserAction(int sequenceNumber) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearLastInputMethodWindowForTransition(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public InputBindResult startInputOrWindowGainedFocus(
-            /* @InputMethodClient.StartInputReason */ int startInputReason,
-            IInputMethodClient client, IBinder windowToken, int controlFlags,
-            /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
-            int windowFlags, EditorInfo attribute, IInputContext inputContext,
-            /* @InputConnectionInspector.MissingMethodFlags */ int missingMethodFlags)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IInputContentUriToken createInputContentUriToken(IBinder token, Uri contentUri,
-            String packageName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void reportFullscreenMode(IBinder token, boolean fullscreen) {
-        // TODO Auto-generated method stub
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
deleted file mode 100644
index f5912e7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.BridgeConstants;
-
-import android.util.AttributeSet;
-
-import java.util.Map;
-
-/**
- * An implementation of the {@link AttributeSet} interface on top of a map of attribute in the form
- * of (name, value).
- *
- * This is meant to be called only from {@link BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * in the case of LayoutParams and therefore isn't a full implementation.
- */
-public class BridgeLayoutParamsMapAttributes implements AttributeSet {
-
-    private final Map<String, String> mAttributes;
-
-    public BridgeLayoutParamsMapAttributes(Map<String, String> attributes) {
-        mAttributes = attributes;
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
-            return mAttributes.get(name);
-        }
-
-        return null;
-    }
-
-    // ---- the following methods are not called from
-    // BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
-    // Should they ever be called, we'll just implement them on a need basis.
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPositionDescription() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getClassAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
deleted file mode 100644
index 1b5a54d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PackageInstallObserver;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ChangedPackages;
-import android.content.pm.InstantAppInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.IntentFilterVerificationInfo;
-import android.content.pm.KeySet;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageItemInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.VersionedPackage;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.storage.VolumeInfo;
-import java.util.List;
-
-/**
- * An implementation of {@link PackageManager} that does nothing.
- */
-@SuppressWarnings("deprecation")
-public class BridgePackageManager extends PackageManager {
-    @Override
-    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfo(VersionedPackage versionedPackage,
-            @PackageInfoFlags int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibraries(@InstallFlags int flags) {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibrariesAsUser(@InstallFlags int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public Intent getLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int flags, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public PermissionInfo getPermissionInfo(String name, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean isPermissionReviewModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getActivityInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ServiceInfo getServiceInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo getProviderInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public int checkPermission(String permName, String pkgName) {
-        return 0;
-    }
-
-    @Override
-    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
-        return false;
-    }
-
-    @Override
-    public String getPermissionControllerPackageName() {
-        return null;
-    }
-
-    @Override
-    public boolean addPermission(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public boolean addPermissionAsync(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public void removePermission(String name) {
-    }
-
-    @Override
-    public void grantRuntimePermission(String packageName, String permissionName, UserHandle user) {
-    }
-
-    @Override
-    public void revokeRuntimePermission(String packageName, String permissionName,
-            UserHandle user) {
-    }
-
-    @Override
-    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
-        return 0;
-    }
-
-    @Override
-    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
-            int flagValues, UserHandle user) {
-    }
-
-    @Override
-    public boolean shouldShowRequestPermissionRationale(String permission) {
-        return false;
-    }
-
-    @Override
-    public int checkSignatures(String pkg1, String pkg2) {
-        return 0;
-    }
-
-    @Override
-    public int checkSignatures(int uid1, int uid2) {
-        return 0;
-    }
-
-    @Override
-    public String[] getPackagesForUid(int uid) {
-        return new String[0];
-    }
-
-    @Override
-    public String getNameForUid(int uid) {
-        return null;
-    }
-
-    @Override
-    public int getUidForSharedUser(String sharedUserName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<InstantAppInfo> getInstantApps() {
-        return null;
-    }
-
-    @Override
-    public Drawable getInstantAppIcon(String packageName) {
-        assert false : "Unsupported operation";
-        return new ColorDrawable();
-    }
-
-    @Override
-    public byte[] getInstantAppCookie() {
-        return new byte[0];
-    }
-
-    @Override
-    public boolean isInstantApp() {
-        return false;
-    }
-
-    @Override
-    public boolean isInstantApp(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxBytes() {
-        return 0;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxSize() {
-        return 0;
-    }
-
-    @Override
-    public void clearInstantAppCookie() {;
-
-    }
-
-    @Override
-    public void updateInstantAppCookie(@Nullable byte[] cookie) {
-
-    }
-
-    @Override
-    public boolean setInstantAppCookie(@NonNull byte[] cookie) {
-        return false;
-    }
-
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        return new String[0];
-    }
-
-    @Override
-    public String getServicesSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public @NonNull String getSharedSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public FeatureInfo[] getSystemAvailableFeatures() {
-        return new FeatureInfo[0];
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name) {
-        return false;
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name, int version) {
-        return false;
-    }
-
-    @Override
-    public ResolveInfo resolveActivity(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
-            Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveService(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProvider(String name, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
-        return null;
-    }
-
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
-        return null;
-    }
-
-    @Override
-    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getDefaultActivityIcon() {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
-            Rect badgeLocation, int badgeDensity) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getApplicationLabel(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForActivity(ComponentName activityName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(String appPackageName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public int installExistingPackage(String packageName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int installExistingPackage(String packageName, int installReason)
-            throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int installExistingPackageAsUser(String packageName, int userId)
-            throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public void verifyPendingInstall(int id, int verificationCode) {
-    }
-
-    @Override
-    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
-            long millisecondsToDelay) {
-    }
-
-    @Override
-    public void verifyIntentFilter(int verificationId, int verificationCode,
-            List<String> outFailedDomains) {
-    }
-
-    @Override
-    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
-        return 0;
-    }
-
-    @Override
-    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
-        return false;
-    }
-
-    @Override
-    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
-        return null;
-    }
-
-    @Override
-    public List<IntentFilter> getAllIntentFilters(String packageName) {
-        return null;
-    }
-
-    @Override
-    public String getDefaultBrowserPackageNameAsUser(int userId) {
-        return null;
-    }
-
-    @Override
-    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
-    }
-
-    @Override
-    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
-    }
-
-    @Override
-    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
-    }
-
-    @Override
-    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
-            int userId) {
-    }
-
-    @Override
-    public String getInstallerPackageName(String packageName) {
-        return null;
-    }
-
-    @Override
-    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
-    }
-
-    @Override
-    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
-            IPackageStatsObserver observer) {
-    }
-
-    @Override
-    public void addPackageToPreferred(String packageName) {
-    }
-
-    @Override
-    public void removePackageFromPreferred(String packageName) {
-    }
-
-    @Override
-    public List<PackageInfo> getPreferredPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void clearPackagePreferredActivities(String packageName) {
-    }
-
-    @Override
-    public int getPreferredActivities(List<IntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName) {
-        return 0;
-    }
-
-    @Override
-    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
-        return null;
-    }
-
-    @Override
-    public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
-    }
-
-    @Override
-    public int getComponentEnabledSetting(ComponentName componentName) {
-        return 0;
-    }
-
-    @Override
-    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
-    }
-
-    @Override
-    public int getApplicationEnabledSetting(String packageName) {
-        return 0;
-    }
-
-    @Override
-    public void flushPackageRestrictionsAsUser(int userId) {
-    }
-
-    @Override
-    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
-            UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean isSafeMode() {
-        return false;
-    }
-
-    @Override
-    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public KeySet getKeySetByAlias(String packageName, String alias) {
-        return null;
-    }
-
-    @Override
-    public KeySet getSigningKeySet(String packageName) {
-        return null;
-    }
-
-    @Override
-    public boolean isSignedBy(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public boolean isSignedByExactly(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
-            int userId) {
-        return new String[]{};
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setApplicationCategoryHint(String packageName, int categoryHint) {
-    }
-
-    @Override
-    public int getMoveStatus(int moveId) {
-        return 0;
-    }
-
-    @Override
-    public void registerMoveCallback(MoveCallback callback, Handler handler) {
-    }
-
-    @Override
-    public void unregisterMoveCallback(MoveCallback callback) {
-    }
-
-    @Override
-    public int movePackage(String packageName, VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public int movePrimaryStorage(VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPrimaryStorageCurrentVolume() {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
-        return null;
-    }
-
-    @Override
-    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
-        return null;
-    }
-
-    @Override
-    public ChangedPackages getChangedPackages(int sequenceNumber) {
-        return null;
-    }
-
-    @Override
-    public boolean isUpgrade() {
-        return false;
-    }
-
-    @Override
-    public PackageInstaller getPackageInstaller() {
-        return null;
-    }
-
-    @Override
-    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
-            int flags) {
-    }
-
-    @Override
-    public void clearCrossProfileIntentFilters(int sourceUserId) {
-    }
-
-    @Override
-    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstallReason(String packageName, UserHandle user) {
-        return INSTALL_REASON_UNKNOWN;
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls() {
-        return false;
-    }
-
-    @Override
-    public ComponentName getInstantAppResolverSettingsComponent() {
-        return null;
-    }
-
-    @Override
-    public ComponentName getInstantAppInstallerComponent() {
-        return null;
-    }
-
-    @Override
-    public String getInstantAppAndroidId(String packageName, UserHandle user) {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
deleted file mode 100644
index ed428ec..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2012 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.layoutlib.bridge.android;
-
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.PowerSaveState;
-import android.os.RemoteException;
-import android.os.WorkSource;
-
-/**
- * Fake implementation of IPowerManager.
- *
- */
-public class BridgePowerManager implements IPowerManager {
-
-    @Override
-    public boolean isInteractive() throws RemoteException {
-        return true;
-    }
-
-    @Override
-    public boolean isPowerSaveMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean setPowerSaveMode(boolean mode) throws RemoteException {
-        return false;
-    }
-
-    public PowerSaveState getPowerSaveState(int serviceType) {
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void powerHint(int hintId, int data) {
-        // pass for now.
-    }
-
-    @Override
-    public void crash(String arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void goToSleep(long arg0, int arg1, int arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void nap(long arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void reboot(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void rebootSafeMode(boolean confirm, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void shutdown(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void releaseWakeLock(IBinder arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setAttentionLight(boolean arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setStayOnSetting(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1, String arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isWakeLockLevelSupported(int level) throws RemoteException {
-        // pass for now.
-        return true;
-    }
-
-    @Override
-    public void userActivity(long time, int event, int flags) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void wakeUp(long time, String reason, String opPackageName) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void boostScreenBrightness(long time) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isLightDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isScreenBrightnessBoosted() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public int getLastShutdownReason() {
-        return PowerManager.SHUTDOWN_REASON_UNKNOWN;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
deleted file mode 100644
index 132ff2f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
+++ /dev/null
@@ -1,138 +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.android.layoutlib.bridge.android;
-
-import android.content.SharedPreferences;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An empty shared preferences implementation which doesn't store anything. It always returns
- * null, 0 or false.
- */
-public class BridgeSharedPreferences implements SharedPreferences {
-    private Editor mEditor;
-
-    @Override
-    public Map<String, ?> getAll() {
-        return null;
-    }
-
-    @Override
-    public String getString(String key, String defValue) {
-        return null;
-    }
-
-    @Override
-    public Set<String> getStringSet(String key, Set<String> defValues) {
-        return null;
-    }
-
-    @Override
-    public int getInt(String key, int defValue) {
-        return 0;
-    }
-
-    @Override
-    public long getLong(String key, long defValue) {
-        return 0;
-    }
-
-    @Override
-    public float getFloat(String key, float defValue) {
-        return 0;
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return false;
-    }
-
-    @Override
-    public boolean contains(String key) {
-        return false;
-    }
-
-    @Override
-    public Editor edit() {
-        if (mEditor != null) {
-            return mEditor;
-        }
-        mEditor = new Editor() {
-            @Override
-            public Editor putString(String key, String value) {
-                return null;
-            }
-
-            @Override
-            public Editor putStringSet(String key, Set<String> values) {
-                return null;
-            }
-
-            @Override
-            public Editor putInt(String key, int value) {
-                return null;
-            }
-
-            @Override
-            public Editor putLong(String key, long value) {
-                return null;
-            }
-
-            @Override
-            public Editor putFloat(String key, float value) {
-                return null;
-            }
-
-            @Override
-            public Editor putBoolean(String key, boolean value) {
-                return null;
-            }
-
-            @Override
-            public Editor remove(String key) {
-                return null;
-            }
-
-            @Override
-            public Editor clear() {
-                return null;
-            }
-
-            @Override
-            public boolean commit() {
-                return false;
-            }
-
-            @Override
-            public void apply() {
-            }
-        };
-        return mEditor;
-    }
-
-    @Override
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    @Override
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
deleted file mode 100644
index ffbe7c4..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.internal.os.IResultReceiver;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.DragEvent;
-import android.view.IWindow;
-
-/**
- * Implementation of {@link IWindow} to pass to the AttachInfo.
- */
-public final class BridgeWindow implements IWindow {
-
-    @Override
-    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchGetNewSurface() throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
-            boolean b, MergedConfiguration mergedConfig, Rect rect7, boolean b2, boolean b3, int i0)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void moved(int arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-            boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperCommand(String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void closeSystemDialogs(String reason) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchDragEvent(DragEvent event) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(float x, float y) {
-        // pass for now
-    }
-
-    @Override
-    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
-            int localValue, int localChanges) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWindowShown() {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void dispatchPointerCaptureChanged(boolean hasCapture) {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
deleted file mode 100644
index 2c88394..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ClipData;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.IWindow;
-import android.view.IWindowId;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.WindowManager.LayoutParams;
-
-/**
- * Implementation of {@link IWindowSession} so that mSession is not null in
- * the {@link SurfaceView}.
- */
-public final class BridgeWindowSession implements IWindowSession {
-
-    @Override
-    public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3, Rect arg4,
-            InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
-                            Rect arg3, Rect arg4, Rect arg5, InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                      Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplayWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                               int displayId, Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void finishDrawing(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean getInTouchMode() throws RemoteException {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
-            int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
-            Rect rect6, Rect rect7, MergedConfiguration mergedConfig, Surface surface)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public boolean outOfMemory(IWindow window) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-        // pass for now.
-    }
-
-    @Override
-    public void remove(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInsets(IWindow window, int touchable, Rect contentInsets,
-            Rect visibleInsets, Region touchableRegion) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder prepareDrag(IWindow window, int flags,
-            int thumbnailWidth, int thumbnailHeight, Surface outSurface)
-            throws RemoteException {
-        // pass for now
-        return null;
-    }
-
-    @Override
-    public boolean performDrag(IWindow window, IBinder dragToken,
-            int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-            ClipData data)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public boolean startMovingTask(IWindow window, float startX, float startY)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void cancelDragAndDrop(IBinder dragToken) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientEntered(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientExited(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void setWallpaperPosition(IBinder window, float x, float y,
-        float xStep, float yStep) {
-        // pass for now.
-    }
-
-    @Override
-    public void wallpaperOffsetsComplete(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void setWallpaperDisplayOffset(IBinder windowToken, int x, int y) {
-        // pass for now.
-    }
-
-    @Override
-    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void wallpaperCommandComplete(IBinder window, Bundle result) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void onRectangleOnScreenRequested(IBinder window, Rect rectangle) {
-        // pass for now.
-    }
-
-    @Override
-    public IWindowId getWindowId(IBinder window) throws RemoteException {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void pokeDrawLock(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(IWindow window) {
-        // pass for now.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
deleted file mode 100644
index ac8712e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge.android;
-
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.BridgeXmlPullAttributes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser.
- * It delegates to both an instance of {@link XmlPullParser} and an instance of
- * XmlPullAttributes (for the {@link AttributeSet} part).
- */
-public class BridgeXmlBlockParser implements XmlResourceParser {
-
-    private final XmlPullParser mParser;
-    private final BridgeXmlPullAttributes mAttrib;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private boolean mStarted = false;
-    private int mEventType = START_DOCUMENT;
-
-    private boolean mPopped = true; // default to true in case it's not pushed.
-
-    /**
-     * Builds a {@link BridgeXmlBlockParser}.
-     * @param parser The XmlPullParser to get the content from.
-     * @param context the Context.
-     * @param platformFile Indicates whether the the file is a platform file or not.
-     */
-    public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("CRTE " + parser.toString());
-        }
-
-        mParser = parser;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
-
-        if (mContext != null) {
-            mContext.pushParser(this);
-            mPopped = false;
-        }
-    }
-
-    public XmlPullParser getParser() {
-        return mParser;
-    }
-
-    public boolean isPlatformFile() {
-        return mPlatformFile;
-    }
-
-    public Object getViewCookie() {
-        if (mParser instanceof ILayoutPullParser) {
-            return ((ILayoutPullParser)mParser).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void ensurePopped() {
-        if (mContext != null && mPopped == false) {
-            mContext.popParser();
-            mPopped = true;
-        }
-    }
-
-    // ------- XmlResourceParser implementation
-
-    @Override
-    public void setFeature(String name, boolean state)
-            throws XmlPullParserException {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
-            return;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
-            return;
-        }
-        throw new XmlPullParserException("Unsupported feature: " + name);
-    }
-
-    @Override
-    public boolean getFeature(String name) {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
-            return true;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void setProperty(String name, Object value) throws XmlPullParserException {
-        throw new XmlPullParserException("setProperty() not supported");
-    }
-
-    @Override
-    public Object getProperty(String name) {
-        return null;
-    }
-
-    @Override
-    public void setInput(Reader in) throws XmlPullParserException {
-        mParser.setInput(in);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String inputEncoding)
-            throws XmlPullParserException {
-        mParser.setInput(inputStream, inputEncoding);
-    }
-
-    @Override
-    public void defineEntityReplacementText(String entityName,
-            String replacementText) throws XmlPullParserException {
-        throw new XmlPullParserException(
-                "defineEntityReplacementText() not supported");
-    }
-
-    @Override
-    public String getNamespacePrefix(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespacePrefix() not supported");
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return null;
-    }
-
-    @Override
-    public String getNamespace(String prefix) {
-        throw new RuntimeException("getNamespace() not supported");
-    }
-
-    @Override
-    public int getNamespaceCount(int depth) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceCount() not supported");
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return "Binary XML file line #" + getLineNumber();
-    }
-
-    @Override
-    public String getNamespaceUri(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceUri() not supported");
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return -1;
-    }
-
-    @Override
-    public int getDepth() {
-        return mParser.getDepth();
-    }
-
-    @Override
-    public String getText() {
-        return mParser.getText();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mParser.getLineNumber();
-    }
-
-    @Override
-    public int getEventType() {
-        return mEventType;
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        // Original comment: whitespace was stripped by aapt.
-        return mParser.isWhitespace();
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new RuntimeException("getPrefix not supported");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] holderForStartAndLength) {
-        String txt = getText();
-        char[] chars = null;
-        if (txt != null) {
-            holderForStartAndLength[0] = 0;
-            holderForStartAndLength[1] = txt.length();
-            chars = new char[txt.length()];
-            txt.getChars(0, txt.length(), chars, 0);
-        }
-        return chars;
-    }
-
-    @Override
-    public String getNamespace() {
-        return mParser.getNamespace();
-    }
-
-    @Override
-    public String getName() {
-        return mParser.getName();
-    }
-
-    @Override
-    public String getAttributeNamespace(int index) {
-        return mParser.getAttributeNamespace(index);
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        return mParser.getAttributeName(index);
-    }
-
-    @Override
-    public String getAttributePrefix(int index) {
-        throw new RuntimeException("getAttributePrefix not supported");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() {
-        // XXX Need to detect this.
-        return false;
-    }
-
-    @Override
-    public int getAttributeCount() {
-        return mParser.getAttributeCount();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        return mParser.getAttributeValue(index);
-    }
-
-    @Override
-    public String getAttributeType(int index) {
-        return "CDATA";
-    }
-
-    @Override
-    public boolean isAttributeDefault(int index) {
-        return false;
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        return next();
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        return mParser.getAttributeValue(namespace, name);
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        if (!mStarted) {
-            mStarted = true;
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("STRT " + mParser.toString());
-            }
-
-            return START_DOCUMENT;
-        }
-
-        int ev = mParser.next();
-
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("NEXT " + mParser.toString() + " " +
-                    eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
-        }
-
-        if (ev == END_TAG && mParser.getDepth() == 1) {
-            // done with parser remove it from the context stack.
-            ensurePopped();
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("");
-            }
-        }
-
-        mEventType = ev;
-        return ev;
-    }
-
-    public static String eventTypeToString(int eventType) {
-        switch (eventType) {
-            case START_DOCUMENT:
-                return "START_DOC";
-            case END_DOCUMENT:
-                return "END_DOC";
-            case START_TAG:
-                return "START_TAG";
-            case END_TAG:
-                return "END_TAG";
-            case TEXT:
-                return "TEXT";
-            case CDSECT:
-                return "CDSECT";
-            case ENTITY_REF:
-                return "ENTITY_REF";
-            case IGNORABLE_WHITESPACE:
-                return "IGNORABLE_WHITESPACE";
-            case PROCESSING_INSTRUCTION:
-                return "PROCESSING_INSTRUCTION";
-            case COMMENT:
-                return "COMMENT";
-            case DOCDECL:
-                return "DOCDECL";
-        }
-
-        return "????";
-    }
-
-    @Override
-    public void require(int type, String namespace, String name)
-            throws XmlPullParserException {
-        if (type != getEventType()
-                || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName())))
-            throw new XmlPullParserException("expected " + TYPES[type]
-                    + getPositionDescription());
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        if (getEventType() != START_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG to read next text", this,
-                    null);
-        }
-        int eventType = next();
-        if (eventType == TEXT) {
-            String result = getText();
-            eventType = next();
-            if (eventType != END_TAG) {
-                throw new XmlPullParserException(
-                        getPositionDescription()
-                                + ": event TEXT it must be immediately followed by END_TAG",
-                        this, null);
-            }
-            return result;
-        } else if (eventType == END_TAG) {
-            return "";
-        } else {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG or TEXT to read text",
-                    this, null);
-        }
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        int eventType = next();
-        if (eventType == TEXT && isWhitespace()) { // skip whitespace
-            eventType = next();
-        }
-        if (eventType != START_TAG && eventType != END_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": expected start or end tag", this, null);
-        }
-        return eventType;
-    }
-
-    // AttributeSet implementation
-
-
-    @Override
-    public void close() {
-        // pass
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(index, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(index, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(int index, String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(index, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        return mAttrib.getAttributeNameResource(index);
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public String getClassAttribute() {
-        return mAttrib.getClassAttribute();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        return mAttrib.getIdAttribute();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        return mAttrib.getIdAttributeResourceValue(defaultValue);
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        return mAttrib.getStyleAttribute();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
deleted file mode 100644
index 051de90..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
+++ /dev/null
@@ -1,65 +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.android.layoutlib.bridge.android;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-
-/**
- * This contains all known keys for the {@link RenderParams#getFlag(Key)}.
- * <p/>
- * The IDE has its own copy of this class which may be newer or older than this one.
- * <p/>
- * Constants should never be modified or removed from this class.
- */
-public final class RenderParamsFlags {
-
-    public static final Key<String> FLAG_KEY_ROOT_TAG =
-            new Key<String>("rootTag", String.class);
-    public static final Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
-            new Key<Boolean>("disableBitmapCaching", Boolean.class);
-    public static final Key<Boolean> FLAG_KEY_RENDER_ALL_DRAWABLE_STATES =
-            new Key<Boolean>("renderAllDrawableStates", Boolean.class);
-    /**
-     * To tell LayoutLib that the IDE supports RecyclerView.
-     * <p/>
-     * Default is false.
-     */
-    public static final Key<Boolean> FLAG_KEY_RECYCLER_VIEW_SUPPORT =
-            new Key<Boolean>("recyclerViewSupport", Boolean.class);
-    /**
-     * The application package name. Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<String> FLAG_KEY_APPLICATION_PACKAGE =
-            new Key<String>("applicationPackage", String.class);
-    /**
-     * To tell LayoutLib that IDE supports providing XML Parser for a file (useful for getting in
-     * memory contents of the file). Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<Boolean> FLAG_KEY_XML_FILE_PARSER_SUPPORT =
-            new Key<Boolean>("xmlFileParser", Boolean.class);
-    /**
-     * To tell LayoutLib to not render when creating a new session. This allows controlling when the first
-     * layout rendering will happen.
-     */
-    public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE =
-            new Key<Boolean>("doNotRenderOnCreate", Boolean.class);
-
-    // Disallow instances.
-    private RenderParamsFlags() {}
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
deleted file mode 100644
index 131aa17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
+++ /dev/null
@@ -1,307 +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.layoutlib.bridge.android.graphics;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.NinePatch;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Picture;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-/**
- * Canvas implementation that does not do any rendering
- */
-public class NopCanvas extends Canvas {
-    private boolean mIsInitialized = false;
-
-    public NopCanvas() {
-        super();
-        mIsInitialized = true;
-    }
-
-    @Override
-    public boolean isHardwareAccelerated() {
-        // We return true the first time so there are no allocations for the software renderer in
-        // the constructor
-        return !mIsInitialized;
-    }
-
-    @Override
-    public int save() {
-        return 0;
-    }
-
-    @Override
-    public int save(int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public void restore() {
-    }
-
-    @Override
-    public int getSaveCount() {
-        return 0;
-    }
-
-    @Override
-    public void restoreToCount(int saveCount) {
-    }
-
-    @Override
-    public void drawRGB(int r, int g, int b) {
-    }
-
-    @Override
-    public void drawARGB(int a, int r, int g, int b) {
-    }
-
-    @Override
-    public void drawColor(int color) {
-    }
-
-    @Override
-    public void drawColor(int color, Mode mode) {
-    }
-
-    @Override
-    public void drawPaint(Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawPoint(float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(RectF rect, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(Rect r, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(RectF oval, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawCircle(float cx, float cy, float radius, Paint paint) {
-    }
-
-    @Override
-    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawArc(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle, boolean useCenter, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawPath(Path path, Paint paint) {
-    }
-
-    @Override
-    protected void throwIfCannotDraw(Bitmap bitmap) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
-            int vertOffset, int[] colors, int colorOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
-            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
-            int indexOffset, int indexCount, Paint paint) {
-    }
-
-    @Override
-    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(String text, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
-            float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, RectF dst) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, Rect dst) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
deleted file mode 100644
index aa873a6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with the design support lib.
- */
-public class DesignLibUtil {
-
-    private static final String PKG_PREFIX = "android.support.design.widget.";
-    public static final String CN_COORDINATOR_LAYOUT = PKG_PREFIX + "CoordinatorLayout";
-    public static final String CN_APPBAR_LAYOUT = PKG_PREFIX + "AppBarLayout";
-    public static final String CN_COLLAPSING_TOOLBAR_LAYOUT =
-            PKG_PREFIX + "CollapsingToolbarLayout";
-    public static final String CN_TOOLBAR = "android.support.v7.widget.Toolbar";
-    public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
-
-    /**
-     * Tries to set the title of a view. This is used to set the title in a
-     * CollapsingToolbarLayout.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setTitle(@NonNull View view, @Nullable String title) {
-        if (title == null) {
-            return;
-        }
-        try {
-            invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title);
-        } catch (ReflectionException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,
-                    "Error occurred while trying to set title.", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
deleted file mode 100644
index 40d3811..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.Nullable;
-import android.view.View;
-
-import static android.view.Gravity.END;
-import static android.view.Gravity.LEFT;
-import static android.view.Gravity.RIGHT;
-import static android.view.Gravity.START;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-public class DrawerLayoutUtil {
-
-    public static final String CN_DRAWER_LAYOUT = "android.support.v4.widget.DrawerLayout";
-
-    public static void openDrawer(View drawerLayout, @Nullable String drawerGravity) {
-        int gravity = -1;
-        if ("left".equals(drawerGravity)) {
-            gravity = LEFT;
-        } else if ("right".equals(drawerGravity)) {
-            gravity = RIGHT;
-        } else if ("start".equals(drawerGravity)) {
-            gravity = START;
-        } else if ("end".equals(drawerGravity)) {
-            gravity = END;
-        }
-        if (gravity > 0) {
-            openDrawer(drawerLayout, gravity);
-        }
-    }
-
-    private static void openDrawer(View drawerLayout, int gravity) {
-        try {
-            invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout,
-                    gravity);
-        } catch (ReflectionException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
-                    getCause(e), null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
deleted file mode 100644
index ab27819..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with android.support.v7.widget.RecyclerView
- */
-public class RecyclerViewUtil {
-
-    private static final String RV_PKG_PREFIX = "android.support.v7.widget.";
-    public static final String CN_RECYCLER_VIEW = RV_PKG_PREFIX + "RecyclerView";
-    private static final String CN_LAYOUT_MANAGER = CN_RECYCLER_VIEW + "$LayoutManager";
-    private static final String CN_ADAPTER = CN_RECYCLER_VIEW + "$Adapter";
-
-    // LinearLayoutManager related constants.
-    private static final String CN_LINEAR_LAYOUT_MANAGER = RV_PKG_PREFIX + "LinearLayoutManager";
-    private static final Class<?>[] LLM_CONSTRUCTOR_SIGNATURE = new Class<?>[]{Context.class};
-
-    /**
-     * Tries to create an Adapter ({@code android.support.v7.widget.RecyclerView.Adapter} and a
-     * LayoutManager {@code RecyclerView.LayoutManager} and assign these to the {@code RecyclerView}
-     * that is passed.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback layoutlibCallback, int adapterLayout) {
-        try {
-            setLayoutManager(recyclerView, context, layoutlibCallback);
-            Object adapter = createAdapter(layoutlibCallback);
-            if (adapter != null) {
-                setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
-                setProperty(adapter, int.class, adapterLayout, "setLayoutId");
-            }
-        } catch (ReflectionException e) {
-            Throwable cause = getCause(e);
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Error occurred while trying to setup RecyclerView.", cause, null);
-        }
-    }
-
-    private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback callback) throws ReflectionException {
-        if (getLayoutManager(recyclerView) == null) {
-            // Only set the layout manager if not already set by the recycler view.
-            Object layoutManager = createLayoutManager(context, callback);
-            if (layoutManager != null) {
-                setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
-            }
-        }
-    }
-
-    /** Creates a LinearLayoutManager using the provided context. */
-    @Nullable
-    private static Object createLayoutManager(@NonNull Context context,
-            @NonNull LayoutlibCallback callback)
-            throws ReflectionException {
-        try {
-            return callback.loadView(CN_LINEAR_LAYOUT_MANAGER, LLM_CONSTRUCTOR_SIGNATURE,
-                    new Object[]{context});
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @Nullable
-    private static Object getLayoutManager(View recyclerView) throws ReflectionException {
-        return invoke(getMethod(recyclerView.getClass(), "getLayoutManager"), recyclerView);
-    }
-
-    @Nullable
-    private static Object createAdapter(@NonNull LayoutlibCallback layoutlibCallback)
-            throws ReflectionException {
-        Boolean ideSupport =
-                layoutlibCallback.getFlag(RenderParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
-        if (ideSupport != Boolean.TRUE) {
-            return null;
-        }
-        try {
-            return layoutlibCallback.loadClass(CN_ADAPTER, new Class[0], new Object[0]);
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull String propertyClassName,
-      @NonNull Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        Class<?> propertyClass = ReflectionUtils.getClassInstance(propertyValue, propertyClassName);
-        setProperty(object, propertyClass, propertyValue, propertySetter);
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull Class<?> propertyClass,
-            @Nullable Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        invoke(getMethod(object.getClass(), propertySetter, propertyClass), object, propertyValue);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
deleted file mode 100644
index 6ad9efc..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
+++ /dev/null
@@ -1,282 +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.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.ScrollView;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getAccessibleMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getClassInstance;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Class with utility methods to instantiate Preferences provided by the support library.
- * This class uses reflection to access the support preference objects so it heavily depends on
- * the API being stable.
- */
-public class SupportPreferencesUtil {
-    private static final String PREFERENCE_PKG = "android.support.v7.preference";
-    private static final String PREFERENCE_MANAGER = PREFERENCE_PKG + ".PreferenceManager";
-    private static final String PREFERENCE_GROUP = PREFERENCE_PKG + ".PreferenceGroup";
-    private static final String PREFERENCE_GROUP_ADAPTER =
-      PREFERENCE_PKG + ".PreferenceGroupAdapter";
-    private static final String PREFERENCE_INFLATER = PREFERENCE_PKG + ".PreferenceInflater";
-
-    private SupportPreferencesUtil() {
-    }
-
-    @NonNull
-    private static Object instantiateClass(@NonNull LayoutlibCallback callback,
-            @NonNull String className, @Nullable Class[] constructorSignature,
-            @Nullable Object[] constructorArgs) throws ReflectionException {
-        try {
-            Object instance = callback.loadClass(className, constructorSignature, constructorArgs);
-            if (instance == null) {
-                throw new ClassNotFoundException(className + " class not found");
-            }
-            return instance;
-        } catch (ClassNotFoundException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    private static Object createPreferenceGroupAdapter(@NonNull LayoutlibCallback callback,
-            @NonNull Object preferenceScreen) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-
-        return instantiateClass(callback, PREFERENCE_GROUP_ADAPTER,
-                new Class[]{preferenceGroupClass}, new Object[]{preferenceScreen});
-    }
-
-    @NonNull
-    private static Object createInflatedPreference(@NonNull LayoutlibCallback callback,
-      @NonNull Context context, @NonNull XmlPullParser parser, @NonNull Object preferenceScreen,
-      @NonNull Object preferenceManager) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-        Object preferenceInflater = instantiateClass(callback, PREFERENCE_INFLATER,
-          new Class[]{Context.class, preferenceManager.getClass()},
-          new Object[]{context, preferenceManager});
-        Object inflatedPreference =
-                invoke(getAccessibleMethod(preferenceInflater.getClass(), "inflate",
-                        XmlPullParser.class, preferenceGroupClass), preferenceInflater, parser,
-                        null);
-
-        if (inflatedPreference == null) {
-            throw new ReflectionException("inflate method returned null");
-        }
-
-        return inflatedPreference;
-    }
-
-    /**
-     * Returns a themed wrapper context of {@link BridgeContext} with the theme specified in
-     * ?attr/preferenceTheme applied to it.
-     */
-    @Nullable
-    private static Context getThemedContext(@NonNull BridgeContext bridgeContext) {
-        RenderResources resources = bridgeContext.getRenderResources();
-        ResourceValue preferenceTheme = resources.findItemInTheme("preferenceTheme", false);
-
-        if (preferenceTheme != null) {
-            // resolve it, if needed.
-            preferenceTheme = resources.resolveResValue(preferenceTheme);
-        }
-        if (preferenceTheme instanceof StyleResourceValue) {
-            int styleId = bridgeContext.getDynamicIdByStyle(((StyleResourceValue) preferenceTheme));
-            if (styleId != 0) {
-                return new ContextThemeWrapper(bridgeContext, styleId);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link LinearLayout} containing all the UI widgets representing the preferences
-     * passed in the group adapter.
-     */
-    @Nullable
-    private static LinearLayout setUpPreferencesListView(@NonNull BridgeContext bridgeContext,
-            @NonNull Context themedContext, @NonNull ArrayList<Object> viewCookie,
-            @NonNull Object preferenceGroupAdapter) throws ReflectionException {
-        // Setup the LinearLayout that will contain the preferences
-        LinearLayout listView = new LinearLayout(themedContext);
-        listView.setOrientation(LinearLayout.VERTICAL);
-        listView.setLayoutParams(
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-
-        if (!viewCookie.isEmpty()) {
-            bridgeContext.addViewKey(listView, viewCookie.get(0));
-        }
-
-        // Get all the preferences and add them to the LinearLayout
-        Integer preferencesCount =
-                (Integer) invoke(getMethod(preferenceGroupAdapter.getClass(), "getItemCount"),
-                        preferenceGroupAdapter);
-        if (preferencesCount == null) {
-            return listView;
-        }
-
-        Method getItemId = getMethod(preferenceGroupAdapter.getClass(), "getItemId", int.class);
-        Method getItemViewType =
-                getMethod(preferenceGroupAdapter.getClass(), "getItemViewType", int.class);
-        Method onCreateViewHolder =
-                getMethod(preferenceGroupAdapter.getClass(), "onCreateViewHolder", ViewGroup.class,
-                        int.class);
-        for (int i = 0; i < preferencesCount; i++) {
-            Long id = (Long) invoke(getItemId, preferenceGroupAdapter, i);
-            if (id == null) {
-                continue;
-            }
-
-            // Get the type of the preference layout and bind it to a newly created view holder
-            Integer type = (Integer) invoke(getItemViewType, preferenceGroupAdapter, i);
-            Object viewHolder =
-                    invoke(onCreateViewHolder, preferenceGroupAdapter, listView, type);
-            if (viewHolder == null) {
-                continue;
-            }
-            invoke(getMethod(preferenceGroupAdapter.getClass(), "onBindViewHolder",
-                    viewHolder.getClass(), int.class), preferenceGroupAdapter, viewHolder, i);
-
-            try {
-                // Get the view from the view holder and add it to our layout
-                View itemView =
-                        (View) viewHolder.getClass().getField("itemView").get(viewHolder);
-
-                int arrayPosition = id.intValue() - 1; // IDs are 1 based
-                if (arrayPosition >= 0 && arrayPosition < viewCookie.size()) {
-                    bridgeContext.addViewKey(itemView, viewCookie.get(arrayPosition));
-                }
-                listView.addView(itemView);
-            } catch (IllegalAccessException | NoSuchFieldException ignored) {
-            }
-        }
-
-        return listView;
-    }
-
-    /**
-     * Inflates a preferences layout using the support library. If the support library is not
-     * available, this method will return null without advancing the parsers.
-     */
-    @Nullable
-    public static View inflatePreference(@NonNull BridgeContext bridgeContext,
-            @NonNull XmlPullParser parser, @Nullable ViewGroup root) {
-        try {
-            LayoutlibCallback callback = bridgeContext.getLayoutlibCallback();
-
-            Context context = getThemedContext(bridgeContext);
-            if (context == null) {
-                // Probably we couldn't find the "preferenceTheme" in the theme
-                return null;
-            }
-
-            // Create PreferenceManager
-            Object preferenceManager =
-                    instantiateClass(callback, PREFERENCE_MANAGER, new Class[]{Context.class},
-                            new Object[]{context});
-
-            // From this moment on, we can assume that we found the support library and that
-            // nothing should fail
-
-            // Create PreferenceScreen
-            Object preferenceScreen =
-                    invoke(getMethod(preferenceManager.getClass(), "createPreferenceScreen",
-                            Context.class), preferenceManager, context);
-            if (preferenceScreen == null) {
-                return null;
-            }
-
-            // Setup a parser that stores the list of cookies in the same order as the preferences
-            // are inflated. That way we can later reconstruct the list using the preference id
-            // since they are sequential and start in 1.
-            ArrayList<Object> viewCookie = new ArrayList<>();
-            if (parser instanceof BridgeXmlBlockParser) {
-                // Setup a parser that stores the XmlTag
-                parser = new BridgeXmlBlockParser(parser, null, false) {
-                    @Override
-                    public Object getViewCookie() {
-                        return ((BridgeXmlBlockParser) getParser()).getViewCookie();
-                    }
-
-                    @Override
-                    public int next() throws XmlPullParserException, IOException {
-                        int ev = super.next();
-                        if (ev == XmlPullParser.START_TAG) {
-                            viewCookie.add(this.getViewCookie());
-                        }
-
-                        return ev;
-                    }
-                };
-            }
-
-            // Create the PreferenceInflater
-            Object inflatedPreference =
-              createInflatedPreference(callback, context, parser, preferenceScreen,
-                preferenceManager);
-
-            // Setup the RecyclerView (set adapter and layout manager)
-            Object preferenceGroupAdapter =
-                    createPreferenceGroupAdapter(callback, inflatedPreference);
-
-            // Instead of just setting the group adapter as adapter for a RecyclerView, we manually
-            // get all the items and add them to a LinearLayout. This allows us to set the view
-            // cookies so the preferences are correctly linked to their XML.
-            LinearLayout listView = setUpPreferencesListView(bridgeContext, context, viewCookie,
-                    preferenceGroupAdapter);
-
-            ScrollView scrollView = new ScrollView(context);
-            scrollView.setLayoutParams(
-              new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-            scrollView.addView(listView);
-
-            if (root != null) {
-                root.addView(scrollView);
-            }
-
-            return scrollView;
-        } catch (ReflectionException e) {
-            return null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
deleted file mode 100644
index d7d16cf..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 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.layoutlib.bridge.android.view;
-
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Display.Mode;
-import android.view.DisplayAdjustments;
-import android.view.DisplayInfo;
-import android.view.View;
-import android.view.WindowManager;
-
-public class WindowManagerImpl implements WindowManager {
-
-    private final DisplayMetrics mMetrics;
-    private final Display mDisplay;
-
-    public WindowManagerImpl(DisplayMetrics metrics) {
-        mMetrics = metrics;
-
-        DisplayInfo info = new DisplayInfo();
-        info.logicalHeight = mMetrics.heightPixels;
-        info.logicalWidth = mMetrics.widthPixels;
-        info.supportedModes = new Mode[] {
-                new Mode(0, mMetrics.widthPixels, mMetrics.heightPixels, 60f)
-        };
-        mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info,
-                DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-    }
-
-    @Override
-    public Display getDefaultDisplay() {
-        return mDisplay;
-    }
-
-
-    @Override
-    public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-    @Override
-    public void removeView(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-
-    @Override
-    public void removeViewImmediate(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            KeyboardShortcutsReceiver receiver, int deviceId) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
deleted file mode 100644
index cdcf0ea..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-
-/**
- * Assumes that the AppCompat library is present in the project's classpath and creates an
- * actionbar around it.
- */
-public class AppCompatActionBar extends BridgeActionBar {
-
-    private Object mWindowDecorActionBar;
-    private static final String WINDOW_ACTION_BAR_CLASS = "android.support.v7.internal.app.WindowDecorActionBar";
-    // This is used on v23.1.1 and later.
-    private static final String WINDOW_ACTION_BAR_CLASS_NEW = "android.support.v7.app.WindowDecorActionBar";
-    private Class<?> mWindowActionBarClass;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-        int contentRootId = context.getProjectResourceValue(ResourceType.ID,
-                "action_bar_activity_content", 0);
-        View contentView = getDecorContent().findViewById(contentRootId);
-        if (contentView != null) {
-            assert contentView instanceof FrameLayout;
-            setContentRoot((FrameLayout) contentView);
-        } else {
-            // Something went wrong. Create a new FrameLayout in the enclosing layout.
-            FrameLayout contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        }
-        try {
-            Class[] constructorParams = {View.class};
-            Object[] constructorArgs = {getDecorContent()};
-            LayoutlibCallback callback = params.getLayoutlibCallback();
-
-            // Check if the old action bar class is present.
-            String actionBarClass = WINDOW_ACTION_BAR_CLASS;
-            try {
-                callback.findClass(actionBarClass);
-            } catch (ClassNotFoundException expected) {
-                // Failed to find the old class, use the newer one.
-                actionBarClass = WINDOW_ACTION_BAR_CLASS_NEW;
-            }
-
-            mWindowDecorActionBar = callback.loadView(actionBarClass,
-                    constructorParams, constructorArgs);
-            mWindowActionBarClass = mWindowDecorActionBar == null ? null :
-                    mWindowDecorActionBar.getClass();
-            setupActionBar();
-        } catch (Exception e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                    "Failed to load AppCompat ActionBar with unknown error.", e);
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        // We always assume that the app has requested the action bar.
-        return context.getRenderResources().getProjectResource(ResourceType.LAYOUT,
-                "abc_screen_toolbar");
-    }
-
-    @Override
-    protected LayoutInflater getInflater(BridgeContext context) {
-        // Other than the resource resolution part, the code has been taken from the support
-        // library. see code from line 269 onwards in
-        // https://android.googlesource.com/platform/frameworks/support/+/android-5.1.0_r1/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
-        Context themedContext = context;
-        RenderResources resources = context.getRenderResources();
-        ResourceValue actionBarTheme = resources.findItemInTheme("actionBarTheme", false);
-        if (actionBarTheme != null) {
-            // resolve it, if needed.
-            actionBarTheme = resources.resolveResValue(actionBarTheme);
-        }
-        if (actionBarTheme instanceof StyleResourceValue) {
-            int styleId = context.getDynamicIdByStyle(((StyleResourceValue) actionBarTheme));
-            if (styleId != 0) {
-                themedContext = new ContextThemeWrapper(context, styleId);
-            }
-        }
-        return LayoutInflater.from(themedContext);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        if (title != null && mWindowDecorActionBar != null) {
-            Method setTitle = getMethod(mWindowActionBarClass, "setTitle", CharSequence.class);
-            invoke(setTitle, mWindowDecorActionBar, title);
-        }
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        if (subtitle != null && mWindowDecorActionBar != null) {
-            Method setSubtitle = getMethod(mWindowActionBarClass, "setSubtitle", CharSequence.class);
-            invoke(setSubtitle, mWindowDecorActionBar, subtitle);
-        }
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        // Do this only if the action bar doesn't already have an icon.
-        if (icon != null && !icon.isEmpty() && mWindowDecorActionBar != null) {
-            if (invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
-                    == Boolean.TRUE) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    Method setIcon = getMethod(mWindowActionBarClass, "setIcon", Drawable.class);
-                    invoke(setIcon, mWindowDecorActionBar, iconDrawable);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        if (mWindowDecorActionBar != null) {
-            Method setHomeAsUp = getMethod(mWindowActionBarClass,
-                    "setDefaultDisplayHomeAsUpEnabled", boolean.class);
-            invoke(setHomeAsUp, mWindowDecorActionBar, homeAsUp);
-        }
-    }
-
-    @Override
-    public void createMenuPopup() {
-        // it's hard to add menus to appcompat's actionbar, since it'll use a lot of reflection.
-        // so we skip it for now.
-    }
-
-    @Nullable
-    private static Method getMethod(Class<?> owner, String name, Class<?>... parameterTypes) {
-        try {
-            return owner == null ? null : owner.getMethod(name, parameterTypes);
-        } catch (NoSuchMethodException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    @Nullable
-    private static Object invoke(Method method, Object owner, Object... args) {
-        try {
-            return method == null ? null : method.invoke(owner, args);
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    // TODO: this is duplicated from FrameworkActionBarWrapper$WindowActionBarWrapper
-    @Nullable
-    private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-        RenderResources res = mBridgeContext.getRenderResources();
-        ResourceValue value = res.findResValue(name, isFramework);
-        value = res.resolveResValue(value);
-        if (value != null) {
-            return ResourceHelper.getDrawable(value, mBridgeContext);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
deleted file mode 100644
index a439e7d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.RelativeLayout;
-
-/**
- * An abstraction over two implementations of the ActionBar - framework and appcompat.
- */
-public abstract class BridgeActionBar {
-    // Store a reference to the context so that we don't have to cast it repeatedly.
-    @NonNull protected final BridgeContext mBridgeContext;
-    @NonNull protected final SessionParams mParams;
-    // A Layout that contains the inflated action bar. The menu popup is added to this layout.
-    @Nullable protected final ViewGroup mEnclosingLayout;
-
-    private final View mDecorContent;
-    private final ActionBarCallback mCallback;
-
-    @SuppressWarnings("NullableProblems")  // Should be initialized by subclasses.
-    @NonNull private FrameLayout mContentRoot;
-
-    public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        mBridgeContext = context;
-        mParams = params;
-        mCallback = params.getLayoutlibCallback().getActionBarCallback();
-        ResourceValue layoutName = getLayoutResource(context);
-
-        int layoutId = 0;
-        if (layoutName == null) {
-            assert false : "Unable to find the layout for Action Bar.";
-        }
-        else {
-            if (layoutName.isFramework()) {
-                layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-            } else {
-                layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-
-            }
-        }
-        if (layoutId == 0) {
-            assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
-                    layoutName.getName(), layoutName.getResourceType());
-            mDecorContent = new MockView(context);
-            mEnclosingLayout = null;
-        }
-        else {
-            if (mCallback.isOverflowPopupNeeded()) {
-                // Create a RelativeLayout around the action bar, to which the overflow popup may be
-                // added.
-                mEnclosingLayout = new RelativeLayout(mBridgeContext);
-                setMatchParent(mEnclosingLayout);
-            } else {
-                mEnclosingLayout = null;
-            }
-
-            // Inflate action bar layout.
-            mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout,
-                    mEnclosingLayout != null);
-        }
-    }
-
-    /**
-     * Returns the Layout Resource that should be used to inflate the action bar. This layout
-     * should cover the complete screen, and have a FrameLayout included, where the content will
-     * be inflated.
-     */
-    protected abstract ResourceValue getLayoutResource(BridgeContext context);
-
-    protected LayoutInflater getInflater(BridgeContext context) {
-        return LayoutInflater.from(context);
-    }
-
-    protected void setContentRoot(@NonNull FrameLayout contentRoot) {
-        mContentRoot = contentRoot;
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    /**
-     * Returns the view inflated. This should contain both the ActionBar and the app content in it.
-     */
-    protected View getDecorContent() {
-        return mDecorContent;
-    }
-
-    /** Setup things like the title, subtitle, icon etc. */
-    protected void setupActionBar() {
-        setTitle();
-        setSutTitle();
-        setIcon();
-        setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP);
-    }
-
-    protected abstract void setTitle(CharSequence title);
-    protected abstract void setSubtitle(CharSequence subtitle);
-    protected abstract void setIcon(String icon);
-    protected abstract void setHomeAsUp(boolean homeAsUp);
-
-    private void setTitle() {
-        RenderResources res = mBridgeContext.getRenderResources();
-
-        String title = mParams.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            setTitle(titleValue.getValue());
-        } else {
-            setTitle(title);
-        }
-    }
-
-    private void setSutTitle() {
-        String subTitle = mCallback.getSubTitle();
-        if (subTitle != null) {
-            setSubtitle(subTitle);
-        }
-    }
-
-    private void setIcon() {
-        String appIcon = mParams.getAppIcon();
-        if (appIcon != null) {
-            setIcon(appIcon);
-        }
-    }
-
-    public abstract void createMenuPopup();
-
-    /**
-     * The root view that represents the action bar and possibly the content included in it.
-     */
-    public View getRootView() {
-        return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout;
-    }
-
-    public ActionBarCallback getCallBack() {
-        return mCallback;
-    }
-
-    protected static void setMatchParent(View view) {
-        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
deleted file mode 100644
index 7f8d992..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ /dev/null
@@ -1,137 +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.android.layoutlib.bridge.bars;
-
-import android.os._Original_Build.VERSION_CODES;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static android.os._Original_Build.VERSION_CODES.*;
-
-/**
- * Various helper methods to simulate older versions of platform.
- */
-public class Config {
-
-    // each of these resource dirs must end in '/'
-    private static final String GINGERBREAD_DIR      = "/bars/v9/";
-    private static final String JELLYBEAN_DIR        = "/bars/v18/";
-    private static final String KITKAT_DIR           = "/bars/v19/";
-    private static final String DEFAULT_RESOURCE_DIR = "/bars/v21/";
-
-    private static final List<String> sDefaultResourceDir =
-            Collections.singletonList(DEFAULT_RESOURCE_DIR);
-
-    private static final int WHITE = 0xFFFFFFFF;
-    private static final int BLACK = 0xFF000000;
-
-    public static boolean showOnScreenNavBar(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, ICE_CREAM_SANDWICH);
-    }
-
-    public static int getStatusBarColor(int platformVersion) {
-        // return white for froyo and earlier; black otherwise.
-        return isGreaterOrEqual(platformVersion, GINGERBREAD) ? BLACK : WHITE;
-    }
-
-    public static List<String> getResourceDirs(int platformVersion) {
-        // Special case the most used scenario.
-        if (platformVersion == 0) {
-            return sDefaultResourceDir;
-        }
-        List<String> list = new ArrayList<String>(4);
-        // Gingerbread - uses custom battery and wifi icons.
-        if (platformVersion <= GINGERBREAD) {
-            list.add(GINGERBREAD_DIR);
-        }
-        // ICS - JellyBean uses custom battery, wifi.
-        if (platformVersion <= JELLY_BEAN_MR2) {
-            list.add(JELLYBEAN_DIR);
-        }
-        // KitKat - uses custom wifi and nav icons.
-        if (platformVersion <= KITKAT) {
-            list.add(KITKAT_DIR);
-        }
-        list.add(DEFAULT_RESOURCE_DIR);
-
-        return Collections.unmodifiableList(list);
-    }
-
-    public static String getTime(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, N)) {
-            return "7:00";
-        }
-        if (platformVersion < GINGERBREAD) {
-            return "2:20";
-        }
-        if (platformVersion < ICE_CREAM_SANDWICH) {
-            return "2:30";
-        }
-        if (platformVersion < JELLY_BEAN) {
-            return "4:00";
-        }
-        if (platformVersion < KITKAT) {
-            return "4:30";
-        }
-        if (platformVersion < LOLLIPOP) {
-            return "4:40";
-        }
-        if (platformVersion < LOLLIPOP_MR1) {
-            return "5:00";
-        }
-        if (platformVersion < M) {
-            return "5:10";
-        }
-        if (platformVersion < N) {
-            return "6:00";
-        }
-        // Should never happen.
-        return "4:04";
-    }
-
-    public static int getTimeColor(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, KITKAT) ||
-                platformVersion > FROYO && platformVersion < HONEYCOMB) {
-            // Gingerbread and KitKat onwards.
-            return WHITE;
-        }
-        // Black for froyo.
-        if (platformVersion < GINGERBREAD) {
-            return BLACK;
-        } else if (platformVersion < KITKAT) {
-            // Honeycomb to JB-mr2: Holo blue light.
-            return 0xff33b5e5;
-        }
-        // Should never happen.
-        return WHITE;
-    }
-
-    public static String getWifiIconType(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, LOLLIPOP) ? "xml" : "png";
-    }
-
-    /**
-     * Compare simulated platform version and code from {@link VERSION_CODES} to check if
-     * the simulated platform is greater than or equal to the version code.
-     */
-    public static boolean isGreaterOrEqual(int platformVersion, int code) {
-        // simulated platform version = 0 means that we use the latest.
-        return platformVersion == 0 || platformVersion >= code;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
deleted file mode 100644
index 2984fc0..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import static android.os._Original_Build.VERSION_CODES.LOLLIPOP;
-
-/**
- * Base "bar" class for the window decor around the the edited layout.
- * This is basically an horizontal layout that loads a given layout on creation (it is read
- * through {@link Class#getResourceAsStream(String)}).
- *
- * The given layout should be a merge layout so that all the children belong to this class directly.
- *
- * It also provides a few utility methods to configure the content of the layout.
- */
-abstract class CustomBar extends LinearLayout {
-
-
-    private final int mSimulatedPlatformVersion;
-
-    protected abstract TextView getStyleableTextView();
-
-    protected CustomBar(BridgeContext context, int orientation, String layoutPath,
-            String name, int simulatedPlatformVersion) {
-        super(context);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-        setOrientation(orientation);
-        if (orientation == LinearLayout.HORIZONTAL) {
-            setGravity(Gravity.CENTER_VERTICAL);
-        } else {
-            setGravity(Gravity.CENTER_HORIZONTAL);
-        }
-
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-
-        XmlPullParser parser;
-        try {
-            parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name);
-
-            BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
-
-            try {
-                inflater.inflate(bridgeParser, this, true);
-            } finally {
-                bridgeParser.ensurePopped();
-            }
-        } catch (XmlPullParserException e) {
-            // Should not happen as the resource is bundled with the jar, and  ParserFactory should
-            // have been initialized.
-            assert false;
-        }
-    }
-
-    protected void loadIcon(int index, String iconName, Density density) {
-        loadIcon(index, iconName, density, false);
-    }
-
-    protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            LayoutDirection dir = isRtl ? LayoutDirection.RTL : null;
-            IconLoader iconLoader = new IconLoader(iconName, density, mSimulatedPlatformVersion,
-                    dir);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                density = iconLoader.getDensity();
-                String path = iconLoader.getPath();
-                // look for a cached bitmap
-                Bitmap bitmap = Bridge.getCachedBitmap(path, Boolean.TRUE /*isFramework*/);
-                if (bitmap == null) {
-                    try {
-                        bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(path, bitmap, Boolean.TRUE /*isFramework*/);
-                    } catch (IOException e) {
-                        return;
-                    }
-                }
-
-                if (bitmap != null) {
-                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
-                            bitmap);
-                    imageView.setImageDrawable(drawable);
-                }
-            }
-        }
-    }
-
-    protected TextView setText(int index, String string, boolean reference) {
-        View child = getChildAt(index);
-        if (child instanceof TextView) {
-            TextView textView = (TextView) child;
-            setText(textView, string, reference);
-            return textView;
-        }
-
-        return null;
-    }
-
-    private void setText(TextView textView, String string, boolean reference) {
-        if (reference) {
-            ResourceValue value = getResourceValue(string);
-            if (value != null) {
-                string = value.getValue();
-            }
-        }
-        textView.setText(string);
-    }
-
-    protected void setStyle(String themeEntryName) {
-
-        BridgeContext bridgeContext = getContext();
-        RenderResources res = bridgeContext.getRenderResources();
-
-        ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/);
-        value = res.resolveResValue(value);
-
-        if (!(value instanceof StyleResourceValue)) {
-            return;
-        }
-
-        StyleResourceValue style = (StyleResourceValue) value;
-
-        // get the background
-        ResourceValue backgroundValue = res.findItemInStyle(style, "background",
-                true /*isFrameworkAttr*/);
-        backgroundValue = res.resolveResValue(backgroundValue);
-        if (backgroundValue != null) {
-            Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
-            if (d != null) {
-                setBackground(d);
-            }
-        }
-
-        TextView textView = getStyleableTextView();
-        if (textView != null) {
-            // get the text style
-            ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle",
-                    true /*isFrameworkAttr*/);
-            textStyleValue = res.resolveResValue(textStyleValue);
-            if (textStyleValue instanceof StyleResourceValue) {
-                StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
-
-                ResourceValue textSize = res.findItemInStyle(textStyle, "textSize",
-                        true /*isFrameworkAttr*/);
-                textSize = res.resolveResValue(textSize);
-
-                if (textSize != null) {
-                    TypedValue out = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
-                            true /*requireUnit*/)) {
-                        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                                out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
-                    }
-                }
-
-
-                ResourceValue textColor = res.findItemInStyle(textStyle, "textColor",
-                        true);
-                textColor = res.resolveResValue(textColor);
-                if (textColor != null) {
-                    ColorStateList stateList = ResourceHelper.getColorStateList(
-                            textColor, bridgeContext);
-                    if (stateList != null) {
-                        textView.setTextColor(stateList);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public BridgeContext getContext() {
-        return (BridgeContext) mContext;
-    }
-
-    /**
-     * Find the background color for this bar from the theme attributes. Only relevant to StatusBar
-     * and NavigationBar.
-     * <p/>
-     * Returns 0 if not found.
-     *
-     * @param colorAttrName the attribute name for the background color
-     * @param translucentAttrName the attribute name for the translucency property of the bar.
-     *
-     * @throws NumberFormatException if color resolved to an invalid string.
-     */
-    protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) {
-        if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) {
-            return 0;
-        }
-        RenderResources renderResources = getContext().getRenderResources();
-        // First check if the bar is translucent.
-        boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources,
-                translucentAttrName, true, false);
-        if (translucent) {
-            // Keep in sync with R.color.system_bar_background_semi_transparent from system ui.
-            return 0x66000000;  // 40% black.
-        }
-        boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources,
-                "windowDrawsSystemBarBackgrounds", true, false);
-        if (transparent) {
-            return getColor(renderResources, colorAttrName);
-        }
-        return 0;
-    }
-
-    private static int getColor(RenderResources renderResources, String attr) {
-        // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue.
-        ResourceValue resource = renderResources.findItemInTheme(attr, true);
-        // Form @color/bar to the #AARRGGBB
-        resource = renderResources.resolveResValue(resource);
-        if (resource != null) {
-            ResourceType type = resource.getResourceType();
-            if (type == null || type == ResourceType.COLOR) {
-                // if no type is specified, the value may have been specified directly in the style
-                // file, rather than referencing a color resource value.
-                try {
-                    return ResourceHelper.getColor(resource.getValue());
-                } catch (NumberFormatException e) {
-                    // Conversion failed.
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Theme attribute @android:" + attr +
-                                    " does not reference a color, instead is '" +
-                                    resource.getValue() + "'.", resource);
-                }
-            }
-        }
-        return 0;
-    }
-
-    private ResourceValue getResourceValue(String reference) {
-        RenderResources res = getContext().getRenderResources();
-
-        // find the resource
-        ResourceValue value = res.findResValue(reference, false);
-
-        // resolve it if needed
-        return res.resolveResValue(value);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
deleted file mode 100644
index fd49c77..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
+++ /dev/null
@@ -1,258 +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.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.internal.R;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.InflateException;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ActionMenuPresenter;
-import android.widget.FrameLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-
-import java.util.ArrayList;
-
-/**
- * Creates the ActionBar as done by the framework.
- */
-public class FrameworkActionBar extends BridgeActionBar {
-
-    private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
-
-    // The Action Bar
-    @NonNull private FrameworkActionBarWrapper mActionBar;
-
-    // A fake parent for measuring views.
-    @Nullable private ViewGroup mMeasureParent;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-
-        View decorContent = getDecorContent();
-
-        mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(),
-                decorContent);
-
-        FrameLayout contentRoot = (FrameLayout) decorContent.findViewById(android.R.id.content);
-
-        // If something went wrong and we were not able to initialize the content root,
-        // just add a frame layout inside this and return.
-        if (contentRoot == null) {
-            contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        } else {
-            setContentRoot(contentRoot);
-            setupActionBar();
-            mActionBar.inflateMenus();
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        ResourceValue layoutName =
-                context.getRenderResources().findItemInTheme(LAYOUT_ATTR_NAME, true);
-        if (layoutName != null) {
-            // We may need to resolve the reference obtained.
-            layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
-                    layoutName.isFramework());
-        }
-        if (layoutName == null) {
-             throw new InflateException("Unable to find action bar layout (" + LAYOUT_ATTR_NAME
-                    + ") in the current theme.");
-        }
-        return layoutName;
-    }
-
-    @Override
-    protected void setupActionBar() {
-        super.setupActionBar();
-        mActionBar.setupActionBar();
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setHomeAsUp(homeAsUp);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        mActionBar.setSubTitle(subtitle);
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        mActionBar.setIcon(icon);
-    }
-
-    /**
-     * Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
-     * the content frame which shall serve as the new content root.
-     */
-    @Override
-    public void createMenuPopup() {
-        if (!isOverflowPopupNeeded()) {
-            return;
-        }
-
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        MenuBuilder menu = mActionBar.getMenuBuilder();
-        OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
-
-        ListView listView = new ListView(mActionBar.getPopupContext(), null,
-                R.attr.dropDownListViewStyle);
-        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
-                measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
-        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
-        if (mActionBar.isSplit()) {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-            layoutParams.bottomMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        } else {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
-            layoutParams.topMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        }
-        layoutParams.setMarginEnd(getPixelValue("5dp", metrics));
-        listView.setLayoutParams(layoutParams);
-        listView.setAdapter(adapter);
-        final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
-                R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
-        listView.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
-        listView.setDivider(a.getDrawable(R.attr.actionBarDivider));
-        a.recycle();
-        listView.setElevation(mActionBar.getMenuPopupElevation());
-        assert mEnclosingLayout != null : "Unable to find view to attach ActionMenuPopup.";
-        mEnclosingLayout.addView(listView);
-    }
-
-    private boolean isOverflowPopupNeeded() {
-        boolean needed = mActionBar.isOverflowPopupNeeded();
-        if (!needed) {
-            return false;
-        }
-        // Copied from android.widget.ActionMenuPresenter.updateMenuView()
-        ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
-        ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
-        if (presenter == null) {
-            assert false : "Failed to create a Presenter for Action Bar Menus.";
-            return false;
-        }
-        if (presenter.isOverflowReserved() &&
-                menus != null) {
-            final int count = menus.size();
-            if (count == 1) {
-                needed = !menus.get(0).isActionViewExpanded();
-            } else {
-                needed = count > 0;
-            }
-        }
-        return needed;
-    }
-
-    // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth()
-    private int measureContentWidth(@NonNull ListAdapter adapter) {
-        // Menus don't tend to be long, so this is more sane than it looks.
-        int maxWidth = 0;
-        View itemView = null;
-        int itemType = 0;
-
-        Context context = mActionBar.getPopupContext();
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int count = adapter.getCount();
-        for (int i = 0; i < count; i++) {
-            final int positionType = adapter.getItemViewType(i);
-            if (positionType != itemType) {
-                itemType = positionType;
-                itemView = null;
-            }
-
-            if (mMeasureParent == null) {
-                mMeasureParent = new FrameLayout(context);
-            }
-
-            itemView = adapter.getView(i, itemView, mMeasureParent);
-            itemView.measure(widthMeasureSpec, heightMeasureSpec);
-
-            final int itemWidth = itemView.getMeasuredWidth();
-            int popupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
-                    context.getResources().getDimensionPixelSize(R.dimen.config_prefDialogWidth));
-            if (itemWidth >= popupMaxWidth) {
-                return popupMaxWidth;
-            } else if (itemWidth > maxWidth) {
-                maxWidth = itemWidth;
-            }
-        }
-
-        return maxWidth;
-    }
-
-    static int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) {
-        TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/);
-        return (int) typedValue.getDimension(metrics);
-    }
-
-    // TODO: This is duplicated from RenderSessionImpl.
-    private int getActionBarHeight() {
-        RenderResources resources = mBridgeContext.getRenderResources();
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        ResourceValue value = resources.findItemInTheme("actionBarSize", true);
-
-        // resolve it
-        value = resources.resolveResValue(value);
-
-        if (value != null) {
-            // get the numerical value, if available
-            TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
-                    true);
-            if (typedValue != null) {
-                // compute the pixel value based on the display metrics
-                return (int) typedValue.getDimension(metrics);
-
-            }
-        }
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
deleted file mode 100644
index 2cdc647..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
+++ /dev/null
@@ -1,379 +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.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.R;
-import com.android.internal.app.ToolbarActionBar;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.widget.ActionBarAccessor;
-import com.android.internal.widget.ActionBarView;
-import com.android.internal.widget.DecorToolbar;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowCallback;
-import android.widget.ActionMenuPresenter;
-import android.widget.ActionMenuView;
-import android.widget.Toolbar;
-import android.widget.Toolbar_Accessor;
-
-import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
-import static com.android.resources.ResourceType.MENU;
-
-/**
- * A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
- */
-public abstract class FrameworkActionBarWrapper {
-
-    @NonNull protected ActionBar mActionBar;
-    @NonNull protected ActionBarCallback mCallback;
-    @NonNull protected BridgeContext mContext;
-
-    /**
-     * Returns a wrapper around different implementations of the Action Bar to provide a common API.
-     *
-     * @param decorContent the top level view returned by inflating
-     *                     ?attr/windowActionBarFullscreenDecorLayout
-     */
-    @NonNull
-    public static FrameworkActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
-            @NonNull ActionBarCallback callback, @NonNull View decorContent) {
-        View view = decorContent.findViewById(R.id.action_bar);
-        if (view instanceof Toolbar) {
-            return new ToolbarWrapper(context, callback, (Toolbar) view);
-        } else if (view instanceof ActionBarView) {
-            return new WindowActionBarWrapper(context, callback, decorContent,
-                    (ActionBarView) view);
-        } else {
-            throw new IllegalStateException("Can't make an action bar out of " +
-                    view.getClass().getSimpleName());
-        }
-    }
-
-    FrameworkActionBarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-            @NonNull ActionBar actionBar) {
-        mActionBar = actionBar;
-        mCallback = callback;
-        mContext = context;
-    }
-
-    /** A call to setup any custom properties. */
-    protected void setupActionBar() {
-        // Nothing to do here.
-    }
-
-    public void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    public void setSubTitle(CharSequence subTitle) {
-        if (subTitle != null) {
-            mActionBar.setSubtitle(subTitle);
-        }
-    }
-
-    public void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setDisplayHomeAsUpEnabled(homeAsUp);
-    }
-
-    public void setIcon(String icon) {
-        // Nothing to do.
-    }
-
-    protected boolean isSplit() {
-        return getDecorToolbar().isSplit();
-    }
-
-    protected boolean isOverflowPopupNeeded() {
-        return mCallback.isOverflowPopupNeeded();
-    }
-
-    /**
-     * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
-     * adds them to the action bar.
-     */
-    protected void inflateMenus() {
-        MenuInflater inflater = new MenuInflater(getActionMenuContext());
-        MenuBuilder menuBuilder = getMenuBuilder();
-        for (String name : mCallback.getMenuIdNames()) {
-            int id;
-            if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
-                // Framework menu.
-                name = name.substring(ANDROID_NS_NAME_PREFIX.length());
-                id = mContext.getFrameworkResourceValue(MENU, name, -1);
-            } else {
-                // Project menu.
-                id = mContext.getProjectResourceValue(MENU, name, -1);
-            }
-            if (id > -1) {
-                inflater.inflate(id, menuBuilder);
-            }
-        }
-    }
-
-    /**
-     * The context used for the ActionBar and the menus in the ActionBarView.
-     */
-    @NonNull
-    protected Context getActionMenuContext() {
-        return mActionBar.getThemedContext();
-    }
-
-    /**
-     * The context used to inflate the popup menu.
-     */
-    @NonNull
-    abstract Context getPopupContext();
-
-    /**
-     * The Menu in which to inflate the user's menus.
-     */
-    @NonNull
-    abstract MenuBuilder getMenuBuilder();
-
-    @Nullable
-    abstract ActionMenuPresenter getActionMenuPresenter();
-
-    /**
-     * Framework's wrapper over two ActionBar implementations.
-     */
-    @NonNull
-    abstract DecorToolbar getDecorToolbar();
-
-    abstract int getMenuPopupElevation();
-
-    /**
-     * Margin between the menu popup and the action bar.
-     */
-    abstract int getMenuPopupMargin();
-
-    // ---- The implementations ----
-
-    /**
-     * Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
-     * Toolbar using a common API.
-     */
-    private static class ToolbarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull
-        private final Toolbar mToolbar;  // This is the view.
-
-        ToolbarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-                @NonNull Toolbar toolbar) {
-            super(context, callback, new ToolbarActionBar(toolbar, "", new WindowCallback()));
-            mToolbar = toolbar;
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // Inflating the menus isn't enough. ActionMenuPresenter needs to be initialized too.
-            MenuBuilder menu = getMenuBuilder();
-            DecorToolbar decorToolbar = getDecorToolbar();
-            // Setting a menu different from the above initializes the presenter.
-            decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
-            // ActionMenuView needs to be recreated to be able to set the menu back.
-            ActionMenuPresenter presenter = getActionMenuPresenter();
-            if (presenter != null) {
-                presenter.setMenuView(new ActionMenuView(getPopupContext()));
-            }
-            decorToolbar.setMenu(menu, null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return Toolbar_Accessor.getPopupContext(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            return (MenuBuilder) mToolbar.getMenu();
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return Toolbar_Accessor.getActionMenuPresenter(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        DecorToolbar getDecorToolbar() {
-            return mToolbar.getWrapper();
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 10;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return 0;
-        }
-    }
-
-    /**
-     * Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
-     * access to it using a common API.
-     */
-    private static class WindowActionBarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull private final WindowDecorActionBar mActionBar;
-        @NonNull private final ActionBarView mActionBarView;
-        @NonNull private final View mDecorContentRoot;
-        private MenuBuilder mMenuBuilder;
-
-        public WindowActionBarWrapper(@NonNull BridgeContext context,
-                @NonNull ActionBarCallback callback, @NonNull View decorContentRoot,
-                @NonNull ActionBarView actionBarView) {
-            super(context, callback, new WindowDecorActionBar(decorContentRoot));
-            mActionBarView = actionBarView;
-            mActionBar = (WindowDecorActionBar) super.mActionBar;
-            mDecorContentRoot = decorContentRoot;
-        }
-
-        @Override
-        protected void setupActionBar() {
-
-            // Set the navigation mode.
-            int navMode = mCallback.getNavigationMode();
-            mActionBar.setNavigationMode(navMode);
-            //noinspection deprecation
-            if (navMode == ActionBar.NAVIGATION_MODE_TABS) {
-                setupTabs(3);
-            }
-
-            // Set action bar to be split, if needed.
-            ViewGroup splitView = (ViewGroup) mDecorContentRoot.findViewById(R.id.split_action_bar);
-            if (splitView != null) {
-                mActionBarView.setSplitView(splitView);
-                Resources res = mContext.getResources();
-                boolean split = res.getBoolean(R.bool.split_action_bar_is_narrow)
-                        && mCallback.getSplitActionBarWhenNarrow();
-                mActionBarView.setSplitToolbar(split);
-            }
-        }
-
-        @Override
-        public void setIcon(String icon) {
-            // Set the icon only if the action bar doesn't specify an icon.
-            if (!mActionBar.hasIcon() && icon != null) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    mActionBar.setIcon(iconDrawable);
-                }
-            }
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // The super implementation doesn't set the menu on the view. Set it here.
-            mActionBarView.setMenu(getMenuBuilder(), null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return getActionMenuContext();
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            if (mMenuBuilder == null) {
-                mMenuBuilder = new MenuBuilder(getActionMenuContext());
-            }
-            return mMenuBuilder;
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return ActionBarAccessor.getActionMenuPresenter(mActionBarView);
-        }
-
-        @NonNull
-        @Override
-        ActionBarView getDecorToolbar() {
-            return mActionBarView;
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 0;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return -FrameworkActionBar.getPixelValue("10dp", mContext.getMetrics());
-        }
-
-        // TODO: Use an adapter, like List View to set up tabs.
-        @SuppressWarnings("deprecation")  // For Tab
-        private void setupTabs(int num) {
-            for (int i = 1; i <= num; i++) {
-                Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
-                    @Override
-                    public void onTabUnselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabSelected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabReselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                });
-                mActionBar.addTab(tab);
-            }
-        }
-
-        @Nullable
-        private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue value = res.findResValue(name, isFramework);
-            value = res.resolveResValue(value);
-            if (value != null) {
-                return ResourceHelper.getDrawable(value, mContext);
-            }
-            return null;
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
deleted file mode 100644
index 9ab2e82..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
+++ /dev/null
@@ -1,125 +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.android.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-
-import java.io.InputStream;
-
-public class IconLoader {
-
-    private final String mIconName;
-    private final Density mDesiredDensity;
-    private final int mPlatformVersion;
-    private final LayoutDirection mDirection;
-
-    private Density mCurrentDensity;
-    private StringBuilder mCurrentPath;
-
-    IconLoader(String iconName, Density density, int platformVersion, LayoutDirection direction) {
-        mIconName = iconName;
-        mDesiredDensity = density;
-        mPlatformVersion = platformVersion;
-        mDirection = direction;
-        // An upper bound on the length of the path for the icon: /bars/v21/ldrtl-xxxhdpi/
-        final int iconPathLength = 24;
-        mCurrentPath = new StringBuilder(iconPathLength + iconName.length());
-    }
-
-    public InputStream getIcon() {
-        for (String resourceDir : Config.getResourceDirs(mPlatformVersion)) {
-            mCurrentDensity = null;
-            InputStream stream = getIcon(resourceDir);
-            if (stream != null) {
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the density of the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public Density getDensity() {
-        return mCurrentDensity;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the path to the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public String getPath() {
-        return mCurrentPath.toString();
-    }
-
-    /**
-     * Search for icon in the resource directory. This iterates over all densities.
-     * If a match is found, mCurrentDensity will be set to the icon's density.
-     */
-    private InputStream getIcon(String resourceDir) {
-        // First check for the desired density.
-        InputStream stream = getIcon(resourceDir, mDesiredDensity);
-        if (stream != null) {
-            mCurrentDensity = mDesiredDensity;
-            return stream;
-        }
-        // Didn't find in the desired density. Search in all.
-        for (Density density : Density.values()) {
-            if (density == mDesiredDensity) {
-                // Skip the desired density since it's already been checked.
-                continue;
-            }
-            stream = getIcon(resourceDir, density);
-            if (stream != null) {
-                mCurrentDensity = density;
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the icon for given density present in the given resource directory, taking layout
-     * direction into consideration.
-     */
-    private InputStream getIcon(String resourceDir, Density density) {
-        mCurrentPath.setLength(0);
-        // Currently we don't have any LTR only resources and hence the check is skipped. If they
-        // are ever added, change to:
-        // if (mDirection == LayoutDirection.RTL || mDirection == LayoutDirection.LTR) {
-        if (mDirection == LayoutDirection.RTL) {
-            mCurrentPath.append(resourceDir)
-                    .append(mDirection.getResourceValue())
-                    .append('-')
-                    .append(density.getResourceValue())
-                    .append('/')
-                    .append(mIconName);
-            InputStream stream = getClass().getResourceAsStream(mCurrentPath.toString());
-            if (stream != null) {
-                return stream;
-            }
-            mCurrentPath.setLength(0);
-        }
-        mCurrentPath.append(resourceDir)
-                .append(density.getResourceValue())
-                .append('/')
-                .append(mIconName);
-        return getClass().getResourceAsStream(mCurrentPath.toString());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
deleted file mode 100644
index dfbc69b..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class NavigationBar extends CustomBar {
-
-    /** Navigation bar background color attribute name. */
-    private static final String ATTR_COLOR = "navigationBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation";
-    // These correspond to @dimen/navigation_side_padding in the system ui code.
-    private static final int PADDING_WIDTH_DEFAULT = 36;
-    private static final int PADDING_WIDTH_SW360 = 40;
-    private static final int PADDING_WIDTH_SW400 = 50;
-    // These corresponds to @dimen/navigation_key_width in the system ui code.
-    private static final int WIDTH_DEFAULT = 36;
-    private static final int WIDTH_SW360 = 40;
-    private static final int WIDTH_SW600 = 48;
-    protected static final String LAYOUT_XML = "/bars/navigation_bar.xml";
-    private static final String LAYOUT_600DP_XML = "/bars/navigation_bar600dp.xml";
-
-    public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion) {
-        this(context, density, orientation, isRtl, rtlEnabled, simulatedPlatformVersion,
-          getShortestWidth(context)>= 600 ? LAYOUT_600DP_XML : LAYOUT_XML);
-    }
-
-    protected NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion, String layoutPath) {
-        super(context, orientation, layoutPath, "navigation_bar.xml", simulatedPlatformVersion);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? 0xFF000000 : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is a spacer.
-        int back = 1;
-        int recent = 5;
-        if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
-            // If RTL is enabled, then layoutlib mirrors the layout for us.
-            back = 5;
-            recent = 1;
-        }
-
-        //noinspection SpellCheckingInspection
-        loadIcon(back, "ic_sysbar_back.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(3, "ic_sysbar_home.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
-        setupNavBar(context, orientation);
-    }
-
-    private void setupNavBar(BridgeContext context, int orientation) {
-        float sw = getShortestWidth(context);
-        View leftPadding = getChildAt(0);
-        View rightPadding = getChildAt(6);
-        setSize(context, leftPadding, orientation, getSidePadding(sw));
-        setSize(context, rightPadding, orientation, getSidePadding(sw));
-        int navButtonWidth = getWidth(sw);
-        for (int i = 1; i < 6; i += 2) {
-            View navButton = getChildAt(i);
-            setSize(context, navButton, orientation, navButtonWidth);
-        }
-        if (sw >= 600) {
-            setSize(context, getChildAt(2), orientation, 128);
-            setSize(context, getChildAt(4), orientation, 128);
-        }
-    }
-
-    private static void setSize(BridgeContext context, View view, int orientation, int size) {
-        size *= context.getMetrics().density;
-        LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
-        if (orientation == HORIZONTAL) {
-            layoutParams.width = size;
-        } else {
-            layoutParams.height = size;
-        }
-        view.setLayoutParams(layoutParams);
-    }
-
-    protected int getSidePadding(float sw) {
-        if (sw >= 400) {
-            return PADDING_WIDTH_SW400;
-        }
-        if (sw >= 360) {
-            return PADDING_WIDTH_SW360;
-        }
-        return PADDING_WIDTH_DEFAULT;
-    }
-
-    private static int getWidth(float sw) {
-        if (sw >= 600) {
-            return WIDTH_SW600;
-        }
-        if (sw >= 360) {
-            return WIDTH_SW360;
-        }
-        return WIDTH_DEFAULT;
-    }
-
-    private static float getShortestWidth(BridgeContext context) {
-        DisplayMetrics metrics = context.getMetrics();
-        float sw = metrics.widthPixels < metrics.heightPixels ?
-                metrics.widthPixels : metrics.heightPixels;
-        sw /= metrics.density;
-        return sw;
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
deleted file mode 100644
index 778305d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
+++ /dev/null
@@ -1,99 +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.android.layoutlib.bridge.bars;
-
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-import java.util.ArrayList;
-
-/**
- * Provides an adapter for Overflow menu popup. This is very similar to
- * {@code MenuPopupHelper.MenuAdapter}
- */
-public class OverflowMenuAdapter extends BaseAdapter {
-
-    private final MenuBuilder mMenu;
-    private int mExpandedIndex = -1;
-    private final Context context;
-
-    public OverflowMenuAdapter(MenuBuilder menu, Context context) {
-        mMenu = menu;
-        findExpandedIndex();
-        this.context = context;
-    }
-
-    @Override
-    public int getCount() {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex < 0) {
-            return items.size();
-        }
-        return items.size() - 1;
-    }
-
-    @Override
-    public MenuItemImpl getItem(int position) {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
-            position++;
-        }
-        return items.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        // Since a menu item's ID is optional, we'll use the position as an
-        // ID for the item in the AdapterView
-        return position;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        if (convertView == null) {
-            LayoutInflater mInflater = LayoutInflater.from(context);
-            convertView = mInflater.inflate(com.android.internal.R.layout.popup_menu_item_layout,
-                    parent, false);
-        }
-
-        MenuView.ItemView itemView = (MenuView.ItemView) convertView;
-        itemView.initialize(getItem(position), 0);
-        return convertView;
-    }
-
-    private void findExpandedIndex() {
-        final MenuItemImpl expandedItem = mMenu.getExpandedItem();
-        if (expandedItem != null) {
-            final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-            final int count = items.size();
-            for (int i = 0; i < count; i++) {
-                final MenuItemImpl item = items.get(i);
-                if (item == expandedItem) {
-                    mExpandedIndex = i;
-                    return;
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
deleted file mode 100644
index 2dc7c65..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class StatusBar extends CustomBar {
-
-    private final int mSimulatedPlatformVersion;
-    /** Status bar background color attribute name. */
-    private static final String ATTR_COLOR = "statusBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus";
-
-    /**
-     * Constructor to be used when creating the {@link StatusBar} as a regular control. This
-     * is currently used by the theme editor.
-     */
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(Context context, AttributeSet attrs) {
-        this((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                context.getApplicationInfo().targetSdkVersion);
-    }
-
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(BridgeContext context, Density density, boolean isRtl, boolean rtlEnabled,
-            int simulatedPlatformVersion) {
-        // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-        super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
-                simulatedPlatformVersion);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-
-        // FIXME: use FILL_H?
-        setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is the spacer
-        loadIcon(1, "stat_sys_wifi_signal_4_fully."
-                        + Config.getWifiIconType(simulatedPlatformVersion), density);
-        loadIcon(2, "stat_sys_battery_100.png", density);
-        setText(3, Config.getTime(simulatedPlatformVersion), false)
-                .setTextColor(Config.getTimeColor(simulatedPlatformVersion));
-    }
-
-    @Override
-    protected void loadIcon(int index, String iconName, Density density) {
-        if (!iconName.endsWith(".xml")) {
-            super.loadIcon(index, iconName, density);
-            return;
-        }
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-            // The xml is stored only in xhdpi.
-            IconLoader iconLoader = new IconLoader(iconName, Density.XHIGH,
-                    mSimulatedPlatformVersion, null);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                try {
-                    BridgeXmlBlockParser parser = new BridgeXmlBlockParser(
-                            ParserFactory.create(stream, null), (BridgeContext) mContext, true);
-                    imageView.setImageDrawable(
-                            Drawable.createFromXml(mContext.getResources(), parser));
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                } catch (IOException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
deleted file mode 100644
index 0435280..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * Navigation Bar for the Theme Editor preview.
- *
- * For small bars, it is identical to {@link NavigationBar}.
- * But wide bars from {@link NavigationBar} are too wide for the Theme Editor preview.
- * To solve that problem, {@link ThemePreviewNavigationBar} use the layout for small bars,
- * and have no padding on the sides. That way, they have a similar look as the true ones,
- * and they fit in the Theme Editor preview.
- */
-public class ThemePreviewNavigationBar extends NavigationBar {
-    private static final int PADDING_WIDTH_SW600 = 0;
-
-    @SuppressWarnings("unused")
-    public ThemePreviewNavigationBar(Context context, AttributeSet attrs) {
-        super((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                0, LAYOUT_XML);
-    }
-
-    @Override
-    protected int getSidePadding(float sw) {
-        if (sw >= 600) {
-            return PADDING_WIDTH_SW600;
-        }
-        return super.getSidePadding(sw);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
deleted file mode 100644
index 4fe1001..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class TitleBar extends CustomBar {
-
-    private TextView mTextView;
-
-    public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) {
-        super(context, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml",
-                simulatedPlatformVersion);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        mTextView = setText(0, label, true);
-
-        setStyle("windowTitleBackgroundStyle");
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return mTextView;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
deleted file mode 100644
index 11da445..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.layoutlib.bridge.util.Debug;
-import com.android.layoutlib.bridge.util.SparseWeakArray;
-
-import android.annotation.Nullable;
-import android.util.SparseArray;
-
-import java.io.PrintStream;
-import java.lang.ref.WeakReference;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Manages native delegates.
- *
- * This is used in conjunction with layoublib_create: certain Android java classes are mere
- * wrappers around a heavily native based implementation, and we need a way to run these classes
- * in our Android Studio rendering framework without bringing all the native code from the Android
- * platform.
- *
- * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their
- * native methods by "delegate calls".
- *
- * For example, a native method android.graphics.Matrix.init(...) will actually become
- * a call to android.graphics.Matrix_Delegate.init(...).
- *
- * The Android java classes that use native code uses an int (Java side) to reference native
- * objects. This int is generally directly the pointer to the C structure counterpart.
- * Typically a creation method will return such an int, and then this int will be passed later
- * to a Java method to identify the C object to manipulate.
- *
- * Since we cannot use the Java object reference as the int directly, DelegateManager manages the
- * int -> Delegate class link.
- *
- * Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(long)} to get the Java object matching the int.
- *
- * Typical native init methods are returning a new int back to the Java class, so
- * {@link #addNewDelegate(Object)} does the same.
- *
- * The JNI references are counted, so we do the same through a {@link WeakReference}. Because
- * the Java object needs to count as a reference (even though it only holds an int), we use the
- * following mechanism:
- *
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes
- *   the delegate to/from a set. This set holds the reference and prevents the GC from reclaiming
- *   the delegate.
- *
- * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a
- *   {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically
- *   when nothing references it. This means that any class that holds a delegate (except for the
- *   Java main class) must not use the int but the Delegate class instead. The integers must
- *   only be used in the API between the main Java class and the Delegate.
- *
- * @param <T> the delegate class to manage
- */
-public final class DelegateManager<T> {
-    @SuppressWarnings("FieldCanBeLocal")
-    private final Class<T> mClass;
-    private static final SparseWeakArray<Object> sDelegates = new SparseWeakArray<>();
-    /** Set used to store delegates when their main object holds a reference to them.
-     * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
-     * @see #addNewDelegate(Object)
-     * @see #removeJavaReferenceFor(long)
-     */
-    private static final Set<Object> sJavaReferences = new HashSet<>();
-    private static final AtomicLong sDelegateCounter = new AtomicLong(1);
-
-    public DelegateManager(Class<T> theClass) {
-        mClass = theClass;
-    }
-
-    /**
-     * Returns the delegate from the given native int.
-     * <p>
-     * If the int is zero, then this will always return null.
-     * <p>
-     * If the int is non zero and the delegate is not found, this will throw an assert.
-     *
-     * @param native_object the native int.
-     * @return the delegate or null if not found.
-     */
-    @Nullable
-    public T getDelegate(long native_object) {
-        if (native_object > 0) {
-            Object delegate;
-            synchronized (DelegateManager.class) {
-                delegate = sDelegates.get(native_object);
-            }
-
-            if (Debug.DEBUG) {
-                if (delegate == null) {
-                    System.err.println("Unknown " + mClass.getSimpleName() + " with int " +
-                            native_object);
-                }
-            }
-
-            assert delegate != null;
-            //noinspection unchecked
-            return (T)delegate;
-        }
-        return null;
-    }
-
-    /**
-     * Adds a delegate to the manager and returns the native int used to identify it.
-     * @param newDelegate the delegate to add
-     * @return a unique native int to identify the delegate
-     */
-    public long addNewDelegate(T newDelegate) {
-        long native_object = sDelegateCounter.getAndIncrement();
-        synchronized (DelegateManager.class) {
-            sDelegates.put(native_object, newDelegate);
-            // Only for development: assert !sJavaReferences.contains(newDelegate);
-            sJavaReferences.add(newDelegate);
-        }
-
-        if (Debug.DEBUG) {
-            System.out.println(
-                    "New " + mClass.getSimpleName() + " " +
-                            "with int " +
-                            native_object);
-        }
-
-        return native_object;
-    }
-
-    /**
-     * Removes the main reference on the given delegate.
-     * @param native_object the native integer representing the delegate.
-     */
-    public void removeJavaReferenceFor(long native_object) {
-        synchronized (DelegateManager.class) {
-            T delegate = getDelegate(native_object);
-
-            if (Debug.DEBUG) {
-                System.out.println("Removing main Java ref on " + mClass.getSimpleName() +
-                        " with int " + native_object);
-            }
-
-            sJavaReferences.remove(delegate);
-        }
-    }
-
-    public synchronized static void dump(PrintStream out) {
-        for (Object reference : sJavaReferences) {
-            int idx = sDelegates.indexOfValue(reference);
-            out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName());
-        }
-        out.printf("\nTotal number of objects: %d\n", sJavaReferences.size());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
deleted file mode 100644
index 7526e09..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter_Delegate;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Region_Delegate;
-import android.graphics.Shader_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-
-/**
- * Class representing a graphics context snapshot, as well as a context stack as a linked list.
- * <p>
- * This is based on top of {@link Graphics2D} but can operate independently if none are available
- * yet when setting transforms and clip information.
- * <p>
- * This allows for drawing through {@link #draw(Drawable, Paint_Delegate, boolean, boolean)} and
- * {@link #draw(Drawable)}
- *
- * Handling of layers (created with {@link Canvas#saveLayer(RectF, Paint, int)}) is handled through
- * a list of Graphics2D for each layers. The class actually maintains a list of {@link Layer}
- * for each layer. Doing a save() will duplicate this list so that each graphics2D object
- * ({@link Layer#getGraphics()}) is configured only for the new snapshot.
- */
-public class GcSnapshot {
-
-    private final GcSnapshot mPrevious;
-    private final int mFlags;
-
-    /** list of layers. The first item in the list is always the  */
-    private final ArrayList<Layer> mLayers = new ArrayList<Layer>();
-
-    /** temp transform in case transformation are set before a Graphics2D exists */
-    private AffineTransform mTransform = null;
-    /** temp clip in case clipping is set before a Graphics2D exists */
-    private Area mClip = null;
-
-    // local layer data
-    /** a local layer created with {@link Canvas#saveLayer(RectF, Paint, int)}.
-     * If this is null, this does not mean there's no layer, just that the snapshot is not the
-     * one that created the layer.
-     * @see #getLayerSnapshot()
-     */
-    private final Layer mLocalLayer;
-    private final Paint_Delegate mLocalLayerPaint;
-    private final Rect mLayerBounds;
-
-    public interface Drawable {
-        void draw(Graphics2D graphics, Paint_Delegate paint);
-    }
-
-    /**
-     * Class containing information about a layer.
-     *
-     * This contains graphics, bitmap and layer information.
-     */
-    private static class Layer {
-        private final Graphics2D mGraphics;
-        private final Bitmap_Delegate mBitmap;
-        private final BufferedImage mImage;
-        /** the flags that were used to configure the layer. This is never changed, and passed
-         * as is when {@link #makeCopy()} is called */
-        private final int mFlags;
-        /** the original content of the layer when the next object was created. This is not
-         * passed in {@link #makeCopy()} and instead is recreated when a new layer is added
-         * (depending on its flags) */
-        private BufferedImage mOriginalCopy;
-
-        /**
-         * Creates a layer with a graphics and a bitmap. This is only used to create
-         * the base layer.
-         *
-         * @param graphics the graphics
-         * @param bitmap the bitmap
-         */
-        Layer(Graphics2D graphics, Bitmap_Delegate bitmap) {
-            mGraphics = graphics;
-            mBitmap = bitmap;
-            mImage = mBitmap.getImage();
-            mFlags = 0;
-        }
-
-        /**
-         * Creates a layer with a graphics and an image. If the image belongs to a
-         * {@link Bitmap_Delegate} (case of the base layer), then
-         * {@link Layer#Layer(Graphics2D, Bitmap_Delegate)} should be used.
-         *
-         * @param graphics the graphics the new graphics for this layer
-         * @param image the image the image from which the graphics came
-         * @param flags the flags that were used to save this layer
-         */
-        Layer(Graphics2D graphics, BufferedImage image, int flags) {
-            mGraphics = graphics;
-            mBitmap = null;
-            mImage = image;
-            mFlags = flags;
-        }
-
-        /** The Graphics2D, guaranteed to be non null */
-        Graphics2D getGraphics() {
-            return mGraphics;
-        }
-
-        /** The BufferedImage, guaranteed to be non null */
-        BufferedImage getImage() {
-            return mImage;
-        }
-
-        /** Returns the layer save flags. This is only valid for additional layers.
-         * For the base layer this will always return 0;
-         * For a given layer, all further copies of this {@link Layer} object in new snapshots
-         * will always return the same value.
-         */
-        int getFlags() {
-            return mFlags;
-        }
-
-        Layer makeCopy() {
-            if (mBitmap != null) {
-                return new Layer((Graphics2D) mGraphics.create(), mBitmap);
-            }
-
-            return new Layer((Graphics2D) mGraphics.create(), mImage, mFlags);
-        }
-
-        /** sets an optional copy of the original content to be used during restore */
-        void setOriginalCopy(BufferedImage image) {
-            mOriginalCopy = image;
-        }
-
-        BufferedImage getOriginalCopy() {
-            return mOriginalCopy;
-        }
-
-        void change() {
-            if (mBitmap != null) {
-                mBitmap.change();
-            }
-        }
-
-        /**
-         * Sets the clip for the graphics2D object associated with the layer.
-         * This should be used over the normal Graphics2D setClip method.
-         *
-         * @param clipShape the shape to use a the clip shape.
-         */
-        void setClip(Shape clipShape) {
-            // because setClip is only guaranteed to work with rectangle shape,
-            // first reset the clip to max and then intersect the current (empty)
-            // clip with the shap.
-            mGraphics.setClip(null);
-            mGraphics.clip(clipShape);
-        }
-
-        /**
-         * Clips the layer with the given shape. This performs an intersect between the current
-         * clip shape and the given shape.
-         * @param shape the new clip shape.
-         */
-        public void clip(Shape shape) {
-            mGraphics.clip(shape);
-        }
-    }
-
-    /**
-     * Creates the root snapshot associating it with a given bitmap.
-     * <p>
-     * If <var>bitmap</var> is null, then {@link GcSnapshot#setBitmap(Bitmap_Delegate)} must be
-     * called before the snapshot can be used to draw. Transform and clip operations are permitted
-     * before.
-     *
-     * @param bitmap the image to associate to the snapshot or null.
-     * @return the root snapshot
-     */
-    public static GcSnapshot createDefaultSnapshot(Bitmap_Delegate bitmap) {
-        GcSnapshot snapshot = new GcSnapshot();
-        if (bitmap != null) {
-            snapshot.setBitmap(bitmap);
-        }
-
-        return snapshot;
-    }
-
-    /**
-     * Saves the current state according to the given flags and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#save(int)}
-     *
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#save(int)
-     */
-    public GcSnapshot save(int flags) {
-        return new GcSnapshot(this, null /*layerbounds*/, null /*paint*/, flags);
-    }
-
-    /**
-     * Saves the current state and creates a new layer, and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#saveLayer(RectF, Paint, int)}
-     *
-     * @param layerBounds the layer bounds
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#saveLayer(RectF, Paint, int)
-     */
-    public GcSnapshot saveLayer(RectF layerBounds, Paint_Delegate paint, int flags) {
-        return new GcSnapshot(this, layerBounds, paint, flags);
-    }
-
-    /**
-     * Creates the root snapshot.
-     * {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
-     */
-    private GcSnapshot() {
-        mPrevious = null;
-        mFlags = 0;
-        mLocalLayer = null;
-        mLocalLayerPaint = null;
-        mLayerBounds = null;
-    }
-
-    /**
-     * Creates a new {@link GcSnapshot} on top of another one, with a layer data to be restored
-     * into the main graphics when {@link #restore()} is called.
-     *
-     * @param previous the previous snapshot head.
-     * @param layerBounds the region of the layer. Optional, if null, this is a normal save()
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the flags regarding what should be saved.
-     */
-    private GcSnapshot(GcSnapshot previous, RectF layerBounds, Paint_Delegate paint, int flags) {
-        assert previous != null;
-        mPrevious = previous;
-        mFlags = flags;
-
-        // make a copy of the current layers before adding the new one.
-        // This keeps the same BufferedImage reference but creates new Graphics2D for this
-        // snapshot.
-        // It does not copy whatever original copy the layers have, as they will be done
-        // only if the new layer doesn't clip drawing to itself.
-        for (Layer layer : mPrevious.mLayers) {
-            mLayers.add(layer.makeCopy());
-        }
-
-        if (layerBounds != null) {
-            // get the current transform
-            AffineTransform matrix = mLayers.get(0).getGraphics().getTransform();
-
-            // transform the layerBounds with the current transform and stores it into a int rect
-            RectF rect2 = new RectF();
-            mapRect(matrix, rect2, layerBounds);
-            mLayerBounds = new Rect();
-            rect2.round(mLayerBounds);
-
-            // get the base layer (always at index 0)
-            Layer baseLayer = mLayers.get(0);
-
-            // create the image for the layer
-            BufferedImage layerImage = new BufferedImage(
-                    baseLayer.getImage().getWidth(),
-                    baseLayer.getImage().getHeight(),
-                    (mFlags & Canvas.HAS_ALPHA_LAYER_SAVE_FLAG) != 0 ?
-                            BufferedImage.TYPE_INT_ARGB :
-                                BufferedImage.TYPE_INT_RGB);
-
-            // create a graphics for it so that drawing can be done.
-            Graphics2D layerGraphics = layerImage.createGraphics();
-
-            // because this layer inherits the current context for transform and clip,
-            // set them to one from the base layer.
-            AffineTransform currentMtx = baseLayer.getGraphics().getTransform();
-            layerGraphics.setTransform(currentMtx);
-
-            // create a new layer for this new layer and add it to the list at the end.
-            mLayers.add(mLocalLayer = new Layer(layerGraphics, layerImage, flags));
-
-            // set the clip on it.
-            Shape currentClip = baseLayer.getGraphics().getClip();
-            mLocalLayer.setClip(currentClip);
-
-            // if the drawing is not clipped to the local layer only, we save the current content
-            // of all other layers. We are only interested in the part that will actually
-            // be drawn, so we create as small bitmaps as we can.
-            // This is so that we can erase the drawing that goes in the layers below that will
-            // be coming from the layer itself.
-            if ((mFlags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0) {
-                int w = mLayerBounds.width();
-                int h = mLayerBounds.height();
-                for (int i = 0 ; i < mLayers.size() - 1 ; i++) {
-                    Layer layer = mLayers.get(i);
-                    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-                    Graphics2D graphics = image.createGraphics();
-                    graphics.drawImage(layer.getImage(),
-                            0, 0, w, h,
-                            mLayerBounds.left, mLayerBounds.top,
-                                    mLayerBounds.right, mLayerBounds.bottom,
-                            null);
-                    graphics.dispose();
-                    layer.setOriginalCopy(image);
-                }
-            }
-        } else {
-            mLocalLayer = null;
-            mLayerBounds = null;
-        }
-
-        mLocalLayerPaint  = paint;
-    }
-
-    public void dispose() {
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        if (mPrevious != null) {
-            mPrevious.dispose();
-        }
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}, and returns the next one.
-     */
-    public GcSnapshot restore() {
-        return doRestore();
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>.
-     * @param saveCount the saveCount or -1 to only restore 1.
-     *
-     * @return the new head of the Gc snapshot stack.
-     */
-    public GcSnapshot restoreTo(int saveCount) {
-        return doRestoreTo(size(), saveCount);
-    }
-
-    public int size() {
-        if (mPrevious != null) {
-            return mPrevious.size() + 1;
-        }
-
-        return 1;
-    }
-
-    /**
-     * Link the snapshot to a Bitmap_Delegate.
-     * <p/>
-     * This is only for the case where the snapshot was created with a null image when calling
-     * {@link #createDefaultSnapshot(Bitmap_Delegate)}, and is therefore not yet linked to
-     * a previous snapshot.
-     * <p/>
-     * If any transform or clip information was set before, they are put into the Graphics object.
-     * @param bitmap the bitmap to link to.
-     */
-    public void setBitmap(Bitmap_Delegate bitmap) {
-        // create a new Layer for the bitmap. This will be the base layer.
-        Graphics2D graphics2D = bitmap.getImage().createGraphics();
-        Layer baseLayer = new Layer(graphics2D, bitmap);
-
-        // Set the current transform and clip which can either come from mTransform/mClip if they
-        // were set when there was no bitmap/layers or from the current base layers if there is
-        // one already.
-
-        graphics2D.setTransform(getTransform());
-        // reset mTransform in case there was one.
-        mTransform = null;
-
-        baseLayer.setClip(getClip());
-        // reset mClip in case there was one.
-        mClip = null;
-
-        // replace whatever current layers we have with this.
-        mLayers.clear();
-        mLayers.add(baseLayer);
-
-    }
-
-    public void translate(float dx, float dy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().translate(dx, dy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.translate(dx, dy);
-        }
-    }
-
-    public void rotate(double radians) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().rotate(radians);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.rotate(radians);
-        }
-    }
-
-    public void scale(float sx, float sy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().scale(sx, sy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.scale(sx, sy);
-        }
-    }
-
-    public AffineTransform getTransform() {
-        if (mLayers.size() > 0) {
-            // all graphics2D in the list have the same transform
-            return mLayers.get(0).getGraphics().getTransform();
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            return mTransform;
-        }
-    }
-
-    public void setTransform(AffineTransform transform) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().setTransform(transform);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.setTransform(transform);
-        }
-    }
-
-    public boolean clip(Shape shape, int regionOp) {
-        // Simple case of intersect with existing layers.
-        // Because Graphics2D#setClip works a bit peculiarly, we optimize
-        // the case of clipping by intersection, as it's supported natively.
-        if (regionOp == Region.Op.INTERSECT.nativeInt && mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.clip(shape);
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        }
-
-        Area area = null;
-
-        if (regionOp == Region.Op.REPLACE.nativeInt) {
-            area = new Area(shape);
-        } else {
-            area = Region_Delegate.combineShapes(getClip(), shape, regionOp);
-        }
-
-        assert area != null;
-
-        if (mLayers.size() > 0) {
-            if (area != null) {
-                for (Layer layer : mLayers) {
-                    layer.setClip(area);
-                }
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        } else {
-            if (area != null) {
-                mClip = area;
-            } else {
-                mClip = new Area();
-            }
-
-            return mClip.getBounds().isEmpty() == false;
-        }
-    }
-
-    public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return clip(new Rectangle2D.Float(left, top, right - left, bottom - top), regionOp);
-    }
-
-    /**
-     * Returns the current clip, or null if none have been setup.
-     */
-    public Shape getClip() {
-        if (mLayers.size() > 0) {
-            // they all have the same clip
-            return mLayers.get(0).getGraphics().getClip();
-        } else {
-            return mClip;
-        }
-    }
-
-    private GcSnapshot doRestoreTo(int size, int saveCount) {
-        if (size <= saveCount) {
-            return this;
-        }
-
-        // restore the current one first.
-        GcSnapshot previous = doRestore();
-
-        if (size == saveCount + 1) { // this was the only one that needed restore.
-            return previous;
-        } else {
-            return previous.doRestoreTo(size - 1, saveCount);
-        }
-    }
-
-    /**
-     * Executes the Drawable's draw method, with a null paint delegate.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     */
-    public void draw(Drawable drawable) {
-        draw(drawable, null, false /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    /**
-     * Executes the Drawable's draw method.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     * @param compositeOnly whether the paint is used for composite only. This is typically
-     *          the case for bitmaps.
-     * @param forceSrcMode if true, this overrides the composite to be SRC
-     */
-    public void draw(Drawable drawable, Paint_Delegate paint, boolean compositeOnly,
-            boolean forceSrcMode) {
-        int forceMode = forceSrcMode ? AlphaComposite.SRC : 0;
-        // the current snapshot may not have a mLocalLayer (ie it was created on save() instead
-        // of saveLayer(), but that doesn't mean there's no layer.
-        // mLayers however saves all the information we need (flags).
-        if (mLayers.size() == 1) {
-            // no layer, only base layer. easy case.
-            drawInLayer(mLayers.get(0), drawable, paint, compositeOnly, forceMode);
-        } else {
-            // draw in all the layers until the layer save flags tells us to stop (ie drawing
-            // in that layer is limited to the layer itself.
-            int flags;
-            int i = mLayers.size() - 1;
-
-            do {
-                Layer layer = mLayers.get(i);
-
-                drawInLayer(layer, drawable, paint, compositeOnly, forceMode);
-
-                // then go to previous layer, only if there are any left, and its flags
-                // doesn't restrict drawing to the layer itself.
-                i--;
-                flags = layer.getFlags();
-            } while (i >= 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-        }
-    }
-
-    private void drawInLayer(Layer layer, Drawable drawable, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        Graphics2D originalGraphics = layer.getGraphics();
-        if (paint == null) {
-            drawOnGraphics((Graphics2D) originalGraphics.create(), drawable,
-                    null /*paint*/, layer);
-        } else {
-            ColorFilter_Delegate filter = paint.getColorFilter();
-            if (filter == null || !filter.isSupported()) {
-                // get a Graphics2D object configured with the drawing parameters.
-                Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                        compositeOnly, forceMode);
-                drawOnGraphics(configuredGraphics, drawable, paint, layer);
-                return;
-            }
-
-            int x = 0;
-            int y = 0;
-            int width;
-            int height;
-            Rectangle clipBounds = originalGraphics.getClip() != null ? originalGraphics
-                    .getClipBounds() : null;
-            if (clipBounds != null) {
-                if (clipBounds.width == 0 || clipBounds.height == 0) {
-                    // Clip is 0 so no need to paint anything.
-                    return;
-                }
-                // If we have clipBounds available, use them as they will always be
-                // smaller than the full layer size.
-                x = clipBounds.x;
-                y = clipBounds.y;
-                width = clipBounds.width;
-                height = clipBounds.height;
-            } else {
-                width = layer.getImage().getWidth();
-                height = layer.getImage().getHeight();
-            }
-
-            // Create a temporary image to which the color filter will be applied.
-            BufferedImage image = new BufferedImage(width, height,
-                    BufferedImage.TYPE_INT_ARGB);
-            Graphics2D imageBaseGraphics = (Graphics2D) image.getGraphics();
-            // Configure the Graphics2D object with drawing parameters and shader.
-            Graphics2D imageGraphics = createCustomGraphics(
-                    imageBaseGraphics, paint, compositeOnly,
-                    AlphaComposite.SRC_OVER);
-            // get a Graphics2D object configured with the drawing parameters, but no shader.
-            Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                    true /*compositeOnly*/, forceMode);
-            try {
-                // The main draw operation.
-                // We translate the operation to take into account that the rendering does not
-                // know about the clipping area.
-                imageGraphics.translate(-x, -y);
-                drawable.draw(imageGraphics, paint);
-
-                // Apply the color filter.
-                // Restore the original coordinates system and apply the filter only to the
-                // clipped area.
-                imageGraphics.translate(x, y);
-                filter.applyFilter(imageGraphics, width, height);
-
-                // Draw the tinted image on the main layer using as start point the clipping
-                // upper left coordinates.
-                configuredGraphics.drawImage(image, x, y, null);
-                layer.change();
-            } finally {
-                // dispose Graphics2D objects
-                imageGraphics.dispose();
-                imageBaseGraphics.dispose();
-                configuredGraphics.dispose();
-            }
-        }
-    }
-
-    private void drawOnGraphics(Graphics2D g, Drawable drawable, Paint_Delegate paint,
-            Layer layer) {
-        try {
-            drawable.draw(g, paint);
-            layer.change();
-        } finally {
-            g.dispose();
-        }
-    }
-
-    private GcSnapshot doRestore() {
-        if (mPrevious != null) {
-            if (mLocalLayer != null) {
-                // prepare to blit the layers in which we have draw, in the layer beneath
-                // them, starting with the top one (which is the current local layer).
-                int i = mLayers.size() - 1;
-                int flags;
-                do {
-                    Layer dstLayer = mLayers.get(i - 1);
-
-                    restoreLayer(dstLayer);
-
-                    flags = dstLayer.getFlags();
-                    i--;
-                } while (i > 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-            }
-
-            // if this snapshot does not save everything, then set the previous snapshot
-            // to this snapshot content
-
-            // didn't save the matrix? set the current matrix on the previous snapshot
-            if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
-                AffineTransform mtx = getTransform();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.getGraphics().setTransform(mtx);
-                }
-            }
-
-            // didn't save the clip? set the current clip on the previous snapshot
-            if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
-                Shape clip = getClip();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.setClip(clip);
-                }
-            }
-        }
-
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        return mPrevious;
-    }
-
-    private void restoreLayer(Layer dstLayer) {
-
-        Graphics2D baseGfx = dstLayer.getImage().createGraphics();
-
-        // if the layer contains an original copy this means the flags
-        // didn't restrict drawing to the local layer and we need to make sure the
-        // layer bounds in the layer beneath didn't receive any drawing.
-        // so we use the originalCopy to erase the new drawings in there.
-        BufferedImage originalCopy = dstLayer.getOriginalCopy();
-        if (originalCopy != null) {
-            Graphics2D g = (Graphics2D) baseGfx.create();
-            g.setComposite(AlphaComposite.Src);
-
-            g.drawImage(originalCopy,
-                    mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                    0, 0, mLayerBounds.width(), mLayerBounds.height(),
-                    null);
-            g.dispose();
-        }
-
-        // now draw put the content of the local layer onto the layer,
-        // using the paint information
-        Graphics2D g = createCustomGraphics(baseGfx, mLocalLayerPaint,
-                true /*alphaOnly*/, 0 /*forceMode*/);
-
-        g.drawImage(mLocalLayer.getImage(),
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                null);
-        g.dispose();
-
-        baseGfx.dispose();
-    }
-
-    /**
-     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
-     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
-     */
-    private Graphics2D createCustomGraphics(Graphics2D original, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        // make new one graphics
-        Graphics2D g = (Graphics2D) original.create();
-
-        // configure it
-
-        if (paint.isAntiAliased()) {
-            g.setRenderingHint(
-                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setRenderingHint(
-                    RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-        }
-
-        // set the shader first, as it'll replace the color if it can be used it.
-        boolean customShader = false;
-        if (!compositeOnly) {
-            customShader = setShader(g, paint);
-            // set the stroke
-            g.setStroke(paint.getJavaStroke());
-        }
-        // set the composite.
-        setComposite(g, paint, compositeOnly || customShader, forceMode);
-
-        return g;
-    }
-
-    private boolean setShader(Graphics2D g, Paint_Delegate paint) {
-        Shader_Delegate shaderDelegate = paint.getShader();
-        if (shaderDelegate != null) {
-            if (shaderDelegate.isSupported()) {
-                java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
-                assert shaderPaint != null;
-                if (shaderPaint != null) {
-                    g.setPaint(shaderPaint);
-                    return true;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
-                        shaderDelegate.getSupportMessage(),
-                        null /*throwable*/, null /*data*/);
-            }
-        }
-
-        // if no shader, use the paint color
-        g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
-
-        return false;
-    }
-
-    private void setComposite(Graphics2D g, Paint_Delegate paint, boolean usePaintAlpha,
-            int forceMode) {
-        // the alpha for the composite. Always opaque if the normal paint color is used since
-        // it contains the alpha
-        int alpha = usePaintAlpha ? paint.getAlpha() : 0xFF;
-        if (forceMode != 0) {
-            g.setComposite(AlphaComposite.getInstance(forceMode, (float) alpha / 255.f));
-            return;
-        }
-        Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-        Composite composite = PorterDuffUtility.getComposite(mode, alpha);
-        g.setComposite(composite);
-    }
-
-    private void mapRect(AffineTransform matrix, RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        matrix.transform(corners, 0, corners, 0, 4);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-    }
-
-    /**
-     * Returns the clip of the oldest snapshot of the stack, appropriately translated to be
-     * expressed in the coordinate system of the latest snapshot.
-     */
-    public Rectangle getOriginalClip() {
-        GcSnapshot originalSnapshot = this;
-        while (originalSnapshot.mPrevious != null) {
-            originalSnapshot = originalSnapshot.mPrevious;
-        }
-        if (originalSnapshot.mLayers.isEmpty()) {
-            return null;
-        }
-        Graphics2D graphics2D = originalSnapshot.mLayers.get(0).getGraphics();
-        Rectangle bounds = graphics2D.getClipBounds();
-        if (bounds == null) {
-            return null;
-        }
-        try {
-            AffineTransform originalTransform =
-                    ((Graphics2D) graphics2D.create()).getTransform().createInverse();
-            AffineTransform latestTransform = getTransform().createInverse();
-            bounds.x += latestTransform.getTranslateX() - originalTransform.getTranslateX();
-            bounds.y += latestTransform.getTranslateY() - originalTransform.getTranslateY();
-        } catch (NoninvertibleTransformException e) {
-            Bridge.getLog().warning(null, "Non invertible transformation", null);
-        }
-        return bounds;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
deleted file mode 100644
index 287334c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.bars.AppCompatActionBar;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
-import com.android.layoutlib.bridge.bars.Config;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
-import com.android.layoutlib.bridge.bars.NavigationBar;
-import com.android.layoutlib.bridge.bars.StatusBar;
-import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-
-import android.annotation.NonNull;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.AttachInfo_Accessor;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.ViewRootImpl_Accessor;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.widget.LinearLayout.VERTICAL;
-import static com.android.layoutlib.bridge.impl.ResourceHelper.getBooleanThemeValue;
-
-/**
- * The Layout used to create the system decor.
- *
- * The layout inflated will contain a content frame where the user's layout can be inflated.
- * <pre>
- *  +-------------------------------------------------+---+
- *  | Status bar                                      | N |
- *  +-------------------------------------------------+ a |
- *  | Title/Action bar (optional)                     | v |
- *  +-------------------------------------------------+   |
- *  | Content, vertical extending                     | b |
- *  |                                                 | a |
- *  |                                                 | r |
- *  +-------------------------------------------------+---+
- * </pre>
- * or
- * <pre>
- *  +-------------------------------------+
- *  | Status bar                          |
- *  +-------------------------------------+
- *  | Title/Action bar (optional)         |
- *  +-------------------------------------+
- *  | Content, vertical extending         |
- *  |                                     |
- *  |                                     |
- *  +-------------------------------------+
- *  | Nav bar                             |
- *  +-------------------------------------+
- * </pre>
- *
- */
-class Layout extends RelativeLayout {
-
-    // Theme attributes used for configuring appearance of the system decor.
-    private static final String ATTR_WINDOW_FLOATING = "windowIsFloating";
-    private static final String ATTR_WINDOW_BACKGROUND = "windowBackground";
-    private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullscreen";
-    private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height";
-    private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width";
-    private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height";
-    private static final String ATTR_WINDOW_ACTION_BAR = "windowActionBar";
-    private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize";
-    private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle";
-    private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize";
-    private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT;
-    private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT;
-
-    // Default sizes
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_NAV_BAR_SIZE = 48;
-
-    // Ids assigned to components created. This is so that we can refer to other components in
-    // layout params.
-    private static final String ID_NAV_BAR = "navBar";
-    private static final String ID_STATUS_BAR = "statusBar";
-    private static final String ID_TITLE_BAR = "titleBar";
-    // Prefix used with the above ids in order to make them unique in framework namespace.
-    private static final String ID_PREFIX = "android_layoutlib_";
-
-    /**
-     * Temporarily store the builder so that it doesn't have to be passed to all methods used
-     * during inflation.
-     */
-    private Builder mBuilder;
-
-    /**
-     * This holds user's layout.
-     */
-    private FrameLayout mContentRoot;
-
-    public Layout(@NonNull Builder builder) {
-        super(builder.mContext);
-        mBuilder = builder;
-        if (builder.mWindowBackground != null) {
-            Drawable d = ResourceHelper.getDrawable(builder.mWindowBackground, builder.mContext);
-            setBackground(d);
-        }
-
-        int simulatedPlatformVersion = getParams().getSimulatedPlatformVersion();
-        HardwareConfig hwConfig = getParams().getHardwareConfig();
-        Density density = hwConfig.getDensity();
-        boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale());
-        setLayoutDirection(isRtl? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR);
-
-        NavigationBar navBar = null;
-        if (mBuilder.hasNavBar()) {
-            navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        StatusBar statusBar = null;
-        if (builder.mStatusBarSize > 0) {
-            statusBar = createStatusBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        View actionBar = null;
-        TitleBar titleBar = null;
-        if (builder.mActionBarSize > 0) {
-            BridgeActionBar bar = createActionBar(getContext(), getParams());
-            mContentRoot = bar.getContentRoot();
-            actionBar = bar.getRootView();
-        } else if (mBuilder.mTitleBarSize > 0) {
-            titleBar = createTitleBar(getContext(), getParams().getAppLabel(),
-                    simulatedPlatformVersion);
-        }
-
-        addViews(titleBar, mContentRoot == null ? (mContentRoot = createContentFrame()) : actionBar,
-                statusBar, navBar);
-        // Done with the builder. Don't hold a reference to it.
-        mBuilder = null;
-     }
-
-    @NonNull
-    private FrameLayout createContentFrame() {
-        FrameLayout contentRoot = new FrameLayout(getContext());
-        LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            params.addRule(rule, getId(ID_NAV_BAR));
-        }
-        int below = -1;
-        if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) {
-            below = getId(ID_TITLE_BAR);
-        } else if (mBuilder.hasSolidStatusBar()) {
-            below = getId(ID_STATUS_BAR);
-        }
-        if (below != -1) {
-            params.addRule(BELOW, below);
-        }
-        contentRoot.setLayoutParams(params);
-        return contentRoot;
-    }
-
-    @NonNull
-    private LayoutParams createLayoutParams(int width, int height) {
-        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
-        if (width > 0) {
-            width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics);
-        }
-        if (height > 0) {
-            height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics);
-        }
-        return new LayoutParams(width, height);
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    @NonNull
-    private SessionParams getParams() {
-        return mBuilder.mParams;
-    }
-
-    @NonNull
-    @Override
-    public BridgeContext getContext(){
-        return (BridgeContext) super.getContext();
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private StatusBar createStatusBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        StatusBar statusBar =
-                new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize);
-        if (mBuilder.isNavBarVertical()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        statusBar.setLayoutParams(params);
-        statusBar.setId(getId(ID_STATUS_BAR));
-        return statusBar;
-    }
-
-    private BridgeActionBar createActionBar(@NonNull BridgeContext context,
-            @NonNull SessionParams params) {
-        boolean isMenu = "menu".equals(params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-
-        BridgeActionBar actionBar;
-        if (context.isAppCompatTheme() && !isMenu) {
-            actionBar = new AppCompatActionBar(context, params);
-        } else {
-            actionBar = new FrameworkActionBar(context, params);
-        }
-        LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            layoutParams.addRule(rule, getId(ID_NAV_BAR));
-        }
-        if (mBuilder.hasSolidStatusBar()) {
-            layoutParams.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        actionBar.getRootView().setLayoutParams(layoutParams);
-        actionBar.createMenuPopup();
-        return actionBar;
-    }
-
-    @NonNull
-    private TitleBar createTitleBar(BridgeContext context, String title,
-            int simulatedPlatformVersion) {
-        TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize);
-        if (mBuilder.hasSolidStatusBar()) {
-            params.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        if (mBuilder.isNavBarVertical() && mBuilder.hasSolidNavBar()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        titleBar.setLayoutParams(params);
-        titleBar.setId(getId(ID_TITLE_BAR));
-        return titleBar;
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private NavigationBar createNavBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        int orientation = mBuilder.mNavBarOrientation;
-        int size = mBuilder.mNavBarSize;
-        NavigationBar navBar = new NavigationBar(context, density, orientation, isRtl,
-                isRtlSupported, simulatedPlatformVersion);
-        boolean isVertical = mBuilder.isNavBarVertical();
-        int w = isVertical ? size : MATCH_PARENT;
-        int h = isVertical ? MATCH_PARENT : size;
-        LayoutParams params = createLayoutParams(w, h);
-        params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM);
-        navBar.setLayoutParams(params);
-        navBar.setId(getId(ID_NAV_BAR));
-        return navBar;
-    }
-
-    private void addViews(@NonNull View... views) {
-        for (View view : views) {
-            if (view != null) {
-                addView(view);
-            }
-        }
-    }
-
-    private int getId(String name) {
-        return Bridge.getResourceId(ResourceType.ID, ID_PREFIX + name);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void requestFitSystemWindows() {
-        // The framework call would usually bubble up to ViewRootImpl but, in layoutlib, Layout will
-        // act as view root for most purposes. That way, we can also save going through the Handler
-        // to dispatch the new applied insets.
-        ViewRootImpl root = AttachInfo_Accessor.getRootView(this);
-        if (root != null) {
-            ViewRootImpl_Accessor.dispatchApplyInsets(root, this);
-        }
-    }
-
-    /**
-     * A helper class to help initialize the Layout.
-     */
-    static class Builder {
-        @NonNull
-        private final SessionParams mParams;
-        @NonNull
-        private final BridgeContext mContext;
-        private final RenderResources mResources;
-        
-        private final boolean mWindowIsFloating;
-        private ResourceValue mWindowBackground;
-        private int mStatusBarSize;
-        private int mNavBarSize;
-        private int mNavBarOrientation;
-        private int mActionBarSize;
-        private int mTitleBarSize;
-        private boolean mTranslucentStatus;
-        private boolean mTranslucentNav;
-
-        public Builder(@NonNull SessionParams params, @NonNull BridgeContext context) {
-            mParams = params;
-            mContext = context;
-            mResources = mParams.getResources();
-            mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
-            
-            findBackground();
-
-            if (!mParams.isForceNoDecor()) {
-                findStatusBar();
-                findActionBar();
-                findNavBar();
-            }
-        }
-
-        private void findBackground() {
-            if (!mParams.isBgColorOverridden()) {
-                mWindowBackground = mResources.findItemInTheme(ATTR_WINDOW_BACKGROUND, true);
-                mWindowBackground = mResources.resolveResValue(mWindowBackground);
-            }
-        }
-
-        private void findStatusBar() {
-            boolean windowFullScreen =
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
-            if (!windowFullScreen && !mWindowIsFloating) {
-                mStatusBarSize =
-                        getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT);
-                mTranslucentStatus = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_STATUS, true, false);
-            }
-        }
-
-        private void  findActionBar() {
-            if (mWindowIsFloating) {
-                return;
-            }
-            // Check if an actionbar is needed
-            boolean isMenu = "menu".equals(mParams.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-            boolean windowActionBar = isMenu ||
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
-                            !mContext.isAppCompatTheme(), true);
-            if (windowActionBar) {
-                mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-            } else {
-                // Maybe the gingerbread era title bar is needed
-                boolean windowNoTitle =
-                        getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
-                if (!windowNoTitle) {
-                    mTitleBarSize =
-                            getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-                }
-            }
-        }
-
-        private void findNavBar() {
-            if (hasSoftwareButtons() && !mWindowIsFloating) {
-
-                // get orientation
-                HardwareConfig hwConfig = mParams.getHardwareConfig();
-                boolean barOnBottom = true;
-
-                if (hwConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
-                    int shortSize = hwConfig.getScreenHeight();
-                    int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
-                            hwConfig.getDensity().getDpiValue();
-
-                    // 0-599dp: "phone" UI with bar on the side
-                    // 600+dp: "tablet" UI with bar on the bottom
-                    barOnBottom = shortSizeDp >= 600;
-                }
-
-                mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL;
-                mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH,
-                        true, DEFAULT_NAV_BAR_SIZE);
-                mTranslucentNav = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_NAV, true, false);
-            }
-        }
-
-        @SuppressWarnings("SameParameterValue")
-        private int getDimension(String attr, boolean isFramework, int defaultValue) {
-            ResourceValue value = mResources.findItemInTheme(attr, isFramework);
-            value = mResources.resolveResValue(value);
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(attr, value.getValue(), true);
-                if (typedValue != null) {
-                    return (int) typedValue.getDimension(mContext.getMetrics());
-                }
-            }
-            return defaultValue;
-        }
-
-        private boolean hasSoftwareButtons() {
-            return mParams.getHardwareConfig().hasSoftwareButtons();
-        }
-
-        /**
-         * Return true if the nav bar is present and not translucent
-         */
-        private boolean hasSolidNavBar() {
-            return hasNavBar() && !mTranslucentNav;
-        }
-
-        /**
-         * Return true if the status bar is present and not translucent
-         */
-        private boolean hasSolidStatusBar() {
-            return hasStatusBar() && !mTranslucentStatus;
-        }
-
-        private boolean hasNavBar() {
-            return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) &&
-                    hasSoftwareButtons() && mNavBarSize > 0;
-        }
-
-        private boolean hasStatusBar() {
-            return mStatusBarSize > 0;
-        }
-
-        /**
-         * Return true if the nav bar is present and is vertical.
-         */
-        private boolean isNavBarVertical() {
-            return hasNavBar() && mNavBarOrientation == VERTICAL;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
deleted file mode 100644
index 71e7fd2..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A wrapper around XmlPullParser that can peek forward to inspect if the file is a data-binding
- * layout and some parts need to be stripped.
- */
-public class LayoutParserWrapper implements XmlPullParser {
-
-    // Data binding constants.
-    private static final String TAG_LAYOUT = "layout";
-    private static final String TAG_DATA = "data";
-    private static final String DEFAULT = "default=";
-
-    private final XmlPullParser mDelegate;
-
-    // Storage for peeked values.
-    private boolean mPeeked;
-    private int mEventType;
-    private int mDepth;
-    private int mNext;
-    private List<Attribute> mAttributes;
-    private String mText;
-    private String mName;
-
-    // Used to end the document before the actual parser ends.
-    private int mFinalDepth = -1;
-    private boolean mEndNow;
-
-    public LayoutParserWrapper(XmlPullParser delegate) {
-        mDelegate = delegate;
-    }
-
-    public LayoutParserWrapper peekTillLayoutStart() throws IOException, XmlPullParserException {
-        final int STATE_LAYOUT_NOT_STARTED = 0;  // <layout> tag not encountered yet.
-        final int STATE_ROOT_NOT_STARTED = 1;    // the main view root not found yet.
-        final int STATE_INSIDE_DATA = 2;         // START_TAG for <data> found, but not END_TAG.
-
-        int state = STATE_LAYOUT_NOT_STARTED;
-        int dataDepth = -1;    // depth of the <data> tag. Should be two.
-        while (true) {
-            int peekNext = peekNext();
-            switch (peekNext) {
-                case START_TAG:
-                    if (state == STATE_LAYOUT_NOT_STARTED) {
-                        if (mName.equals(TAG_LAYOUT)) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        } else {
-                            return this; // no layout tag in the file.
-                        }
-                    } else if (state == STATE_ROOT_NOT_STARTED) {
-                        if (mName.equals(TAG_DATA)) {
-                            state = STATE_INSIDE_DATA;
-                            dataDepth = mDepth;
-                        } else {
-                            mFinalDepth = mDepth;
-                            return this;
-                        }
-                    }
-                    break;
-                case END_TAG:
-                    if (state == STATE_INSIDE_DATA) {
-                        if (mDepth <= dataDepth) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        }
-                    }
-                    break;
-                case END_DOCUMENT:
-                    // No layout start found.
-                    return this;
-            }
-            // consume the peeked tag.
-            next();
-        }
-    }
-
-    private int peekNext() throws IOException, XmlPullParserException {
-        if (mPeeked) {
-            return mNext;
-        }
-        mEventType = mDelegate.getEventType();
-        mNext = mDelegate.next();
-        if (mEventType == START_TAG) {
-            int count = mDelegate.getAttributeCount();
-            mAttributes = count > 0 ? new ArrayList<Attribute>(count) :
-                    Collections.<Attribute>emptyList();
-            for (int i = 0; i < count; i++) {
-                mAttributes.add(new Attribute(mDelegate.getAttributeNamespace(i),
-                        mDelegate.getAttributeName(i), mDelegate.getAttributeValue(i)));
-            }
-        }
-        mDepth = mDelegate.getDepth();
-        mText = mDelegate.getText();
-        mName = mDelegate.getName();
-        mPeeked = true;
-        return mNext;
-    }
-
-    private void reset() {
-        mAttributes = null;
-        mText = null;
-        mName = null;
-        mPeeked = false;
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        int returnValue;
-        int depth;
-        if (mPeeked) {
-            returnValue = mNext;
-            depth = mDepth;
-            reset();
-        } else if (mEndNow) {
-            return END_DOCUMENT;
-        } else {
-            returnValue = mDelegate.next();
-            depth = getDepth();
-        }
-        if (returnValue == END_TAG && depth <= mFinalDepth) {
-            mEndNow = true;
-        }
-        return returnValue;
-    }
-
-    @Override
-    public int getEventType() throws XmlPullParserException {
-        return mPeeked ? mEventType : mDelegate.getEventType();
-    }
-
-    @Override
-    public int getDepth() {
-        return mPeeked ? mDepth : mDelegate.getDepth();
-    }
-
-    @Override
-    public String getName() {
-        return mPeeked ? mName : mDelegate.getName();
-    }
-
-    @Override
-    public String getText() {
-        return mPeeked ? mText : mDelegate.getText();
-    }
-
-    @Override
-    public String getAttributeValue(@Nullable String namespace, String name) {
-        String returnValue = null;
-        if (mPeeked) {
-            if (mAttributes == null) {
-                if (mEventType != START_TAG) {
-                    throw new IndexOutOfBoundsException("getAttributeValue() called when not at START_TAG.");
-                } else {
-                    return null;
-                }
-            } else {
-                for (Attribute attribute : mAttributes) {
-                    //noinspection StringEquality for nullness check.
-                    if (attribute.name.equals(name) && (attribute.namespace == namespace ||
-                            attribute.namespace != null && attribute.namespace.equals(namespace))) {
-                        returnValue = attribute.value;
-                        break;
-                    }
-                }
-            }
-        } else {
-            returnValue = mDelegate.getAttributeValue(namespace, name);
-        }
-        // Check if the value is bound via data-binding, if yes get the default value.
-        if (returnValue != null && mFinalDepth >= 0 && returnValue.startsWith("@{")) {
-            // TODO: Improve the detection of default keyword.
-            int i = returnValue.lastIndexOf(DEFAULT);
-            return i > 0 ? returnValue.substring(i + DEFAULT.length(), returnValue.length() - 1)
-                    : null;
-        }
-        return returnValue;
-    }
-
-    private static class Attribute {
-        @Nullable
-        public final String namespace;
-        public final String name;
-        public final String value;
-
-        public Attribute(@Nullable String namespace, String name, String value) {
-            this.namespace = namespace;
-            this.name = name;
-            this.value = value;
-        }
-    }
-
-    // Not affected by peeking.
-
-    @Override
-    public void setFeature(String s, boolean b) throws XmlPullParserException {
-        mDelegate.setFeature(s, b);
-    }
-
-    @Override
-    public void setProperty(String s, Object o) throws XmlPullParserException {
-        mDelegate.setProperty(s, o);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String s) throws XmlPullParserException {
-        mDelegate.setInput(inputStream, s);
-    }
-
-    @Override
-    public void setInput(Reader reader) throws XmlPullParserException {
-        mDelegate.setInput(reader);
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return mDelegate.getInputEncoding();
-    }
-
-    @Override
-    public String getNamespace(String s) {
-        return mDelegate.getNamespace(s);
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return mDelegate.getPositionDescription();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mDelegate.getLineNumber();
-    }
-
-    @Override
-    public String getNamespace() {
-        return mDelegate.getNamespace();
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return mDelegate.getColumnNumber();
-    }
-
-    // -- We don't care much about the methods that follow.
-
-    @Override
-    public void require(int i, String s, String s1) throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean getFeature(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public void defineEntityReplacementText(String s, String s1) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public Object getProperty(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getNamespaceCount(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespacePrefix(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespaceUri(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] ints) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeNamespace(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeName(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributePrefix(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeType(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isAttributeDefault(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeValue(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
deleted file mode 100644
index 1ae9cb6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.impl;
-
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A factory for {@link XmlPullParser}.
- *
- */
-public class ParserFactory {
-
-    public final static boolean LOG_PARSER = false;
-
-    // Used to get a new XmlPullParser from the client.
-    @Nullable
-    private static com.android.ide.common.rendering.api.ParserFactory sParserFactory;
-
-    public static void setParserFactory(
-            @Nullable com.android.ide.common.rendering.api.ParserFactory parserFactory) {
-        sParserFactory = parserFactory;
-    }
-
-    @NonNull
-    public static XmlPullParser create(@NonNull File f)
-            throws XmlPullParserException, FileNotFoundException {
-        return create(f, false);
-    }
-
-    public static XmlPullParser create(@NonNull File f, boolean isLayout)
-      throws XmlPullParserException, FileNotFoundException {
-        InputStream stream = new FileInputStream(f);
-        return create(stream, f.getName(), f.length(), isLayout);
-    }
-    @NonNull
-    public static XmlPullParser create(@NonNull InputStream stream, @Nullable String name)
-        throws XmlPullParserException {
-        return create(stream, name, -1, false);
-    }
-
-    @NonNull
-    private static XmlPullParser create(@NonNull InputStream stream, @Nullable String name,
-            long size, boolean isLayout) throws XmlPullParserException {
-        XmlPullParser parser = instantiateParser(name);
-
-        stream = readAndClose(stream, name, size);
-
-        parser.setInput(stream, null);
-        if (isLayout) {
-            try {
-                return new LayoutParserWrapper(parser).peekTillLayoutStart();
-            } catch (IOException e) {
-                throw new XmlPullParserException(null, parser, e);
-            }
-        }
-        return parser;
-    }
-
-    @NonNull
-    public static XmlPullParser instantiateParser(@Nullable String name)
-            throws XmlPullParserException {
-        if (sParserFactory == null) {
-            throw new XmlPullParserException("ParserFactory not initialized.");
-        }
-        XmlPullParser parser = sParserFactory.createParser(name);
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        return parser;
-    }
-
-    @NonNull
-    private static InputStream readAndClose(@NonNull InputStream stream, @Nullable String name,
-            long size) throws XmlPullParserException {
-        // just a sanity check. It's doubtful we'll have such big files!
-        if (size > Integer.MAX_VALUE) {
-            throw new XmlPullParserException("File " + name + " is too big to be parsed");
-        }
-        int intSize = (int) size;
-
-        // create a buffered reader to facilitate reading.
-        BufferedInputStream bufferedStream = new BufferedInputStream(stream);
-        try {
-            int avail;
-            if (intSize != -1) {
-                avail = intSize;
-            } else {
-                // get the size to read.
-                avail = bufferedStream.available();
-            }
-
-            // create the initial buffer and read it.
-            byte[] buffer = new byte[avail];
-            int read = stream.read(buffer);
-
-            // this is the easy case.
-            if (read == intSize) {
-                return new ByteArrayInputStream(buffer);
-            }
-
-            // check if there is more to read (read() does not necessarily read all that
-            // available() returned!)
-            while ((avail = bufferedStream.available()) > 0) {
-                if (read + avail > buffer.length) {
-                    // just allocate what is needed. We're mostly reading small files
-                    // so it shouldn't be too problematic.
-                    byte[] moreBuffer = new byte[read + avail];
-                    System.arraycopy(buffer, 0, moreBuffer, 0, read);
-                    buffer = moreBuffer;
-                }
-
-                read += stream.read(buffer, read, avail);
-            }
-
-            // return a new stream encapsulating this buffer.
-            return new ByteArrayInputStream(buffer);
-
-        } catch (IOException e) {
-            throw new XmlPullParserException("Failed to read " + name, null, e);
-        } finally {
-            try {
-                bufferedStream.close();
-            } catch (IOException ignored) {
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
deleted file mode 100644
index 7b70180..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-
-public class PlayAnimationThread extends AnimationThread {
-
-    private final Animator mAnimator;
-
-    public PlayAnimationThread(Animator animator, RenderSessionImpl scene, String animName,
-            IAnimationListener listener) {
-        super(scene, animName, listener);
-        mAnimator = animator;
-    }
-
-    @Override
-    public Result preAnimation() {
-        // start the animation. This will send a message to the handler right away, so
-        // the queue is filled when this method returns.
-        mAnimator.start();
-
-        return Status.SUCCESS.createResult();
-    }
-
-    @Override
-    public void postAnimation() {
-        // nothing to be done.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
deleted file mode 100644
index 70e2eb1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
+++ /dev/null
@@ -1,107 +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.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.BlendComposite;
-import android.graphics.BlendComposite.BlendingMode;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Composite;
-
-/**
- * Provides various utility methods for {@link PorterDuffColorFilter_Delegate}.
- */
-public final class PorterDuffUtility {
-
-    private static final int MODES_COUNT = Mode.values().length;
-
-    // Make the class non-instantiable.
-    private PorterDuffUtility() {
-    }
-
-    /**
-     * Convert the porterDuffMode from the framework to its corresponding enum. This defaults to
-     * {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Mode getPorterDuffMode(int porterDuffMode) {
-        if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
-            return PorterDuff.intToMode(porterDuffMode);
-        }
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null);
-        assert false;
-        return Mode.SRC_OVER;
-    }
-
-    /**
-     * A utility method to get the {@link Composite} that represents the filter for the given
-     * PorterDuff mode and the alpha. Defaults to {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Composite getComposite(Mode mode, int alpha255) {
-        float alpha1 = alpha255 != 0xFF ? alpha255 / 255.f : 1.f;
-        switch (mode) {
-            case CLEAR:
-                return AlphaComposite.getInstance(AlphaComposite.CLEAR, alpha1);
-            case SRC:
-                return AlphaComposite.getInstance(AlphaComposite.SRC, alpha1);
-            case DST:
-                return AlphaComposite.getInstance(AlphaComposite.DST, alpha1);
-            case SRC_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-            case DST_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, alpha1);
-            case SRC_IN:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha1);
-            case DST_IN:
-                return AlphaComposite.getInstance(AlphaComposite.DST_IN, alpha1);
-            case SRC_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, alpha1);
-            case DST_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, alpha1);
-            case SRC_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha1);
-            case DST_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, alpha1);
-            case XOR:
-                return AlphaComposite.getInstance(AlphaComposite.XOR, alpha1);
-            case DARKEN:
-                return BlendComposite.getInstance(BlendingMode.DARKEN, alpha1);
-            case LIGHTEN:
-                return BlendComposite.getInstance(BlendingMode.LIGHTEN, alpha1);
-            case MULTIPLY:
-                return BlendComposite.getInstance(BlendingMode.MULTIPLY, alpha1);
-            case SCREEN:
-                return BlendComposite.getInstance(BlendingMode.SCREEN, alpha1);
-            case ADD:
-                return BlendComposite.getInstance(BlendingMode.ADD, alpha1);
-            case OVERLAY:
-                return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1);
-            default:
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unsupported PorterDuff Mode: %1$s", mode.name()),
-                        null, null /*data*/);
-
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
deleted file mode 100644
index 0c53753..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRound;
-import com.android.resources.ScreenSize;
-
-import android.content.res.Configuration;
-import android.os.HandlerThread_Delegate;
-import android.util.DisplayMetrics;
-import android.view.ViewConfiguration_Accessor;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodManager_Accessor;
-
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-/**
- * Base class for rendering action.
- *
- * It provides life-cycle methods to init and stop the rendering.
- * The most important methods are:
- * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
- * after the rendering.
- *
- *
- * @param <T> the {@link RenderParams} implementation
- *
- */
-public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
-
-    /**
-     * The current context being rendered. This is set through {@link #acquire(long)} and
-     * {@link #init(long)}, and unset in {@link #release()}.
-     */
-    private static BridgeContext sCurrentContext = null;
-
-    private final T mParams;
-
-    private BridgeContext mContext;
-
-    /**
-     * Creates a renderAction.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderAction#init(long)}, which act as a
-     * call to {@link RenderAction#acquire(long)}
-     *
-     * @param params the RenderParams. This must be a copy that the action can keep
-     *
-     */
-    protected RenderAction(T params) {
-        mParams = params;
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    public Result init(long timeout) {
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
-
-        // setup the display Metrics.
-        DisplayMetrics metrics = new DisplayMetrics();
-        metrics.densityDpi = metrics.noncompatDensityDpi =
-                hardwareConfig.getDensity().getDpiValue();
-
-        metrics.density = metrics.noncompatDensity =
-                metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
-
-        metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
-
-        metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
-        metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
-        metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
-        metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
-
-        RenderResources resources = mParams.getResources();
-
-        // build the context
-        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(mParams),
-                mParams.getTargetSdkVersion(), mParams.isRtlSupported());
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Prepares the scene for action.
-     * <p>
-     * This call is blocking if another rendering/inflating is currently happening, and will return
-     * whether the preparation worked.
-     *
-     * The preparation can fail if another rendering took too long and the timeout was elapsed.
-     *
-     * More than one call to this from the same thread will have no effect and will return
-     * {@link Result.Status#SUCCESS}.
-     *
-     * After scene actions have taken place, only one call to {@link #release()} must be
-     * done.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #release()
-     *
-     * @throws IllegalStateException if {@link #init(long)} was never called.
-     */
-    public Result acquire(long timeout) {
-        if (mContext == null) {
-            throw new IllegalStateException("After scene creation, #init() must be called");
-        }
-
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Acquire the lock so that the scene can be acted upon.
-     * <p>
-     * This returns null if the lock was just acquired, otherwise it returns
-     * {@link Result.Status#SUCCESS} if the lock already belonged to that thread, or another
-     * instance (see {@link Result#getStatus()}) if an error occurred.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     * @return null if the lock was just acquire or another result depending on the state.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene.
-     */
-    private Result acquireLock(long timeout) {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            try {
-                boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
-
-                if (!acquired) {
-                    return ERROR_TIMEOUT.createResult();
-                }
-            } catch (InterruptedException e) {
-                return ERROR_LOCK_INTERRUPTED.createResult();
-            }
-        } else {
-            // This thread holds the lock already. Checks that this wasn't for a different context.
-            // If this is called by init, mContext will be null and so should sCurrentContext
-            // anyway
-            if (mContext != sCurrentContext) {
-                throw new IllegalStateException("Acquiring different scenes from same thread without releases");
-            }
-            return SUCCESS.createResult();
-        }
-
-        return null;
-    }
-
-    /**
-     * Cleans up the scene after an action.
-     */
-    public void release() {
-        ReentrantLock lock = Bridge.getLock();
-
-        // with the use of finally blocks, it is possible to find ourself calling this
-        // without a successful call to prepareScene. This test makes sure that unlock() will
-        // not throw IllegalMonitorStateException.
-        if (lock.isHeldByCurrentThread()) {
-            tearDown();
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Sets up the session for rendering.
-     * <p/>
-     * The counterpart is {@link #tearDown()}.
-     */
-    private void setUp() {
-        // setup the ParserFactory
-        ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory());
-
-        // make sure the Resources object references the context (and other objects) for this
-        // scene
-        mContext.initResources();
-        sCurrentContext = mContext;
-
-        // create an InputMethodManager
-        InputMethodManager.getInstance();
-
-        LayoutLog currentLog = mParams.getLog();
-        Bridge.setLog(currentLog);
-        mContext.getRenderResources().setFrameworkResourceIdProvider(this);
-        mContext.getRenderResources().setLogger(currentLog);
-    }
-
-    /**
-     * Tear down the session after rendering.
-     * <p/>
-     * The counterpart is {@link #setUp()}.
-     */
-    private void tearDown() {
-        // The context may be null, if there was an error during init().
-        if (mContext != null) {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            mContext.disposeResources();
-        }
-
-        if (sCurrentContext != null) {
-            // quit HandlerThread created during this session.
-            HandlerThread_Delegate.cleanUp(sCurrentContext);
-        }
-
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration_Accessor.clearConfigurations();
-
-        // remove the InputMethodManager
-        InputMethodManager_Accessor.resetInstance();
-
-        sCurrentContext = null;
-
-        Bridge.setLog(null);
-        if (mContext != null) {
-            mContext.getRenderResources().setFrameworkResourceIdProvider(null);
-            mContext.getRenderResources().setLogger(null);
-        }
-        ParserFactory.setParserFactory(null);
-    }
-
-    public static BridgeContext getCurrentContext() {
-        return sCurrentContext;
-    }
-
-    protected T getParams() {
-        return mParams;
-    }
-
-    protected BridgeContext getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the log associated with the session.
-     * @return the log or null if there are none.
-     */
-    public LayoutLog getLog() {
-        if (mParams != null) {
-            return mParams.getLog();
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks that the lock is owned by the current thread and that the current context is the one
-     * from this scene.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     */
-    protected void checkLock() {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-        if (sCurrentContext != mContext) {
-            throw new IllegalStateException("Thread acquired a scene but is rendering a different one");
-        }
-    }
-
-    // VisibleForTesting
-    public static Configuration getConfiguration(RenderParams params) {
-        Configuration config = new Configuration();
-
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        ScreenSize screenSize = hardwareConfig.getScreenSize();
-        if (screenSize != null) {
-            switch (screenSize) {
-                case SMALL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
-                    break;
-                case NORMAL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
-                    break;
-                case LARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
-                    break;
-                case XLARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
-                    break;
-            }
-        }
-
-        Density density = hardwareConfig.getDensity();
-        if (density == null) {
-            density = Density.MEDIUM;
-        }
-
-        config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
-        config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
-        if (config.screenHeightDp < config.screenWidthDp) {
-            //noinspection SuspiciousNameCombination
-            config.smallestScreenWidthDp = config.screenHeightDp;
-        } else {
-            config.smallestScreenWidthDp = config.screenWidthDp;
-        }
-        config.densityDpi = density.getDpiValue();
-
-        // never run in compat mode:
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-
-        ScreenOrientation orientation = hardwareConfig.getOrientation();
-        if (orientation != null) {
-            switch (orientation) {
-            case PORTRAIT:
-                config.orientation = Configuration.ORIENTATION_PORTRAIT;
-                break;
-            case LANDSCAPE:
-                config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-                break;
-            case SQUARE:
-                //noinspection deprecation
-                config.orientation = Configuration.ORIENTATION_SQUARE;
-                break;
-            }
-        } else {
-            config.orientation = Configuration.ORIENTATION_UNDEFINED;
-        }
-
-        ScreenRound roundness = hardwareConfig.getScreenRoundness();
-        if (roundness != null) {
-            switch (roundness) {
-                case ROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
-                    break;
-                case NOTROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_NO;
-            }
-        } else {
-            config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_UNDEFINED;
-        }
-        String locale = params.getLocale();
-        if (locale != null && !locale.isEmpty()) config.locale = new Locale(locale);
-
-        // TODO: fill in more config info.
-
-        return config;
-    }
-
-
-    // --- FrameworkResourceIdProvider methods
-
-    @Override
-    public Integer getId(ResourceType resType, String resName) {
-        return Bridge.getResourceId(resType, resName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
deleted file mode 100644
index d797eec..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.view.AttachInfo_Accessor;
-import android.view.View.MeasureSpec;
-import android.widget.FrameLayout;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
- *
- * The class only provides a simple {@link #render()} method, but the full life-cycle of the
- * action must be respected.
- *
- * @see RenderAction
- *
- */
-public class RenderDrawable extends RenderAction<DrawableParams> {
-
-    public RenderDrawable(DrawableParams params) {
-        super(new DrawableParams(params));
-    }
-
-    public Result render() {
-        checkLock();
-        // get the drawable resource value
-        DrawableParams params = getParams();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-        ResourceValue drawableResource = params.getDrawable();
-
-        // resolve it
-        BridgeContext context = getContext();
-        drawableResource = context.getRenderResources().resolveResValue(drawableResource);
-
-        if (drawableResource == null) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        ResourceType resourceType = drawableResource.getResourceType();
-        if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
-
-        final Boolean allStates =
-                params.getFlag(RenderParamsFlags.FLAG_KEY_RENDER_ALL_DRAWABLE_STATES);
-        if (allStates == Boolean.TRUE) {
-            final List<BufferedImage> result;
-
-            if (d instanceof StateListDrawable) {
-                result = new ArrayList<BufferedImage>();
-                final StateListDrawable stateList = (StateListDrawable) d;
-                for (int i = 0; i < stateList.getStateCount(); i++) {
-                    final Drawable stateDrawable = stateList.getStateDrawable(i);
-                    result.add(renderImage(hardwareConfig, stateDrawable, context));
-                }
-            } else {
-                result = Collections.singletonList(renderImage(hardwareConfig, d, context));
-            }
-
-            return Status.SUCCESS.createResult(result);
-        } else {
-            BufferedImage image = renderImage(hardwareConfig, d, context);
-            return Status.SUCCESS.createResult(image);
-        }
-    }
-
-    private BufferedImage renderImage(HardwareConfig hardwareConfig, Drawable d,
-            BridgeContext context) {
-        // create a simple FrameLayout
-        FrameLayout content = new FrameLayout(context);
-
-        // get the actual Drawable object to draw
-        content.setBackground(d);
-
-        // set the AttachInfo on the root view.
-        AttachInfo_Accessor.setAttachInfo(content);
-
-
-        // measure
-        int w = d.getIntrinsicWidth();
-        int h = d.getIntrinsicHeight();
-
-        final int screenWidth = hardwareConfig.getScreenWidth();
-        final int screenHeight = hardwareConfig.getScreenHeight();
-
-        if (w == -1 || h == -1) {
-            // Use screen size when either intrinsic width or height isn't available
-            w = screenWidth;
-            h = screenHeight;
-        } else if (w > screenWidth || h > screenHeight) {
-            // If image wouldn't fit to the screen, resize it to avoid cropping.
-
-            // We need to find scale such that scale * w <= screenWidth, scale * h <= screenHeight
-            double scale = Math.min((double) screenWidth / w, (double) screenHeight / h);
-
-            // scale * w / scale * h = w / h, so, proportions are preserved.
-            w = (int) Math.floor(scale * w);
-            h = (int) Math.floor(scale * h);
-        }
-
-        int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
-        int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
-        content.measure(w_spec, h_spec);
-
-        // now do the layout.
-        content.layout(0, 0, w, h);
-
-        // preDraw setup
-        AttachInfo_Accessor.dispatchOnPreDraw(content);
-
-        // draw into a new image
-        BufferedImage image = getImage(w, h);
-
-        // create an Android bitmap around the BufferedImage
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
-                true /*isMutable*/, hardwareConfig.getDensity());
-
-        // create a Canvas around the Android bitmap
-        Canvas canvas = new Canvas(bitmap);
-        canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-
-        // and draw
-        content.draw(canvas);
-        return image;
-    }
-
-    protected BufferedImage getImage(int w, int h) {
-        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D gc = image.createGraphics();
-        gc.setComposite(AlphaComposite.Src);
-
-        gc.setColor(new Color(0x00000000, true));
-        gc.fillRect(0, 0, w, h);
-
-        // done
-        gc.dispose();
-
-        return image;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
deleted file mode 100644
index d21955e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-import com.android.internal.view.menu.ActionMenuItemView;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.IconMenuItemView;
-import com.android.internal.view.menu.ListMenuItemView;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.android.graphics.NopCanvas;
-import com.android.layoutlib.bridge.android.support.DesignLibUtil;
-import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
-import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
-import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Fragment_Delegate;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.os.Looper;
-import android.preference.Preference_Delegate;
-import android.view.AttachInfo_Accessor;
-import android.view.BridgeInflater;
-import android.view.Choreographer_Delegate;
-import android.view.IWindowManager;
-import android.view.IWindowManagerImpl;
-import android.view.Surface;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.ViewParent;
-import android.view.WindowManagerGlobal_Delegate;
-import android.widget.AbsListView;
-import android.widget.AbsSpinner;
-import android.widget.ActionMenuView;
-import android.widget.AdapterView;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.QuickContactBadge;
-import android.widget.TabHost;
-import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf;
-
-/**
- * Class implementing the render session.
- * <p/>
- * A session is a stateful representation of a layout file. It is initialized with data coming
- * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
- * be done on the layout.
- */
-public class RenderSessionImpl extends RenderAction<SessionParams> {
-
-    private static final Canvas NOP_CANVAS = new NopCanvas();
-
-    // scene state
-    private RenderSession mScene;
-    private BridgeXmlBlockParser mBlockParser;
-    private BridgeInflater mInflater;
-    private ViewGroup mViewRoot;
-    private FrameLayout mContentRoot;
-    private Canvas mCanvas;
-    private int mMeasuredScreenWidth = -1;
-    private int mMeasuredScreenHeight = -1;
-    private boolean mIsAlphaChannelImage;
-    /** If >= 0, a frame will be executed */
-    private long mElapsedFrameTimeNanos = -1;
-    /** True if one frame has been already executed to start the animations */
-    private boolean mFirstFrameExecuted = false;
-
-    // information being returned through the API
-    private BufferedImage mImage;
-    private List<ViewInfo> mViewInfoList;
-    private List<ViewInfo> mSystemViewInfoList;
-    private Layout.Builder mLayoutBuilder;
-    private boolean mNewRenderSize;
-
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        private PostInflateException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Creates a layout scene with all the information coming from the layout bridge API.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)},
-     * which act as a
-     * call to {@link RenderSessionImpl#acquire(long)}
-     *
-     * @see Bridge#createSession(SessionParams)
-     */
-    public RenderSessionImpl(SessionParams params) {
-        super(new SessionParams(params));
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    @Override
-    public Result init(long timeout) {
-        Result result = super.init(timeout);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        SessionParams params = getParams();
-        BridgeContext context = getContext();
-
-        // use default of true in case it's not found to use alpha by default
-        mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(),
-                "windowIsFloating", true, true);
-
-        mLayoutBuilder = new Layout.Builder(params, context);
-
-        // FIXME: find those out, and possibly add them to the render params
-        boolean hasNavigationBar = true;
-        //noinspection ConstantConditions
-        IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
-                context.getMetrics(), Surface.ROTATION_0, hasNavigationBar);
-        WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
-
-        // build the inflater and parser.
-        mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
-        context.setBridgeInflater(mInflater);
-
-        mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
-     */
-    private void measureLayout(@NonNull SessionParams params) {
-        // only do the screen measure when needed.
-        if (mMeasuredScreenWidth != -1) {
-            return;
-        }
-
-        RenderingMode renderingMode = params.getRenderingMode();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        mNewRenderSize = true;
-        mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
-        mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
-
-        if (renderingMode != RenderingMode.NORMAL) {
-            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-
-            // We used to compare the measured size of the content to the screen size but
-            // this does not work anymore due to the 2 following issues:
-            // - If the content is in a decor (system bar, title/action bar), the root view
-            //   will not resize even with the UNSPECIFIED because of the embedded layout.
-            // - If there is no decor, but a dialog frame, then the dialog padding prevents
-            //   comparing the size of the content to the screen frame (as it would not
-            //   take into account the dialog padding).
-
-            // The solution is to first get the content size in a normal rendering, inside
-            // the decor or the dialog padding.
-            // Then measure only the content with UNSPECIFIED to see the size difference
-            // and apply this to the screen size.
-
-            View measuredView = mContentRoot.getChildAt(0);
-
-            // first measure the full layout, with EXACTLY to get the size of the
-            // content as it is inside the decor/dialog
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> exactMeasure = measureView(
-                    mViewRoot, measuredView,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-
-            // now measure the content only using UNSPECIFIED (where applicable, based on
-            // the rendering mode). This will give us the size the content needs.
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> result = measureView(
-                    mContentRoot, mContentRoot.getChildAt(0),
-                    mMeasuredScreenWidth, widthMeasureSpecMode,
-                    mMeasuredScreenHeight, heightMeasureSpecMode);
-
-            // If measuredView is not null, exactMeasure nor result will be null.
-            assert exactMeasure != null;
-            assert result != null;
-
-            // now look at the difference and add what is needed.
-            if (renderingMode.isHorizExpand()) {
-                int measuredWidth = exactMeasure.getFirst();
-                int neededWidth = result.getFirst();
-                if (neededWidth > measuredWidth) {
-                    mMeasuredScreenWidth += neededWidth - measuredWidth;
-                }
-                if (mMeasuredScreenWidth < measuredWidth) {
-                    // If the screen width is less than the exact measured width,
-                    // expand to match.
-                    mMeasuredScreenWidth = measuredWidth;
-                }
-            }
-
-            if (renderingMode.isVertExpand()) {
-                int measuredHeight = exactMeasure.getSecond();
-                int neededHeight = result.getSecond();
-                if (neededHeight > measuredHeight) {
-                    mMeasuredScreenHeight += neededHeight - measuredHeight;
-                }
-                if (mMeasuredScreenHeight < measuredHeight) {
-                    // If the screen height is less than the exact measured height,
-                    // expand to match.
-                    mMeasuredScreenHeight = measuredHeight;
-                }
-            }
-        }
-    }
-
-    /**
-     * Inflates the layout.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #init(long)} was not called.
-     */
-    public Result inflate() {
-        checkLock();
-
-        try {
-            mViewRoot = new Layout(mLayoutBuilder);
-            mLayoutBuilder = null;  // Done with the builder.
-            mContentRoot = ((Layout) mViewRoot).getContentRoot();
-            SessionParams params = getParams();
-            BridgeContext context = getContext();
-
-            if (Bridge.isLocaleRtl(params.getLocale())) {
-                if (!params.isRtlSupported()) {
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED,
-                            "You are using a right-to-left " +
-                                    "(RTL) locale but RTL is not enabled", null);
-                } else if (params.getSimulatedPlatformVersion() < 17) {
-                    // This will render ok because we are using the latest layoutlib but at least
-                    // warn the user that this might fail in a real device.
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
-                            "right-to-left " +
-                            "(RTL) locale but RTL is not supported for API level < 17", null);
-                }
-            }
-
-            // Sets the project callback (custom view loader) to the fragment delegate so that
-            // it can instantiate the custom Fragment.
-            Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
-
-            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
-            boolean isPreference = "PreferenceScreen".equals(rootTag);
-            View view;
-            if (isPreference) {
-                // First try to use the support library inflater. If something fails, fallback
-                // to the system preference inflater.
-                view = SupportPreferencesUtil.inflatePreference(getContext(), mBlockParser,
-                        mContentRoot);
-                if (view == null) {
-                    view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
-                            mContentRoot);
-                }
-            } else {
-                view = mInflater.inflate(mBlockParser, mContentRoot);
-            }
-
-            // done with the parser, pop it.
-            context.popParser();
-
-            Fragment_Delegate.setLayoutlibCallback(null);
-
-            // set the AttachInfo on the root view.
-            AttachInfo_Accessor.setAttachInfo(mViewRoot);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
-            mInflater.onDoneInflation();
-
-            setActiveToolbar(view, context, params);
-
-            measureLayout(params);
-            measureView(mViewRoot, null /*measuredView*/,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            return SUCCESS.createResult();
-        } catch (PostInflateException e) {
-            return ERROR_INFLATION.createResult(e.getMessage(), e);
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_INFLATION.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Sets the time for which the next frame will be selected. The time is the elapsed time from
-     * the current system nanos time. You
-     */
-    public void setElapsedFrameTimeNanos(long nanos) {
-        mElapsedFrameTimeNanos = nanos;
-    }
-
-    /**
-     * Runs a layout pass for the given view root
-     */
-    private static void doLayout(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot,
-            int width, int height) {
-        // measure again with the size we need
-        // This must always be done before the call to layout
-        measureView(viewRoot, null /*measuredView*/,
-                width, MeasureSpec.EXACTLY,
-                height, MeasureSpec.EXACTLY);
-
-        // now do the layout.
-        viewRoot.layout(0, 0, width, height);
-        handleScrolling(context, viewRoot);
-    }
-
-    /**
-     * Renders the given view hierarchy to the passed canvas and returns the result of the render
-     * operation.
-     * @param canvas an optional canvas to render the views to. If null, only the measure and
-     * layout steps will be executed.
-     */
-    private static Result renderAndBuildResult(@NonNull ViewGroup viewRoot, @Nullable Canvas canvas) {
-        if (canvas == null) {
-            return SUCCESS.createResult();
-        }
-
-        AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
-        viewRoot.draw(canvas);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result render(boolean freshRender) {
-        return renderAndBuildResult(freshRender, false);
-    }
-
-    /**
-     * Measures the layout
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result measure() {
-        return renderAndBuildResult(false, true);
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    private Result renderAndBuildResult(boolean freshRender, boolean onlyMeasure) {
-        checkLock();
-
-        SessionParams params = getParams();
-
-        try {
-            if (mViewRoot == null) {
-                return ERROR_NOT_INFLATED.createResult();
-            }
-
-            measureLayout(params);
-
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-            Result renderResult = SUCCESS.createResult();
-            if (onlyMeasure) {
-                // delete the canvas and image to reset them on the next full rendering
-                mImage = null;
-                mCanvas = null;
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            } else {
-                // draw the views
-                // create the BufferedImage into which the layout will be rendered.
-                boolean newImage = false;
-
-                // When disableBitmapCaching is true, we do not reuse mImage and
-                // we create a new one in every render.
-                // This is useful when mImage is just a wrapper of Graphics2D so
-                // it doesn't get cached.
-                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
-                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
-                if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
-                    mNewRenderSize = false;
-                    if (params.getImageFactory() != null) {
-                        mImage = params.getImageFactory().getImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight);
-                    } else {
-                        mImage = new BufferedImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight,
-                                BufferedImage.TYPE_INT_ARGB);
-                        newImage = true;
-                    }
-
-                    if (params.isBgColorOverridden()) {
-                        // since we override the content, it's the same as if it was a new image.
-                        newImage = true;
-                        Graphics2D gc = mImage.createGraphics();
-                        gc.setColor(new Color(params.getOverrideBgColor(), true));
-                        gc.setComposite(AlphaComposite.Src);
-                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                        gc.dispose();
-                    }
-
-                    // create an Android bitmap around the BufferedImage
-                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
-                            true /*isMutable*/, hardwareConfig.getDensity());
-
-                    if (mCanvas == null) {
-                        // create a Canvas around the Android bitmap
-                        mCanvas = new Canvas(bitmap);
-                    } else {
-                        mCanvas.setBitmap(bitmap);
-                    }
-                    mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-                }
-
-                if (freshRender && !newImage) {
-                    Graphics2D gc = mImage.createGraphics();
-                    gc.setComposite(AlphaComposite.Src);
-
-                    gc.setColor(new Color(0x00000000, true));
-                    gc.fillRect(0, 0,
-                            mMeasuredScreenWidth, mMeasuredScreenHeight);
-
-                    // done
-                    gc.dispose();
-                }
-
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                if (mElapsedFrameTimeNanos >= 0) {
-                    long initialTime = System_Delegate.nanoTime();
-                    if (!mFirstFrameExecuted) {
-                        // We need to run an initial draw call to initialize the animations
-                        renderAndBuildResult(mViewRoot, NOP_CANVAS);
-
-                        // The first frame will initialize the animations
-                        Choreographer_Delegate.doFrame(initialTime);
-                        mFirstFrameExecuted = true;
-                    }
-                    // Second frame will move the animations
-                    Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
-                }
-                renderResult = renderAndBuildResult(mViewRoot, mCanvas);
-            }
-
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            // success!
-            return renderResult;
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
-     * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
-     *
-     * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
-     * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
-     *
-     * @param viewToMeasure the view on which to execute measure().
-     * @param measuredView if non null, the view to query for its measured width/height.
-     * @param width the width to use in the MeasureSpec.
-     * @param widthMode the MeasureSpec mode to use for the width.
-     * @param height the height to use in the MeasureSpec.
-     * @param heightMode the MeasureSpec mode to use for the height.
-     * @return the measured width/height if measuredView is non-null, null otherwise.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
-            int width, int widthMode, int height, int heightMode) {
-        int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
-        int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
-        viewToMeasure.measure(w_spec, h_spec);
-
-        if (measuredView != null) {
-            return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
-        }
-
-        return null;
-    }
-
-    /**
-     * Animate an object
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#animate(Object, String, boolean, IAnimationListener)
-     */
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // find the animation file.
-        ResourceValue animationResource;
-        int animationId = 0;
-        if (isFrameworkAnimation) {
-            animationResource = context.getRenderResources().getFrameworkResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName);
-            }
-        } else {
-            animationResource = context.getRenderResources().getProjectResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = context.getLayoutlibCallback().getResourceId(
-                        ResourceType.ANIMATOR, animationName);
-            }
-        }
-
-        if (animationResource != null) {
-            try {
-                Animator anim = AnimatorInflater.loadAnimator(context, animationId);
-                if (anim != null) {
-                    anim.setTarget(targetObject);
-
-                    new PlayAnimationThread(anim, this, animationName, listener).start();
-
-                    return SUCCESS.createResult();
-                }
-            } catch (Exception e) {
-                // get the real cause of the exception.
-                Throwable t = e;
-                while (t.getCause() != null) {
-                    t = t.getCause();
-                }
-
-                return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-            }
-        }
-
-        return ERROR_ANIM_NOT_FOUND.createResult();
-    }
-
-    /**
-     * Insert a new child into an existing parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
-     */
-    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
-            final int index, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // create a block parser for the XML
-        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                childXml, context, false /* platformResourceFlag */);
-
-        // inflate the child without adding it to the root since we want to control where it'll
-        // get added. We do pass the parentView however to ensure that the layoutParams will
-        // be created correctly.
-        final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
-        blockParser.ensurePopped();
-
-        invalidateRenderingSize();
-
-        if (listener != null) {
-            new AnimationThread(this, "insertChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parentView.setLayoutTransition(new LayoutTransition());
-                    return addView(parentView, child, index);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parentView.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(child);
-        }
-
-        // add it to the parentView in the correct location
-        Result result = addView(parentView, child, index);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (result.isSuccess()) {
-            result = result.getCopyWithData(child);
-        }
-
-        return result;
-    }
-
-    /**
-     * Adds a given view to a given parent at a given index.
-     *
-     * @param parent the parent to receive the view
-     * @param view the view to add to the parent
-     * @param index the index where to do the add.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result addView(ViewGroup parent, View view, int index) {
-        try {
-            parent.addView(view, index);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Moves a view to a new parent at a given location
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
-     */
-    public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
-            Map<String, String> layoutParamsMap, final IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        LayoutParams layoutParams = null;
-        if (layoutParamsMap != null) {
-            // need to create a new LayoutParams object for the new parent.
-            layoutParams = newParentView.generateLayoutParams(
-                    new BridgeLayoutParamsMapAttributes(layoutParamsMap));
-        }
-
-        // get the current parent of the view that needs to be moved.
-        final ViewGroup previousParent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            final LayoutParams params = layoutParams;
-
-            // there is no support for animating views across layouts, so in case the new and old
-            // parent views are different we fake the animation through a no animation thread.
-            if (previousParent != newParentView) {
-                new Thread("not animated moveChild") {
-                    @Override
-                    public void run() {
-                        Result result = moveView(previousParent, newParentView, childView, index,
-                                params);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                        }
-
-                        // ready to do the work, acquire the scene.
-                        result = acquire(250);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                            return;
-                        }
-
-                        try {
-                            result = render(false /*freshRender*/);
-                            if (result.isSuccess()) {
-                                listener.onNewFrame(RenderSessionImpl.this.getSession());
-                            }
-                        } finally {
-                            release();
-                        }
-
-                        listener.done(result);
-                    }
-                }.start();
-            } else {
-                new AnimationThread(this, "moveChild", listener) {
-
-                    @Override
-                    public Result preAnimation() {
-                        // set up the transition for the parent.
-                        LayoutTransition transition = new LayoutTransition();
-                        previousParent.setLayoutTransition(transition);
-
-                        // tweak the animation durations and start delays (to match the duration of
-                        // animation playing just before).
-                        // Note: Cannot user Animation.setDuration() directly. Have to set it
-                        // on the LayoutTransition.
-                        transition.setDuration(LayoutTransition.DISAPPEARING, 100);
-                        // CHANGE_DISAPPEARING plays after DISAPPEARING
-                        transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100);
-                        // CHANGE_APPEARING plays after CHANGE_APPEARING
-                        transition.setStartDelay(LayoutTransition.APPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.APPEARING, 100);
-
-                        return moveView(previousParent, newParentView, childView, index, params);
-                    }
-
-                    @Override
-                    public void postAnimation() {
-                        previousParent.setLayoutTransition(null);
-                        newParentView.setLayoutTransition(null);
-                    }
-                }.start();
-            }
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(layoutParams);
-        }
-
-        Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (layoutParams != null && result.isSuccess()) {
-            result = result.getCopyWithData(layoutParams);
-        }
-
-        return result;
-    }
-
-    /**
-     * Moves a View from its current parent to a new given parent at a new given location, with
-     * an optional new {@link LayoutParams} instance
-     *
-     * @param previousParent the previous parent, still owning the child at the time of the call.
-     * @param newParent the new parent
-     * @param movedView the view to move
-     * @param index the new location in the new parent
-     * @param params an option (can be null) {@link LayoutParams} instance.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result moveView(ViewGroup previousParent, final ViewGroup newParent,
-            final View movedView, final int index, final LayoutParams params) {
-        try {
-            // check if there is a transition on the previousParent.
-            LayoutTransition previousTransition = previousParent.getLayoutTransition();
-            if (previousTransition != null) {
-                // in this case there is an animation. This means we have to wait for the child's
-                // parent reference to be null'ed out so that we can add it to the new parent.
-                // It is technically removed right before the DISAPPEARING animation is done (if
-                // the animation of this type is not null, otherwise it's after which is impossible
-                // to handle).
-                // Because there is no move animation, if the new parent is the same as the old
-                // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before
-                // adding the child or the child will appear in its new location before the
-                // other children have made room for it.
-
-                // add a listener to the transition to be notified of the actual removal.
-                previousTransition.addTransitionListener(new TransitionListener() {
-                    private int mChangeDisappearingCount = 0;
-
-                    @Override
-                    public void startTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount++;
-                        }
-                    }
-
-                    @Override
-                    public void endTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount--;
-                        }
-
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING &&
-                                mChangeDisappearingCount == 0) {
-                            // add it to the parentView in the correct location
-                            if (params != null) {
-                                newParent.addView(movedView, index, params);
-                            } else {
-                                newParent.addView(movedView, index);
-                            }
-                        }
-                    }
-                });
-
-                // remove the view from the current parent.
-                previousParent.removeView(movedView);
-
-                // and return since adding the view to the new parent is done in the listener.
-                return SUCCESS.createResult();
-            } else {
-                // standard code with no animation. pretty simple.
-                previousParent.removeView(movedView);
-
-                // add it to the parentView in the correct location
-                if (params != null) {
-                    newParent.addView(movedView, index, params);
-                } else {
-                    newParent.addView(movedView, index);
-                }
-
-                return SUCCESS.createResult();
-            }
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Removes a child from its current parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#removeChild(Object, IAnimationListener)
-     */
-    public Result removeChild(final View childView, IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        final ViewGroup parent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            new AnimationThread(this, "moveChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parent.setLayoutTransition(new LayoutTransition());
-                    return removeView(parent, childView);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parent.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult();
-        }
-
-        Result result = removeView(parent, childView);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        return render(false /*freshRender*/);
-    }
-
-    /**
-     * Removes a given view from its current parent.
-     *
-     * @param view the view to remove from its parent
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result removeView(ViewGroup parent, View view) {
-        try {
-            parent.removeView(view);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Post process on a view hierarchy that was just inflated.
-     * <p/>
-     * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param layoutlibCallback callback to the project.
-     * @param skip the view and it's children are not processed.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
-            throws PostInflateException {
-        if (view == skip) {
-            return;
-        }
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost) view, layoutlibCallback);
-        } else if (view instanceof QuickContactBadge) {
-            QuickContactBadge badge = (QuickContactBadge) view;
-            badge.setImageToDefault();
-        } else if (view instanceof AdapterView<?>) {
-            // get the view ID.
-            int id = view.getId();
-
-            BridgeContext context = getContext();
-
-            // get a ResourceReference from the integer ID.
-            ResourceReference listRef = context.resolveId(id);
-
-            if (listRef != null) {
-                SessionParams params = getParams();
-                AdapterBinding binding = params.getAdapterBindings().get(listRef);
-
-                // if there was no adapter binding, trying to get it from the call back.
-                if (binding == null) {
-                    binding = layoutlibCallback.getAdapterBinding(
-                            listRef, context.getViewKey(view), view);
-                }
-
-                if (binding != null) {
-
-                    if (view instanceof AbsListView) {
-                        if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
-                                view instanceof ListView) {
-                            ListView list = (ListView) view;
-
-                            boolean skipCallbackParser = false;
-
-                            int count = binding.getHeaderCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getHeaderAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addHeaderView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-
-                            count = binding.getFooterCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getFooterAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addFooterView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-                        }
-
-                        if (view instanceof ExpandableListView) {
-                            ((ExpandableListView) view).setAdapter(
-                                    new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
-                        } else {
-                            ((AbsListView) view).setAdapter(
-                                    new FakeAdapter(listRef, binding, layoutlibCallback));
-                        }
-                    } else if (view instanceof AbsSpinner) {
-                        ((AbsSpinner) view).setAdapter(
-                                new FakeAdapter(listRef, binding, layoutlibCallback));
-                    }
-                }
-            }
-        } else if (view instanceof ViewGroup) {
-            mInflater.postInflateProcess(view);
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int c = 0; c < count; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, layoutlibCallback, skip);
-            }
-        }
-    }
-
-    /**
-     * If the root layout is a CoordinatorLayout with an AppBar:
-     * Set the title of the AppBar to the title of the activity context.
-     */
-    private void setActiveToolbar(View view, BridgeContext context, SessionParams params) {
-        View coordinatorLayout = findChildView(view, DesignLibUtil.CN_COORDINATOR_LAYOUT);
-        if (coordinatorLayout == null) {
-            return;
-        }
-        View appBar = findChildView(coordinatorLayout, DesignLibUtil.CN_APPBAR_LAYOUT);
-        if (appBar == null) {
-            return;
-        }
-        ViewGroup collapsingToolbar =
-                (ViewGroup) findChildView(appBar, DesignLibUtil.CN_COLLAPSING_TOOLBAR_LAYOUT);
-        if (collapsingToolbar == null) {
-            return;
-        }
-        if (!hasToolbar(collapsingToolbar)) {
-            return;
-        }
-        RenderResources res = context.getRenderResources();
-        String title = params.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            title = titleValue.getValue();
-        }
-        DesignLibUtil.setTitle(collapsingToolbar, title);
-    }
-
-    private View findChildView(View view, String className) {
-        if (!(view instanceof ViewGroup)) {
-            return null;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), className)) {
-                return group.getChildAt(i);
-            }
-        }
-        return null;
-    }
-
-    private boolean hasToolbar(View collapsingToolbar) {
-        if (!(collapsingToolbar instanceof ViewGroup)) {
-            return false;
-        }
-        ViewGroup group = (ViewGroup) collapsingToolbar;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), DesignLibUtil.CN_TOOLBAR)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If
-     * the component supports nested scrolling attempt that first, then use the unconsumed scroll
-     * part to scroll the content in the component.
-     */
-    private static void handleScrolling(BridgeContext context, View view) {
-        int scrollPosX = context.getScrollXPos(view);
-        int scrollPosY = context.getScrollYPos(view);
-        if (scrollPosX != 0 || scrollPosY != 0) {
-            if (view.isNestedScrollingEnabled()) {
-                int[] consumed = new int[2];
-                int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0;
-                axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0;
-                if (view.startNestedScroll(axis)) {
-                    view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null);
-                    view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY,
-                            null);
-                    view.stopNestedScroll();
-                    scrollPosX -= consumed[0];
-                    scrollPosY -= consumed[1];
-                }
-            }
-            if (scrollPosX != 0 || scrollPosY != 0) {
-                view.scrollTo(scrollPosX, scrollPosY);
-            }
-        }
-
-        if (!(view instanceof ViewGroup)) {
-            return;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            View child = group.getChildAt(i);
-            handleScrolling(context, child);
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param layoutlibCallback The project callback object to access the project R class.
-     * @throws PostInflateException if TabHost is missing the required ids for TabHost
-     */
-    private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if (!(v instanceof TabWidget)) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty)
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if (!(v instanceof FrameLayout)) {
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the frameLayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        if (count == 0) {
-            // Create a dummy child to get a single tab
-            TabSpec spec = tabHost.newTabSpec("tag")
-                    .setIndicator("Tab Label", tabHost.getResources()
-                            .getDrawable(android.R.drawable.ic_menu_info_details, null))
-                    .setContent(tag -> new LinearLayout(getContext()));
-            tabHost.addTab(spec);
-        } else {
-            // for each child of the frameLayout, add a new TabSpec
-            for (int i = 0 ; i < count ; i++) {
-                View child = content.getChildAt(i);
-                String tabSpec = String.format("tab_spec%d", i+1);
-                @SuppressWarnings("ConstantConditions")  // child cannot be null.
-                int id = child.getId();
-                @SuppressWarnings("deprecation")
-                Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
-                String name;
-                if (resource != null) {
-                    name = resource.getSecond();
-                } else {
-                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
-                }
-                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-            }
-        }
-    }
-
-    /**
-     * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the
-     * bounds of all the views.
-     *
-     * @param view the root View
-     * @param hOffset horizontal offset for the view bounds.
-     * @param vOffset vertical offset for the view bounds.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame.
-     *
-     * @return {@code ViewInfo} containing the bounds of the view and it children otherwise.
-     */
-    private ViewInfo visit(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        ViewInfo result = createViewInfo(view, hOffset, vOffset, setExtendedInfo, isContentFrame);
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            result.setChildren(visitAllChildren(group, isContentFrame ? 0 : hOffset,
-                    isContentFrame ? 0 : vOffset,
-                    setExtendedInfo, isContentFrame));
-        }
-        return result;
-    }
-
-    /**
-     * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo}
-     * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with
-     * the children of the {@code mContentRoot}.
-     *
-     * @param viewGroup the root View
-     * @param hOffset horizontal offset from the top for the content view frame.
-     * @param vOffset vertical offset from the top for the content view frame.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame. {@code false} if the {@code ViewInfo} to be created is
-     *                       part of the system decor.
-     */
-    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int hOffset, int vOffset,
-            boolean setExtendedInfo, boolean isContentFrame) {
-        if (viewGroup == null) {
-            return null;
-        }
-
-        if (!isContentFrame) {
-            vOffset += viewGroup.getTop();
-            hOffset += viewGroup.getLeft();
-        }
-
-        int childCount = viewGroup.getChildCount();
-        if (viewGroup == mContentRoot) {
-            List<ViewInfo> childrenWithoutOffset = new ArrayList<>(childCount);
-            List<ViewInfo> childrenWithOffset = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                ViewInfo[] childViewInfo =
-                        visitContentRoot(viewGroup.getChildAt(i), hOffset, vOffset,
-                        setExtendedInfo);
-                childrenWithoutOffset.add(childViewInfo[0]);
-                childrenWithOffset.add(childViewInfo[1]);
-            }
-            mViewInfoList = childrenWithOffset;
-            return childrenWithoutOffset;
-        } else {
-            List<ViewInfo> children = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                children.add(visit(viewGroup.getChildAt(i), hOffset, vOffset, setExtendedInfo,
-                        isContentFrame));
-            }
-            return children;
-        }
-    }
-
-    /**
-     * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the
-     * bounds of all the views. It returns two {@code ViewInfo} objects with the same children,
-     * one with the {@code offset} and other without the {@code offset}. The offset is needed to
-     * get the right bounds if the {@code ViewInfo} hierarchy is accessed from
-     * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the
-     * offset is not needed.
-     *
-     * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at
-     *         index 1 is with the offset.
-     */
-    @NonNull
-    private ViewInfo[] visitContentRoot(View view, int hOffset, int vOffset,
-            boolean setExtendedInfo) {
-        ViewInfo[] result = new ViewInfo[2];
-        if (view == null) {
-            return result;
-        }
-
-        result[0] = createViewInfo(view, 0, 0, setExtendedInfo, true);
-        result[1] = createViewInfo(view, hOffset, vOffset, setExtendedInfo, true);
-        if (view instanceof ViewGroup) {
-            List<ViewInfo> children =
-                    visitAllChildren((ViewGroup) view, 0, 0, setExtendedInfo, true);
-            result[0].setChildren(children);
-            result[1].setChildren(children);
-        }
-        return result;
-    }
-
-    /**
-     * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children
-     * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not
-     * set.
-     * @param hOffset horizontal offset for the view bounds. Used only if view is part of the
-     * content frame.
-     * @param vOffset vertial an offset for the view bounds. Used only if view is part of the
-     * content frame.
-     */
-    private ViewInfo createViewInfo(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        if (view == null) {
-            return null;
-        }
-
-        ViewParent parent = view.getParent();
-        ViewInfo result;
-        if (isContentFrame) {
-            // Account for parent scroll values when calculating the bounding box
-            int scrollX = parent != null ? ((View)parent).getScrollX() : 0;
-            int scrollY = parent != null ? ((View)parent).getScrollY() : 0;
-
-            // The view is part of the layout added by the user. Hence,
-            // the ViewCookie may be obtained only through the Context.
-            result = new ViewInfo(view.getClass().getName(),
-                    getContext().getViewKey(view), -scrollX + view.getLeft() + hOffset,
-                    -scrollY + view.getTop() + vOffset, -scrollX + view.getRight() + hOffset,
-                    -scrollY + view.getBottom() + vOffset,
-                    view, view.getLayoutParams());
-        } else {
-            // We are part of the system decor.
-            SystemViewInfo r = new SystemViewInfo(view.getClass().getName(),
-                    getViewKey(view),
-                    view.getLeft(), view.getTop(), view.getRight(),
-                    view.getBottom(), view, view.getLayoutParams());
-            result = r;
-            // We currently mark three kinds of views:
-            // 1. Menus in the Action Bar
-            // 2. Menus in the Overflow popup.
-            // 3. The overflow popup button.
-            if (view instanceof ListMenuItemView) {
-                // Mark 2.
-                // All menus in the popup are of type ListMenuItemView.
-                r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
-            } else {
-                // Mark 3.
-                ViewGroup.LayoutParams lp = view.getLayoutParams();
-                if (lp instanceof ActionMenuView.LayoutParams &&
-                        ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
-                    r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
-                } else {
-                    // Mark 1.
-                    // A view is a menu in the Action Bar is it is not the overflow button and of
-                    // its parent is of type ActionMenuView. We can also check if the view is
-                    // instanceof ActionMenuItemView but that will fail for menus using
-                    // actionProviderClass.
-                    while (parent != mViewRoot && parent instanceof ViewGroup) {
-                        if (parent instanceof ActionMenuView) {
-                            r.setViewType(ViewType.ACTION_BAR_MENU);
-                            break;
-                        }
-                        parent = parent.getParent();
-                    }
-                }
-            }
-        }
-
-        if (setExtendedInfo) {
-            MarginLayoutParams marginParams = null;
-            LayoutParams params = view.getLayoutParams();
-            if (params instanceof MarginLayoutParams) {
-                marginParams = (MarginLayoutParams) params;
-            }
-            result.setExtendedInfo(view.getBaseline(),
-                    marginParams != null ? marginParams.leftMargin : 0,
-                    marginParams != null ? marginParams.topMargin : 0,
-                    marginParams != null ? marginParams.rightMargin : 0,
-                    marginParams != null ? marginParams.bottomMargin : 0);
-        }
-
-        return result;
-    }
-
-    /* (non-Javadoc)
-     * The cookie for menu items are stored in menu item and not in the map from View stored in
-     * BridgeContext.
-     */
-    @Nullable
-    private Object getViewKey(View view) {
-        BridgeContext context = getContext();
-        if (!(view instanceof MenuView.ItemView)) {
-            return context.getViewKey(view);
-        }
-        MenuItemImpl menuItem;
-        if (view instanceof ActionMenuItemView) {
-            menuItem = ((ActionMenuItemView) view).getItemData();
-        } else if (view instanceof ListMenuItemView) {
-            menuItem = ((ListMenuItemView) view).getItemData();
-        } else if (view instanceof IconMenuItemView) {
-            menuItem = ((IconMenuItemView) view).getItemData();
-        } else {
-            menuItem = null;
-        }
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            return ((BridgeMenuItemImpl) menuItem).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void invalidateRenderingSize() {
-        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public boolean isAlphaChannelImage() {
-        return mIsAlphaChannelImage;
-    }
-
-    public List<ViewInfo> getViewInfos() {
-        return mViewInfoList;
-    }
-
-    public List<ViewInfo> getSystemViewInfos() {
-        return mSystemViewInfoList;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return getContext().getDefaultProperties();
-    }
-
-    public void setScene(RenderSession session) {
-        mScene = session;
-    }
-
-    public RenderSession getSession() {
-        return mScene;
-    }
-
-    public void dispose() {
-        boolean createdLooper = false;
-        if (Looper.myLooper() == null) {
-            // Detaching the root view from the window will try to stop any running animations.
-            // The stop method checks that it can run in the looper so, if there is no current
-            // looper, we create a temporary one to complete the shutdown.
-            Bridge.prepareThread();
-            createdLooper = true;
-        }
-        AttachInfo_Accessor.detachFromWindow(mViewRoot);
-        if (mCanvas != null) {
-            mCanvas.release();
-            mCanvas = null;
-        }
-        if (mViewInfoList != null) {
-            mViewInfoList.clear();
-        }
-        if (mSystemViewInfoList != null) {
-            mSystemViewInfoList.clear();
-        }
-        mImage = null;
-        mViewRoot = null;
-        mContentRoot = null;
-
-        if (createdLooper) {
-            Bridge.cleanupThread();
-            Choreographer_Delegate.dispose();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
deleted file mode 100644
index 75f9ec5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge.impl;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.ninepatch.NinePatch;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.ColorStateList;
-import android.content.res.ComplexColor;
-import android.content.res.ComplexColor_Accessor;
-import android.content.res.FontResourcesParser;
-import android.content.res.GradientColor;
-import android.content.res.Resources.Theme;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Color;
-import android.graphics.NinePatch_Delegate;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Accessor;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.text.FontConfig;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to provide various conversion method used in handling android resources.
- */
-public final class ResourceHelper {
-
-    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
-    private final static float[] sFloatOut = new float[1];
-
-    private final static TypedValue mValue = new TypedValue();
-
-    /**
-     * Returns the color value represented by the given string value
-     * @param value the color value
-     * @return the color as an int
-     * @throws NumberFormatException if the conversion failed.
-     */
-    public static int getColor(String value) {
-        if (value != null) {
-            value = value.trim();
-            if (!value.startsWith("#")) {
-                if (value.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                    throw new NumberFormatException(String.format(
-                            "Attribute '%s' not found. Are you using the right theme?", value));
-                }
-                throw new NumberFormatException(
-                        String.format("Color value '%s' must start with #", value));
-            }
-
-            value = value.substring(1);
-
-            // make sure it's not longer than 32bit
-            if (value.length() > 8) {
-                throw new NumberFormatException(String.format(
-                        "Color value '%s' is too long. Format is either" +
-                        "#AARRGGBB, #RRGGBB, #RGB, or #ARGB",
-                        value));
-            }
-
-            if (value.length() == 3) { // RGB format
-                char[] color = new char[8];
-                color[0] = color[1] = 'F';
-                color[2] = color[3] = value.charAt(0);
-                color[4] = color[5] = value.charAt(1);
-                color[6] = color[7] = value.charAt(2);
-                value = new String(color);
-            } else if (value.length() == 4) { // ARGB format
-                char[] color = new char[8];
-                color[0] = color[1] = value.charAt(0);
-                color[2] = color[3] = value.charAt(1);
-                color[4] = color[5] = value.charAt(2);
-                color[6] = color[7] = value.charAt(3);
-                value = new String(color);
-            } else if (value.length() == 6) {
-                value = "FF" + value;
-            }
-
-            // this is a RRGGBB or AARRGGBB value
-
-            // Integer.parseInt will fail to parse strings like "ff191919", so we use
-            // a Long, but cast the result back into an int, since we know that we're only
-            // dealing with 32 bit values.
-            return (int)Long.parseLong(value, 16);
-        }
-
-        throw new NumberFormatException();
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     * @param theme the theme to use when resolving the complex color
-     * @param allowGradients when false, only {@link ColorStateList} will be returned. If a {@link
-     * GradientColor} is found, null will be returned.
-     */
-    @Nullable
-    private static ComplexColor getInternalComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context, @Nullable Theme theme, boolean allowGradients) {
-        String value = resValue.getValue();
-        if (value == null || RenderResources.REFERENCE_NULL.equals(value)) {
-            return null;
-        }
-
-        XmlPullParser parser = null;
-        // first check if the value is a file (xml most likely)
-        Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-        if (psiParserSupport != null && psiParserSupport) {
-            parser = context.getLayoutlibCallback().getXmlFileParser(value);
-        }
-        if (parser == null) {
-            File f = new File(value);
-            if (f.isFile()) {
-                // let the framework inflate the color from the XML file, by
-                // providing an XmlPullParser
-                try {
-                    parser = ParserFactory.create(f);
-                } catch (XmlPullParserException | FileNotFoundException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed to parse file " + value, e, null /*data*/);
-                }
-            }
-        }
-
-        if (parser != null) {
-            try {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, resValue.isFramework());
-                try {
-                    // Advance the parser to the first element so we can detect if it's a
-                    // color list or a gradient color
-                    int type;
-                    //noinspection StatementWithEmptyBody
-                    while ((type = blockParser.next()) != XmlPullParser.START_TAG
-                            && type != XmlPullParser.END_DOCUMENT) {
-                        // Seek parser to start tag.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        assert false : "No start tag found";
-                        return null;
-                    }
-
-                    final String name = blockParser.getName();
-                    if (allowGradients && "gradient".equals(name)) {
-                        return ComplexColor_Accessor.createGradientColorFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    } else if ("selector".equals(name)) {
-                        return ComplexColor_Accessor.createColorStateListFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    }
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value, e, null /*data*/);
-                // we'll return null below.
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is
-                // checked before attempting to parse it.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                        "Failed to parse file " + value, e, null /*data*/);
-
-                return null;
-            }
-        } else {
-            // try to load the color state list from an int
-            try {
-                int color = getColor(value);
-                return ColorStateList.valueOf(color);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Failed to convert " + value + " into a ColorStateList", e,
-                        null /*data*/);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link ColorStateList} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ColorStateList getColorStateList(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return (ColorStateList) getInternalComplexColor(resValue, context, context.getTheme(),
-                false);
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ComplexColor getComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return getInternalComplexColor(resValue, context, context.getTheme(), true);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
-        return getDrawable(value, context, null);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     * @param theme the theme to be used to inflate the drawable.
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-        String stringValue = value.getValue();
-        if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
-            return null;
-        }
-
-        String lowerCaseValue = stringValue.toLowerCase();
-
-        Density density = Density.MEDIUM;
-        if (value instanceof DensityBasedResourceValue) {
-            density = ((DensityBasedResourceValue) value).getResourceDensity();
-        }
-
-        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File file = new File(stringValue);
-            if (file.isFile()) {
-                try {
-                    return getNinePatchDrawable(new FileInputStream(file), density,
-                            value.isFramework(), stringValue, context);
-                } catch (IOException e) {
-                    // failed to read the file, we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
-                }
-            }
-
-            return null;
-        } else if (lowerCaseValue.endsWith(".xml") || stringValue.startsWith("@aapt:_aapt/")) {
-            // create a block parser for the file
-            try {
-                XmlPullParser parser = context.getLayoutlibCallback().getParser(value);
-                if (parser == null) {
-                    File drawableFile = new File(stringValue);
-                    if (drawableFile.isFile()) {
-                        parser = ParserFactory.create(drawableFile);
-                    }
-                }
-
-                BridgeXmlBlockParser blockParser =
-                        new BridgeXmlBlockParser(parser, context, value.isFramework());
-                try {
-                    return Drawable.createFromXml(context.getResources(), blockParser, theme);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is checked before
-                // attempting to parse it.
-                Bridge.getLog().error(null, "Failed to parse file " + stringValue, e,
-                        null /*data*/);
-            }
-
-            return null;
-        } else {
-            File bmpFile = new File(stringValue);
-            if (bmpFile.isFile()) {
-                try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                            value.isFramework() ? null : context.getProjectKey());
-
-                    if (bitmap == null) {
-                        bitmap =
-                                Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(stringValue, bitmap,
-                                value.isFramework() ? null : context.getProjectKey());
-                    }
-
-                    return new BitmapDrawable(context.getResources(), bitmap);
-                } catch (IOException e) {
-                    // we'll return null below
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/);
-                }
-            } else {
-                // attempt to get a color from the value
-                try {
-                    int color = getColor(stringValue);
-                    return new ColorDrawable(color);
-                } catch (NumberFormatException e) {
-                    // we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Failed to convert " + stringValue + " into a drawable", e,
-                            null /*data*/);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(String fontName, BridgeContext context, Theme theme, boolean
-            isFramework) {
-        if (fontName == null) {
-            return null;
-        }
-
-        if (Typeface_Accessor.isSystemFont(fontName)) {
-            // Shortcut for the case where we are asking for a system font name. Those are not
-            // loaded using external resources.
-            return null;
-        }
-
-        // Check if this is an asset that we've already loaded dynamically
-        Typeface typeface = Typeface.findFromCache(context.getAssets(), fontName);
-        if (typeface != null) {
-            return typeface;
-        }
-
-        String lowerCaseValue = fontName.toLowerCase();
-        if (lowerCaseValue.endsWith(".xml")) {
-            // create a block parser for the file
-            Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                    RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-            XmlPullParser parser = null;
-            if (psiParserSupport != null && psiParserSupport) {
-                parser = context.getLayoutlibCallback().getXmlFileParser(fontName);
-            }
-            else {
-                File f = new File(fontName);
-                if (f.isFile()) {
-                    try {
-                        parser = ParserFactory.create(f);
-                    } catch (XmlPullParserException | FileNotFoundException e) {
-                        // this is an error and not warning since the file existence is checked before
-                        // attempting to parse it.
-                        Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                                e, null /*data*/);
-                    }
-                }
-            }
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, isFramework);
-                try {
-                    FontResourcesParser.FamilyResourceEntry entry =
-                            FontResourcesParser.parse(blockParser, context.getResources());
-                    typeface = Typeface.createFromResources(entry, context.getAssets(),
-                            fontName);
-                } catch (XmlPullParserException | IOException e) {
-                    Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                            e, null /*data*/);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s does not exist (or is not a file)", fontName),
-                        null /*data*/);
-            }
-        } else {
-            typeface = Typeface.createFromResources(context.getAssets(), fontName, 0);
-        }
-
-        return typeface;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-
-        return getFont(value.getValue(), context, theme, value.isFramework());
-    }
-
-    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
-            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
-        // see if we still have both the chunk and the bitmap in the caches
-        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
-                isFramework ? null : context.getProjectKey());
-        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
-                isFramework ? null : context.getProjectKey());
-
-        // if either chunk or bitmap is null, then we reload the 9-patch file.
-        if (chunk == null || bitmap == null) {
-            try {
-                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
-                        false /* convert */);
-                if (ninePatch != null) {
-                    if (chunk == null) {
-                        chunk = ninePatch.getChunk();
-
-                        Bridge.setCached9Patch(cacheKey, chunk,
-                                isFramework ? null : context.getProjectKey());
-                    }
-
-                    if (bitmap == null) {
-                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
-                                false /*isMutable*/,
-                                density);
-
-                        Bridge.setCachedBitmap(cacheKey, bitmap,
-                                isFramework ? null : context.getProjectKey());
-                    }
-                }
-            } catch (MalformedURLException e) {
-                // URL is wrong, we'll return null below
-            }
-        }
-
-        if (chunk != null && bitmap != null) {
-            int[] padding = chunk.getPadding();
-            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
-
-            return new NinePatchDrawable(context.getResources(), bitmap,
-                    NinePatch_Delegate.serialize(chunk),
-                    paddingRect, null);
-        }
-
-        return null;
-    }
-
-    /**
-     * Looks for an attribute in the current theme.
-     *
-     * @param resources the render resources
-     * @param name the name of the attribute
-     * @param defaultValue the default value.
-     * @param isFrameworkAttr if the attribute is in android namespace
-     * @return the value of the attribute or the default one if not found.
-     */
-    public static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name,
-            boolean isFrameworkAttr, boolean defaultValue) {
-        ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr);
-        value = resources.resolveResValue(value);
-        if (value == null) {
-            return defaultValue;
-        }
-        return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
-    }
-
-    // ------- TypedValue stuff
-    // This is taken from //device/libs/utils/ResourceTypes.cpp
-
-    private static final class UnitEntry {
-        String name;
-        int type;
-        int unit;
-        float scale;
-
-        UnitEntry(String name, int type, int unit, float scale) {
-            this.name = name;
-            this.type = type;
-            this.unit = unit;
-            this.scale = scale;
-        }
-    }
-
-    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
-        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
-        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
-        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
-        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
-        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
-        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
-        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
-    };
-
-    /**
-     * Returns the raw value from the given attribute float-type value string.
-     * This object is only valid until the next call on to {@link ResourceHelper}.
-     */
-    public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
-        if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Parse a float attribute and return the parsed value into a given TypedValue.
-     * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
-     * @param value the string value of the attribute
-     * @param outValue the TypedValue to receive the parsed value
-     * @param requireUnit whether the value is expected to contain a unit.
-     * @return true if success.
-     */
-    public static boolean parseFloatAttribute(String attribute, @NonNull String value,
-            TypedValue outValue, boolean requireUnit) {
-        assert !requireUnit || attribute != null;
-
-        // remove the space before and after
-        value = value.trim();
-        int len = value.length();
-
-        if (len <= 0) {
-            return false;
-        }
-
-        // check that there's no non ascii characters.
-        char[] buf = value.toCharArray();
-        for (int i = 0 ; i < len ; i++) {
-            if (buf[i] > 255) {
-                return false;
-            }
-        }
-
-        // check the first character
-        if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') {
-            return false;
-        }
-
-        // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(value);
-        if (m.matches()) {
-            String f_str = m.group(1);
-            String end = m.group(2);
-
-            float f;
-            try {
-                f = Float.parseFloat(f_str);
-            } catch (NumberFormatException e) {
-                // this shouldn't happen with the regexp above.
-                return false;
-            }
-
-            if (end.length() > 0 && end.charAt(0) != ' ') {
-                // Might be a unit...
-                if (parseUnit(end, outValue, sFloatOut)) {
-                    computeTypedValue(outValue, f, sFloatOut[0]);
-                    return true;
-                }
-                return false;
-            }
-
-            // make sure it's only spaces at the end.
-            end = end.trim();
-
-            if (end.length() == 0) {
-                if (outValue != null) {
-                    if (!requireUnit) {
-                        outValue.type = TypedValue.TYPE_FLOAT;
-                        outValue.data = Float.floatToIntBits(f);
-                    } else {
-                        // no unit when required? Use dp and out an error.
-                        applyUnit(sUnitNames[1], outValue, sFloatOut);
-                        computeTypedValue(outValue, f, sFloatOut[0]);
-
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                                String.format(
-                                        "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
-                                        value, attribute),
-                                null);
-                    }
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static void computeTypedValue(TypedValue outValue, float value, float scale) {
-        value *= scale;
-        boolean neg = value < 0;
-        if (neg) {
-            value = -value;
-        }
-        long bits = (long)(value*(1<<23)+.5f);
-        int radix;
-        int shift;
-        if ((bits&0x7fffff) == 0) {
-            // Always use 23p0 if there is no fraction, just to make
-            // things easier to read.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        } else if ((bits&0xffffffffff800000L) == 0) {
-            // Magnitude is zero -- can fit in 0 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_0p23;
-            shift = 0;
-        } else if ((bits&0xffffffff80000000L) == 0) {
-            // Magnitude can fit in 8 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_8p15;
-            shift = 8;
-        } else if ((bits&0xffffff8000000000L) == 0) {
-            // Magnitude can fit in 16 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_16p7;
-            shift = 16;
-        } else {
-            // Magnitude needs entire range, so no fractional part.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        }
-        int mantissa = (int)(
-            (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-        if (neg) {
-            mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-        }
-        outValue.data |=
-            (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-            | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
-    }
-
-    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
-        str = str.trim();
-
-        for (UnitEntry unit : sUnitNames) {
-            if (unit.name.equals(str)) {
-                applyUnit(unit, outValue, outScale);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
-        outValue.type = unit.type;
-        // COMPLEX_UNIT_SHIFT is 0 and hence intelliJ complains about it. Suppress the warning.
-        //noinspection PointlessBitwiseExpression
-        outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-        outScale[0] = unit.scale;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
deleted file mode 100644
index 9bd0015..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import java.util.ArrayList;
-
-/**
- * Custom Stack implementation on top of an {@link ArrayList} instead of
- * using {@link java.util.Stack} which is on top of a vector.
- *
- * @param <T>
- */
-public class Stack<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    public Stack() {
-        super();
-    }
-
-    public Stack(int size) {
-        super(size);
-    }
-
-    /**
-     * Pushes the given object to the stack
-     * @param object the object to push
-     */
-    public void push(T object) {
-        add(object);
-    }
-
-    /**
-     * Remove the object at the top of the stack and returns it.
-     * @return the removed object or null if the stack was empty.
-     */
-    public T pop() {
-        if (size() > 0) {
-            return remove(size() - 1);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the object at the top of the stack.
-     * @return the object at the top or null if the stack is empty.
-     */
-    public T peek() {
-        if (size() > 0) {
-            return get(size() - 1);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
deleted file mode 100644
index 9fea167..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
+++ /dev/null
@@ -1,51 +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.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-
-/**
- * ViewInfo for views added by the platform.
- */
-public class SystemViewInfo extends ViewInfo {
-
-    private ViewType mViewType;
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom) {
-        super(name, cookie, left, top, right, bottom);
-    }
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom, Object viewObject, Object layoutParamsObject) {
-        super(name, cookie, left, top, right, bottom, viewObject,
-                layoutParamsObject);
-    }
-
-    @Override
-    public ViewType getViewType() {
-        if (mViewType != null) {
-            return mViewType;
-        }
-        return ViewType.SYSTEM_UNKNOWN;
-    }
-
-    public void setViewType(ViewType type) {
-        mViewType = type;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
deleted file mode 100644
index c0ca1d5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ /dev/null
@@ -1,148 +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.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.Checkable;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * A Helper class to do fake data binding in {@link AdapterView} objects.
- */
-public class AdapterHelper {
-
-    @SuppressWarnings("deprecation")
-    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
-            LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
-        // we don't care about recycling here because we never scroll.
-        DataBindingItem dataBindingItem = item.getDataBindingItem();
-
-        BridgeContext context = RenderAction.getCurrentContext();
-
-        Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
-                parent, false /*attachToRoot*/, skipCallbackParser);
-
-        View view = pair.getFirst();
-        skipCallbackParser |= pair.getSecond();
-
-        if (view != null) {
-            fillView(context, view, item, parentItem, callback, adapterRef);
-        } else {
-            // create a text view to display an error.
-            TextView tv = new TextView(context);
-            tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName());
-            view = tv;
-        }
-
-        return Pair.of(view, skipCallbackParser);
-    }
-
-    private static void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
-        if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int i = 0 ; i < count ; i++) {
-                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
-            }
-        } else {
-            int id = view.getId();
-            if (id != 0) {
-                ResourceReference resolvedRef = context.resolveId(id);
-                if (resolvedRef != null) {
-                    int fullPosition = item.getFullPosition();
-                    int positionPerType = item.getPositionPerType();
-                    int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0;
-                    int parentPositionPerType = parentItem != null ?
-                            parentItem.getPositionPerType() : 0;
-
-                    if (view instanceof TextView) {
-                        TextView tv = (TextView) view;
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected String, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                tv.setText((String) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof Checkable) {
-                        Checkable cb = (Checkable) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                cb.setChecked((Boolean) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof ImageView) {
-                        ImageView iv = (ImageView) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.SRC, iv.getDrawable());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                // FIXME
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
deleted file mode 100644
index 8e28dba..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
+++ /dev/null
@@ -1,74 +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.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-
-/**
- * This is the items provided by the adapter. They are dynamically generated.
- */
-final class AdapterItem {
-    private final DataBindingItem mItem;
-    private final int mType;
-    private final int mFullPosition;
-    private final int mPositionPerType;
-    private List<AdapterItem> mChildren;
-
-    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
-            int positionPerType) {
-        mItem = item;
-        mType = type;
-        mFullPosition = fullPosition;
-        mPositionPerType = positionPerType;
-    }
-
-    void addChild(AdapterItem child) {
-        if (mChildren == null) {
-            mChildren = new ArrayList<AdapterItem>();
-        }
-
-        mChildren.add(child);
-    }
-
-    List<AdapterItem> getChildren() {
-        if (mChildren != null) {
-            return mChildren;
-        }
-
-        return Collections.emptyList();
-    }
-
-    int getType() {
-        return mType;
-    }
-
-    int getFullPosition() {
-        return mFullPosition;
-    }
-
-    int getPositionPerType() {
-        return mPositionPerType;
-    }
-
-    DataBindingItem getDataBindingItem() {
-        return mItem;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
deleted file mode 100644
index 142eac1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.ListAdapter;
-import android.widget.SpinnerAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Fake adapter to do fake data binding in {@link AdapterView} objects for {@link ListAdapter}
- * and {@link SpinnerAdapter}.
- *
- */
-public class FakeAdapter extends BaseAdapter {
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-    private boolean mSkipCallbackParser = false;
-
-    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        final int repeatCount = binding.getRepeatCount();
-        final int itemCount = binding.getItemCount();
-
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // We put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : binding) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = mTypes.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = mTypes.size();
-                    mTypes.add(viewRef);
-                }
-
-                int count = dataBindingItem.getCount();
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    mItems.add(new AdapterItem(dataBindingItem, typeIndex, mItems.size(), index++));
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return true;
-    }
-
-    @Override
-    public int getCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mItems.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mItems.get(position).getType();
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(position);
-        @SuppressWarnings("deprecation")
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return mTypes.size();
-    }
-
-    // ---- SpinnerAdapter
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        // pass
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
deleted file mode 100644
index 344b17e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ExpandableListAdapter;
-import android.widget.HeterogeneousExpandableList;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("deprecation")
-public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
-
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private boolean mSkipCallbackParser = false;
-
-    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
-    private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
-
-    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
-    }
-
-    private void createItems(Iterable<DataBindingItem> iterable, final int itemCount,
-            final int repeatCount, List<ResourceReference> types, int depth) {
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // we put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : iterable) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = types.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = types.size();
-                    types.add(viewRef);
-                }
-
-                List<DataBindingItem> children = dataBindingItem.getChildren();
-                int count = dataBindingItem.getCount();
-
-                // if there are children, we use the count as a repeat count for the children.
-                if (children.size() > 0) {
-                    count = 1;
-                }
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(),
-                            index++);
-                    mItems.add(item);
-
-                    if (children.size() > 0) {
-                        createItems(dataBindingItem, depth + 1);
-                    }
-                }
-            }
-        }
-    }
-
-    private void createItems(DataBindingItem item, int depth) {
-        if (depth == 2) {
-            createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth);
-        }
-    }
-
-    private AdapterItem getChildItem(int groupPosition, int childPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-
-        List<AdapterItem> children = item.getChildren();
-        return children.get(childPosition);
-    }
-
-    // ---- ExpandableListAdapter
-
-    @Override
-    public int getGroupCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public int getChildrenCount(int groupPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-        return item.getChildren().size();
-    }
-
-    @Override
-    public Object getGroup(int groupPosition) {
-        return mItems.get(groupPosition);
-    }
-
-    @Override
-    public Object getChild(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition);
-    }
-
-    @Override
-    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-            ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(groupPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-            View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem parentItem = mItems.get(groupPosition);
-        AdapterItem item = getChildItem(groupPosition, childPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public long getGroupId(int groupPosition) {
-        return groupPosition;
-    }
-
-    @Override
-    public long getChildId(int groupPosition, int childPosition) {
-        return childPosition;
-    }
-
-    @Override
-    public long getCombinedGroupId(long groupId) {
-        return groupId << 16 | 0x0000FFFF;
-    }
-
-    @Override
-    public long getCombinedChildId(long groupId, long childId) {
-        return groupId << 16 | childId;
-    }
-
-    @Override
-    public boolean isChildSelectable(int groupPosition, int childPosition) {
-        return true;
-    }
-
-    @Override
-    public void onGroupCollapsed(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void onGroupExpanded(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mItems.isEmpty();
-    }
-
-    // ---- HeterogeneousExpandableList
-
-    @Override
-    public int getChildType(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition).getType();
-    }
-
-    @Override
-    public int getChildTypeCount() {
-        return mChildrenTypes.size();
-    }
-
-    @Override
-    public int getGroupType(int groupPosition) {
-        return mItems.get(groupPosition).getType();
-    }
-
-    @Override
-    public int getGroupTypeCount() {
-        return mGroupTypes.size();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
deleted file mode 100644
index 96cba78..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
+++ /dev/null
@@ -1,81 +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.android.layoutlib.bridge.libcore.io;
-
-import java.nio.ByteBuffer;
-
-import libcore.io.BufferIterator;
-
-/**
- * Provides an implementation of {@link BufferIterator} over a {@link ByteBuffer}.
- */
-public class BridgeBufferIterator extends BufferIterator {
-
-    private final long mSize;
-    private final ByteBuffer mByteBuffer;
-
-    public BridgeBufferIterator(long size, ByteBuffer buffer) {
-        mSize = size;
-        mByteBuffer = buffer;
-    }
-
-    @Override
-    public void seek(int offset) {
-        assert offset <= mSize;
-        mByteBuffer.position(offset);
-    }
-
-    @Override
-    public int pos() {
-        return mByteBuffer.position();
-    }
-
-    @Override
-    public void skip(int byteCount) {
-        int newPosition = mByteBuffer.position() + byteCount;
-        assert newPosition <= mSize;
-        mByteBuffer.position(newPosition);
-    }
-
-    @Override
-    public void readByteArray(byte[] dst, int dstOffset, int byteCount) {
-        assert dst.length >= dstOffset + byteCount;
-        mByteBuffer.get(dst, dstOffset, byteCount);
-    }
-
-    @Override
-    public byte readByte() {
-        return mByteBuffer.get();
-    }
-
-    @Override
-    public int readInt() {
-        return mByteBuffer.getInt();
-    }
-
-    @Override
-    public void readIntArray(int[] dst, int dstOffset, int intCount) {
-        while (--intCount >= 0) {
-            dst[dstOffset++] = mByteBuffer.getInt();
-        }
-    }
-
-    @Override
-    public short readShort() {
-        return mByteBuffer.getShort();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
deleted file mode 100644
index ae33e1d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
+++ /dev/null
@@ -1,181 +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.
- */
-
-package com.android.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-
-public class ShadowBuffer {
-
-    private int mWidth;
-    private int mHeight;
-    private Bitmap mBitmap;
-    private int[] mData;
-
-    public ShadowBuffer(int width, int height) {
-        mWidth = width;
-        mHeight = height;
-        mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
-        mData = new int[mBitmap.getWidth() * mBitmap.getHeight()];
-        mBitmap.getPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    public void generateTriangles(@NonNull float[] strip, float scale) {
-        for (int i = 0; i < strip.length - 8; i += 3) {
-            float fx3 = strip[i];
-            float fy3 = strip[i + 1];
-            float fz3 = scale * strip[i + 2];
-
-            float fx2 = strip[i + 3];
-            float fy2 = strip[i + 4];
-            float fz2 = scale * strip[i + 5];
-
-            float fx1 = strip[i + 6];
-            float fy1 = strip[i + 7];
-            float fz1 = scale * strip[i + 8];
-
-            if (fx1 * (fy2 - fy3) + fx2 * (fy3 - fy1) + fx3 * (fy1 - fy2) == 0) {
-                continue;
-            }
-
-            triangleZBuffMin(mData, mWidth, mHeight, fx3, fy3, fz3, fx2, fy2, fz2, fx1, fy1, fz1);
-            triangleZBuffMin(mData, mWidth, mHeight, fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3);
-        }
-        mBitmap.setPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    private void triangleZBuffMin(@NonNull int[] buff, int w, int h, float fx3, float fy3,
-            float fz3, float fx2, float fy2, float fz2, float fx1, float fy1, float fz1) {
-        if (((fx1 - fx2) * (fy3 - fy2) - (fy1 - fy2) * (fx3 - fx2)) < 0) {
-            float tmpX = fx1;
-            float tmpY = fy1;
-            float tmpZ = fz1;
-            fx1 = fx2;
-            fy1 = fy2;
-            fz1 = fz2;
-            fx2 = tmpX;
-            fy2 = tmpY;
-            fz2 = tmpZ;
-        }
-        double d = (fx1 * (fy3 - fy2) - fx2 * fy3 + fx3 * fy2 + (fx2 - fx3) * fy1);
-
-        if (d == 0) {
-            return;
-        }
-        float dx = (float) (-(fy1 * (fz3 - fz2) - fy2 * fz3 + fy3 * fz2 + (fy2 - fy3) * fz1) / d);
-        float dy = (float) ((fx1 * (fz3 - fz2) - fx2 * fz3 + fx3 * fz2 + (fx2 - fx3) * fz1) / d);
-        float zOff = (float) ((fx1 * (fy3 * fz2 - fy2 * fz3) + fy1 * (fx2 * fz3 - fx3 * fz2) +
-                (fx3 * fy2 - fx2 * fy3) * fz1) / d);
-
-        int Y1 = (int) (16.0f * fy1 + .5f);
-        int Y2 = (int) (16.0f * fy2 + .5f);
-        int Y3 = (int) (16.0f * fy3 + .5f);
-
-        int X1 = (int) (16.0f * fx1 + .5f);
-        int X2 = (int) (16.0f * fx2 + .5f);
-        int X3 = (int) (16.0f * fx3 + .5f);
-
-        int DX12 = X1 - X2;
-        int DX23 = X2 - X3;
-        int DX31 = X3 - X1;
-
-        int DY12 = Y1 - Y2;
-        int DY23 = Y2 - Y3;
-        int DY31 = Y3 - Y1;
-
-        int FDX12 = DX12 << 4;
-        int FDX23 = DX23 << 4;
-        int FDX31 = DX31 << 4;
-
-        int FDY12 = DY12 << 4;
-        int FDY23 = DY23 << 4;
-        int FDY31 = DY31 << 4;
-
-        int minX = (min(X1, X2, X3) + 0xF) >> 4;
-        int maxX = (max(X1, X2, X3) + 0xF) >> 4;
-        int minY = (min(Y1, Y2, Y3) + 0xF) >> 4;
-        int maxY = (max(Y1, Y2, Y3) + 0xF) >> 4;
-
-        if (minY < 0) {
-            minY = 0;
-        }
-        if (minX < 0) {
-            minX = 0;
-        }
-        if (maxX > w) {
-            maxX = w;
-        }
-        if (maxY > h) {
-            maxY = h;
-        }
-        int off = minY * w;
-
-        int C1 = DY12 * X1 - DX12 * Y1;
-        int C2 = DY23 * X2 - DX23 * Y2;
-        int C3 = DY31 * X3 - DX31 * Y3;
-
-        if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) {
-            C1++;
-        }
-        if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) {
-            C2++;
-        }
-        if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) {
-            C3++;
-        }
-        int CY1 = C1 + DX12 * (minY << 4) - DY12 * (minX << 4);
-        int CY2 = C2 + DX23 * (minY << 4) - DY23 * (minX << 4);
-        int CY3 = C3 + DX31 * (minY << 4) - DY31 * (minX << 4);
-
-        for (int y = minY; y < maxY; y++) {
-            int CX1 = CY1;
-            int CX2 = CY2;
-            int CX3 = CY3;
-            float p = zOff + dy * y;
-            for (int x = minX; x < maxX; x++) {
-                if (CX1 > 0 && CX2 > 0 && CX3 > 0) {
-                    int point = x + off;
-                    float zVal = p + dx * x;
-                    buff[point] |= ((int) (zVal * 255)) << 24;
-                }
-                CX1 -= FDY12;
-                CX2 -= FDY23;
-                CX3 -= FDY31;
-            }
-            CY1 += FDX12;
-            CY2 += FDX23;
-            CY3 += FDX31;
-            off += w;
-        }
-    }
-
-    private int min(int x1, int x2, int x3) {
-        return (x1 > x2) ? ((x2 > x3) ? x3 : x2) : ((x1 > x3) ? x3 : x1);
-    }
-
-    private int max(int x1, int x2, int x3) {
-        return (x1 < x2) ? ((x2 < x3) ? x3 : x2) : ((x1 < x3) ? x3 : x1);
-    }
-
-    public void draw(@NonNull Canvas c) {
-        c.drawBitmap(mBitmap, 0, 0, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
deleted file mode 100644
index 33375ff..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
+++ /dev/null
@@ -1,630 +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.
- */
-
-package com.android.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-
-public class SpotShadow {
-
-    private static float rayIntersectPoly(@NonNull float[] poly, int polyLength, float px, float py,
-            float dx, float dy) {
-        int p1 = polyLength - 1;
-        for (int p2 = 0; p2 < polyLength; p2++) {
-            float p1x = poly[p1 * 2 + 0];
-            float p1y = poly[p1 * 2 + 1];
-            float p2x = poly[p2 * 2 + 0];
-            float p2y = poly[p2 * 2 + 1];
-            float div = (dx * (p1y - p2y) + dy * p2x - dy * p1x);
-            if (div != 0) {
-                float t = (dx * (p1y - py) + dy * px - dy * p1x) / (div);
-                if (t >= 0 && t <= 1) {
-                    float t2 = (p1x * (py - p2y) + p2x * (p1y - py) + px * (p2y - p1y)) / div;
-                    if (t2 > 0) {
-                        return t2;
-                    }
-                }
-            }
-            p1 = p2;
-        }
-        return Float.NaN;
-    }
-
-    private static void centroid2d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        float sumX = 0;
-        float sumY = 0;
-        int p1 = len - 1;
-        float area = 0;
-        for (int p2 = 0; p2 < len; p2++) {
-            float x1 = poly[p1 * 2 + 0];
-            float y1 = poly[p1 * 2 + 1];
-            float x2 = poly[p2 * 2 + 0];
-            float y2 = poly[p2 * 2 + 1];
-            float a = (x1 * y2 - x2 * y1);
-            sumX += (x1 + x2) * a;
-            sumY += (y1 + y2) * a;
-            area += a;
-            p1 = p2;
-        }
-
-        float centroidX = sumX / (3 * area);
-        float centroidY = sumY / (3 * area);
-        ret[0] = centroidX;
-        ret[1] = centroidY;
-    }
-
-    /**
-     * calculates the Centroid of a 3d polygon
-     * @param poly The flatten 3d vertices coordinates of polygon, the format is like
-     * [x0, y0, z0, x1, y1, z1, x2, ...]
-     * @param len The number of polygon vertices. So the length of poly should be len * 3.
-     * @param ret The array used to sotre the result. The length should be 3.
-     */
-    private static void centroid3d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        int n = len - 1;
-        double area = 0;
-        double cx = 0, cy = 0, cz = 0;
-        for (int i = 1; i < n; i++) {
-            int k = i + 1;
-            float a0 = poly[i * 3 + 0] - poly[0 * 3 + 0];
-            float a1 = poly[i * 3 + 1] - poly[0 * 3 + 1];
-            float a2 = poly[i * 3 + 2] - poly[0 * 3 + 2];
-            float b0 = poly[k * 3 + 0] - poly[0 * 3 + 0];
-            float b1 = poly[k * 3 + 1] - poly[0 * 3 + 1];
-            float b2 = poly[k * 3 + 2] - poly[0 * 3 + 2];
-            float c0 = a1 * b2 - b1 * a2;
-            float c1 = a2 * b0 - b2 * a0;
-            float c2 = a0 * b1 - b0 * a1;
-            double areaOfTriangle = Math.sqrt(c0 * c0 + c1 * c1 + c2 * c2);
-            area += areaOfTriangle;
-            cx += areaOfTriangle * (poly[i * 3 + 0] + poly[k * 3 + 0] + poly[0 * 3 + 0]);
-            cy += areaOfTriangle * (poly[i * 3 + 1] + poly[k * 3 + 1] + poly[0 * 3 + 1]);
-            cz += areaOfTriangle * (poly[i * 3 + 2] + poly[k * 3 + 2] + poly[0 * 3 + 2]);
-        }
-        ret[0] = (float) (cx / (3 * area));
-        ret[1] = (float) (cy / (3 * area));
-        ret[2] = (float) (cz / (3 * area));
-    }
-
-    /**
-     * Extracts the convex hull of a polygon.
-     * @param points The vertices coordinates of polygon
-     * @param pointsLength The number of polygon vertices. So the length of poly should be len * 3.
-     * @param retPoly retPoly is at most the size of the input polygon
-     * @return The number of points in the retPolygon
-     */
-    private static int hull(@NonNull float[] points, int pointsLength, @NonNull float[] retPoly) {
-        quicksortX(points, 0, pointsLength - 1);
-        int n = pointsLength;
-        float[] lUpper = new float[n * 2];
-        lUpper[0] = points[0];
-        lUpper[1] = points[1];
-        lUpper[2] = points[2];
-        lUpper[3] = points[3];
-
-        int lUpperSize = 2;
-
-        for (int i = 2; i < n; i++) {
-            lUpper[lUpperSize * 2 + 0] = points[i * 2 + 0];
-            lUpper[lUpperSize * 2 + 1] = points[i * 2 + 1];
-            lUpperSize++;
-
-            while (lUpperSize > 2 &&
-                    !rightTurn(lUpper[(lUpperSize - 3) * 2], lUpper[(lUpperSize - 3) * 2 + 1],
-                            lUpper[(lUpperSize - 2) * 2], lUpper[(lUpperSize - 2) * 2 + 1],
-                            lUpper[(lUpperSize - 1) * 2], lUpper[(lUpperSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lUpper[(lUpperSize - 2) * 2 + 0] = lUpper[(lUpperSize - 1) * 2 + 0];
-                lUpper[(lUpperSize - 2) * 2 + 1] = lUpper[(lUpperSize - 1) * 2 + 1];
-                lUpperSize--;
-            }
-        }
-
-        float[] lLower = new float[n * 2];
-        lLower[0] = points[(n - 1) * 2 + 0];
-        lLower[1] = points[(n - 1) * 2 + 1];
-        lLower[2] = points[(n - 2) * 2 + 0];
-        lLower[3] = points[(n - 2) * 2 + 1];
-
-        int lLowerSize = 2;
-
-        for (int i = n - 3; i >= 0; i--) {
-            lLower[lLowerSize * 2 + 0] = points[i * 2 + 0];
-            lLower[lLowerSize * 2 + 1] = points[i * 2 + 1];
-            lLowerSize++;
-
-            while (lLowerSize > 2 &&
-                    !rightTurn(lLower[(lLowerSize - 3) * 2], lLower[(lLowerSize - 3) * 2 + 1],
-                            lLower[(lLowerSize - 2) * 2], lLower[(lLowerSize - 2) * 2 + 1],
-                            lLower[(lLowerSize - 1) * 2], lLower[(lLowerSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lLower[(lLowerSize - 2) * 2 + 0] = lLower[(lLowerSize - 1) * 2 + 0];
-                lLower[(lLowerSize - 2) * 2 + 1] = lLower[(lLowerSize - 1) * 2 + 1];
-                lLowerSize--;
-            }
-        }
-
-        int count = 0;
-        for (int i = 0; i < lUpperSize; i++) {
-            retPoly[count * 2 + 0] = lUpper[i * 2 + 0];
-            retPoly[count * 2 + 1] = lUpper[i * 2 + 1];
-            count++;
-        }
-        for (int i = 1; i < lLowerSize - 1; i++) {
-            retPoly[count * 2 + 0] = lLower[i * 2 + 0];
-            retPoly[count * 2 + 1] = lLower[i * 2 + 1];
-            count++;
-        }
-        return count;
-    }
-
-    private static boolean rightTurn(float ax, float ay, float bx, float by, float cx, float cy) {
-        return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > 0.00001;
-    }
-
-    /**
-     * calculates the intersection of poly1 with poly2 and put in poly2
-     * @param poly1 The flatten 2d coordinates of polygon
-     * @param poly1length The vertices number of poly1
-     * @param poly2 The flatten 2d coordinates of polygon
-     * @param poly2length The vertices number of poly2
-     * @return number of vertices in poly2
-     */
-    private static int intersection(@NonNull float[] poly1, int poly1length, @NonNull float[] poly2,
-            int poly2length) {
-        makeClockwise(poly1, poly1length);
-        makeClockwise(poly2, poly2length);
-        float[] poly = new float[(poly1length * poly2length + 2) * 2];
-        int count = 0;
-        int pCount = 0;
-        for (int i = 0; i < poly1length; i++) {
-            if (pointInsidePolygon(poly1[i * 2 + 0], poly1[i * 2 + 1], poly2, poly2length)) {
-                poly[count * 2 + 0] = poly1[i * 2 + 0];
-                poly[count * 2 + 1] = poly1[i * 2 + 1];
-                count++;
-                pCount++;
-            }
-        }
-        int fromP1 = pCount;
-        for (int i = 0; i < poly2length; i++) {
-            if (pointInsidePolygon(poly2[i * 2 + 0], poly2[i * 2 + 1], poly1, poly1length)) {
-                poly[count * 2 + 0] = poly2[i * 2 + 0];
-                poly[count * 2 + 1] = poly2[i * 2 + 1];
-                count++;
-            }
-        }
-        int fromP2 = count - fromP1;
-        if (fromP1 == poly1length) { // use p1
-            for (int i = 0; i < poly1length; i++) {
-                poly2[i * 2 + 0] = poly1[i * 2 + 0];
-                poly2[i * 2 + 1] = poly1[i * 2 + 1];
-            }
-            return poly1length;
-        }
-        if (fromP2 == poly2length) { // use p2
-            return poly2length;
-        }
-        float[] intersection = new float[2];
-        for (int i = 0; i < poly2length; i++) {
-            for (int j = 0; j < poly1length; j++) {
-                int i1_by_2 = i * 2;
-                int i2_by_2 = ((i + 1) % poly2length) * 2;
-                int j1_by_2 = j * 2;
-                int j2_by_2 = ((j + 1) % poly1length) * 2;
-                boolean found =
-                        lineIntersection(poly2[i1_by_2 + 0], poly2[i1_by_2 + 1], poly2[i2_by_2 + 0],
-                                poly2[i2_by_2 + 1], poly1[j1_by_2 + 0], poly1[j1_by_2 + 1],
-                                poly1[j2_by_2 + 0], poly1[j2_by_2 + 1], intersection);
-                if (found) {
-                    poly[count * 2 + 0] = intersection[0];
-                    poly[count * 2 + 1] = intersection[1];
-                    count++;
-                } else {
-                    float dx = poly2[i * 2 + 0] - poly1[j * 2 + 0];
-                    float dy = poly2[i * 2 + 1] - poly1[j * 2 + 1];
-
-                    if (dx * dx + dy * dy < 0.01) {
-                        poly[count * 2 + 0] = poly2[i * 2 + 0];
-                        poly[count * 2 + 1] = poly2[i * 2 + 1];
-                        count++;
-                    }
-                }
-            }
-        }
-        if (count == 0) {
-            return 0;
-        }
-        float avgX = 0;
-        float avgY = 0;
-        for (int i = 0; i < count; i++) {
-            avgX += poly[i * 2 + 0];
-            avgY += poly[i * 2 + 1];
-        }
-        avgX /= count;
-        avgY /= count;
-
-        float[] ctr = new float[]{avgX, avgY};
-        sort(poly, count, ctr);
-        int size = count;
-
-        poly2[0] = poly[0];
-        poly2[1] = poly[1];
-
-        count = 1;
-        for (int i = 1; i < size; i++) {
-            float dx = poly[i * 2 + 0] - poly[(i - 1) * 2 + 0];
-            float dy = poly[i * 2 + 1] - poly[(i - 1) * 2 + 1];
-            if (dx * dx + dy * dy >= 0.01) {
-                poly2[count * 2 + 0] = poly[i * 2 + 0];
-                poly2[count * 2 + 1] = poly[i * 2 + 1];
-                count++;
-            }
-        }
-        return count;
-    }
-
-    public static void sort(@NonNull float[] poly, int polyLength, @NonNull float[] ctr) {
-        quicksortCircle(poly, 0, polyLength - 1, ctr);
-    }
-
-    public static float angle(float x1, float y1, @NonNull float[] ctr) {
-        return -(float) Math.atan2(x1 - ctr[0], y1 - ctr[1]);
-    }
-
-    private static void swapPair(@NonNull float[] points, int i, int j) {
-        float x = points[i * 2 + 0];
-        float y = points[i * 2 + 1];
-        points[i * 2 + 0] = points[j * 2 + 0];
-        points[i * 2 + 1] = points[j * 2 + 1];
-        points[j * 2 + 0] = x;
-        points[j * 2 + 1] = y;
-    }
-
-    private static void quicksortCircle(@NonNull float[] points, int low, int high,
-            @NonNull float[] ctr) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = angle(points[p * 2], points[p * 2 + 1], ctr);
-        while (i <= j) {
-            while (angle(points[i * 2 + 0], points[i * 2 + 1], ctr) < pivot) {
-                i++;
-            }
-            while (angle(points[j * 2 + 0], points[j * 2 + 1], ctr) > pivot) {
-                j--;
-            }
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortCircle(points, low, j, ctr);
-        }
-        if (i < high) {
-            quicksortCircle(points, i, high, ctr);
-        }
-    }
-
-    /**
-     * This function do Quick Sort by comparing X axis only.<br>
-     * Note that the input values of points are paired coordinates, e.g. {@code [x0, y0, x1, y1, x2,
-     * y2, ...]).}
-     * @param points The input point pairs. Every {@code (2 * i, 2 * i + 1)} points are pairs.
-     * @param low lowest index used to do quick sort sort
-     * @param high highest index used to do quick sort
-     */
-    private static void quicksortX(@NonNull float[] points, int low, int high) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = points[p * 2];
-        while (i <= j) {
-            while (points[i * 2 + 0] < pivot) {
-                i++;
-            }
-            while (points[j * 2 + 0] > pivot) {
-                j--;
-            }
-
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortX(points, low, j);
-        }
-        if (i < high) {
-            quicksortX(points, i, high);
-        }
-    }
-
-    private static boolean pointInsidePolygon(float x, float y, @NonNull float[] poly, int len) {
-        boolean c = false;
-        float testX = x;
-        float testY = y;
-        for (int i = 0, j = len - 1; i < len; j = i++) {
-            if (((poly[i * 2 + 1] > testY) != (poly[j * 2 + 1] > testY)) && (testX <
-                    (poly[j * 2 + 0] - poly[i * 2 + 0]) * (testY - poly[i * 2 + 1]) /
-                            (poly[j * 2 + 1] - poly[i * 2 + 1]) + poly[i * 2 + 0])) {
-                c = !c;
-            }
-        }
-        return c;
-    }
-
-    private static void makeClockwise(@NonNull float[] polygon, int len) {
-        if (polygon == null || len == 0) {
-            return;
-        }
-        if (!isClockwise(polygon, len)) {
-            reverse(polygon, len);
-        }
-    }
-
-    private static boolean isClockwise(@NonNull float[] polygon, int len) {
-        float sum = 0;
-        float p1x = polygon[(len - 1) * 2 + 0];
-        float p1y = polygon[(len - 1) * 2 + 1];
-        for (int i = 0; i < len; i++) {
-            float p2x = polygon[i * 2 + 0];
-            float p2y = polygon[i * 2 + 1];
-            sum += p1x * p2y - p2x * p1y;
-            p1x = p2x;
-            p1y = p2y;
-        }
-        return sum < 0;
-    }
-
-    private static void reverse(@NonNull float[] polygon, int len) {
-        int n = len / 2;
-        for (int i = 0; i < n; i++) {
-            float tmp0 = polygon[i * 2 + 0];
-            float tmp1 = polygon[i * 2 + 1];
-            int k = len - 1 - i;
-            polygon[i * 2 + 0] = polygon[k * 2 + 0];
-            polygon[i * 2 + 1] = polygon[k * 2 + 1];
-            polygon[k * 2 + 0] = tmp0;
-            polygon[k * 2 + 1] = tmp1;
-        }
-    }
-
-    /**
-     * Intersects two lines in parametric form.
-     */
-    private static final boolean lineIntersection(float x1, float y1, float x2, float y2, float x3,
-            float y3, float x4, float y4, @NonNull float[] ret) {
-        float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-        if (d == 0.000f) {
-            return false;
-        }
-
-        float dx = (x1 * y2 - y1 * x2);
-        float dy = (x3 * y4 - y3 * x4);
-        float x = (dx * (x3 - x4) - (x1 - x2) * dy) / d;
-        float y = (dx * (y3 - y4) - (y1 - y2) * dy) / d;
-
-        if (((x - x1) * (x - x2) > 0.0000001) || ((x - x3) * (x - x4) > 0.0000001) ||
-                ((y - y1) * (y - y2) > 0.0000001) || ((y - y3) * (y - y4) > 0.0000001)) {
-            return false;
-        }
-        ret[0] = x;
-        ret[1] = y;
-        return true;
-    }
-
-    @NonNull
-    public static float[] calculateLight(float size, int points, float x, float y, float height) {
-        float[] ret = new float[points * 3];
-        for (int i = 0; i < points; i++) {
-            double angle = 2 * i * Math.PI / points;
-            ret[i * 3 + 0] = (float) Math.cos(angle) * size + x;
-            ret[i * 3 + 1] = (float) Math.sin(angle) * size + y;
-            ret[i * 3 + 2] = (height);
-        }
-        return ret;
-    }
-
-    /**
-     layers indicates the number of circular strips to generate.
-     Strength is how dark a shadow to generate.
-
-    /**
-     * This calculates a collection of triangles that represent the shadow cast by a polygonal
-     * light source (lightPoly) hitting a convex polygon (poly).
-     * @param lightPoly The flatten 3d coordinates of light
-     * @param lightPolyLength The vertices number of light polygon.
-     * @param poly The flatten 3d coordinates of item
-     * @param polyLength The vertices number of light polygon.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength
-     * @return true if the params is able to calculate a shadow, else false.
-     */
-    public static boolean calcShadow(@NonNull float[] lightPoly, int lightPolyLength,
-            @NonNull float[] poly, int polyLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        float[] shadowRegion = new float[lightPolyLength * polyLength * 2];
-        float[] outline = new float[polyLength * 2];
-        float[] umbra = new float[polyLength * lightPolyLength * 2];
-        int umbraLength = 0;
-
-        int k = 0;
-        for (int j = 0; j < lightPolyLength; j++) {
-            int m = 0;
-            for (int i = 0; i < polyLength; i++) {
-                float t = lightPoly[j * 3 + 2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = lightPoly[j * 3 + 2] / t;
-                float x = lightPoly[j * 3 + 0] - t * (lightPoly[j * 3 + 0] - poly[i * 3 + 0]);
-                float y = lightPoly[j * 3 + 1] - t * (lightPoly[j * 3 + 1] - poly[i * 3 + 1]);
-
-                shadowRegion[k * 2 + 0] = x;
-                shadowRegion[k * 2 + 1] = y;
-                outline[m * 2 + 0] = x;
-                outline[m * 2 + 1] = y;
-
-                k++;
-                m++;
-            }
-            if (umbraLength == 0) {
-                System.arraycopy(outline, 0, umbra, 0, polyLength);
-                umbraLength = polyLength;
-            } else {
-                umbraLength = intersection(outline, polyLength, umbra, umbraLength);
-                if (umbraLength == 0) {
-                    break;
-                }
-            }
-        }
-        int shadowRegionLength = k;
-
-        float[] penumbra = new float[k * 2];
-        int penumbraLength = hull(shadowRegion, shadowRegionLength, penumbra);
-        if (umbraLength < 3) {// no real umbra make a fake one
-            float[] p = new float[3];
-            centroid3d(lightPoly, lightPolyLength, p);
-            float[] centShadow = new float[polyLength * 2];
-            for (int i = 0; i < polyLength; i++) {
-                float t = p[2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = p[2] / t;
-                float x = p[0] - t * (p[0] - poly[i * 3 + 0]);
-                float y = p[1] - t * (p[1] - poly[i * 3 + 1]);
-
-                centShadow[i * 2 + 0] = x;
-                centShadow[i * 2 + 1] = y;
-            }
-            float[] c = new float[2];
-            centroid2d(centShadow, polyLength, c);
-            for (int i = 0; i < polyLength; i++) {
-                centShadow[i * 2 + 0] = (c[0] * 9 + centShadow[i * 2 + 0]) / 10;
-                centShadow[i * 2 + 1] = (c[1] * 9 + centShadow[i * 2 + 1]) / 10;
-            }
-            umbra = centShadow; // fake umbra
-            umbraLength = polyLength; // same size as the original polygon
-        }
-
-        triangulateConcentricPolygon(penumbra, penumbraLength, umbra, umbraLength, rays, layers,
-                strength, retStrips);
-        return true;
-    }
-
-    /**
-     * triangulate concentric circles.
-     * This takes the inner and outer polygons of the umbra and penumbra and triangulates it.
-     * @param penumbra The 2d flatten vertices of penumbra polygons.
-     * @param penumbraLength The number of vertices in penumbra.
-     * @param umbra The 2d flatten vertices of umbra polygons.
-     * @param umbraLength The number of vertices in umbra.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength.
-     */
-    private static void triangulateConcentricPolygon(@NonNull float[] penumbra, int penumbraLength,
-            @NonNull float[] umbra, int umbraLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        int rings = layers + 1;
-        double step = Math.PI * 2 / rays;
-        float[] retXY = new float[2];
-        centroid2d(umbra, umbraLength, retXY);
-        float cx = retXY[0];
-        float cy = retXY[1];
-
-        float[] t1 = new float[rays];
-        float[] t2 = new float[rays];
-
-        for (int i = 0; i < rays; i++) {
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-            t2[i] = rayIntersectPoly(umbra, umbraLength, cx, cy, dx, dy);
-            t1[i] = rayIntersectPoly(penumbra, penumbraLength, cx, cy, dx, dy);
-        }
-
-        int p = 0;
-        // Calculate the vertex
-        for (int r = 0; r < layers; r++) {
-            int startP = p;
-            for (int i = 0; i < rays; i++) {
-                float dx = (float) Math.cos(Math.PI / 4 + step * i);
-                float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-                for (int j = r; j < (r + 2); j++) {
-                    float jf = j / (float) (rings - 1);
-                    float t = t1[i] + jf * (t2[i] - t1[i]);
-                    float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-                    retStrips[p * 3 + 0] = dx * t + cx;
-                    retStrips[p * 3 + 1] = dy * t + cy;
-                    retStrips[p * 3 + 2] = jf * op * strength;
-                    p++;
-
-                }
-            }
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-            startP++;
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-        }
-        int oldP = p - 1;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-        p++;
-
-        // Skip the first point here, then make it same as last point later.
-        oldP = p;
-        p++;
-        for (int k = 0; k < rays; k++) {
-            int i = k / 2;
-            if ((k & 1) == 1) { // traverse the inside in a zig zag pattern
-                // for strips
-                i = rays - i - 1;
-            }
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-            float jf = 1;
-
-            float t = t1[i] + jf * (t2[i] - t1[i]);
-            float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-
-            retStrips[p * 3 + 0] = dx * t + cx;
-            retStrips[p * 3 + 1] = dy * t + cy;
-            retStrips[p * 3 + 2] = jf * op * strength;
-            p++;
-        }
-        p = oldP;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-    }
-
-    public static int getStripSize(int rays, int layers) {
-        return (2 + rays + ((layers) * 2 * (rays + 1)));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
deleted file mode 100644
index 0a9b9ec..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-
-import java.awt.geom.CubicCurve2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.QuadCurve2D;
-import java.util.ArrayList;
-
-import com.google.android.collect.Lists;
-
-/**
- * Class that returns iterators for a given path. These iterators are lightweight and can be reused
- * multiple times to iterate over the path.
- */
-public class CachedPathIteratorFactory {
-    /*
-     * A few conventions used in the code:
-     * Coordinates or coords arrays store segment coordinates. They use the same format as
-     * PathIterator#currentSegment coordinates array.
-     * float arrays store always points where the first element is X and the second is Y.
-     */
-
-    // This governs how accurate the approximation of the Path is.
-    private static final float PRECISION = 0.002f;
-
-    private final int mWindingRule;
-    private final int[] mTypes;
-    private final float[][] mCoordinates;
-    private final float[] mSegmentsLength;
-    private final float mTotalLength;
-
-    public CachedPathIteratorFactory(@NonNull PathIterator iterator) {
-        mWindingRule = iterator.getWindingRule();
-
-        ArrayList<Integer> typesArray = Lists.newArrayList();
-        ArrayList<float[]> pointsArray = Lists.newArrayList();
-        float[] points = new float[6];
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(points);
-            int nPoints = getNumberOfPoints(type) * 2; // 2 coordinates per point
-
-            typesArray.add(type);
-            float[] itemPoints = new float[nPoints];
-            System.arraycopy(points, 0, itemPoints, 0, nPoints);
-            pointsArray.add(itemPoints);
-            iterator.next();
-        }
-
-        mTypes = new int[typesArray.size()];
-        mCoordinates = new float[mTypes.length][];
-        for (int i = 0; i < typesArray.size(); i++) {
-            mTypes[i] = typesArray.get(i);
-            mCoordinates[i] = pointsArray.get(i);
-        }
-
-        // Do measurement
-        mSegmentsLength = new float[mTypes.length];
-
-        // Curves that we can reuse to estimate segments length
-        CubicCurve2D.Float cubicCurve = new CubicCurve2D.Float();
-        QuadCurve2D.Float quadCurve = new QuadCurve2D.Float();
-        float lastX = 0;
-        float lastY = 0;
-        float totalLength = 0;
-        for (int i = 0; i < mTypes.length; i++) {
-            switch (mTypes[i]) {
-                case PathIterator.SEG_CUBICTO:
-                    cubicCurve.setCurve(lastX, lastY,
-                            mCoordinates[i][0], mCoordinates[i][1], mCoordinates[i][2],
-                            mCoordinates[i][3], lastX = mCoordinates[i][4],
-                            lastY = mCoordinates[i][5]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(cubicCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    quadCurve.setCurve(lastX, lastY, mCoordinates[i][0], mCoordinates[i][1],
-                            lastX = mCoordinates[i][2], lastY = mCoordinates[i][3]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(quadCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY,
-                            lastX = mCoordinates[0][0],
-                            lastY = mCoordinates[0][1]);
-                    mCoordinates[i] = new float[2];
-                    // We convert a SEG_CLOSE segment to a SEG_LINETO so we do not have to worry
-                    // about this special case in the rest of the code.
-                    mTypes[i] = PathIterator.SEG_LINETO;
-                    mCoordinates[i][0] = mCoordinates[0][0];
-                    mCoordinates[i][1] = mCoordinates[0][1];
-                    break;
-                case PathIterator.SEG_MOVETO:
-                    mSegmentsLength[i] = 0;
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                    break;
-                case PathIterator.SEG_LINETO:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY, mCoordinates[i][0],
-                            mCoordinates[i][1]);
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                default:
-            }
-            totalLength += mSegmentsLength[i];
-        }
-
-        mTotalLength = totalLength;
-    }
-
-    private static void quadCurveSegment(float[] coords, float t0, float t1) {
-        // Calculate X and Y at 0.5 (We'll use this to reconstruct the control point later)
-        float mt = t0 + (t1 - t0) / 2;
-        float mu = 1 - mt;
-        float mx = mu * mu * coords[0] + 2 * mu * mt * coords[2] + mt * mt * coords[4];
-        float my = mu * mu * coords[1] + 2 * mu * mt * coords[3] + mt * mt * coords[5];
-
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // coords at t0
-        coords[0] = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        coords[1] = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-
-        // coords at t1
-        coords[4] = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        coords[5] = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-
-        // estimated control point at t'=0.5
-        coords[2] = 2 * mx - coords[0] / 2 - coords[4] / 2;
-        coords[3] = 2 * my - coords[1] / 2 - coords[5] / 2;
-    }
-
-    private static void cubicCurveSegment(float[] coords, float t0, float t1) {
-        // http://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // Calculate the points at t0 and t1 for the quadratic curves formed by (P0, P1, P2) and
-        // (P1, P2, P3)
-        float qxa = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        float qxb = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        float qxc = coords[2] * u0 * u0 + coords[4] * 2 * t0 * u0 + coords[6] * t0 * t0;
-        float qxd = coords[2] * u1 * u1 + coords[4] * 2 * t1 * u1 + coords[6] * t1 * t1;
-
-        float qya = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-        float qyb = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-        float qyc = coords[3] * u0 * u0 + coords[5] * 2 * t0 * u0 + coords[7] * t0 * t0;
-        float qyd = coords[3] * u1 * u1 + coords[5] * 2 * t1 * u1 + coords[7] * t1 * t1;
-
-        // Linear interpolation
-        coords[0] = qxa * u0 + qxc * t0;
-        coords[1] = qya * u0 + qyc * t0;
-
-        coords[2] = qxa * u1 + qxc * t1;
-        coords[3] = qya * u1 + qyc * t1;
-
-        coords[4] = qxb * u0 + qxd * t0;
-        coords[5] = qyb * u0 + qyd * t0;
-
-        coords[6] = qxb * u1 + qxd * t1;
-        coords[7] = qyb * u1 + qyd * t1;
-    }
-
-    /**
-     * Returns the end point of a given segment
-     *
-     * @param type the segment type
-     * @param coords the segment coordinates array
-     * @param point the return array where the point will be stored
-     */
-    private static void getShapeEndPoint(int type, @NonNull float[] coords, @NonNull float[]
-            point) {
-        // start index of the end point for the segment type
-        int pointIndex = (getNumberOfPoints(type) - 1) * 2;
-        point[0] = coords[pointIndex];
-        point[1] = coords[pointIndex + 1];
-    }
-
-    /**
-     * Returns the number of points stored in a coordinates array for the given segment type.
-     */
-    private static int getNumberOfPoints(int segmentType) {
-        switch (segmentType) {
-            case PathIterator.SEG_QUADTO:
-                return 2;
-            case PathIterator.SEG_CUBICTO:
-                return 3;
-            case PathIterator.SEG_CLOSE:
-                return 0;
-            default:
-                return 1;
-        }
-    }
-
-    /**
-     * Returns the estimated length of a flat path. If the passed path is not flat (i.e. contains a
-     * segment that is not {@link PathIterator#SEG_CLOSE}, {@link PathIterator#SEG_MOVETO} or {@link
-     * PathIterator#SEG_LINETO} this method will fail.
-     */
-    private static float getFlatPathLength(@NonNull PathIterator iterator) {
-        float segment[] = new float[6];
-        float totalLength = 0;
-        float[] previousPoint = new float[2];
-        boolean isFirstPoint = true;
-
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            assert type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE || type ==
-                    PathIterator.SEG_MOVETO;
-
-            // MoveTo shouldn't affect the length
-            if (!isFirstPoint && type != PathIterator.SEG_MOVETO) {
-                totalLength += Point2D.distance(previousPoint[0], previousPoint[1], segment[0],
-                        segment[1]);
-            } else {
-                isFirstPoint = false;
-            }
-            previousPoint[0] = segment[0];
-            previousPoint[1] = segment[1];
-            iterator.next();
-        }
-
-        return totalLength;
-    }
-
-    /**
-     * Returns the estimated position along a path of the given length.
-     */
-    private void getPointAtLength(int type, @NonNull float[] coords, float lastX, float
-            lastY, float t, @NonNull float[] point) {
-        if (type == PathIterator.SEG_LINETO) {
-            point[0] = lastX + (coords[0] - lastX) * t;
-            point[1] = lastY + (coords[1] - lastY) * t;
-            // Return here, since we do not need a shape to estimate
-            return;
-        }
-
-        float[] curve = new float[8];
-        int lastPointIndex = (getNumberOfPoints(type) - 1) * 2;
-
-        System.arraycopy(coords, 0, curve, 2, coords.length);
-        curve[0] = lastX;
-        curve[1] = lastY;
-        if (type == PathIterator.SEG_CUBICTO) {
-            cubicCurveSegment(curve, 0f, t);
-        } else {
-            quadCurveSegment(curve, 0f, t);
-        }
-
-        point[0] = curve[2 + lastPointIndex];
-        point[1] = curve[2 + lastPointIndex + 1];
-    }
-
-    public CachedPathIterator iterator() {
-        return new CachedPathIterator();
-    }
-
-    /**
-     * Class that allows us to iterate over a path multiple times
-     */
-    public class CachedPathIterator implements PathIterator {
-        private int mNextIndex;
-
-        /**
-         * Current segment type.
-         *
-         * @see PathIterator
-         */
-        private int mCurrentType;
-
-        /**
-         * Stores the coordinates array of the current segment. The number of points stored depends
-         * on the segment type.
-         *
-         * @see PathIterator
-         */
-        private float[] mCurrentCoords = new float[6];
-        private float mCurrentSegmentLength;
-
-        /**
-         * Current segment length offset. When asking for the length of the current segment, the
-         * length will be reduced by this amount. This is useful when we are only using portions of
-         * the segment.
-         *
-         * @see #jumpToSegment(float)
-         */
-        private float mOffsetLength;
-
-        /** Point where the current segment started */
-        private float[] mLastPoint = new float[2];
-        private boolean isIteratorDone;
-
-        private CachedPathIterator() {
-            next();
-        }
-
-        public float getCurrentSegmentLength() {
-            return mCurrentSegmentLength;
-        }
-
-        @Override
-        public int getWindingRule() {
-            return mWindingRule;
-        }
-
-        @Override
-        public boolean isDone() {
-            return isIteratorDone;
-        }
-
-        @Override
-        public void next() {
-            if (mNextIndex >= mTypes.length) {
-                isIteratorDone = true;
-                return;
-            }
-
-            if (mNextIndex >= 1) {
-                // We've already called next() once so there is a previous segment in this path.
-                // We want to get the coordinates where the path ends.
-                getShapeEndPoint(mCurrentType, mCurrentCoords, mLastPoint);
-            } else {
-                // This is the first segment, no previous point so initialize to 0, 0
-                mLastPoint[0] = mLastPoint[1] = 0f;
-            }
-            mCurrentType = mTypes[mNextIndex];
-            mCurrentSegmentLength = mSegmentsLength[mNextIndex] - mOffsetLength;
-
-            if (mOffsetLength > 0f && (mCurrentType == SEG_CUBICTO || mCurrentType == SEG_QUADTO)) {
-                // We need to skip part of the start of the current segment (because
-                // mOffsetLength > 0)
-                float[] points = new float[8];
-
-                if (mNextIndex < 1) {
-                    points[0] = points[1] = 0f;
-                } else {
-                    getShapeEndPoint(mTypes[mNextIndex - 1], mCoordinates[mNextIndex - 1], points);
-                }
-
-                System.arraycopy(mCoordinates[mNextIndex], 0, points, 2,
-                        mCoordinates[mNextIndex].length);
-                float t0 = (mSegmentsLength[mNextIndex] - mCurrentSegmentLength) /
-                        mSegmentsLength[mNextIndex];
-                if (mCurrentType == SEG_CUBICTO) {
-                    cubicCurveSegment(points, t0, 1f);
-                } else {
-                    quadCurveSegment(points, t0, 1f);
-                }
-                System.arraycopy(points, 2, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
-            } else {
-                System.arraycopy(mCoordinates[mNextIndex], 0, mCurrentCoords, 0,
-                        mCoordinates[mNextIndex].length);
-            }
-
-            mOffsetLength = 0f;
-            mNextIndex++;
-        }
-
-        @Override
-        public int currentSegment(float[] coords) {
-            System.arraycopy(mCurrentCoords, 0, coords, 0, getNumberOfPoints(mCurrentType) * 2);
-            return mCurrentType;
-        }
-
-        @Override
-        public int currentSegment(double[] coords) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
-         * Returns the point where the current segment ends
-         */
-        public void getCurrentSegmentEnd(float[] point) {
-            point[0] = mLastPoint[0];
-            point[1] = mLastPoint[1];
-        }
-
-        /**
-         * Restarts the iterator and jumps all the segments of this path up to the length value.
-         */
-        public void jumpToSegment(float length) {
-            isIteratorDone = false;
-            if (length <= 0f) {
-                mNextIndex = 0;
-                return;
-            }
-
-            float accLength = 0;
-            float lastPoint[] = new float[2];
-            for (mNextIndex = 0; mNextIndex < mTypes.length; mNextIndex++) {
-                float segmentLength = mSegmentsLength[mNextIndex];
-                if (accLength + segmentLength >= length && mTypes[mNextIndex] != SEG_MOVETO) {
-                    float[] estimatedPoint = new float[2];
-                    getPointAtLength(mTypes[mNextIndex],
-                            mCoordinates[mNextIndex], lastPoint[0], lastPoint[1],
-                            (length - accLength) / segmentLength,
-                            estimatedPoint);
-
-                    // This segment makes us go further than length so we go back one step,
-                    // set a moveto and offset the length of the next segment by the length
-                    // of this segment that we've already used.
-                    mCurrentType = PathIterator.SEG_MOVETO;
-                    mCurrentCoords[0] = estimatedPoint[0];
-                    mCurrentCoords[1] = estimatedPoint[1];
-                    mCurrentSegmentLength = 0;
-
-                    // We need to offset next path length to account for the segment we've just
-                    // skipped.
-                    mOffsetLength = length - accLength;
-                    return;
-                }
-                accLength += segmentLength;
-                getShapeEndPoint(mTypes[mNextIndex], mCoordinates[mNextIndex], lastPoint);
-            }
-        }
-
-        /**
-         * Returns the current segment up to certain length. If the current segment is shorter than
-         * length, then the whole segment is returned. The segment coordinates are copied into the
-         * coords array.
-         *
-         * @return the segment type
-         */
-        public int currentSegment(@NonNull float[] coords, float length) {
-            int type = currentSegment(coords);
-            // If the length is greater than the current segment length, no need to find
-            // the cut point. Same if this is a SEG_MOVETO.
-            if (mCurrentSegmentLength <= length || type == SEG_MOVETO) {
-                return type;
-            }
-
-            float t = length / getCurrentSegmentLength();
-
-            // We find at which offset the end point is located within the coords array and set
-            // a new end point to cut the segment short
-            switch (type) {
-                case SEG_CUBICTO:
-                case SEG_QUADTO:
-                    float[] curve = new float[8];
-                    curve[0] = mLastPoint[0];
-                    curve[1] = mLastPoint[1];
-                    System.arraycopy(coords, 0, curve, 2, coords.length);
-                    if (type == SEG_CUBICTO) {
-                        cubicCurveSegment(curve, 0f, t);
-                    } else {
-                        quadCurveSegment(curve, 0f, t);
-                    }
-                    System.arraycopy(curve, 2, coords, 0, coords.length);
-                    break;
-                default:
-                    float[] point = new float[2];
-                    getPointAtLength(type, coords, mLastPoint[0], mLastPoint[1], t, point);
-                    coords[0] = point[0];
-                    coords[1] = point[1];
-            }
-
-            return type;
-        }
-
-        /**
-         * Returns the total length of the path
-         */
-        public float getTotalLength() {
-            return mTotalLength;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
deleted file mode 100644
index 82eab85..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.util;
-
-public class Debug {
-
-    public final static boolean DEBUG = false;
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
deleted file mode 100644
index 161bf41..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 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.layoutlib.bridge.util;
-
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.util.SparseArray;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DynamicIdMap {
-
-    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<>();
-    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<>();
-    private int mDynamicSeed;
-
-    public DynamicIdMap(int seed) {
-        mDynamicSeed = seed;
-    }
-
-    public void reset(int seed) {
-        mDynamicIds.clear();
-        mRevDynamicIds.clear();
-        mDynamicSeed = seed;
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(ResourceType type, String name) {
-        return getId(Pair.of(type, name));
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param resource the type/name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(Pair<ResourceType, String> resource) {
-        Integer value = mDynamicIds.get(resource);
-        if (value == null) {
-            value = ++mDynamicSeed;
-            mDynamicIds.put(resource, value);
-            mRevDynamicIds.put(value, resource);
-        }
-
-        return value;
-    }
-
-    public Pair<ResourceType, String> resolveId(int id) {
-        return mRevDynamicIds.get(id);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
deleted file mode 100644
index f149b6c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
+++ /dev/null
@@ -1,47 +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.layoutlib.bridge.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-/**
- * Simpler wrapper around FileInputStream. This is used when the input stream represent
- * not a normal bitmap but a nine patch.
- * This is useful when the InputStream is created in a method but used in another that needs
- * to know whether this is 9-patch or not, such as BitmapFactory.
- */
-public class NinePatchInputStream extends FileInputStream {
-    private boolean mFakeMarkSupport = true;
-    public NinePatchInputStream(File file) throws FileNotFoundException {
-        super(file);
-    }
-
-    @Override
-    public boolean markSupported() {
-        // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
-        return mFakeMarkSupport || super.markSupported();
-
-    }
-
-    public void disableFakeMarkSupport() {
-        // disable fake mark support so that in case codec actually try to use them
-        // we don't lie to them.
-        mFakeMarkSupport = false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
deleted file mode 100644
index b89718f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Utility to convert checked Reflection exceptions to unchecked exceptions.
- */
-public class ReflectionUtils {
-
-    @NonNull
-    public static Method getMethod(@NonNull Class<?> clazz, @NonNull String name,
-            @Nullable Class<?>... params) throws ReflectionException {
-        try {
-            return clazz.getMethod(name, params);
-        } catch (NoSuchMethodException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    public static Method getAccessibleMethod(@NonNull Class<?> clazz, @NonNull String name,
-      @Nullable Class<?>... params) throws ReflectionException {
-        Method method = getMethod(clazz, name, params);
-        method.setAccessible(true);
-
-        return method;
-    }
-
-    @Nullable
-    public static Object invoke(@NonNull Method method, @Nullable Object object,
-            @Nullable Object... args) throws ReflectionException {
-        Exception ex;
-        try {
-            return method.invoke(object, args);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            ex = e;
-        }
-        throw new ReflectionException(ex);
-    }
-
-    /**
-     * Check if the object is an instance of a class named {@code className}. This doesn't work
-     * for interfaces.
-     */
-    public static boolean isInstanceOf(Object object, String className) {
-        Class superClass = object.getClass();
-        while (superClass != null) {
-            String name = superClass.getName();
-            if (name.equals(className)) {
-                return true;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        return false;
-    }
-
-    @NonNull
-    public static Throwable getCause(@NonNull Throwable throwable) {
-        Throwable cause = throwable.getCause();
-        return cause == null ? throwable : cause;
-    }
-
-    /**
-     * Looks through the class hierarchy of {@code object} at runtime and returns the class matching
-     * the name {@code className}.
-     * <p>
-     * This is used when we cannot use Class.forName() since the class we want was loaded from a
-     * different ClassLoader.
-     */
-    @NonNull
-    public static Class<?> getClassInstance(@NonNull Object object, @NonNull String className) {
-        Class<?> superClass = object.getClass();
-        while (superClass != null) {
-            if (className.equals(superClass.getName())) {
-                return superClass;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        throw new RuntimeException("invalid object/classname combination.");
-    }
-
-    /**
-     * Wraps all reflection related exceptions. Created since ReflectiveOperationException was
-     * introduced in 1.7 and we are still on 1.6
-     */
-    public static class ReflectionException extends Exception {
-        public ReflectionException() {
-            super();
-        }
-
-        public ReflectionException(String message) {
-            super(message);
-        }
-
-        public ReflectionException(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public ReflectionException(Throwable cause) {
-            super(cause);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
deleted file mode 100644
index a2a8aa9..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2011 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.layoutlib.bridge.util;
-
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.GrowingArrayUtils;
-
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added
- * to it. When the array is compacted, not only deleted indices but also empty references
- * are removed, making the array efficient at removing references that were reclaimed.
- *
- * The code is taken from {@link SparseArray} directly and adapted to use weak references.
- *
- * Because our usage means that we never actually call {@link #remove(long)} or
- * {@link #delete(long)}, we must manually check if there are reclaimed references to
- * trigger an internal compact step (which is normally only triggered when an item is manually
- * removed).
- *
- * SparseArrays map integral values to Objects.  Unlike a normal array of Objects,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers (or Longs) to Objects.
- */
-@SuppressWarnings("unchecked")
-public class SparseWeakArray<E> {
-
-    private static final Object DELETED_REF = new Object();
-    private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF);
-    private boolean mGarbage = false;
-
-    /**
-     * Creates a new SparseArray containing no mappings.
-     */
-    public SparseWeakArray() {
-        this(10);
-    }
-
-    /**
-     * Creates a new SparseArray containing no mappings that will not
-     * require any additional memory allocation to store the specified
-     * number of mappings.
-     */
-    public SparseWeakArray(int initialCapacity) {
-        mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
-        mValues = new WeakReference[mKeys.length];
-        mSize = 0;
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or <code>null</code>
-     * if no such mapping has been made.
-     */
-    public E get(long key) {
-        return get(key, null);
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or the specified Object
-     * if no such mapping has been made.
-     */
-    public E get(long key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) {
-            return valueIfKeyNotFound;
-        } else {
-            return (E) mValues[i].get();
-        }
-    }
-
-    /**
-     * Removes the mapping from the specified key, if there was any.
-     */
-    public void delete(long key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            if (mValues[i] != DELETED) {
-                mValues[i] = DELETED;
-                mGarbage = true;
-            }
-        }
-    }
-
-    /**
-     * Alias for {@link #delete(long)}.
-     */
-    public void remove(long key) {
-        delete(key);
-    }
-
-    /**
-     * Removes the mapping at the specified index.
-     */
-    public void removeAt(int index) {
-        if (mValues[index] != DELETED) {
-            mValues[index] = DELETED;
-            mGarbage = true;
-        }
-    }
-
-    private void gc() {
-        int n = mSize;
-        int o = 0;
-        long[] keys = mKeys;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            WeakReference<?> val = values[i];
-
-            // Don't keep any non DELETED values, but only the one that still have a valid
-            // reference.
-            if (val != DELETED && val.get() != null) {
-                if (i != o) {
-                    keys[o] = keys[i];
-                    values[o] = val;
-                }
-
-                o++;
-            }
-        }
-
-        mGarbage = false;
-        mSize = o;
-    }
-
-    /**
-     * Adds a mapping from the specified key to the specified value,
-     * replacing the previous mapping from the specified key if there
-     * was one.
-     */
-    public void put(long key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            mValues[i] = new WeakReference(value);
-        } else {
-            i = ~i;
-
-            if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) {
-                mKeys[i] = key;
-                mValues[i] = new WeakReference(value);
-                return;
-            }
-
-            if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-                gc();
-
-                // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
-            }
-
-            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
-            mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value));
-            mSize++;
-        }
-    }
-
-    /**
-     * Returns the number of key-value mappings that this SparseArray
-     * currently stores.
-     */
-    public int size() {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mSize;
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the key from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public long keyAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mKeys[index];
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the value from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public E valueAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return (E) mValues[index].get();
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, sets a new
-     * value for the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public void setValueAt(int index, E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        mValues[index] = new WeakReference(value);
-    }
-
-    /**
-     * Returns the index for which {@link #keyAt} would return the
-     * specified key, or a negative number if the specified
-     * key is not mapped.
-     */
-    public int indexOfKey(long key) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return binarySearch(mKeys, 0, mSize, key);
-    }
-
-    /**
-     * Returns an index for which {@link #valueAt} would return the
-     * specified key, or a negative number if no keys map to the
-     * specified value.
-     * Beware that this is a linear search, unlike lookups by key,
-     * and that multiple keys can map to the same value and this will
-     * find only one of them.
-     */
-    public int indexOfValue(E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        for (int i = 0; i < mSize; i++)
-            if (mValues[i].get() == value)
-                return i;
-
-        return -1;
-    }
-
-    /**
-     * Removes all key-value mappings from this SparseArray.
-     */
-    public void clear() {
-        int n = mSize;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            values[i] = null;
-        }
-
-        mSize = 0;
-        mGarbage = false;
-    }
-
-    /**
-     * Puts a key/value pair into the array, optimizing for the case where
-     * the key is greater than all existing keys in the array.
-     */
-    public void append(long key, E value) {
-        if (mSize != 0 && key <= mKeys[mSize - 1]) {
-            put(key, value);
-            return;
-        }
-
-        if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-            gc();
-        }
-
-        mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
-        mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value));
-        mSize++;
-    }
-
-    private boolean hasReclaimedRefs() {
-        for (int i = 0 ; i < mSize ; i++) {
-            if (mValues[i].get() == null) { // DELETED.get() never returns null.
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static int binarySearch(long[] a, int start, int len, long key) {
-        int high = start + len, low = start - 1, guess;
-
-        while (high - low > 1) {
-            guess = (high + low) / 2;
-
-            if (a[guess] < key)
-                low = guess;
-            else
-                high = guess;
-        }
-
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
-    }
-
-    private long[] mKeys;
-    private WeakReference<?>[] mValues;
-    private int mSize;
-}
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
deleted file mode 100644
index 6d013bb..0000000
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 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.google.android.maps;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the MapView.
- * Only non override public methods from the real MapView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class MapView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public MapView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public MapView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.mapViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public MapView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void displayZoomControls(boolean takeFocus) {
-    }
-
-    public boolean canCoverCenter() {
-        return false;
-    }
-
-    public void preLoad() {
-    }
-
-    public int getZoomLevel() {
-        return 0;
-    }
-
-    public void setSatellite(boolean on) {
-    }
-
-    public boolean isSatellite() {
-        return false;
-    }
-
-    public void setTraffic(boolean on) {
-    }
-
-    public boolean isTraffic() {
-        return false;
-    }
-
-    public void setStreetView(boolean on) {
-    }
-
-    public boolean isStreetView() {
-        return false;
-    }
-
-    public int getLatitudeSpan() {
-        return 0;
-    }
-
-    public int getLongitudeSpan() {
-        return 0;
-    }
-
-    public int getMaxZoomLevel() {
-        return 0;
-    }
-
-    public void onSaveInstanceState(Bundle state) {
-    }
-
-    public void onRestoreInstanceState(Bundle state) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java b/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
deleted file mode 100644
index 36efc3a..0000000
--- a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
+++ /dev/null
@@ -1,78 +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 dalvik.system;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link VMRuntime}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of VMRuntime have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class VMRuntime_Delegate {
-
-    // Copied from libcore/libdvm/src/main/java/dalvik/system/VMRuntime
-    @LayoutlibDelegate
-    /*package*/ static Object newUnpaddedArray(VMRuntime runtime, Class<?> componentType,
-            int minLength) {
-        // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc,
-        // allocations are 8byte aligned so having 4bytes of array data avoids padding.
-        if (!componentType.isPrimitive()) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return java.lang.reflect.Array.newInstance(componentType, size);
-        } else if (componentType == char.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new char[size];
-        } else if (componentType == int.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new int[size];
-        } else if (componentType == byte.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new byte[size];
-        } else if (componentType == boolean.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new boolean[size];
-        } else if (componentType == short.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new short[size];
-        } else if (componentType == float.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new float[size];
-        } else if (componentType == long.class) {
-            return new long[minLength];
-        } else if (componentType == double.class) {
-            return new double[minLength];
-        } else {
-            assert componentType == void.class;
-            throw new IllegalArgumentException("Can't allocate an array of void");
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
deleted file mode 100644
index 9c58010..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2011 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 libcore.icu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.DateTimePatternGenerator;
-import android.icu.util.Currency;
-import android.icu.util.ULocale;
-import android.icu.util.VersionInfo;
-
-import java.util.Locale;
-
-/**
- * Delegate implementing the native methods of libcore.icu.ICU
- *
- * Through the layoutlib_create tool, the original native methods of ICU have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ICU_Delegate {
-
-    // --- Java delegates
-
-    @LayoutlibDelegate
-    /*package*/ static String toLowerCase(String s, String localeName) {
-        return s.toLowerCase();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String toUpperCase(String s, String localeName) {
-        return s.toUpperCase();
-    }
-
-    // --- Native methods accessing ICU's database.
-
-    @LayoutlibDelegate
-    /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) {
-        return DateTimePatternGenerator.getInstance(new ULocale(localeName))
-                .getBestPattern(skeleton);
-    }
-
-    @LayoutlibDelegate
-    @SuppressWarnings("deprecation")
-    /*package*/ static String getCldrVersion() {
-        return VersionInfo.ICU_DATA_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getIcuVersion() {
-        return VersionInfo.ICU_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getUnicodeVersion() {
-        return VersionInfo.UNICODE_7_0.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableBreakIteratorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCalendarLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCollatorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableDateFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableNumberFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCurrencyCodes() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyCode(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyFractionDigits(String currencyCode) {
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyNumericCode(String currencyCode) {
-        return Currency.getInstance(currencyCode).getNumericCode();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayCountryNative(String countryCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayLanguageNative(String languageCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayVariantNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayScriptNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Country(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Language(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String addLikelySubtags(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getScript(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOLanguagesNative() {
-        return Locale.getISOLanguages();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOCountriesNative() {
-        return Locale.getISOCountries();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
-
-        // Used by Calendar.
-        result.firstDayOfWeek = 1;
-        result.minimalDaysInFirstWeek = 1;
-
-        // Used by DateFormatSymbols.
-        result.amPm = new String[] { "AM", "PM" };
-        result.eras = new String[] { "BC", "AD" };
-
-        result.longMonthNames = new String[] { "January", "February", "March", "April", "May",
-                "June", "July", "August", "September", "October", "November", "December" };
-        result.shortMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
-                "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-        result.longStandAloneMonthNames = result.longMonthNames;
-        result.shortStandAloneMonthNames = result.shortMonthNames;
-
-        // The platform code expects this to begin at index 1, rather than 0. It maps it directly to
-        // the constants from java.util.Calendar.<weekday>
-        result.longWeekdayNames = new String[] {
-                "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
-        result.shortWeekdayNames = new String[] {
-                "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" };
-        result.tinyWeekdayNames = new String[] {
-                "", "S", "M", "T", "W", "T", "F", "S" };
-
-        result.longStandAloneWeekdayNames = result.longWeekdayNames;
-        result.shortStandAloneWeekdayNames = result.shortWeekdayNames;
-        result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames;
-
-        result.fullTimeFormat = "";
-        result.longTimeFormat = "";
-        result.mediumTimeFormat = "";
-        result.shortTimeFormat = "";
-
-        result.fullDateFormat = "";
-        result.longDateFormat = "";
-        result.mediumDateFormat = "";
-        result.shortDateFormat = "";
-
-        // Used by DecimalFormatSymbols.
-        result.zeroDigit = '0';
-        result.decimalSeparator = '.';
-        result.groupingSeparator = ',';
-        result.patternSeparator = ' ';
-        result.percent = "%";
-        result.perMill = '\u2030';
-        result.monetarySeparator = ' ';
-        result.minusSign = "-";
-        result.exponentSeparator = "e";
-        result.infinity = "\u221E";
-        result.NaN = "NaN";
-        // Also used by Currency.
-        result.currencySymbol = "$";
-        result.internationalCurrencySymbol = "USD";
-
-        // Used by DecimalFormat and NumberFormat.
-        result.numberPattern = "%f";
-        result.integerPattern = "%d";
-        result.currencyPattern = "%s";
-        result.percentPattern = "%f";
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setDefaultLocale(String locale) {
-        ICU.setDefaultLocale(locale);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDefaultLocale() {
-        return ICU.getDefaultLocale();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getTZDataVersion() {
-        return ICU.getTZDataVersion();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java b/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
deleted file mode 100644
index 723d5c4..0000000
--- a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
+++ /dev/null
@@ -1,118 +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 libcore.io;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.libcore.io.BridgeBufferIterator;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.system.ErrnoException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel.MapMode;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate used to provide alternate implementation of select methods of {@link MemoryMappedFile}.
- */
-public class MemoryMappedFile_Delegate {
-
-    private static final DelegateManager<MemoryMappedFile_Delegate> sManager = new
-            DelegateManager<MemoryMappedFile_Delegate>(MemoryMappedFile_Delegate.class);
-
-    private static final Map<MemoryMappedFile, Long> sMemoryMappedFileMap =
-            new HashMap<MemoryMappedFile, Long>();
-
-    private final MappedByteBuffer mMappedByteBuffer;
-    private final long mSize;
-
-    /** Path on the target device where the data file is available. */
-    private static final String TARGET_PATH = System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo";
-    /** Path on the host (inside the SDK) where the data files are available. */
-    private static File sRootPath;
-
-    @LayoutlibDelegate
-    static MemoryMappedFile mmapRO(String path) throws ErrnoException {
-        if (!path.startsWith(TARGET_PATH)) {
-            throw new ErrnoException("Custom timezone data files are not supported.", 1);
-        }
-        if (sRootPath == null) {
-            throw new ErrnoException("Bridge has not been initialized properly.", 1);
-        }
-        path = path.substring(TARGET_PATH.length());
-        try {
-            File f = new File(sRootPath, path);
-            if (!f.exists()) {
-                throw new ErrnoException("File not found: " + f.getPath(), 1);
-            }
-            RandomAccessFile file = new RandomAccessFile(f, "r");
-            try {
-                long size = file.length();
-                MemoryMappedFile_Delegate newDelegate = new MemoryMappedFile_Delegate(file);
-                long filePointer = file.getFilePointer();
-                MemoryMappedFile mmFile = new MemoryMappedFile(filePointer, size);
-                long delegateIndex = sManager.addNewDelegate(newDelegate);
-                sMemoryMappedFileMap.put(mmFile, delegateIndex);
-                return mmFile;
-            } finally {
-                file.close();
-            }
-        } catch (IOException e) {
-            throw new ErrnoException("mmapRO", 1, e);
-        }
-    }
-
-    @LayoutlibDelegate
-    static void close(MemoryMappedFile thisFile) throws ErrnoException {
-        Long index = sMemoryMappedFileMap.get(thisFile);
-        if (index != null) {
-            sMemoryMappedFileMap.remove(thisFile);
-            sManager.removeJavaReferenceFor(index);
-        }
-    }
-
-    @LayoutlibDelegate
-    static BufferIterator bigEndianIterator(MemoryMappedFile file) {
-        MemoryMappedFile_Delegate delegate = getDelegate(file);
-        return new BridgeBufferIterator(delegate.mSize, delegate.mMappedByteBuffer.duplicate());
-    }
-
-    // TODO: implement littleEndianIterator()
-
-    public MemoryMappedFile_Delegate(RandomAccessFile file) throws IOException {
-        mSize = file.length();
-        // It's weird that map() takes size as long, but returns MappedByteBuffer which uses an int
-        // to store the marker to the position.
-        mMappedByteBuffer = file.getChannel().map(MapMode.READ_ONLY, 0, mSize);
-        assert mMappedByteBuffer.order() == ByteOrder.BIG_ENDIAN;
-    }
-
-    public static void setDataDir(File path) {
-        sRootPath = path;
-    }
-
-    private static MemoryMappedFile_Delegate getDelegate(MemoryMappedFile file) {
-        Long index = sMemoryMappedFileMap.get(file);
-        return index == null ? null : sManager.getDelegate(index);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
deleted file mode 100644
index 04fabc2..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
+++ /dev/null
@@ -1,70 +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 libcore.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of {@link NativeAllocationRegistry}
- *
- * Through the layoutlib_create tool, the original native methods of NativeAllocationRegistry have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original NativeAllocationRegistry class.
- *
- * @see DelegateManager
- */
-public class NativeAllocationRegistry_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NativeAllocationRegistry_Delegate> sManager =
-            new DelegateManager<>(NativeAllocationRegistry_Delegate.class);
-
-    private final FreeFunction mFinalizer;
-
-    private NativeAllocationRegistry_Delegate(FreeFunction finalizer) {
-        mFinalizer = finalizer;
-    }
-
-    /**
-     * The result of this method should be cached by the class and reused.
-     */
-    public static long createFinalizer(FreeFunction finalizer) {
-        return sManager.addNewDelegate(new NativeAllocationRegistry_Delegate(finalizer));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void applyFreeFunction(long freeFunction, long nativePtr) {
-        // This method MIGHT run in the context of the finalizer thread. If the delegate method
-        // crashes, it could bring down the VM. That's why we catch all the exceptions and ignore
-        // them.
-        try {
-            NativeAllocationRegistry_Delegate delegate = sManager.getDelegate(freeFunction);
-            if (delegate != null) {
-                delegate.mFinalizer.free(nativePtr);
-            }
-        } catch (Throwable ignore) {
-        }
-    }
-
-    public interface FreeFunction {
-        void free(long nativePtr);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
deleted file mode 100644
index 2b32e09..0000000
--- a/tools/layoutlib/bridge/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="res"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project
deleted file mode 100644
index 2325eed..0000000
--- a/tools/layoutlib/bridge/tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
deleted file mode 100644
index 1b65eee..0000000
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2011 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)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src) \
-	$(call all-java-files-under, res/testApp/MyApplication/src/main/myapplication.widgets)
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_MODULE := layoutlib-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib \
-			kxml2-2.3.0 \
-			layoutlib_api-prebuilt \
-			tools-common-prebuilt \
-			sdk-common \
-			junit-host \
-			guavalib \
-			mockito-host
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
deleted file mode 100644
index b8fc947..0000000
--- a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (C) 2008 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_width="match_parent"
-    android:layout_height="match_parent"
-	android:orientation="vertical"
->
-	<Button
-		android:id="@+id/bouton"
-	    android:layout_width="wrap_content"
-	    android:layout_height="wrap_content"
-	    android:layout_weight="1"
-	    android:text="My Button Text"
-	    >
-	    </Button>
-	<View
-		android:id="@+id/surface"
-	    android:layout_width="match_parent"
-	    android:layout_height="match_parent"
-	    android:layout_weight="2"
-	    />
-	<TextView
-	    android:id="@+id/status"
-	    android:paddingLeft="2dip"
-	    android:layout_weight="0"
-	    android:background="@drawable/black"
-	    android:layout_width="match_parent"
-	    android:layout_height="wrap_content"
-	    android:lines="1"
-	    android:gravity="center_vertical|center_horizontal"
-	    android:text="My TextView Text"
-	    />
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/empty.xml b/tools/layoutlib/bridge/tests/res/empty.xml
deleted file mode 100644
index e69de29..0000000
--- a/tools/layoutlib/bridge/tests/res/empty.xml
+++ /dev/null
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
deleted file mode 100644
index a2ce0dc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-.gradle
-local.properties
-.idea
-.DS_Store
-*.iml
-# We need the built .class files to load custom views and R class.
-# The only way to negate an exclusion is by including every single parent
-# and excluding all children of those parents.
-
-/build/*
-!/build/intermediates/
-
-/build/intermediates/*
-!/build/intermediates/classes/
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
deleted file mode 100644
index 4781660..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
+++ /dev/null
@@ -1,48 +0,0 @@
-buildscript {
-    repositories {
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-    }
-}
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 25
-    buildToolsVersion '25.0.0'
-    defaultConfig {
-        applicationId 'com.android.layoutlib.test.myapplication'
-        minSdkVersion 21
-        targetSdkVersion 25
-        versionCode 1
-        versionName '1.0'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-    lintOptions {
-        abortOnError false
-    }
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_6
-        targetCompatibility JavaVersion.VERSION_1_6
-    }
-}
-
-dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
deleted file mode 100644
index 1ca7e01..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
deleted file mode 100644
index f73528a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
deleted file mode 100644
index ceb56bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
deleted file mode 100644
index 5bb04fc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
deleted file mode 100644
index b87f193..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
deleted file mode 100644
index e2968d40..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
deleted file mode 100644
index ff699d1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
deleted file mode 100644
index a3931b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
deleted file mode 100644
index e293677..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
deleted file mode 100644
index d6268bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
deleted file mode 100644
index 08b98fb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
deleted file mode 100644
index f9be1ca..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
deleted file mode 100644
index 6874b49..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
deleted file mode 100644
index a4205a8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
deleted file mode 100644
index 4fb3b61..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
deleted file mode 100644
index dba67fd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
deleted file mode 100644
index affc31e..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
deleted file mode 100644
index 7014ddb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
deleted file mode 100644
index f15d669..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
deleted file mode 100644
index 88fa9dd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
deleted file mode 100644
index e33f92d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
deleted file mode 100644
index 915868c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
deleted file mode 100644
index ee72a6f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
deleted file mode 100644
index 781d617..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
deleted file mode 100644
index 5b64d33..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
deleted file mode 100644
index 736b287..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
deleted file mode 100644
index a8567b3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
deleted file mode 100644
index 5ae95ea..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
deleted file mode 100644
index b2b6a97..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
deleted file mode 100644
index cf1a769..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
deleted file mode 100644
index 67355b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
deleted file mode 100644
index e0abcf4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
deleted file mode 100644
index 3d0fbd6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
deleted file mode 100644
index 86b00415..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
deleted file mode 100644
index 7bbae09..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
deleted file mode 100644
index e9dca692..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
deleted file mode 100644
index 5d08ba7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Settings specified in this file will override any Gradle settings
-# configured through the IDE.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 3b51ffe..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Tue Mar 17 15:13:06 PDT 2015
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
deleted file mode 100755
index 91a7e26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
-    echo "$*"
-}
-
-die ( ) {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
deleted file mode 100644
index aec9973..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off

-@rem ##########################################################################

-@rem

-@rem  Gradle startup script for Windows

-@rem

-@rem ##########################################################################

-

-@rem Set local scope for the variables with windows NT shell

-if "%OS%"=="Windows_NT" setlocal

-

-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

-set DEFAULT_JVM_OPTS=

-

-set DIRNAME=%~dp0

-if "%DIRNAME%" == "" set DIRNAME=.

-set APP_BASE_NAME=%~n0

-set APP_HOME=%DIRNAME%

-

-@rem Find java.exe

-if defined JAVA_HOME goto findJavaFromJavaHome

-

-set JAVA_EXE=java.exe

-%JAVA_EXE% -version >NUL 2>&1

-if "%ERRORLEVEL%" == "0" goto init

-

-echo.

-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

-

-goto fail

-

-:findJavaFromJavaHome

-set JAVA_HOME=%JAVA_HOME:"=%

-set JAVA_EXE=%JAVA_HOME%/bin/java.exe

-

-if exist "%JAVA_EXE%" goto init

-

-echo.

-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

-

-goto fail

-

-:init

-@rem Get command-line arguments, handling Windowz variants

-

-if not "%OS%" == "Windows_NT" goto win9xME_args

-if "%@eval[2+2]" == "4" goto 4NT_args

-

-:win9xME_args

-@rem Slurp the command line arguments.

-set CMD_LINE_ARGS=

-set _SKIP=2

-

-:win9xME_args_slurp

-if "x%~1" == "x" goto execute

-

-set CMD_LINE_ARGS=%*

-goto execute

-

-:4NT_args

-@rem Get arguments from the 4NT Shell from JP Software

-set CMD_LINE_ARGS=%$

-

-:execute

-@rem Setup the command line

-

-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

-

-@rem Execute Gradle

-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

-

-:end

-@rem End local scope for the variables with windows NT shell

-if "%ERRORLEVEL%"=="0" goto mainEnd

-

-:fail

-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

-rem the _cmd.exe /c_ return code!

-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

-exit /b 1

-

-:mainEnd

-if "%OS%"=="Windows_NT" endlocal

-

-:omega

diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
deleted file mode 100644
index b0fcd2d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /usr/local/google/home/deepanshu/ssd/sdk_out/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# 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/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
deleted file mode 100644
index 2067474..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.layoutlib.test.myapplication" >
-<!-- If changing package here, update LayoutLibCallBack in tests. -->
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name="com.android.layoutlib.test.myapplication.MyActivity"
-            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/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
deleted file mode 100644
index e7f22bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
+++ /dev/null
@@ -1,57 +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.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-/**
- * A widget to test obtaining arrays from resources.
- */
-public class ArraysCheckWidget extends LinearLayout {
-    public ArraysCheckWidget(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        Resources resources = context.getResources();
-        for (CharSequence chars : resources.getTextArray(R.array.array)) {
-            addTextView(context, chars);
-        }
-        for (int i : resources.getIntArray(R.array.int_array)) {
-            addTextView(context, String.valueOf(i));
-        }
-        for (String string : resources.getStringArray(R.array.string_array)) {
-            addTextView(context, string);
-        }
-    }
-
-    private void addTextView(Context context, CharSequence string) {
-        TextView textView = new TextView(context);
-        textView.setText(string);
-        textView.setTextSize(30);
-        addView(textView);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
deleted file mode 100644
index 59de457..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class MyActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity);
-    }
-
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // Inflate the menu; this adds items to the action bar if it is present.
-        getMenuInflater().inflate(R.menu.my, menu);
-        return true;
-    }
-
-    @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);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
deleted file mode 100644
index 3b819e5..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
+++ /dev/null
@@ -1,47 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CalendarView;
-
-public class CustomCalendar extends CalendarView {
-    public CustomCalendar(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        setDate(871732800000L, false, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
deleted file mode 100644
index f3877f1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
+++ /dev/null
@@ -1,47 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.DatePicker;
-
-public class CustomDate extends DatePicker {
-    public CustomDate(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        init(2015, 0, 20, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
deleted file mode 100644
index 36e5c26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
+++ /dev/null
@@ -1,43 +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.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.WindowInsets;
-import android.widget.TextView;
-
-public class InsetsWidget extends TextView {
-    public static boolean sApplyInsetsCalled = false;
-
-    public InsetsWidget(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        requestApplyInsets();
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        sApplyInsetsCalled = true;
-        return super.onApplyWindowInsets(insets);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
deleted file mode 100644
index 58ad46d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains custom widgets used to set a specific time for the DayTimePicker during
- * testing.
- * The classes here are both used from the Android project and from the Bridge test project.
- */
-package com.android.layoutlib.test.myapplication.widgets;
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
deleted file mode 100644
index fc0afa6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
+++ /dev/null
@@ -1,24 +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.
-  -->
-
-
-<gradient xmlns:android="http://schemas.android.com/apk/res/android"
-          android:startX="10"
-          android:startY="10"
-          android:endX="50"
-          android:endY="50"
-          android:startColor="#ffff0000"
-          android:endColor="#ff00ff00" />
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
deleted file mode 100644
index 8f862c8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@android:color/red" />
-    <foreground android:drawable="@drawable/headset" />
-</adaptive-icon>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
deleted file mode 100644
index 42e3beb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:viewportWidth="1102"
-        android:viewportHeight="642"
-        android:width="1102px"
-        android:height="642px">
-
-    <group
-        android:translateX="-126.347"
-        android:translateY="6.7928655e-4">
-
-
-        <path
-            android:fillColor="#94c147"
-            android:pathData="
-            m 552.777,147.57
-            c -14.147,0 -25.622,11.652 -25.622,26.02
-            v 101.68
-            c 0,14.372 11.475,26.019 25.622,26.019 14.147,0 25.61,-11.646 25.61,-26.019
-            V 173.59
-            c 0.001,-14.368 -11.462,-26.02 -25.61,-26.02
-            z
-
-            m -309.011,0
-            c -14.155,0 -25.618,11.652 -25.618,26.02
-            v 101.68
-            c 0,14.372 11.462,26.019 25.618,26.019 14.153,0 25.623,-11.646 25.623,-26.019
-            V 173.59
-            c -0.008,-14.368 -11.475,-26.02 -25.623,-26.02
-            z" />
-
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 284.799,148.364 v 185.768 c 0,11.035 8.948,19.98 19.983,19.98 h 22.815 v 56.567 c 0,14.37 11.47,26.016 25.623,26.016 14.148,0 25.623,-11.646 25.623,-26.016 v -56.567 h 39.878 v 56.567 c 0,14.37 11.463,26.016 25.61,26.016 14.147,0 25.622,-11.646 25.622,-26.016 v -56.567 h 22.828 c 11.022,0 19.971,-8.953 19.971,-19.98 V 148.364 H 284.799 l 0,0 z" />
-
-        <group
-        android:name="head"
-        android:pivotX="400"
-        android:pivotY="131.105">
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 452.302,52.105 21.057,-30.572 c 1.245,-1.819 0.939,-4.199 -0.695,-5.329 -1.637,-1.123 -3.968,-0.568 -5.225,1.251 l -21.875,31.75 c -14.404,-5.682 -30.418,-8.844 -47.293,-8.844 -16.87,0 -32.893,3.162 -47.297,8.844 l -21.875,-31.75 c -1.257,-1.819 -3.589,-2.375 -5.225,-1.251 -1.636,1.124 -1.946,3.509 -0.696,5.329 l 21.057,30.572 c -33.464,15.57 -56.951,45.166 -59.941,79.706 H 512.25 C 509.259,97.271 485.772,67.676 452.302,52.105 z M 350.187,100.28 c -6.965,0 -12.617,-5.646 -12.617,-12.616 0,-6.958 5.647,-12.61 12.617,-12.61 6.97,0 12.603,5.652 12.603,12.61 0,6.965 -5.64,12.616 -12.603,12.616 z m 97.744,0 c -6.97,0 -12.609,-5.646 -12.609,-12.616 0,-6.958 5.64,-12.61 12.609,-12.61 6.971,0 12.61,5.652 12.61,12.61 0,6.965 -5.64,12.616 -12.61,12.616 z" />
-        </group>
-
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
deleted file mode 100644
index 897c411..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
+++ /dev/null
@@ -1,25 +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.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="150dp"
-        android:height="150dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="m12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h4v1h-7v2h6c1.66,0 3,-1.34 3,-3V10c0,-4.97 -4.03,-9 -9,-9z"/>
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
deleted file mode 100644
index 67481d4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="#ff0000" />
-    <size
-        android:width="20dp"
-        android:height="20dp" />
-</shape>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
deleted file mode 100644
index 0998b25..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="76dp"
-        android:width="76dp"
-        android:viewportHeight="48"
-        android:viewportWidth="48"
-        android:alpha="0.6">
-
-    <group
-        android:name="root"
-        android:translateX="24.0"
-        android:translateY="24.0">
-        <!--
-            This is the same as the material indeterminate progressbar which involves drawing
-            several cubic segments
-        -->
-        <path
-            android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#00FF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.8"
-            android:trimPathStart="0.3" />
-        <!-- Same figure with reversed end and start -->
-        <path
-            android:pathData="M0, 0 m 0, -12 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#FFFF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.3"
-            android:trimPathStart="0.8" />
-
-        <!--
-            Draw a few partial quadratic segments
-        -->
-        <path
-            android:strokeWidth="2"
-            android:strokeColor="#FFFF00"
-            android:pathData="M2,2 Q 5 30 15 0"
-            android:trimPathStart="0.1"
-            android:trimPathEnd="0.9"
-        />
-
-        <!--
-            Draw a line
-        -->
-        <path
-            android:strokeWidth="3"
-            android:strokeColor="#00FFFF"
-            android:pathData="M-10,-10 L 10, 10"
-            android:trimPathStart="0.2"
-            android:trimPathEnd="0.8"
-        />
-
-        <!--
-            Draw a line with gradient stroke color
-        -->
-        <path
-            android:strokeWidth="1"
-            android:strokeColor="#FF00FF"
-            android:fillColor="@color/gradient"
-            android:pathData="M-20,-20 l0, 10 l10, 0 l0, -10 l-10,0 "
-        />
-
-        <!--
-            Draw squares with different fill types
-        -->
-        <path
-            android:fillType="evenOdd"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#AAEFCC"
-            android:pathData="M-20,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-
-        <path
-            android:fillType="nonZero"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#40AAEFCC"
-            android:pathData="M0,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
deleted file mode 100644
index b1e9206..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<font-family xmlns:android="http://schemas.android.com/apk/res/android">
-    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/testfont" />
-    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/testfont2" />
-</font-family>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
deleted file mode 100644
index 97d1983..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<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:paddingLeft="@dimen/activity_horizontal_margin"
-    android:paddingRight="@dimen/activity_horizontal_margin"
-    android:paddingTop="@dimen/activity_vertical_margin"
-    android:paddingBottom="@dimen/activity_vertical_margin"
-    tools:context=".MyActivity">
-
-    <TextView
-        android:text="@string/hello_world"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/text1"/>
-
-    <include layout="@layout/layout"
-        android:layout_below="@+id/text1"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content" />
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml
deleted file mode 100644
index ca9fa55..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/adaptive_icon.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content"
-             android:src="@drawable/adaptive" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
deleted file mode 100644
index 456b5f6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<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"
-    tools:ignore="HardcodedText,LabelFor,TextFields,ContentDescription,RtlHardcoded">
-
-    <FrameLayout
-        android:id="@id/frameLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginEnd="311dp">
-
-        <TextView
-            android:id="@id/textView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="left|top"
-            android:text="New Text" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@id/textView2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/frameLayout"
-        android:text="Large Text"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:pointerIcon="hand" />
-
-    <TextView
-        android:id="@id/textView3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Medium Text"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <TextView
-        android:id="@id/textView4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/textView2"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Small Text"
-        android:textAppearance="?android:attr/textAppearanceSmall" />
-
-    <Button
-        android:id="@id/button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/textView3"
-        android:layout_toEndOf="@id/textView4"
-        android:text="New Button" />
-
-    <Button
-        android:id="@id/button2"
-        style="?android:attr/buttonStyleSmall"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/button"
-        android:text="New Button" />
-
-    <CheckBox
-        android:id="@id/checkBox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignEnd="@id/button"
-        android:layout_below="@id/button"
-        android:text="New CheckBox" />
-
-    <Switch
-        android:id="@id/switch1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/textView2"
-        android:text="New Switch" />
-
-    <ImageButton
-        android:id="@id/imageButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/switch1" />
-
-    <ImageView
-        android:id="@id/imageView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_launcher"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/imageButton" />
-
-    <GridLayout
-        android:id="@id/gridLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/imageButton"
-        android:columnCount="2"
-        android:rowCount="2">
-
-        <ProgressBar
-            android:id="@id/progressBar"
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar3"
-            style="?android:attr/progressBarStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="1" />
-
-        <ProgressBar
-            android:id="@id/progressBar4"
-            style="?android:attr/progressBarStyleHorizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="1" />
-    </GridLayout>
-
-    <SeekBar
-        android:id="@id/seekBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/gridLayout"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <RatingBar
-        android:id="@id/ratingBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/switch2"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <Switch
-        android:id="@id/switch2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/seekBar"
-        android:layout_toEndOf="@id/switch1"
-        android:checked="true" />
-
-    <EditText
-        android:id="@id/editText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBottom="@id/ratingBar"
-        android:layout_alignParentStart="true"
-        android:text="plain text" />
-
-    <EditText
-        android:id="@id/editText2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/ratingBar"
-        android:ems="3"
-        android:inputType="textPersonName"
-        android:text="Name" />
-
-    <EditText
-        android:id="@id/editText3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_toEndOf="@id/editText2"
-        android:ems="2"
-        android:inputType="textPassword"
-        android:text="password" />
-
-    <EditText
-        android:id="@id/editText4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText3"
-        android:layout_toEndOf="@id/editText3"
-        android:ems="3"
-        android:inputType="numberPassword"
-        android:text="numeric password" />
-
-    <ToggleButton
-        android:id="@+id/toggleButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText4"
-        android:layout_toEndOf="@id/editText4"
-        android:text="New ToggleButton" />
-
-    <EditText
-        android:id="@id/editText5"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText3"
-        android:layout_toStartOf="@id/editText6"
-        android:ems="7"
-        android:inputType="textEmailAddress"
-        android:text="email@domain.com" />
-
-    <EditText
-        android:id="@id/editText6"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_below="@id/editText4"
-        android:ems="7"
-        android:inputType="phone"
-        android:text="+11235554344" />
-
-    <EditText
-        android:id="@id/editText7"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText"
-        android:layout_toEndOf="@id/editText4"
-        android:ems="10"
-        android:inputType="textPostalAddress"
-        android:text="1600 Amphitheatre" />
-
-    <EditText
-        android:id="@id/editText9"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_alignParentStart="true"
-        android:ems="3"
-        android:inputType="time"
-        android:text="12:12" />
-
-    <RadioGroup
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_toEndOf="@id/editText9"
-        android:orientation="horizontal">
-
-        <RadioButton
-            android:id="@id/radioButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton" />
-
-        <RadioButton
-            android:id="@id/radioButton2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton"
-            android:checked="true" />
-
-    </RadioGroup>
-
-    <CheckedTextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CheckedTextView"
-        android:id="@id/checkedTextView"
-        android:layout_below="@id/button2"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/button2" />
-
-    <DialerFilter
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/checkBox"
-        android:layout_toStartOf="@id/quickContactBadge"
-        android:id="@id/dialerFilter"
-        android:layout_above="@id/ratingBar"
-        android:layout_toEndOf="@id/seekBar">
-
-        <EditText
-            android:id="@android:id/hint"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="Hint" />
-
-        <EditText
-            android:id="@android:id/primary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/hint"
-            android:text="Primary" />
-    </DialerFilter>
-
-    <QuickContactBadge
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/quickContactBadge"
-        android:layout_below="@id/checkedTextView"
-        android:layout_alignParentEnd="true" />
-
-    <android.inputmethodservice.ExtractEditText
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="ExtractEditText"
-        android:id="@id/extractEditText"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/checkedTextView" />
-
-    <ZoomControls
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/zoomControls"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentStart="true" />
-
-    <TextureView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/textureView"
-        android:layout_below="@id/zoomControls"
-        android:layout_alignParentStart="true"
-        android:layout_alignBottom="@id/extractEditText"
-        android:layout_toStartOf="@id/editText3" />
-
-    <ListView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/listView"
-        android:layout_below="@id/textureView"
-        android:layout_alignParentStart="true"
-        android:layout_alignEnd="@id/textureView" />
-
-    <GridView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/gridView"
-        android:layout_below="@id/extractEditText"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/extractEditText" />
-
-    <ScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/scrollView"
-        android:layout_below="@id/zoomControls"
-        android:layout_toRightOf="@id/listView"
-        android:layout_toLeftOf="@id/extractEditText">
-
-    <TabHost
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:id="@id/tabHost">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
-
-            <TabWidget
-                android:id="@android:id/tabs"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-
-            <FrameLayout
-                android:id="@android:id/tabcontent"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-                <LinearLayout
-                    android:id="@id/linearLayout"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-                <LinearLayout
-                    android:id="@id/linearLayout2"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-            </FrameLayout>
-        </LinearLayout>
-    </TabHost>
-</ScrollView>
-
-    <SearchView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/searchView"
-        android:layout_alignBottom="@id/zoomControls"
-        android:layout_toEndOf="@id/seekBar" />
-
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
deleted file mode 100644
index e9aa9e1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.layoutlib.test.myapplication.ArraysCheckWidget
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-</com.android.layoutlib.test.myapplication.ArraysCheckWidget>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
deleted file mode 100644
index 2c66b7f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
deleted file mode 100644
index a255da7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-        android:background="#FF0000"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FF00"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#0000FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#FF00FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FFFF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-</merge>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
deleted file mode 100644
index 5319654..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="vertical"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
deleted file mode 100644
index c63b211..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED"
-        android:textSize="50sp"
-        android:fontFamily="sans-serif-condensed"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED ITALIC"
-        android:textSize="30sp"
-        android:fontFamily="sans-serif-condensed"
-        android:textStyle="italic"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="MONOSPACE"
-        android:textSize="50sp"
-        android:fontFamily="monospace"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfont"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"/>
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"
-        android:textStyle="italic"/>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
deleted file mode 100644
index c42284a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Bottom Text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Top text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="Start text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="End text" />
-</RelativeLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml
deleted file mode 100644
index 70d7396..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/indeterminate_progressbar.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-
-    <ProgressBar
-             android:layout_height="fill_parent"
-             android:layout_width="fill_parent" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml
deleted file mode 100644
index ff06d79..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/insets.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <com.android.layoutlib.test.myapplication.widgets.InsetsWidget
-        android:text="Hello world"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/text1"/>
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
deleted file mode 100644
index ff14ce0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:columnCount="2"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Some text"/>
-    <Switch
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:checked="true"
-        android:layout_gravity="center"
-        />
-    <com.android.layoutlib.test.myapplication.widgets.CustomDate
-        android:layout_width="100dp"
-        android:layout_height="wrap_content"/>
-    <com.android.layoutlib.test.myapplication.widgets.CustomCalendar
-        android:layout_width="200dp"
-        android:layout_gravity="center_horizontal"
-        android:layout_height="200dp"/>
-</GridLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
deleted file mode 100644
index a07498c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical"
-              android:scrollX="30px"
-              android:scrollY="90px">
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#FF0000" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#00FF00" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#0000FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#FF00FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#00FFFF" />
-
-    <LinearLayout
-        android:layout_width="200dp"
-        android:layout_height="400dp"
-        android:orientation="vertical"
-        android:scrollX="-90px"
-        android:scrollY="450px">
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#FF0000" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#00FF00" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#0000FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#FF00FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#00FFFF" />
-    </LinearLayout>
-
-
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
deleted file mode 100644
index b1d6a60..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
+++ /dev/null
@@ -1,97 +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.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent" >
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="0dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="12dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml
deleted file mode 100644
index 14b93f3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/simple_activity.xml
+++ /dev/null
@@ -1,32 +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.
-  -->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:paddingLeft="@dimen/activity_horizontal_margin"
-                android:paddingRight="@dimen/activity_horizontal_margin"
-                android:paddingTop="@dimen/activity_vertical_margin"
-                android:paddingBottom="@dimen/activity_vertical_margin">
-
-    <TextView
-        android:text="@string/hello_world"
-        android:layout_width="wrap_content"
-        android:layout_height="200dp"
-        android:background="#FF0000"
-        android:id="@+id/text1"/>
-
-</RelativeLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
deleted file mode 100644
index 2ce4f4c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
+++ /dev/null
@@ -1,30 +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:padding="16dp"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-             android:layout_height="fill_parent"
-             android:layout_width="fill_parent"
-             android:src="@drawable/multi_path" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml
deleted file mode 100644
index 3b01ea0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable_android.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="vertical"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent">
-    <ImageView
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:src="@drawable/android"/>
-    <ImageView
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:src="@drawable/headset"/>
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
deleted file mode 100644
index bea58cc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context=".MyActivity" >
-    <item android:id="@+id/action_settings"
-        android:title="@string/action_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
deleted file mode 100644
index 5f58d39..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <array name="array">
-        <item>first</item>
-        <item>second</item>
-    </array>
-    <integer-array name="int_array">
-        <item>1</item>
-        <item>0xaB</item>  <!-- hex entry (decimal 171) -->
-        <item>010</item>   <!-- octal entry -->
-        <item>@integer/ten</item>  <!-- value reference -->
-        <item>?attr/myattr</item>  <!-- theme attr reference -->
-    </integer-array>
-    <string-array name="string_array">
-        <item>mystring</item>
-        <item>@string/hello_world</item>   <!-- string ref in appNs -->
-        <!-- theme ref in android NS. value = @string/candidates_style = <u>candidates</u> -->
-        <item>?android:attr/candidatesTextStyleSpans</item>
-        <item>@android:string/unknownName</item>  <!-- value = Unknown -->
-        <item>?EC</item>
-    </string-array>
-
-    <!-- resources that the above array can refer to -->
-    <integer name="ten">10</integer>
-    <integer name="twelve">12</integer>
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
deleted file mode 100644
index 894e18c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <attr name="myattr" format="integer" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
deleted file mode 100644
index 1dc2fa0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <item type="id" name="button" />
-    <item type="id" name="button2" />
-    <item type="id" name="checkBox" />
-    <item type="id" name="checkedTextView" />
-    <item type="id" name="dialerFilter" />
-    <item type="id" name="editText" />
-    <item type="id" name="editText2" />
-    <item type="id" name="editText3" />
-    <item type="id" name="editText4" />
-    <item type="id" name="editText5" />
-    <item type="id" name="editText6" />
-    <item type="id" name="editText7" />
-    <item type="id" name="editText8" />
-    <item type="id" name="editText9" />
-    <item type="id" name="extractEditText" />
-    <item type="id" name="frameLayout" />
-    <item type="id" name="gridLayout" />
-    <item type="id" name="gridView" />
-    <item type="id" name="imageButton" />
-    <item type="id" name="imageView" />
-    <item type="id" name="linearLayout" />
-    <item type="id" name="linearLayout2" />
-    <item type="id" name="listView" />
-    <item type="id" name="progressBar" />
-    <item type="id" name="progressBar2" />
-    <item type="id" name="progressBar3" />
-    <item type="id" name="progressBar4" />
-    <item type="id" name="quickContactBadge" />
-    <item type="id" name="radioButton" />
-    <item type="id" name="radioButton2" />
-    <item type="id" name="ratingBar" />
-    <item type="id" name="scrollView" />
-    <item type="id" name="searchView" />
-    <item type="id" name="seekBar" />
-    <item type="id" name="spinner" />
-    <item type="id" name="switch1" />
-    <item type="id" name="switch2" />
-    <item type="id" name="tabHost" />
-    <item type="id" name="textView" />
-    <item type="id" name="textView2" />
-    <item type="id" name="textView3" />
-    <item type="id" name="textView4" />
-    <item type="id" name="textureView" />
-    <item type="id" name="zoomControls" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
deleted file mode 100644
index 2b7083b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">My Application</string>
-    <string name="hello_world">Hello world!</string>
-    <string name="action_settings">Settings</string>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
deleted file mode 100644
index debe33b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
-        <item name="myattr">@integer/ten</item>
-    </style>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java b/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
deleted file mode 100644
index 4f1c16c..0000000
--- a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
+++ /dev/null
@@ -1,39 +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.
- */
-
-package android.app;
-
-import org.junit.Test;
-
-import android.content.Context;
-import android.hardware.input.InputManager;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-
-import static org.junit.Assert.*;
-
-public class SystemServiceRegistry_AccessorTest {
-    @Test
-    public void testRegistry() {
-        // Just check a few services to make sure we don't break the accessor
-        assertEquals(Context.ACCESSIBILITY_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(AccessibilityManager.class));
-        assertEquals(Context.INPUT_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(InputManager.class));
-        assertEquals(Context.WINDOW_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(WindowManager.class));
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
deleted file mode 100644
index d20fb14..0000000
--- a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 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.graphics;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class Matrix_DelegateTest extends TestCase {
-
-    public void testIdentity() {
-        Matrix m1 = new Matrix();
-
-        assertTrue(m1.isIdentity());
-
-        m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 });
-        assertTrue(m1.isIdentity());
-    }
-
-    public void testCopyConstructor() {
-        Matrix m1 = new Matrix();
-        Matrix m2 = new Matrix(m1);
-
-        float[] v1 = new float[9];
-        float[] v2 = new float[9];
-        m1.getValues(v1);
-        m2.getValues(v2);
-
-        for (int i = 0 ; i < 9; i++) {
-            assertEquals(v1[i], v2[i]);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java b/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
deleted file mode 100644
index 2fcec8e..0000000
--- a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
+++ /dev/null
@@ -1,110 +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.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.junit.Test;
-import org.xmlpull.v1.XmlPullParser;
-
-import com.google.common.collect.ImmutableMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class BridgeXmlPullAttributesTest {
-    @Test
-    public void testGetAttributeIntValueForEnums() {
-        RenderResources renderResources = new RenderResources();
-
-        XmlPullParser parser = mock(XmlPullParser.class);
-        when(parser.getAttributeValue(BridgeConstants.NS_RESOURCES, "layout_width"))
-                .thenReturn("match_parent");
-        when(parser.getAttributeName(0)).thenReturn("layout_width");
-        when(parser.getAttributeNamespace(0)).thenReturn(BridgeConstants.NS_RESOURCES);
-        // Return every value twice since there is one test using name and other using index
-        when(parser.getAttributeValue("http://custom", "my_custom_attr"))
-                .thenReturn("a", "a", "b", "b", "invalid", "invalid");
-        when(parser.getAttributeName(1)).thenReturn("my_custom_attr");
-        when(parser.getAttributeNamespace(1)).thenReturn("http://custom");
-
-        BridgeContext context = mock(BridgeContext.class);
-        when(context.getRenderResources()).thenReturn(renderResources);
-
-        BridgeXmlPullAttributes attributes = new BridgeXmlPullAttributes(
-                parser,
-                context,
-                false,
-                attrName -> {
-                    if ("layout_width".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "match_parent", 123);
-                    }
-                    return ImmutableMap.of();
-                },
-                attrName -> {
-                    if ("my_custom_attr".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "a", 1,
-                                "b", 2
-                        );
-                    }
-                    return ImmutableMap.of();
-                });
-
-        // Test a framework defined enum attribute
-        assertEquals(123, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_width", 500));
-        assertEquals(123, attributes.getAttributeIntValue(0, 500));
-        // Test non existing attribute (it should return the default value)
-        assertEquals(500, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_height", 500));
-        assertEquals(500, attributes.getAttributeIntValue(2, 500));
-
-        // Test project defined enum attribute
-        assertEquals(1, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(1, attributes.getAttributeIntValue(1, 500));
-        assertEquals(2, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(2, attributes.getAttributeIntValue(1, 500));
-        // Test an invalid enum
-        boolean exception = false;
-        try {
-            attributes.getAttributeIntValue("http://custom", "my_custom_attr", 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-        exception = false;
-        try {
-            attributes.getAttributeIntValue(1, 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-
-        // Test non existing project attribute
-        assertEquals(500, attributes.getAttributeIntValue("http://custom",
-                "my_other_attr", 500));
-    }
-
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
deleted file mode 100644
index 63b9b43..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
+++ /dev/null
@@ -1,37 +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.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class BridgeRenderSessionTest {
-    @Test
-    public void testNullSession() {
-        BridgeRenderSession renderSession = new BridgeRenderSession(null, Status.ERROR_UNKNOWN
-                .createResult("Test result"));
-
-        assertNotNull(renderSession.getImage());
-        assertNotNull(renderSession.getRootViews());
-        assertNotNull(renderSession.getSystemRootViews());
-        assertNotNull(renderSession.getDefaultProperties());
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
deleted file mode 100644
index d8937f4..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.create.CreateInfo;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * Tests that native delegate classes implement all the required methods.
- *
- * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that
- * have their native methods reimplemented through a delegate.
- *
- * Since the reimplemented methods are not native anymore, we look for the annotation
- * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same
- * as the modified class with _Delegate added as a suffix).
- * If the original native method is not static, then we make sure the delegate method also
- * include the original class as first parameter (to access "this").
- *
- */
-public class TestDelegates extends TestCase {
-
-    private List<String> mErrors = new ArrayList<String>();
-
-    public void testNativeDelegates() {
-
-        final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES;
-        mErrors.clear();
-        for (String clazz : classes) {
-            loadAndCompareClasses(clazz, clazz + "_Delegate");
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    public void testMethodDelegates() {
-        final String[] methods = CreateInfo.DELEGATE_METHODS;
-        mErrors.clear();
-        for (String methodName : methods) {
-            // extract the class name
-            String className = methodName.substring(0, methodName.indexOf('#'));
-            String targetClassName = className.replace('$', '_') + "_Delegate";
-
-            loadAndCompareClasses(className, targetClassName);
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    private void loadAndCompareClasses(String originalClassName, String delegateClassName) {
-        // load the classes
-        try {
-            ClassLoader classLoader = TestDelegates.class.getClassLoader();
-            Class<?> originalClass = classLoader.loadClass(originalClassName);
-            Class<?> delegateClass = classLoader.loadClass(delegateClassName);
-
-            compare(originalClass, delegateClass);
-        } catch (ClassNotFoundException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        } catch (SecurityException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        }
-    }
-
-    private void compare(Class<?> originalClass, Class<?> delegateClass) throws SecurityException {
-        List<Method> checkedDelegateMethods = new ArrayList<Method>();
-
-        // loop on the methods of the original class, and for the ones that are annotated
-        // with @LayoutlibDelegate, look for a matching method in the delegate class.
-        // The annotation is automatically added by layoutlib_create when it replace a method
-        // by a call to a delegate
-        Method[] originalMethods = originalClass.getDeclaredMethods();
-        for (Method originalMethod : originalMethods) {
-            // look for methods that are delegated: they have the LayoutlibDelegate annotation
-            if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            // get the signature.
-            Class<?>[] parameters = originalMethod.getParameterTypes();
-
-            // if the method is not static, then the class is added as the first parameter
-            // (for "this")
-            if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) {
-
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass;
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            // if the original class is an inner class that's not static, then
-            // we add this on the enclosing class at the beginning
-            if (originalClass.getEnclosingClass() != null &&
-                    (originalClass.getModifiers() & Modifier.STATIC) == 0) {
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass.getEnclosingClass();
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            try {
-                // try to load the method with the given parameter types.
-                Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
-                        parameters);
-
-                // check the return type of the methods match.
-                if (delegateMethod.getReturnType() != originalMethod.getReturnType()) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s.%2$s does not match the " +
-                                    "corresponding framework method which returns %3$s",
-                            delegateClass.getName(),
-                            getMethodName(delegateMethod),
-                            originalMethod.getReturnType().getName()));
-                }
-
-                // check that the method has the annotation
-                if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s for class %2$s does not have the " +
-                                            "@LayoutlibDelegate annotation",
-                                    delegateMethod.getName(),
-                                    originalClass.getName()));
-                }
-
-                // check that the method is static
-                if ((delegateMethod.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
-                    mErrors.add(
-                            String.format(
-                                    "Delegate method %1$s for class %2$s is not static",
-                                    delegateMethod.getName(),
-                                    originalClass.getName())
-                    );
-                }
-
-                // add the method as checked.
-                checkedDelegateMethods.add(delegateMethod);
-            } catch (NoSuchMethodException e) {
-                String name = getMethodName(originalMethod, parameters);
-                mErrors.add(String.format("Missing %1$s.%2$s", delegateClass.getName(), name));
-            }
-        }
-
-        // look for dead (delegate) code.
-        // This looks for all methods in the delegate class, and if they have the
-        // @LayoutlibDelegate annotation, make sure they have been previously found as a
-        // match for a method in the original class.
-        // If not, this means the method is a delegate for a method that either doesn't exist
-        // anymore or is not delegated anymore.
-        Method[] delegateMethods = delegateClass.getDeclaredMethods();
-        for (Method delegateMethod : delegateMethods) {
-            // look for methods that are delegates: they have the LayoutlibDelegate annotation
-            if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            if (!checkedDelegateMethods.contains(delegateMethod)) {
-                mErrors.add(String.format(
-                        "Delegate method %1$s.%2$s is not used anymore and must be removed",
-                        delegateClass.getName(),
-                        getMethodName(delegateMethod)));
-            }
-        }
-
-    }
-
-    private String getMethodName(Method method) {
-        return getMethodName(method, method.getParameterTypes());
-    }
-
-    private String getMethodName(Method method, Class<?>[] parameters) {
-        // compute a full class name that's long but not too long.
-        StringBuilder sb = new StringBuilder(method.getName() + "(");
-        for (int j = 0; j < parameters.length; j++) {
-            Class<?> theClass = parameters[j];
-            int dimensions = 0;
-            while (theClass.isArray()) {
-                dimensions++;
-                theClass = theClass.getComponentType();
-            }
-            sb.append(theClass.getName());
-            for (int i = 0; i < dimensions; i++) {
-                sb.append("[]");
-            }
-            if (j < (parameters.length - 1)) {
-                sb.append(",");
-            }
-        }
-        sb.append(")");
-
-        return sb.toString();
-    }
-
-    private String getErrors() {
-        StringBuilder s = new StringBuilder();
-        for (String error : mErrors) {
-            s.append(error).append('\n');
-        }
-        return s.toString();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
deleted file mode 100644
index 77c997b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 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.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-
-import static org.junit.Assert.assertEquals;
-
-public class BridgeXmlBlockParserTest {
-
-    @BeforeClass
-    public static void setUp() {
-        ParserFactory.setParserFactory(new ParserFactoryImpl());
-    }
-
-    @Test
-    public void testXmlBlockParser() throws Exception {
-
-        XmlPullParser parser = ParserFactory.create(
-                getClass().getResourceAsStream("/com/android/layoutlib/testdata/layout1.xml"),
-                        "layout1.xml");
-
-        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
-
-        assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("LinearLayout", parser.getName());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("Button", parser.getName());
-        assertEquals(XmlPullParser.TEXT, parser.next());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("View", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("TextView", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-        assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
-    }
-
-    //------------
-
-    /**
-     * Quick 'n' dirty debug helper that dumps an XML structure to stdout.
-     */
-    @SuppressWarnings("unused")
-    private void dump(Node node, String prefix) {
-        Node n;
-
-        String[] types = {
-                "unknown",
-                "ELEMENT_NODE",
-                "ATTRIBUTE_NODE",
-                "TEXT_NODE",
-                "CDATA_SECTION_NODE",
-                "ENTITY_REFERENCE_NODE",
-                "ENTITY_NODE",
-                "PROCESSING_INSTRUCTION_NODE",
-                "COMMENT_NODE",
-                "DOCUMENT_NODE",
-                "DOCUMENT_TYPE_NODE",
-                "DOCUMENT_FRAGMENT_NODE",
-                "NOTATION_NODE"
-        };
-
-        String s = String.format("%s<%s> %s %s",
-                prefix,
-                types[node.getNodeType()],
-                node.getNodeName(),
-                node.getNodeValue() == null ? "" : node.getNodeValue().trim());
-
-        System.out.println(s);
-
-        n = node.getFirstChild();
-        if (n != null) {
-            dump(n, prefix + "- ");
-        }
-
-        n = node.getNextSibling();
-        if (n != null) {
-            dump(n, prefix);
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        ParserFactory.setParserFactory(null);
-    }
-
-    private static class ParserFactoryImpl
-            extends com.android.ide.common.rendering.api.ParserFactory {
-
-        @NonNull
-        @Override
-        public XmlPullParser createParser(String displayName) throws XmlPullParserException {
-            return new KXmlParser();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
deleted file mode 100644
index 2c33862..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.StringReader;
-
-import static com.android.SdkConstants.NS_RESOURCES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
-
-public class LayoutParserWrapperTest {
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")  // some for loops need to be empty statements.
-    public void testDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that data-binding part is stripped.
-        assertEquals("Bound attribute android:text incorrect", "World",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")
-    public void testNonDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sNonDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that value isn't modified.
-        assertEquals("Bound attribute android:text incorrect", "@{user.firstName,default=World}",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    private static LayoutParserWrapper getParserFromString(String layoutContent) throws
-            XmlPullParserException {
-        XmlPullParser parser = new KXmlParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(new StringReader(layoutContent));
-        return new LayoutParserWrapper(parser);
-    }
-
-    private static final String sDataBindingLayout =
-            //language=XML
-            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-                    "<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "        xmlns:tools=\"http://schemas.android.com/tools\"\n" +
-                    "        tools:context=\".MainActivity\"\n" +
-                    "        tools:showIn=\"@layout/activity_main\">\n" +
-                    "\n" +
-                    "    <data>\n" +
-                    "\n" +
-                    "        <variable\n" +
-                    "            name=\"user\"\n" +
-                    "            type=\"com.example.User\" />\n" +
-                    "        <variable\n" +
-                    "            name=\"activity\"\n" +
-                    "            type=\"com.example.MainActivity\" />\n" +
-                    "    </data>\n" +
-                    "\n" +
-                    "    <RelativeLayout\n" +
-                    "        android:layout_width=\"match_parent\"\n" +
-                    "        android:layout_height=\"match_parent\"\n" +
-                    "        android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "        android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    "    >\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/first\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_alignParentStart=\"true\"\n" +
-                    "            android:layout_alignParentLeft=\"true\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/last\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_toEndOf=\"@id/first\"\n" +
-                    "            android:layout_toRightOf=\"@id/first\"\n" +
-                    "            android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "        <Button\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_below=\"@id/last\"\n" +
-                    "            android:text=\"Submit\"\n" +
-                    "            android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "    </RelativeLayout>\n" +
-                    "</layout>";
-
-    private static final String sNonDataBindingLayout =
-            //language=XML
-            "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "    android:layout_width=\"match_parent\"\n" +
-                    "    android:layout_height=\"match_parent\"\n" +
-                    "    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    ">\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/first\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_alignParentStart=\"true\"\n" +
-                    "        android:layout_alignParentLeft=\"true\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/last\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_toEndOf=\"@id/first\"\n" +
-                    "        android:layout_toRightOf=\"@id/first\"\n" +
-                    "        android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "    <Button\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_below=\"@id/last\"\n" +
-                    "        android:text=\"Submit\"\n" +
-                    "        android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "</RelativeLayout>";
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
deleted file mode 100644
index eb264d65..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ /dev/null
@@ -1,42 +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.layoutlib.bridge.intensive;
-
-import com.android.layoutlib.bridge.BridgeRenderSessionTest;
-import com.android.layoutlib.bridge.TestDelegates;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest;
-import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-import android.graphics.Matrix_DelegateTest;
-import android.util.BridgeXmlPullAttributesTest;
-
-/**
- * Suite used by the layoutlib build system
- */
-@RunWith(Suite.class)
-@SuiteClasses({
-        RenderTests.class, LayoutParserWrapperTest.class,
-        BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
-        Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class,
-        BridgeRenderSessionTest.class
-})
-public class Main {
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
deleted file mode 100644
index c90c26a..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
+++ /dev/null
@@ -1,55 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.util.perf.PerformanceRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.annotation.NonNull;
-
-/**
- * Set of render tests
- */
-@RunWith(PerformanceRunner.class)
-public class PerformanceTests extends RenderTestBase {
-
-    @Before
-    public void setUp() {
-        ignoreAllLogging();
-    }
-
-
-    private void render(@NonNull String layoutFileName) throws ClassNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, ConfigGenerator.NEXUS_5);
-        render(params, 250);
-    }
-
-    @Test
-    public void testActivity() throws ClassNotFoundException {
-        render("activity.xml");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        render("allwidgets.xml");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
deleted file mode 100644
index 087478f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
+++ /dev/null
@@ -1,72 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-class RenderResult {
-    private final List<ViewInfo> mRootViews;
-    private final List<ViewInfo> mSystemViews;
-    private final Result mRenderResult;
-    private BufferedImage mImage;
-
-    private RenderResult(@Nullable Result result, @Nullable List<ViewInfo> systemViewInfoList,
-            @Nullable List<ViewInfo> rootViewInfoList, @Nullable BufferedImage image) {
-        mSystemViews = systemViewInfoList == null ? Collections.emptyList() : systemViewInfoList;
-        mRootViews = rootViewInfoList == null ? Collections.emptyList() : rootViewInfoList;
-        mRenderResult = result;
-        mImage = image;
-    }
-
-    @NonNull
-    static RenderResult getFromSession(@NonNull RenderSession session) {
-        return new RenderResult(session.getResult(),
-                new ArrayList<>(session.getSystemRootViews()),
-                new ArrayList<>(session.getRootViews()),
-                session.getImage());
-    }
-
-    @Nullable
-    Result getResult() {
-        return mRenderResult;
-    }
-
-    @NonNull
-    public List<ViewInfo> getRootViews() {
-        return mRootViews;
-    }
-
-    @NonNull
-    public List<ViewInfo> getSystemViews() {
-        return mSystemViews;
-    }
-
-    @Nullable
-    public BufferedImage getImage() {
-        return mImage;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
deleted file mode 100644
index 8739b7f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ /dev/null
@@ -1,545 +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.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.resources.FrameworkResources;
-import com.android.ide.common.resources.ResourceItem;
-import com.android.ide.common.resources.ResourceRepository;
-import com.android.ide.common.resources.ResourceResolver;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.io.FolderWrapper;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.layoutlib.bridge.intensive.util.ImageUtils;
-import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
-import com.android.layoutlib.bridge.intensive.util.TestAssetRepository;
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.utils.ILogger;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import com.google.android.collect.Lists;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-/**
- * Base class for render tests. The render tests load all the framework resources and a project
- * checked in this test's resources. The main dependencies
- * are:
- * 1. Fonts directory.
- * 2. Framework Resources.
- * 3. App resources.
- * 4. build.prop file
- * <p>
- * These are configured by two variables set in the system properties.
- * <p>
- * 1. platform.dir: This is the directory for the current platform in the built SDK
- * (.../sdk/platforms/android-<version>).
- * <p>
- * The fonts are platform.dir/data/fonts.
- * The Framework resources are platform.dir/data/res.
- * build.prop is at platform.dir/build.prop.
- * <p>
- * 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
- * falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
- * <p>
- * The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
- */
-public class RenderTestBase {
-
-    private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
-    private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
-
-    private static final String PLATFORM_DIR;
-    private static final String TEST_RES_DIR;
-    /** Location of the app to test inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_DIR = "testApp/MyApplication";
-    /** Location of the app's res dir inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
-    private static final String APP_CLASSES_LOCATION =
-            APP_TEST_DIR + "/build/intermediates/classes/debug/";
-    protected static Bridge sBridge;
-    /** List of log messages generated by a render call. It can be used to find specific errors */
-    protected static ArrayList<String> sRenderMessages = Lists.newArrayList();
-    private static LayoutLog sLayoutLibLog;
-    private static FrameworkResources sFrameworkRepo;
-    private static ResourceRepository sProjectResources;
-    private static ILogger sLogger;
-
-    static {
-        // Test that System Properties are properly set.
-        PLATFORM_DIR = getPlatformDir();
-        if (PLATFORM_DIR == null) {
-            fail(String.format("System Property %1$s not properly set. The value is %2$s",
-                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
-        }
-
-        TEST_RES_DIR = getTestResDir();
-        if (TEST_RES_DIR == null) {
-            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
-                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
-        }
-    }
-
-    @Rule
-    public TestWatcher sRenderMessageWatcher = new TestWatcher() {
-        @Override
-        protected void succeeded(Description description) {
-            // We only check error messages if the rest of the test case was successful.
-            if (!sRenderMessages.isEmpty()) {
-                fail(description.getMethodName() + " render error message: " +
-                        sRenderMessages.get(0));
-            }
-        }
-    };
-    // Default class loader with access to the app classes
-    protected ClassLoader mDefaultClassLoader =
-            new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader());
-
-    private static String getPlatformDir() {
-        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
-        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
-            return platformDir;
-        }
-        // System Property not set. Try to find the directory in the build directory.
-        String androidHostOut = System.getenv("ANDROID_HOST_OUT");
-        if (androidHostOut != null) {
-            platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        String workingDirString = System.getProperty("user.dir");
-        File workingDir = new File(workingDirString);
-        // Test if workingDir is android checkout root.
-        platformDir = getPlatformDirFromRoot(workingDir);
-        if (platformDir != null) {
-            return platformDir;
-        }
-
-        // Test if workingDir is platform/frameworks/base/tools/layoutlib/bridge.
-        File currentDir = workingDir;
-        if (currentDir.getName().equalsIgnoreCase("bridge")) {
-            currentDir = currentDir.getParentFile();
-        }
-        // Test if currentDir is  platform/frameworks/base/tools/layoutlib. That is, root should be
-        // workingDir/../../../../  (4 levels up)
-        for (int i = 0; i < 4; i++) {
-            if (currentDir != null) {
-                currentDir = currentDir.getParentFile();
-            }
-        }
-        return currentDir == null ? null : getPlatformDirFromRoot(currentDir);
-    }
-
-    private static String getPlatformDirFromRoot(File root) {
-        if (!root.isDirectory()) {
-            return null;
-        }
-        File out = new File(root, "out");
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File host = new File(out, "host");
-        if (!host.isDirectory()) {
-            return null;
-        }
-        File[] hosts = host.listFiles(path -> path.isDirectory() &&
-                (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
-        assert hosts != null;
-        for (File hostOut : hosts) {
-            String platformDir = getPlatformDirFromHostOut(hostOut);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOut(File out) {
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File sdkDir = new File(out, "sdk");
-        if (!sdkDir.isDirectory()) {
-            return null;
-        }
-        File[] sdkDirs = sdkDir.listFiles(path -> {
-            // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
-            return path.isDirectory() && path.getName().startsWith("sdk");
-        });
-        assert sdkDirs != null;
-        for (File dir : sdkDirs) {
-            String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
-        File[] possibleSdks = sdkDir.listFiles(
-                path -> path.isDirectory() && path.getName().contains("android-sdk"));
-        assert possibleSdks != null;
-        for (File possibleSdk : possibleSdks) {
-            File platformsDir = new File(possibleSdk, "platforms");
-            File[] platforms = platformsDir.listFiles(
-                    path -> path.isDirectory() && path.getName().startsWith("android-"));
-            if (platforms == null || platforms.length == 0) {
-                continue;
-            }
-            Arrays.sort(platforms, (o1, o2) -> {
-                final int MAX_VALUE = 1000;
-                String suffix1 = o1.getName().substring("android-".length());
-                String suffix2 = o2.getName().substring("android-".length());
-                int suff1, suff2;
-                try {
-                    suff1 = Integer.parseInt(suffix1);
-                } catch (NumberFormatException e) {
-                    suff1 = MAX_VALUE;
-                }
-                try {
-                    suff2 = Integer.parseInt(suffix2);
-                } catch (NumberFormatException e) {
-                    suff2 = MAX_VALUE;
-                }
-                if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
-                    return suff2 - suff1;
-                }
-                return suffix2.compareTo(suffix1);
-            });
-            return platforms[0].getAbsolutePath();
-        }
-        return null;
-    }
-
-    private static String getTestResDir() {
-        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
-        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
-            return resourceDir;
-        }
-        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
-        try {
-            URL location = RenderTestBase.class.getProtectionDomain().getCodeSource().getLocation();
-            return new File(location.getPath()).exists() ? location.getPath() : null;
-        } catch (NullPointerException e) {
-            // Prevent a lot of null checks by just catching the exception.
-            return null;
-        }
-    }
-
-    /**
-     * Initialize the bridge and the resource maps.
-     */
-    @BeforeClass
-    public static void beforeClass() {
-        File data_dir = new File(PLATFORM_DIR, "data");
-        File res = new File(data_dir, "res");
-        sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
-        sFrameworkRepo.loadResources();
-        sFrameworkRepo.loadPublicResources(getLogger());
-
-        sProjectResources =
-                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
-                        false) {
-                    @NonNull
-                    @Override
-                    protected ResourceItem createResourceItem(@NonNull String name) {
-                        return new ResourceItem(name);
-                    }
-                };
-        sProjectResources.loadResources();
-
-        File fontLocation = new File(data_dir, "fonts");
-        File buildProp = new File(PLATFORM_DIR, "build.prop");
-        File attrs = new File(res, "values" + File.separator + "attrs.xml");
-        sBridge = new Bridge();
-        sBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
-                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
-        Bridge.getLock().lock();
-        try {
-            Bridge.setLog(getLayoutLog());
-        } finally {
-            Bridge.getLock().unlock();
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        sLayoutLibLog = null;
-        sFrameworkRepo = null;
-        sProjectResources = null;
-        sLogger = null;
-        sBridge = null;
-
-        TestUtils.gc();
-
-        System.out.println("Objects still linked from the DelegateManager:");
-        DelegateManager.dump(System.out);
-    }
-
-    @NonNull
-    protected static RenderResult render(SessionParams params, long frameTimeNanos) {
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        RenderSession session = sBridge.createSession(params);
-
-        try {
-            if (frameTimeNanos != -1) {
-                session.setElapsedFrameTimeNanos(frameTimeNanos);
-            }
-
-            if (!session.getResult().isSuccess()) {
-                getLogger().error(session.getResult().getException(),
-                        session.getResult().getErrorMessage());
-            }
-            else {
-                // Render the session with a timeout of 50s.
-                Result renderResult = session.render(50000);
-                if (!renderResult.isSuccess()) {
-                    getLogger().error(session.getResult().getException(),
-                            session.getResult().getErrorMessage());
-                }
-            }
-
-            return RenderResult.getFromSession(session);
-        } finally {
-            session.dispose();
-        }
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     * <p>
-     * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
-     * how far in the future is.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName,
-            long frameTimeNanos) throws ClassNotFoundException {
-        RenderResult result = RenderTestBase.render(params, frameTimeNanos);
-        try {
-            String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
-            assertNotNull(result.getImage());
-            ImageUtils.requireSimilar(goldenImagePath, result.getImage());
-        } catch (IOException e) {
-            getLogger().error(e, e.getMessage());
-        }
-
-        return result;
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName)
-            throws ClassNotFoundException {
-        return RenderTestBase.renderAndVerify(params, goldenFileName, -1);
-    }
-
-    private static LayoutLog getLayoutLog() {
-        if (sLayoutLibLog == null) {
-            sLayoutLibLog = new LayoutLog() {
-                @Override
-                public void warning(String tag, String message, Object data) {
-                    System.out.println("Warning " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void fidelityWarning(@Nullable String tag, String message,
-                        Throwable throwable, Object data) {
-
-                    System.out.println("FidelityWarning " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message == null ? "" : message);
-                }
-
-                @Override
-                public void error(String tag, String message, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void error(String tag, String message, Throwable throwable, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message);
-                }
-            };
-        }
-        return sLayoutLibLog;
-    }
-
-    protected static void ignoreAllLogging() {
-        sLayoutLibLog = new LayoutLog();
-        sLogger = new ILogger() {
-            @Override
-            public void error(Throwable t, String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void warning(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void info(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void verbose(String msgFormat, Object... args) {
-            }
-        };
-    }
-
-    protected static ILogger getLogger() {
-        if (sLogger == null) {
-            sLogger = new ILogger() {
-                @Override
-                public void error(Throwable t, @Nullable String msgFormat, Object... args) {
-                    if (t != null) {
-                        t.printStackTrace();
-                    }
-                    failWithMsg(msgFormat == null ? "" : msgFormat, args);
-                }
-
-                @Override
-                public void warning(@NonNull String msgFormat, Object... args) {
-                    failWithMsg(msgFormat, args);
-                }
-
-                @Override
-                public void info(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-
-                @Override
-                public void verbose(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-            };
-        }
-        return sLogger;
-    }
-
-    private static void failWithMsg(@NonNull String msgFormat, Object... args) {
-        sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args));
-    }
-
-    @Before
-    public void beforeTestCase() {
-        sRenderMessages.clear();
-    }
-
-    @NonNull
-    protected LayoutPullParser createLayoutPullParser(String layoutPath) {
-        return new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutPath);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on nexus 5
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName)
-            throws ClassNotFoundException {
-        return renderAndVerify(layoutFileName, goldenFileName, ConfigGenerator.NEXUS_5);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on given device
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName,
-            ConfigGenerator deviceConfig) throws ClassNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, deviceConfig);
-        return renderAndVerify(params, goldenFileName);
-    }
-
-    protected SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
-            throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser(layoutFileName);
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        return getSessionParams(parser, deviceConfig, layoutLibCallback, "AppTheme", true,
-                RenderingMode.NORMAL, 22);
-    }
-
-    /**
-     * Uses Theme.Material and Target sdk version as 22.
-     */
-    protected SessionParams getSessionParams(LayoutPullParser layoutParser,
-            ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback,
-            String themeName, boolean isProjectTheme, RenderingMode renderingMode,
-            @SuppressWarnings("SameParameterValue") int targetSdk) {
-        FolderConfiguration config = configGenerator.getFolderConfig();
-        ResourceResolver resourceResolver =
-                ResourceResolver.create(sProjectResources.getConfiguredResources(config),
-                        sFrameworkRepo.getConfiguredResources(config), themeName, isProjectTheme);
-
-        SessionParams sessionParams =
-                new SessionParams(layoutParser, renderingMode, null /*used for caching*/,
-                        configGenerator.getHardwareConfig(), resourceResolver, layoutLibCallback, 0,
-                        targetSdk, getLayoutLog());
-        sessionParams.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true);
-        sessionParams.setAssetRepository(new TestAssetRepository());
-        return sessionParams;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
deleted file mode 100644
index 7b565b1..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ /dev/null
@@ -1,449 +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.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.resources.Density;
-import com.android.resources.Navigation;
-import com.android.resources.ResourceType;
-
-import org.junit.Test;
-
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Set of render tests
- */
-public class RenderTests extends RenderTestBase {
-
-    @Test
-    public void testActivity() throws ClassNotFoundException {
-        renderAndVerify("activity.xml", "activity.png");
-    }
-
-    @Test
-    public void testActivityOnOldTheme() throws ClassNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.NoTitleBar", false,
-                RenderingMode.NORMAL, 22);
-
-        renderAndVerify(params, "simple_activity-old-theme.png");
-    }
-
-    @Test
-    public void testTranslucentBars() throws ClassNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = createLayoutPullParser("four_corners.xml");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent.png");
-
-        parser = createLayoutPullParser("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5_LAND,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent_land.png");
-
-        parser = createLayoutPullParser("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners.png");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets.png");
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testArrayCheck() throws ClassNotFoundException {
-        renderAndVerify("array_check.xml", "array_check.png");
-    }
-
-    @Test
-    public void testAllWidgetsTablet() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testActivityActionBar() throws ClassNotFoundException {
-        LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity_noactionbar.png");
-
-        parser = createLayoutPullParser("simple_activity.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity.png");
-
-        // This also tests that a theme with "NoActionBar" DOES HAVE an action bar when we are
-        // displaying menus.
-        parser = createLayoutPullParser("simple_activity.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG, "menu");
-        renderAndVerify(params, "simple_activity.png");
-    }
-
-    @Test
-    public void testOnApplyInsetsCall()
-            throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
-        // We get the widget via reflection to avoid IntelliJ complaining about the class being
-        // located in the wrong package. (From the Bridge tests point of view, it is)
-        Class insetsWidgetClass = Class.forName("com.android.layoutlib.test.myapplication.widgets" +
-                ".InsetsWidget");
-        Field field = insetsWidgetClass.getDeclaredField("sApplyInsetsCalled");
-        assertFalse((Boolean)field.get(null));
-
-        LayoutPullParser parser = createLayoutPullParser("insets.xml");
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-
-        render(params, -1);
-
-        assertTrue((Boolean)field.get(null));
-        field.set(null, false);
-    }
-
-    /** Test expand_layout.xml */
-    @Test
-    public void testExpand() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("expand_vert_layout.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        ConfigGenerator customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(300)
-                .setScreenHeight(20)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-
-        SessionParams params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "expand_vert_layout.png");
-
-        customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(20)
-                .setScreenHeight(300)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-        parser = createLayoutPullParser("expand_horz_layout.xml");
-        params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.H_SCROLL, 22);
-
-        renderAndVerify(params, "expand_horz_layout.png");
-    }
-
-    /** Test indeterminate_progressbar.xml */
-    @Test
-    public void testVectorAnimation() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("indeterminate_progressbar.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "animated_vector.png", TimeUnit.SECONDS.toNanos(2));
-
-        parser = createLayoutPullParser("indeterminate_progressbar.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        renderAndVerify(params, "animated_vector_1.png", TimeUnit.SECONDS.toNanos(3));
-    }
-
-    /**
-     * Test a vector drawable that uses trimStart and trimEnd. It also tests all the primitives
-     * for vector drawables (lines, moves and cubic and quadratic curves).
-     */
-    @Test
-    public void testVectorDrawable() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /**
-     * Regression test for http://b.android.com/91383 and http://b.android.com/203797
-     */
-    @Test
-    public void testVectorDrawable91383() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("vector_drawable_android.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable_91383.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /** Test activity.xml */
-    @Test
-    public void testScrollingAndMeasure() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        // Do an only-measure pass
-        RenderSession session = sBridge.createSession(params);
-        session.measure();
-        RenderResult result = RenderResult.getFromSession(session);
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-
-        ViewInfo rootLayout = result.getRootViews().get(0);
-        // Check the first box in the main LinearLayout
-        assertEquals(-90, rootLayout.getChildren().get(0).getTop());
-        assertEquals(-30, rootLayout.getChildren().get(0).getLeft());
-        assertEquals(90, rootLayout.getChildren().get(0).getBottom());
-        assertEquals(150, rootLayout.getChildren().get(0).getRight());
-
-        // Check the first box within the nested LinearLayout
-        assertEquals(-450, rootLayout.getChildren().get(5).getChildren().get(0).getTop());
-        assertEquals(90, rootLayout.getChildren().get(5).getChildren().get(0).getLeft());
-        assertEquals(-270, rootLayout.getChildren().get(5).getChildren().get(0).getBottom());
-        assertEquals(690, rootLayout.getChildren().get(5).getChildren().get(0).getRight());
-
-        // Do a full render pass
-        parser = createLayoutPullParser("scrolled.xml");
-
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        result = renderAndVerify(params, "scrolled.png");
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-    }
-
-    @Test
-    public void testGetResourceNameVariants() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-        // Test
-        assertEquals("android:style/ButtonBar",
-                resources.getResourceName(android.R.style.ButtonBar));
-        assertEquals("android", resources.getResourcePackageName(android.R.style.ButtonBar));
-        assertEquals("ButtonBar", resources.getResourceEntryName(android.R.style.ButtonBar));
-        assertEquals("style", resources.getResourceTypeName(android.R.style.ButtonBar));
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.STRING, "app_name");
-        assertEquals("com.android.layoutlib.test.myapplication:string/app_name",
-                resources.getResourceName(id));
-        assertEquals("com.android.layoutlib.test.myapplication",
-                resources.getResourcePackageName(id));
-        assertEquals("string", resources.getResourceTypeName(id));
-        assertEquals("app_name", resources.getResourceEntryName(id));
-    }
-
-    @Test
-    public void testStringEscaping() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.ARRAY, "string_array");
-        String[] strings = resources.getStringArray(id);
-        assertArrayEquals(
-                new String[]{"mystring", "Hello world!", "candidates", "Unknown", "?EC"},
-                strings);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    //@Test
-    // Temporarily disabled (b/37725933)
-    public void testFonts() throws ClassNotFoundException {
-        // TODO: styles seem to be broken in TextView
-        renderAndVerify("fonts_test.xml", "font_test.png");
-    }
-
-    @Test
-    public void testAdaptiveIcon() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createLayoutPullParser("adaptive_icon.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "adaptive_icon.png");
-    }
-
-    @Test
-    public void testColorTypedValue() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        TypedValue outValue = new TypedValue();
-        resources.mContext.resolveThemeAttribute(android.R.attr.colorPrimary, outValue, true);
-        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, outValue.type);
-        assertNotEquals(0, outValue.data);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    @Test
-    public void testRectangleShadow() throws Exception {
-        renderAndVerify("shadows_test.xml", "shadows_test.png");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
deleted file mode 100644
index 34fc726..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ /dev/null
@@ -1,322 +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.android.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.resources.configuration.CountryCodeQualifier;
-import com.android.ide.common.resources.configuration.DensityQualifier;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
-import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
-import com.android.ide.common.resources.configuration.LocaleQualifier;
-import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
-import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
-import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
-import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
-import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
-import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
-import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
-import com.android.ide.common.resources.configuration.TouchScreenQualifier;
-import com.android.ide.common.resources.configuration.UiModeQualifier;
-import com.android.ide.common.resources.configuration.VersionQualifier;
-import com.android.resources.Density;
-import com.android.resources.Keyboard;
-import com.android.resources.KeyboardState;
-import com.android.resources.Navigation;
-import com.android.resources.NightMode;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRatio;
-import com.android.resources.ScreenSize;
-import com.android.resources.TouchScreen;
-import com.android.resources.UiMode;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-import com.google.android.collect.Maps;
-
-/**
- * Provides {@link FolderConfiguration} and {@link HardwareConfig} for various devices. Also
- * provides utility methods to parse build.prop and attrs.xml to generate the appropriate maps.
- */
-@SuppressWarnings("UnusedDeclaration") // For the pre-configured nexus generators.
-public class ConfigGenerator {
-
-    public static final ConfigGenerator NEXUS_4 = new ConfigGenerator();
-
-    public static final ConfigGenerator NEXUS_5 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1080)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1200)
-                                                        .setXdpi(323)
-                                                        .setYdpi(323)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_10 = new ConfigGenerator()
-                                                        .setScreenHeight(1600)
-                                                        .setScreenWidth(2560)
-                                                        .setXdpi(300)
-                                                        .setYdpi(300)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.XLARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_5_LAND = new ConfigGenerator()
-                                                        .setScreenHeight(1080)
-                                                        .setScreenWidth(1920)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7_2012 = new ConfigGenerator()
-                                                        .setScreenHeight(1280)
-                                                        .setScreenWidth(800)
-                                                        .setXdpi(195)
-                                                        .setYdpi(200)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.TV)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    private static final String TAG_ATTR = "attr";
-    private static final String TAG_ENUM = "enum";
-    private static final String TAG_FLAG = "flag";
-    private static final String ATTR_NAME = "name";
-    private static final String ATTR_VALUE = "value";
-
-    // Device Configuration. Defaults are for a Nexus 4 device.
-    private int mScreenHeight = 1280;
-    private int mScreenWidth = 768;
-    private int mXdpi = 320;
-    private int mYdpi = 320;
-    private ScreenOrientation mOrientation = ScreenOrientation.PORTRAIT;
-    private Density mDensity = Density.XHIGH;
-    private ScreenRatio mRatio = ScreenRatio.NOTLONG;
-    private ScreenSize mSize = ScreenSize.NORMAL;
-    private Keyboard mKeyboard = Keyboard.NOKEY;
-    private TouchScreen mTouchScreen = TouchScreen.FINGER;
-    private KeyboardState mKeyboardState = KeyboardState.SOFT;
-    private boolean mSoftButtons = true;
-    private Navigation mNavigation = Navigation.NONAV;
-
-    public FolderConfiguration getFolderConfig() {
-        FolderConfiguration config = new FolderConfiguration();
-        config.createDefault();
-        config.setDensityQualifier(new DensityQualifier(mDensity));
-        config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation));
-        if (mScreenWidth > mScreenHeight) {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth,
-                    mScreenHeight));
-        } else {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight,
-                    mScreenWidth));
-        }
-        config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio));
-        config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize));
-        config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard));
-        config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen));
-        config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState));
-        config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation));
-
-        config.updateScreenWidthAndHeight();
-
-        // some default qualifiers.
-        config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
-        config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
-        config.setCountryCodeQualifier(new CountryCodeQualifier());
-        config.setLayoutDirectionQualifier(new LayoutDirectionQualifier());
-        config.setNetworkCodeQualifier(new NetworkCodeQualifier());
-        config.setLocaleQualifier(new LocaleQualifier());
-        config.setVersionQualifier(new VersionQualifier());
-        return config;
-    }
-
-    public HardwareConfig getHardwareConfig() {
-        return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize,
-                mOrientation, null, mSoftButtons);
-    }
-
-    public static Map<String, String> loadProperties(File path) {
-        Properties p = new Properties();
-        Map<String, String> map = Maps.newHashMap();
-        try {
-            p.load(new FileInputStream(path));
-            for (String key : p.stringPropertyNames()) {
-                map.put(key, p.getProperty(key));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    public static Map<String, Map<String, Integer>> getEnumMap(File path) {
-        Map<String, Map<String, Integer>> map = Maps.newHashMap();
-        try {
-            XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
-            xmlPullParser.setInput(new FileInputStream(path), null);
-            int eventType = xmlPullParser.getEventType();
-            String attr = null;
-            while (eventType != XmlPullParser.END_DOCUMENT) {
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                    } else if (TAG_ENUM.equals(xmlPullParser.getName())
-                            || TAG_FLAG.equals(xmlPullParser.getName())) {
-                        String name = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                        String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE);
-                        // Integer.decode cannot handle "ffffffff", see JDK issue 6624867
-                        int i = (int) (long) Long.decode(value);
-                        assert attr != null;
-                        Map<String, Integer> attributeMap = map.get(attr);
-                        if (attributeMap == null) {
-                            attributeMap = Maps.newHashMap();
-                            map.put(attr, attributeMap);
-                        }
-                        attributeMap.put(name, i);
-                    }
-                } else if (eventType == XmlPullParser.END_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = null;
-                    }
-                }
-                eventType = xmlPullParser.next();
-            }
-        } catch (XmlPullParserException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    // Methods to set the configuration values.
-
-    public ConfigGenerator setScreenHeight(int height) {
-        mScreenHeight = height;
-        return this;
-    }
-
-    public ConfigGenerator setScreenWidth(int width) {
-        mScreenWidth = width;
-        return this;
-    }
-
-    public ConfigGenerator setXdpi(int xdpi) {
-        mXdpi = xdpi;
-        return this;
-    }
-
-    public ConfigGenerator setYdpi(int ydpi) {
-        mYdpi = ydpi;
-        return this;
-    }
-
-    public ConfigGenerator setOrientation(ScreenOrientation orientation) {
-        mOrientation = orientation;
-        return this;
-    }
-
-    public ConfigGenerator setDensity(Density density) {
-        mDensity = density;
-        return this;
-    }
-
-    public ConfigGenerator setRatio(ScreenRatio ratio) {
-        mRatio = ratio;
-        return this;
-    }
-
-    public ConfigGenerator setSize(ScreenSize size) {
-        mSize = size;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboard(Keyboard keyboard) {
-        mKeyboard = keyboard;
-        return this;
-    }
-
-    public ConfigGenerator setTouchScreen(TouchScreen touchScreen) {
-        mTouchScreen = touchScreen;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboardState(KeyboardState state) {
-        mKeyboardState = state;
-        return this;
-    }
-
-    public ConfigGenerator setSoftButtons(boolean softButtons) {
-        mSoftButtons = softButtons;
-        return this;
-    }
-
-    public ConfigGenerator setNavigation(Navigation navigation) {
-        mNavigation = navigation;
-        return this;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
deleted file mode 100644
index 8ebfc65..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ /dev/null
@@ -1,197 +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.android.layoutlib.bridge.intensive.setup;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ParserFactory;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.ide.common.resources.IntArrayWrapper;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.utils.ILogger;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-
-import static org.junit.Assert.fail;
-
-@SuppressWarnings("deprecation") // For Pair
-public class LayoutLibTestCallback extends LayoutlibCallback {
-
-    private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
-    private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
-
-    private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
-    private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
-    private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
-    private final ILogger mLog;
-    private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
-    private final ClassLoader mModuleClassLoader;
-
-    public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
-        mLog = logger;
-        mModuleClassLoader = classLoader;
-    }
-
-    public void initResources() throws ClassNotFoundException {
-        Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
-        Class<?>[] nestedClasses = rClass.getDeclaredClasses();
-        for (Class<?> resClass : nestedClasses) {
-            final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
-
-            if (resType != null) {
-                final Map<String, Integer> resName2Id = Maps.newHashMap();
-                mResources.put(resType, resName2Id);
-
-                for (Field field : resClass.getDeclaredFields()) {
-                    final int modifiers = field.getModifiers();
-                    if (Modifier.isStatic(modifiers)) { // May not be final in library projects
-                        final Class<?> type = field.getType();
-                        try {
-                            if (type.isArray() && type.getComponentType() == int.class) {
-                                mStyleableValueToNameMap.put(
-                                        new IntArrayWrapper((int[]) field.get(null)),
-                                        field.getName());
-                            } else if (type == int.class) {
-                                final Integer value = (Integer) field.get(null);
-                                mProjectResources.put(value, Pair.of(resType, field.getName()));
-                                resName2Id.put(field.getName(), value);
-                            } else {
-                                mLog.error(null, "Unknown field type in R class: %1$s", type);
-                            }
-                        } catch (IllegalAccessException ignored) {
-                            mLog.error(ignored, "Malformed R class: %1$s", PACKAGE_NAME + ".R");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
-            throws Exception {
-        Class<?> viewClass = mModuleClassLoader.loadClass(name);
-        Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
-        viewConstructor.setAccessible(true);
-        return viewConstructor.newInstance(constructorArgs);
-    }
-
-    @Override
-    public String getNamespace() {
-        return String.format(SdkConstants.NS_CUSTOM_RESOURCES_S,
-                PACKAGE_NAME);
-    }
-
-    @Override
-    public Pair<ResourceType, String> resolveResourceId(int id) {
-        return mProjectResources.get(id);
-    }
-
-    @Override
-    public String resolveResourceId(int[] id) {
-        return mStyleableValueToNameMap.get(new IntArrayWrapper(id));
-    }
-
-    @Override
-    public Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> resName2Id = mResources.get(type);
-        if (resName2Id == null) {
-            return null;
-        }
-        return resName2Id.get(name);
-    }
-
-    @Override
-    public ILayoutPullParser getParser(String layoutName) {
-        fail("This method shouldn't be called by this version of LayoutLib.");
-        return null;
-    }
-
-    @Override
-    public ILayoutPullParser getParser(ResourceValue layoutResource) {
-        return new LayoutPullParser(new File(layoutResource.getValue()));
-    }
-
-    @Override
-    public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
-            ResourceReference itemRef, int fullPosition, int positionPerType,
-            int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
-            ViewAttribute viewAttribute, Object defaultValue) {
-        return null;
-    }
-
-    @Override
-    public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
-            Object viewObject) {
-        return null;
-    }
-
-    @Override
-    public ActionBarCallback getActionBarCallback() {
-        return mActionBarCallback;
-    }
-
-    @Override
-    public boolean supports(int ideFeature) {
-        return false;
-    }
-
-    @NonNull
-    @Override
-    public ParserFactory getParserFactory() {
-        return new ParserFactory() {
-            @NonNull
-            @Override
-            public XmlPullParser createParser(@Nullable String debugName)
-                    throws XmlPullParserException {
-                return new KXmlParser();
-            }
-        };
-    }
-
-    @Override
-    public <T> T getFlag(Key<T> key) {
-        if (key.equals(RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE)) {
-            return (T) PACKAGE_NAME;
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
deleted file mode 100644
index bc8083f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
+++ /dev/null
@@ -1,111 +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.android.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOError;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.android.SdkConstants.ATTR_IGNORE;
-import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
-import static com.android.SdkConstants.GRID_VIEW;
-import static com.android.SdkConstants.LIST_VIEW;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TOOLS_URI;
-
-public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
-
-    /**
-     * @param layoutPath Must start with '/' and be relative to test resources.
-     */
-    public LayoutPullParser(String layoutPath) {
-        if (layoutPath.startsWith("/")) {
-            layoutPath = layoutPath.substring(1);
-        }
-        try {
-            init(getClass().getClassLoader().getResourceAsStream(layoutPath));
-        } catch (XmlPullParserException e) {
-            throw new IOError(e);
-        }
-    }
-
-    /**
-     * @param layoutFile Path of the layout xml file on disk.
-     */
-    public LayoutPullParser(File layoutFile) {
-        try {
-            init(new FileInputStream(layoutFile));
-        } catch (XmlPullParserException | FileNotFoundException e) {
-            throw new IOError(e);
-        }
-    }
-
-    private void init(InputStream stream) throws XmlPullParserException {
-        setFeature(FEATURE_PROCESS_NAMESPACES, true);
-        setInput(stream, null);
-    }
-
-    @Override
-    public Object getViewCookie() {
-        // TODO: Implement this properly.
-        String name = super.getName();
-        if (name == null) {
-            return null;
-        }
-
-        // Store tools attributes if this looks like a layout we'll need adapter view
-        // bindings for in the LayoutlibCallback.
-        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
-            Map<String, String> map = null;
-            int count = getAttributeCount();
-            for (int i = 0; i < count; i++) {
-                String namespace = getAttributeNamespace(i);
-                if (namespace != null && namespace.equals(TOOLS_URI)) {
-                    String attribute = getAttributeName(i);
-                    if (attribute.equals(ATTR_IGNORE)) {
-                        continue;
-                    }
-                    if (map == null) {
-                        map = new HashMap<String, String>(4);
-                    }
-                    map.put(attribute, getAttributeValue(i));
-                }
-            }
-
-            return map;
-        }
-
-        return null;
-    }
-
-    @Override
-    @Deprecated
-    public ILayoutPullParser getParser(String layoutName) {
-        // Studio returns null.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
deleted file mode 100644
index cdf5633..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
+++ /dev/null
@@ -1,341 +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.layoutlib.bridge.intensive.util;
-
-import android.annotation.NonNull;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-import static java.awt.RenderingHints.*;
-import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
-import static java.io.File.separatorChar;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-
-// Adapted by taking the relevant pieces of code from the following classes:
-//
-// com.android.tools.idea.rendering.ImageUtils,
-// com.android.tools.idea.tests.gui.framework.fixture.layout.ImageFixture and
-// com.android.tools.idea.rendering.RenderTestBase
-/**
- * Utilities related to image processing.
- */
-public class ImageUtils {
-    /**
-     * Normally, this test will fail when there is a missing thumbnail. However, when
-     * you create creating a new test, it's useful to be able to turn this off such that
-     * you can generate all the missing thumbnails in one go, rather than having to run
-     * the test repeatedly to get to each new render assertion generating its thumbnail.
-     */
-    private static final boolean FAIL_ON_MISSING_THUMBNAIL = true;
-
-    private static final int THUMBNAIL_SIZE = 1000;
-
-    private static final double MAX_PERCENT_DIFFERENCE = 0.3;
-
-    public static void requireSimilar(@NonNull String relativePath, @NonNull BufferedImage image)
-            throws IOException {
-        int maxDimension = Math.max(image.getWidth(), image.getHeight());
-        double scale = THUMBNAIL_SIZE / (double)maxDimension;
-        BufferedImage thumbnail = scale(image, scale, scale);
-
-        InputStream is = ImageUtils.class.getClassLoader().getResourceAsStream(relativePath);
-        if (is == null) {
-            String message = "Unable to load golden thumbnail: " + relativePath + "\n";
-            message = saveImageAndAppendMessage(thumbnail, message, relativePath);
-            if (FAIL_ON_MISSING_THUMBNAIL) {
-                fail(message);
-            } else {
-                System.out.println(message);
-            }
-        }
-        else {
-            try {
-                BufferedImage goldenImage = ImageIO.read(is);
-                assertImageSimilar(relativePath, goldenImage, thumbnail, MAX_PERCENT_DIFFERENCE);
-            } finally {
-                is.close();
-            }
-        }
-    }
-
-    public static void assertImageSimilar(String relativePath, BufferedImage goldenImage,
-            BufferedImage image, double maxPercentDifferent) throws IOException {
-        assertEquals("Only TYPE_INT_ARGB image types are supported",  TYPE_INT_ARGB, image.getType());
-
-        if (goldenImage.getType() != TYPE_INT_ARGB) {
-            BufferedImage temp = new BufferedImage(goldenImage.getWidth(), goldenImage.getHeight(),
-                    TYPE_INT_ARGB);
-            temp.getGraphics().drawImage(goldenImage, 0, 0, null);
-            goldenImage = temp;
-        }
-        assertEquals(TYPE_INT_ARGB, goldenImage.getType());
-
-        int imageWidth = Math.min(goldenImage.getWidth(), image.getWidth());
-        int imageHeight = Math.min(goldenImage.getHeight(), image.getHeight());
-
-        // Blur the images to account for the scenarios where there are pixel
-        // differences
-        // in where a sharp edge occurs
-        // goldenImage = blur(goldenImage, 6);
-        // image = blur(image, 6);
-
-        int width = 3 * imageWidth;
-        @SuppressWarnings("UnnecessaryLocalVariable")
-        int height = imageHeight; // makes code more readable
-        BufferedImage deltaImage = new BufferedImage(width, height, TYPE_INT_ARGB);
-        Graphics g = deltaImage.getGraphics();
-
-        // Compute delta map
-        long delta = 0;
-        for (int y = 0; y < imageHeight; y++) {
-            for (int x = 0; x < imageWidth; x++) {
-                int goldenRgb = goldenImage.getRGB(x, y);
-                int rgb = image.getRGB(x, y);
-                if (goldenRgb == rgb) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                // If the pixels have no opacity, don't delta colors at all
-                if (((goldenRgb & 0xFF000000) == 0) && (rgb & 0xFF000000) == 0) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                int deltaR = ((rgb & 0xFF0000) >>> 16) - ((goldenRgb & 0xFF0000) >>> 16);
-                int newR = 128 + deltaR & 0xFF;
-                int deltaG = ((rgb & 0x00FF00) >>> 8) - ((goldenRgb & 0x00FF00) >>> 8);
-                int newG = 128 + deltaG & 0xFF;
-                int deltaB = (rgb & 0x0000FF) - (goldenRgb & 0x0000FF);
-                int newB = 128 + deltaB & 0xFF;
-
-                int avgAlpha = ((((goldenRgb & 0xFF000000) >>> 24)
-                        + ((rgb & 0xFF000000) >>> 24)) / 2) << 24;
-
-                int newRGB = avgAlpha | newR << 16 | newG << 8 | newB;
-                deltaImage.setRGB(imageWidth + x, y, newRGB);
-
-                delta += Math.abs(deltaR);
-                delta += Math.abs(deltaG);
-                delta += Math.abs(deltaB);
-            }
-        }
-
-        // 3 different colors, 256 color levels
-        long total = imageHeight * imageWidth * 3L * 256L;
-        float percentDifference = (float) (delta * 100 / (double) total);
-
-        String error = null;
-        String imageName = getName(relativePath);
-        if (percentDifference > maxPercentDifferent) {
-            error = String.format("Images differ (by %.1f%%)", percentDifference);
-        } else if (Math.abs(goldenImage.getWidth() - image.getWidth()) >= 2) {
-            error = "Widths differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        } else if (Math.abs(goldenImage.getHeight() - image.getHeight()) >= 2) {
-            error = "Heights differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        }
-
-        assertEquals(TYPE_INT_ARGB, image.getType());
-        if (error != null) {
-            // Expected on the left
-            // Golden on the right
-            g.drawImage(goldenImage, 0, 0, null);
-            g.drawImage(image, 2 * imageWidth, 0, null);
-
-            // Labels
-            if (imageWidth > 80) {
-                g.setColor(Color.RED);
-                g.drawString("Expected", 10, 20);
-                g.drawString("Actual", 2 * imageWidth + 10, 20);
-            }
-
-            File output = new File(getFailureDir(), "delta-" + imageName);
-            if (output.exists()) {
-                boolean deleted = output.delete();
-                assertTrue(deleted);
-            }
-            ImageIO.write(deltaImage, "PNG", output);
-            error += " - see details in " + output.getPath() + "\n";
-            error = saveImageAndAppendMessage(image, error, relativePath);
-            System.out.println(error);
-            fail(error);
-        }
-
-        g.dispose();
-    }
-
-    /**
-     * Resize the given image
-     *
-     * @param source the image to be scaled
-     * @param xScale x scale
-     * @param yScale y scale
-     * @return the scaled image
-     */
-    @NonNull
-    public static BufferedImage scale(@NonNull BufferedImage source, double xScale, double yScale) {
-
-        int sourceWidth = source.getWidth();
-        int sourceHeight = source.getHeight();
-        int destWidth = Math.max(1, (int) (xScale * sourceWidth));
-        int destHeight = Math.max(1, (int) (yScale * sourceHeight));
-        int imageType = source.getType();
-        if (imageType == BufferedImage.TYPE_CUSTOM) {
-            imageType = BufferedImage.TYPE_INT_ARGB;
-        }
-        if (xScale > 0.5 && yScale > 0.5) {
-            BufferedImage scaled =
-                    new BufferedImage(destWidth, destHeight, imageType);
-            Graphics2D g2 = scaled.createGraphics();
-            g2.setComposite(AlphaComposite.Src);
-            g2.setColor(new Color(0, true));
-            g2.fillRect(0, 0, destWidth, destHeight);
-            if (xScale == 1 && yScale == 1) {
-                g2.drawImage(source, 0, 0, null);
-            } else {
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, destWidth, destHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-            }
-            g2.dispose();
-            return scaled;
-        } else {
-            // When creating a thumbnail, using the above code doesn't work very well;
-            // you get some visible artifacts, especially for text. Instead use the
-            // technique of repeatedly scaling the image into half; this will cause
-            // proper averaging of neighboring pixels, and will typically (for the kinds
-            // of screen sizes used by this utility method in the layout editor) take
-            // about 3-4 iterations to get the result since we are logarithmically reducing
-            // the size. Besides, each successive pass in operating on much fewer pixels
-            // (a reduction of 4 in each pass).
-            //
-            // However, we may not be resizing to a size that can be reached exactly by
-            // successively diving in half. Therefore, once we're within a factor of 2 of
-            // the final size, we can do a resize to the exact target size.
-            // However, we can get even better results if we perform this final resize
-            // up front. Let's say we're going from width 1000 to a destination width of 85.
-            // The first approach would cause a resize from 1000 to 500 to 250 to 125, and
-            // then a resize from 125 to 85. That last resize can distort/blur a lot.
-            // Instead, we can start with the destination width, 85, and double it
-            // successfully until we're close to the initial size: 85, then 170,
-            // then 340, and finally 680. (The next one, 1360, is larger than 1000).
-            // So, now we *start* the thumbnail operation by resizing from width 1000 to
-            // width 680, which will preserve a lot of visual details such as text.
-            // Then we can successively resize the image in half, 680 to 340 to 170 to 85.
-            // We end up with the expected final size, but we've been doing an exact
-            // divide-in-half resizing operation at the end so there is less distortion.
-
-            int iterations = 0; // Number of halving operations to perform after the initial resize
-            int nearestWidth = destWidth; // Width closest to source width that = 2^x, x is integer
-            int nearestHeight = destHeight;
-            while (nearestWidth < sourceWidth / 2) {
-                nearestWidth *= 2;
-                nearestHeight *= 2;
-                iterations++;
-            }
-
-            BufferedImage scaled = new BufferedImage(nearestWidth, nearestHeight, imageType);
-
-            Graphics2D g2 = scaled.createGraphics();
-            setRenderingHints(g2);
-            g2.drawImage(source, 0, 0, nearestWidth, nearestHeight, 0, 0, sourceWidth, sourceHeight,
-                    null);
-            g2.dispose();
-
-            sourceWidth = nearestWidth;
-            sourceHeight = nearestHeight;
-            source = scaled;
-
-            for (int iteration = iterations - 1; iteration >= 0; iteration--) {
-                int halfWidth = sourceWidth / 2;
-                int halfHeight = sourceHeight / 2;
-                scaled = new BufferedImage(halfWidth, halfHeight, imageType);
-                g2 = scaled.createGraphics();
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, halfWidth, halfHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-                g2.dispose();
-
-                sourceWidth = halfWidth;
-                sourceHeight = halfHeight;
-                source = scaled;
-                iterations--;
-            }
-            return scaled;
-        }
-    }
-
-    private static void setRenderingHints(@NonNull Graphics2D g2) {
-        g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
-        g2.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY);
-        g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
-    }
-
-    /**
-     * Directory where to write the thumbnails and deltas.
-     */
-    @NonNull
-    private static File getFailureDir() {
-        String workingDirString = System.getProperty("user.dir");
-        File failureDir = new File(workingDirString, "out/failures");
-
-        //noinspection ResultOfMethodCallIgnored
-        failureDir.mkdirs();
-        return failureDir; //$NON-NLS-1$
-    }
-
-    /**
-     * Saves the generated thumbnail image and appends the info message to an initial message
-     */
-    @NonNull
-    private static String saveImageAndAppendMessage(@NonNull BufferedImage image,
-            @NonNull String initialMessage, @NonNull String relativePath) throws IOException {
-        File output = new File(getFailureDir(), getName(relativePath));
-        if (output.exists()) {
-            boolean deleted = output.delete();
-            assertTrue(deleted);
-        }
-        ImageIO.write(image, "PNG", output);
-        initialMessage += "Thumbnail for current rendering stored at " + output.getPath();
-//        initialMessage += "\nRun the following command to accept the changes:\n";
-//        initialMessage += String.format("mv %1$s %2$s", output.getPath(),
-//                ImageUtils.class.getResource(relativePath).getPath());
-        // The above has been commented out, since the destination path returned is in out dir
-        // and it makes the tests pass without the code being actually checked in.
-        return initialMessage;
-    }
-
-    private static String getName(@NonNull String relativePath) {
-        return relativePath.substring(relativePath.lastIndexOf(separatorChar) + 1);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
deleted file mode 100644
index da360f3..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
+++ /dev/null
@@ -1,62 +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.layoutlib.bridge.intensive.util;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import libcore.io.Streams;
-
-/**
- * Module class loader that loads classes from the test project.
- */
-public class ModuleClassLoader extends ClassLoader {
-    private final Map<String, Class<?>> mClasses = new HashMap<>();
-    private String myModuleRoot;
-
-    /**
-     * @param moduleRoot The path to the module root
-     * @param parent The parent class loader
-     */
-    public ModuleClassLoader(String moduleRoot, ClassLoader parent) {
-        super(parent);
-        myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/");
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        try {
-            return super.findClass(name);
-        } catch (ClassNotFoundException ignored) {
-        }
-
-        Class<?> clazz = mClasses.get(name);
-        if (clazz == null) {
-            String path = name.replace('.', '/').concat(".class");
-            try {
-                byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path));
-                clazz = defineClass(name, b, 0, b.length);
-                mClasses.put(name, clazz);
-            } catch (IOException ignore) {
-                throw new ClassNotFoundException(name + " not found");
-            }
-        }
-
-        return clazz;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
deleted file mode 100644
index 0856ac9..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
+++ /dev/null
@@ -1,54 +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.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * {@link AssetRepository} used for render tests.
- */
-public class TestAssetRepository extends AssetRepository {
-    private static InputStream open(String path) throws FileNotFoundException {
-        File asset = new File(path);
-        if (asset.isFile()) {
-            return new FileInputStream(asset);
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public InputStream openAsset(String path, int mode) throws IOException {
-        return open(path);
-    }
-
-    @Override
-    public InputStream openNonAsset(int cookie, String path, int mode) throws IOException {
-        return open(path);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
deleted file mode 100644
index 1df8e79..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
+++ /dev/null
@@ -1,36 +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.layoutlib.bridge.intensive.util;
-
-import java.lang.ref.WeakReference;
-
-public class TestUtils {
-    public static void gc() {
-        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
-        Object obj = new Object();
-        WeakReference ref = new WeakReference<>(obj);
-        //noinspection UnusedAssignment
-        obj = null;
-        while (ref.get() != null) {
-            System.gc();
-            System.runFinalization();
-        }
-
-        System.gc();
-        System.runFinalization();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
deleted file mode 100644
index ee98b4b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
+++ /dev/null
@@ -1,97 +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.layoutlib.bridge.intensive.util.perf;
-
-import android.annotation.NonNull;
-import android.util.LongArray;
-
-import java.util.Arrays;
-import java.util.function.LongConsumer;
-
-/**
- * Class that collect a series of longs and produces the median, min and max values.
- */
-public class LongStatsCollector implements LongConsumer {
-    private final LongArray mAllValues;
-    private long mMin = Long.MAX_VALUE;
-    private long mMax = Long.MIN_VALUE;
-    public LongStatsCollector(int estimatedRuns) {
-        mAllValues = new LongArray(estimatedRuns);
-    }
-
-    public int size() {
-        return mAllValues.size();
-    }
-
-    @NonNull
-    public Stats getStats() {
-        if (mAllValues.size() == 0) {
-            throw new IndexOutOfBoundsException("No data");
-        }
-
-        double median;
-        int size = mAllValues.size();
-        long[] buffer = new long[size];
-        for (int i = 0; i < size; i++) {
-            buffer[i] = mAllValues.get(i);
-        }
-
-        Arrays.sort(buffer);
-
-        int midPoint = size / 2;
-        median = (size % 2 == 0) ? (buffer[midPoint - 1] + buffer[midPoint]) / 2 : buffer[midPoint];
-
-        return new Stats(mAllValues.size(), mMin, mMax, median);
-    }
-
-    @Override
-    public void accept(long value) {
-        mMin = Math.min(mMin, value);
-        mMax = Math.max(mMax, value);
-        mAllValues.add(value);
-    }
-
-    public static class Stats {
-        private final int mSamples;
-        private final long mMin;
-        private final long mMax;
-        private final double mMedian;
-
-        private Stats(int samples, long min, long max, double median) {
-            mSamples = samples;
-            mMin = min;
-            mMax = max;
-            mMedian = median;
-        }
-
-        public int getSampleCount() {
-            return mSamples;
-        }
-
-        public long getMin() {
-            return mMin;
-        }
-
-        public long getMax() {
-            return mMax;
-        }
-
-        public double getMedian() {
-            return mMedian;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
deleted file mode 100644
index 7225a10..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
+++ /dev/null
@@ -1,80 +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.layoutlib.bridge.intensive.util.perf;
-
-import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * JUnit {@link Runner} that times the test execution and produces some stats.
- */
-public class PerformanceRunner extends BlockJUnit4ClassRunner {
-    private static final int DEFAULT_WARMUP_ITERATIONS = 50;
-    private static final int DEFAULT_RUNS = 100;
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-
-    public PerformanceRunner(Class<?> testClass) throws InitializationError {
-        super(testClass);
-
-        Configuration classConfig = testClass.getAnnotation(Configuration.class);
-        mWarmUpIterations = classConfig != null && classConfig.warmUpIterations() != -1 ?
-                classConfig.warmUpIterations() :
-                DEFAULT_WARMUP_ITERATIONS;
-        mRuns = classConfig != null && classConfig.runs() != -1 ?
-                classConfig.runs() :
-                DEFAULT_RUNS;
-    }
-
-    @Override
-    protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        int warmUpIterations;
-        int runs;
-
-        Configuration methodConfig = method.getAnnotation(Configuration.class);
-        warmUpIterations = methodConfig != null && methodConfig.warmUpIterations() != -1 ?
-                methodConfig.warmUpIterations() :
-                mWarmUpIterations;
-        runs = methodConfig != null && methodConfig.runs() != -1 ?
-                methodConfig.runs() :
-                mRuns;
-        return new TimedStatement(super.methodInvoker(method, test), warmUpIterations, runs,
-                (result) -> System.out.println(result.toString()));
-    }
-
-    @Override
-    public void run(RunNotifier notifier) {
-        super.run(notifier);
-    }
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Inherited
-    public @interface Configuration {
-        int warmUpIterations() default -1;
-
-        int runs() default -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
deleted file mode 100644
index 77a2b0e..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
+++ /dev/null
@@ -1,178 +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.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-
-import org.junit.runners.model.Statement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-/**
- * JUnit {@link Statement} used to measure some statistics about the test method.
- */
-public class TimedStatement extends Statement {
-    private static final int CALIBRATION_WARMUP_ITERATIONS = 50;
-    private static final int CALIBRATION_RUNS = 100;
-
-    private static boolean sIsCalibrated;
-    private static double sCalibrated;
-
-    private final Statement mStatement;
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final Runtime mRuntime = Runtime.getRuntime();
-    private final Consumer<TimedStatementResult> mCallback;
-
-    TimedStatement(Statement statement, int warmUpIterations, int runs,
-            Consumer<TimedStatementResult> finishedCallback) {
-        mStatement = statement;
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCallback = finishedCallback;
-    }
-
-    /**
-     * The calibrate method tries to do some work that involves IO, memory allocations and some
-     * operations on the randomly generated data to calibrate the speed of the machine with
-     * something that resembles the execution of a test case.
-     */
-    private static void calibrateMethod() throws IOException {
-        File tmpFile = File.createTempFile("test", "file");
-        Random rnd = new Random();
-        HashFunction hashFunction = Hashing.sha512();
-        for (int i = 0; i < 5 + rnd.nextInt(5); i++) {
-            FileOutputStream stream = new FileOutputStream(tmpFile);
-            int bytes = 30000 + rnd.nextInt(60000);
-            byte[] buffer = new byte[bytes];
-
-            rnd.nextBytes(buffer);
-            byte acc = 0;
-            for (int j = 0; j < bytes; j++) {
-                acc += buffer[i];
-            }
-            buffer[0] = acc;
-            stream.write(buffer);
-            System.gc();
-            stream.close();
-            FileInputStream input = new FileInputStream(tmpFile);
-            byte[] readBuffer = new byte[bytes];
-            //noinspection ResultOfMethodCallIgnored
-            input.read(readBuffer);
-            buffer = readBuffer;
-            HashCode code1 = hashFunction.hashBytes(buffer);
-            Arrays.sort(buffer);
-            HashCode code2 = hashFunction.hashBytes(buffer);
-            input.close();
-
-            FileOutputStream hashStream = new FileOutputStream(tmpFile);
-            hashStream.write(code1.asBytes());
-            hashStream.write(code2.asBytes());
-            hashStream.close();
-        }
-    }
-
-    /**
-     * Runs the calibration process and sets the calibration measure in {@link #sCalibrated}
-     */
-    private static void doCalibration() throws IOException {
-        System.out.println("Calibrating ...");
-        TestUtils.gc();
-        for (int i = 0; i < CALIBRATION_WARMUP_ITERATIONS; i++) {
-            calibrateMethod();
-        }
-
-        LongStatsCollector stats = new LongStatsCollector(CALIBRATION_RUNS);
-        for (int i = 0; i < CALIBRATION_RUNS; i++) {
-            TestUtils.gc();
-            long start = System.currentTimeMillis();
-            calibrateMethod();
-            stats.accept(System.currentTimeMillis() - start);
-        }
-
-        sCalibrated = stats.getStats().getMedian();
-        sIsCalibrated = true;
-        System.out.printf("  DONE %fms\n", sCalibrated);
-    }
-
-    private long getUsedMemory() {
-        return mRuntime.totalMemory() - mRuntime.freeMemory();
-    }
-
-
-    @Override
-    public void evaluate() throws Throwable {
-        if (!sIsCalibrated) {
-            doCalibration();
-        }
-
-        for (int i = 0; i < mWarmUpIterations; i++) {
-            mStatement.evaluate();
-        }
-
-        LongStatsCollector timeStats = new LongStatsCollector(mRuns);
-        LongStatsCollector memoryUseStats = new LongStatsCollector(mRuns);
-        AtomicBoolean collectSamples = new AtomicBoolean(false);
-
-        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
-        TestUtils.gc();
-        executorService.scheduleAtFixedRate(() -> {
-            if (!collectSamples.get()) {
-                return;
-            }
-            memoryUseStats.accept(getUsedMemory());
-        }, 0, 200, TimeUnit.MILLISECONDS);
-
-        try {
-            for (int i = 0; i < mRuns; i++) {
-                TestUtils.gc();
-                collectSamples.set(true);
-                long startTimeMs = System.currentTimeMillis();
-                mStatement.evaluate();
-                long stopTimeMs = System.currentTimeMillis();
-                collectSamples.set(true);
-                timeStats.accept(stopTimeMs - startTimeMs);
-
-            }
-        } finally {
-            executorService.shutdownNow();
-        }
-
-        TimedStatementResult result = new TimedStatementResult(
-                mWarmUpIterations,
-                mRuns,
-                sCalibrated,
-                timeStats.getStats(),
-                memoryUseStats.getStats());
-        mCallback.accept(result);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
deleted file mode 100644
index 59f90d2..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
+++ /dev/null
@@ -1,64 +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.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.perf.LongStatsCollector.Stats;
-
-import java.text.DecimalFormat;
-
-/**
- * Result value of a {@link TimedStatement}
- */
-public class TimedStatementResult {
-    private static final DecimalFormat UNITS_FORMAT = new DecimalFormat("#.##");
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final double mCalibrationTimeMs;
-    private final Stats mTimeStats;
-    private final Stats mMemoryStats;
-
-    TimedStatementResult(int warmUpIterations, int runs,
-            double calibrationTimeMs,
-            Stats timeStats,
-            Stats memoryStats) {
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCalibrationTimeMs = calibrationTimeMs;
-        mTimeStats = timeStats;
-        mMemoryStats = memoryStats;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "Warm up %d. Runs %d\n" + "Time:             %s ms (min: %s, max %s)\n" +
-                        "Calibration Time: %f ms\n" +
-                        "Calibrated Time:  %s units (min: %s, max %s)\n" +
-                        "Sampled %d times\n" +
-                        "   Memory used:  %d bytes (max %d)\n\n",
-                mWarmUpIterations, mRuns,
-                mTimeStats.getMedian(), mTimeStats.getMin(), mTimeStats.getMax(),
-                mCalibrationTimeMs,
-                UNITS_FORMAT.format((mTimeStats.getMedian() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMin() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMax() / mCalibrationTimeMs) * 100000),
-                mMemoryStats.getSampleCount(),
-                (long)mMemoryStats.getMedian() - mMemoryStats.getMin(),
-                mMemoryStats.getMax() - mMemoryStats.getMin());
-    }
-}
diff --git a/tools/layoutlib/bridge/update_nav_icons.sh b/tools/layoutlib/bridge/update_nav_icons.sh
deleted file mode 100755
index 7030d19..0000000
--- a/tools/layoutlib/bridge/update_nav_icons.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-# copies the navigation bar icons from system ui code to layoutlib.
-# to run, simply execute the script. (if not using bash, cd to the dir
-# containing this script and then run by ./update_nav_icons.sh)
-
-# Try to get the location of this script.
-if [ -n $BASH ]; then
-  # see http://stackoverflow.com/a/246128/1546000
-  MY_LOCATION=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-  cd $MY_LOCATION
-else
-  # Let's assume script was run from the same dir.
-  MY_LOCATION=$(pwd)
-fi
-
-# Check mac or linux to get sed argument to enable extended regex.
-case $(uname -s) in
-  Darwin)
-    EXT_REGEX="-E"
-    ;;
-  *)
-    EXT_REGEX="-r"
-    ;;
-esac
-
-
-FB="frameworks/base"
-# frameworks/base relative to current location
-FB=$(echo $MY_LOCATION | sed $EXT_REGEX -e "s,.*$FB[^/]*/,," -e "s,[^/]+,..,g")
-CURRENT_API=21  # update only if icons change from this api version.
-DENSITIES="ldpi mdpi hdpi xhdpi xxhdpi"
-ICONS="ic_sysbar_back.png ic_sysbar_home.png ic_sysbar_recent.png"
-BARS="./resources/bars/"
-
-for icon in $ICONS
-do
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/$density/"
-    mkdir -p "$destination"  # create if not present.
-    cp -v "$FB/packages/SystemUI/res/drawable-$density/$icon" "$destination"
-  done
-
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/ldrtl-$density/"
-    mkdir -p "$destination"
-    cp -v "$FB/packages/SystemUI/res/drawable-ldrtl-$density/$icon" "$destination"
-    done
-done
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
deleted file mode 100644
index 25c3b3e..0000000
--- a/tools/layoutlib/create/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry excluding="mock_data/" kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/asm/asm-4.0.jar" sourcepath="/ANDROID_PLAT_SRC/prebuilts/misc/common/asm/src.zip"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/create/.project b/tools/layoutlib/create/.project
deleted file mode 100644
index e100d17..0000000
--- a/tools/layoutlib/create/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_create</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/create/.settings/README.txt b/tools/layoutlib/create/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/create/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
deleted file mode 100644
index 7611cde..0000000
--- a/tools/layoutlib/create/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 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)
-
-LOCAL_JAR_MANIFEST := manifest.txt
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	asm-5.2
-
-LOCAL_MODULE := layoutlib_create
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
deleted file mode 100644
index 727b194..0000000
--- a/tools/layoutlib/create/README.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-
-
-- Description -
----------------
-
-Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor to perform
-layout.
-
-
-- Usage -
----------
-
- ./layoutlib_create destination.jar path/to/android1.jar path/to/android2.jar
-
-
-- Design Overview -
--------------------
-
-Layoutlib_create uses a few jars from the framework containing the Java code used by Android as
-generated by the Android build, right before the classes are converted to a DEX format.
-
-These jars can't be used directly in Eclipse as:
-- they contains references to native code (which we want to avoid in Eclipse),
-- some classes need to be overridden, for example all the drawing code that is replaced by Java 2D
-  calls in Eclipse.
-- some of the classes that need to be changed are final and/or we need access to their private
-  internal state.
-
-Consequently this tool:
-- parses the input JAR,
-- modifies some of the classes directly using some bytecode manipulation,
-- filters some packages and removes those we don't want in the output JAR,
-- injects some new classes,
-- generates a modified JAR file that is suitable for the Android plugin for Eclipse to perform
-  rendering.
-
-The ASM library is used to do the bytecode modification using its visitor pattern API.
-
-The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the configuration
-is done in the main() method and the CreateInfo structure is expected to change with the Android
-platform as new classes are added, changed or removed. Some configuration that may be platform
-dependent is also present elsewhere in code.
-
-The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the platform, that
-provides all the necessary missing implementation for rendering graphics in Eclipse.
-
-
-
-- Implementation Notes -
-------------------------
-
-The tool works in two phases:
-- first analyze the input jar (AsmAnalyzer class)
-- then generate the output jar (AsmGenerator class),
-
-
-- Analyzer
-----------
-
-The goal of the analyzer is to create a graph of all the classes from the input JAR with their
-dependencies and then only keep the ones we want.
-
-To do that, the analyzer is created with a list of base classes to keep -- everything that derives
-from these is kept. Currently the one such class is android.view.View: since we want to render
-layouts, anything that is sort of a view needs to be kept.
-
-The analyzer is also given a list of class names to keep in the output. This is done using
-shell-like glob patterns that filter on the fully-qualified class names, for example "android.*.R**"
-("*" does not matches dots whilst "**" does, and "." and "$" are interpreted as-is). In practice we
-almost but not quite request the inclusion of full packages.
-
-The analyzer is also given a list of classes to exclude. A fake implementation of these classes is
-injected by the Generator.
-
-With this information, the analyzer parses the input zip to find all the classes. All classes
-deriving from the requested bases classes are kept. All classes whose name match the glob pattern
-are kept. The analysis then finds all the dependencies of the classes that are to be kept using an
-ASM visitor on the class, the field types, the method types and annotations types. Classes that
-belong to the current JRE are excluded.
-
-The output of the analyzer is a set of ASM ClassReader instances which are then fed to the
-generator.
-
-
-- Generator
------------
-
-The generator is constructed from a CreateInfo struct that acts as a config file and lists:
-- the classes to inject in the output JAR -- these classes are directly implemented in
-  layoutlib_create and will be used to interface with the renderer in Eclipse.
-- specific methods to override (see method stubs details below).
-- specific methods for which to delegate calls.
-- specific methods to remove based on their return type.
-- specific classes to rename.
-- specific classes to refactor.
-
-Each of these are specific strategies we use to be able to modify the Android code to fit within the
-Eclipse renderer. These strategies are explained below.
-
-The core method of the generator is transform(): it takes an input ASM ClassReader and modifies it
-to produce a byte array suitable for the final JAR file.
-
-The first step of the transformation is to implement the method delegates.
-
-The TransformClassAdapter is then used to process the potentially renamed class.  All protected or
-private classes are market as public. All classes are made non-final. Interfaces are left as-is.
-
-If a method has a return type that must be erased, the whole method is skipped.  Methods are also
-changed from protected/private to public. The code of the methods is then kept as-is, except for
-native methods which are replaced by a stub. Methods that are to be overridden are also replaced by
-a stub.
-
-Finally fields are also visited and changed from protected/private to public.
-
-The next step of the transformation is changing the name of the class in case we requested the class
-to be renamed. This uses the RenameClassAdapter to also rename all inner classes and references in
-methods and types. Note that other classes are not transformed and keep referencing the original
-name.
-
-The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but updates the
-references in all classes. This is used to update the references of classes in the java package that
-were added in the Dalvik VM but are not a part of the Desktop VM. The existing classes are
-modified to update all references to these non-desktop classes. An alternate implementation of
-these (com.android.tools.layoutlib.java.*) is injected.
-
-RenameClassAdapter and RefactorClassAdapter both inherit from AbstractClassAdapter which changes the
-class version (version of the JDK used to compile the class) to 50 (corresponding to Java 6), if the
-class was originally compiled with Java 7 (version 51). This is because we don't currently generate
-the StackMapTable correctly and Java 7 VM enforces that classes with version greater than 51 have
-valid StackMapTable. As a side benefit of this, we can continue to support Java 6 because Java 7 on
-Mac has horrible font rendering support.
-
-ReplaceMethodCallsAdapter replaces calls to certain methods. This is different from the
-DelegateMethodAdapter since it doesn't preserve the original copy of the method and more importantly
-changes the calls to a method in each class instead of changing the implementation of the method.
-This is useful for methods in the Java namespace where we cannot add delegates. The configuration
-for this is not done through the CreateInfo class, but done in the ReplaceMethodAdapter.
-
-The ClassAdapters are chained together to achieve the desired output. (Look at section 2.2.7
-Transformation chains in the asm user guide, link in the References.) The order of execution of
-these is:
-ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
-RefactorClassAdapter -> [ReplaceMethodCallsAdapter] -> ClassWriter
-
-- Method stubs
---------------
-
-As indicated above, all native and overridden methods are replaced by a stub.  We don't have the
-code to replace with in layoutlib_create. Instead the StubMethodAdapter replaces the code of the
-method by a call to OverrideMethod.invokeX(). When using the final JAR, the bridge can register
-listeners from these overridden method calls based on the method signatures.
-
-The listeners are currently pretty basic: we only pass the signature of the method being called, its
-caller object and a flag indicating whether the method was native. We do not currently provide the
-parameters. The listener can however specify the return value of the overridden method.
-
-This strategy is now obsolete and replaced by the method delegates.
-
-
-- Strategies
-------------
-
-We currently have 6 strategies to deal with overriding the rendering code and make it run in
-Eclipse. Most of these strategies are implemented hand-in-hand by the bridge (which runs in Eclipse)
-and the generator.
-
-
-1- Class Injection
-
-This is the easiest: we currently inject the following classes:
-- OverrideMethod and its associated MethodListener and MethodAdapter are used to intercept calls to
-  some specific methods that are stubbed out and change their return value.
-- CreateInfo class, which configured the generator. Not used yet, but could in theory help us track
-  what the generator changed.
-- AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new classes are
-  injected. The implementation for these classes has been taken from Android's libcore
-  (platform/libcore/luni/src/main/java/java/...).
-- Charsets, IntegralToString and UnsafeByteSequence are not part of the Desktop VM. They are
-  added to the Dalvik VM for performance reasons. An implementation that is very close to the
-  original (which is at platform/libcore/luni/src/main/java/...) is injected. Since these classees
-  were in part of the java package, where we can't inject classes, all references to these have been
-  updated (See strategy 4- Refactoring Classes).
-
-
-2- Overriding methods
-
-As explained earlier, the creator doesn't have any replacement code for methods to override. Instead
-it removes the original code and replaces it by a call to a specific OveriddeMethod.invokeX(). The
-bridge then registers a listener on the method signature and can provide an implementation.
-
-This strategy is now obsolete and replaced by the method delegates (See strategy 6- Method
-Delegates).
-
-
-3- Renaming classes
-
-This simply changes the name of a class in its definition, as well as all its references in internal
-inner classes and methods. Calls from other classes are not modified -- they keep referencing the
-original class name. This allows the bridge to literally replace an implementation.
-
-An example will make this easier: android.graphics.Paint is the main drawing class that we need to
-replace. To do so, the generator renames Paint to _original_Paint. Later the bridge provides its own
-replacement version of Paint which will be used by the rest of the Android stack. The replacement
-version of Paint can still use (either by inheritance or delegation) all the original non-native
-code of _original_Paint if it so desires.
-
-Some of the Android classes are basically wrappers over native objects and since we don't have the
-native code in Eclipse, we need to provide a full alternate implementation. Sub-classing doesn't
-work as some native methods are static and we don't control object creation.
-
-This won't rename/replace the inner static methods of a given class.
-
-
-4- Refactoring classes
-
-This is very similar to the Renaming classes except that it also updates the reference in all
-classes. This is done for classes which are added to the Dalvik VM for performance reasons but are
-not present in the Desktop VM. An implementation for these classes is also injected.
-
-
-5- Method erasure based on return type
-
-This is mostly an implementation detail of the bridge: in the Paint class mentioned above, some
-inner static classes are used to pass around attributes (e.g. FontMetrics, or the Style enum) and
-all the original implementation is native.
-
-In this case we have a strategy that tells the generator that anything returning, for example, the
-inner class Paint$Style in the Paint class should be discarded and the bridge will provide its own
-implementation.
-
-
-6- Method Delegates
-
-This strategy is used to override method implementations. Given a method SomeClass.MethodName(), 1
-or 2 methods are generated:
-a- A copy of the original method named SomeClass.MethodName_Original(). The content is the original
-method as-is from the reader. This step is omitted if the method is native, since it has no Java
-implementation.
-b- A brand new implementation of SomeClass.MethodName() which calls to a non-existing static method
-named SomeClass_Delegate.MethodName(). The implementation of this 'delegate' method is done in
-layoutlib_bridge.
-
-The delegate method is a static method. If the original method is non-static, the delegate method
-receives the original 'this' as its first argument. If the original method is an inner non-static
-method, it also receives the inner 'this' as the second argument.
-
-
-
-- References -
---------------
-
-
-The JVM Specification 2nd edition:
-  http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
-
-Understanding bytecode:
-  http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
-
-Bytecode opcode list:
-  http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
-
-ASM user guide:
-  http://download.forge.objectweb.org/asm/asm4-guide.pdf
-
-
---
-end
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
deleted file mode 100644
index ac97502..0000000
--- a/tools/layoutlib/create/create.iml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/data" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module-library">
-      <library name="asm-5.2">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.2.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/src.zip!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/create/manifest.txt b/tools/layoutlib/create/manifest.txt
deleted file mode 100644
index 238e7f9..0000000
--- a/tools/layoutlib/create/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.tools.layoutlib.create.Main
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
deleted file mode 100644
index 9a48ea6..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a method that has been converted to a delegate by layoutlib_create.
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface LayoutlibDelegate {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
deleted file mode 100644
index 0689c92..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a parameter or field can be null.
- * <p/>
- * When decorating a method call parameter, this denotes the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically used
- * on optional parameters.
- * <p/>
- * When decorating a method, this denotes the method might legitimately return null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface Nullable {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
deleted file mode 100644
index e4e016b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
deleted file mode 100644
index 01c940a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ /dev/null
@@ -1,418 +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.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-import org.objectweb.asm.signature.SignatureWriter;
-
-/**
- * Provides the common code for RenameClassAdapter and RefactorClassAdapter. It
- * goes through the complete class and finds references to other classes. It
- * then calls {@link #renameInternalType(String)} to convert the className to
- * the new value, if need be.
- */
-public abstract class AbstractClassAdapter extends ClassVisitor {
-
-    /**
-     * Returns the new FQCN for the class, if the reference to this class needs
-     * to be updated. Else, it returns the same string.
-     * @param name Old FQCN
-     * @return New FQCN if it needs to be renamed, else the old FQCN
-     */
-    abstract String renameInternalType(String name);
-
-    public AbstractClassAdapter(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    /**
-     * Renames a type descriptor, e.g. "Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    String renameTypeDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        return renameType(Type.getType(desc));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    String renameType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            return "L" + renameInternalType(in) + ";";
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return sb.toString();
-        }
-        return type.getDescriptor();
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;".
-     * This is like renameType() except that it returns a Type object.
-     * If the type doesn't need to be renamed, returns the input type object.
-     */
-    Type renameTypeAsType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            String newIn = renameInternalType(in);
-            if (!newIn.equals(in)) {
-                return Type.getType("L" + newIn + ";");
-            }
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return Type.getType(sb.toString());
-        }
-        return type;
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    String renameMethodDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        Type[] args = Type.getArgumentTypes(desc);
-
-        StringBuilder sb = new StringBuilder("(");
-        for (Type arg : args) {
-            String name = renameType(arg);
-            sb.append(name);
-        }
-        sb.append(')');
-
-        Type ret = Type.getReturnType(desc);
-        String name = renameType(ret);
-        sb.append(name);
-
-        return sb.toString();
-    }
-
-
-    /**
-     * Renames the ClassSignature handled by ClassVisitor.visit
-     * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
-     */
-    String renameTypeSignature(String sig) {
-        if (sig == null) {
-            return null;
-        }
-        SignatureReader reader = new SignatureReader(sig);
-        SignatureWriter writer = new SignatureWriter();
-        reader.accept(new RenameSignatureAdapter(writer));
-        sig = writer.toString();
-        return sig;
-    }
-
-
-    /**
-     * Renames the FieldTypeSignature handled by ClassVisitor.visitField
-     * or MethodVisitor.visitLocalVariable.
-     */
-    String renameFieldSignature(String sig) {
-        return renameTypeSignature(sig);
-    }
-
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        name = renameInternalType(name);
-        superName = renameInternalType(superName);
-        signature = renameTypeSignature(signature);
-        if (interfaces != null) {
-            for (int i = 0; i < interfaces.length; ++i) {
-                interfaces[i] = renameInternalType(interfaces[i]);
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        name = renameInternalType(name);
-        outerName = renameInternalType(outerName);
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        super.visitOuterClass(renameInternalType(owner), name, renameTypeDesc(desc));
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        desc = renameMethodDesc(desc);
-        signature = renameTypeSignature(signature);
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-        return new RenameMethodAdapter(mw);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        desc = renameTypeDesc(desc);
-        return super.visitAnnotation(desc, visible);
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        desc = renameTypeDesc(desc);
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-
-    //----------------------------------
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name.
-     */
-    public class RenameMethodAdapter extends MethodVisitor {
-
-        /**
-         * Creates a method visitor that renames all references from a given old name to a given new
-         * name. The method visitor will also rename all inner classes.
-         * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-         */
-        public RenameMethodAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitAnnotation(desc, visible);
-        }
-
-        @Override
-        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitParameterAnnotation(parameter, desc, visible);
-        }
-
-        @Override
-        public void visitTypeInsn(int opcode, String type) {
-            // The type sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (type.indexOf(';') > 0) {
-                type = renameTypeDesc(type);
-            } else {
-                type = renameInternalType(type);
-            }
-            super.visitTypeInsn(opcode, type);
-        }
-
-        @Override
-        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-            owner = renameInternalType(owner);
-            desc = renameTypeDesc(desc);
-
-            super.visitFieldInsn(opcode, owner, name, desc);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            // The owner sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (owner.indexOf(';') > 0) {
-                owner = renameTypeDesc(owner);
-            } else {
-                owner = renameInternalType(owner);
-            }
-            desc = renameMethodDesc(desc);
-
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-
-        @Override
-        public void visitLdcInsn(Object cst) {
-            // If cst is a Type, this means the code is trying to pull the .class constant
-            // for this class, so it needs to be renamed too.
-            if (cst instanceof Type) {
-                cst = renameTypeAsType((Type) cst);
-            }
-            super.visitLdcInsn(cst);
-        }
-
-        @Override
-        public void visitMultiANewArrayInsn(String desc, int dims) {
-            desc = renameTypeDesc(desc);
-
-            super.visitMultiANewArrayInsn(desc, dims);
-        }
-
-        @Override
-        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-            type = renameInternalType(type);
-
-            super.visitTryCatchBlock(start, end, handler, type);
-        }
-
-        @Override
-        public void visitLocalVariable(String name, String desc, String signature,
-                Label start, Label end, int index) {
-            desc = renameTypeDesc(desc);
-            signature = renameFieldSignature(signature);
-
-            super.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-
-    }
-
-    //----------------------------------
-
-    public class RenameSignatureAdapter extends SignatureVisitor {
-
-        private final SignatureVisitor mSv;
-
-        public RenameSignatureAdapter(SignatureVisitor sv) {
-            super(Main.ASM_VERSION);
-            mSv = sv;
-        }
-
-        @Override
-        public void visitClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitClassType(name);
-        }
-
-        @Override
-        public void visitInnerClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitInnerClassType(name);
-        }
-
-        @Override
-        public SignatureVisitor visitArrayType() {
-            SignatureVisitor sv = mSv.visitArrayType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitBaseType(char descriptor) {
-            mSv.visitBaseType(descriptor);
-        }
-
-        @Override
-        public SignatureVisitor visitClassBound() {
-            SignatureVisitor sv = mSv.visitClassBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitEnd() {
-            mSv.visitEnd();
-        }
-
-        @Override
-        public SignatureVisitor visitExceptionType() {
-            SignatureVisitor sv = mSv.visitExceptionType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitFormalTypeParameter(String name) {
-            mSv.visitFormalTypeParameter(name);
-        }
-
-        @Override
-        public SignatureVisitor visitInterface() {
-            SignatureVisitor sv = mSv.visitInterface();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitInterfaceBound() {
-            SignatureVisitor sv = mSv.visitInterfaceBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitParameterType() {
-            SignatureVisitor sv = mSv.visitParameterType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitReturnType() {
-            SignatureVisitor sv = mSv.visitReturnType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitSuperclass() {
-            SignatureVisitor sv = mSv.visitSuperclass();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeArgument() {
-            mSv.visitTypeArgument();
-        }
-
-        @Override
-        public SignatureVisitor visitTypeArgument(char wildcard) {
-            SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeVariable(String name) {
-            mSv.visitTypeVariable(name);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
deleted file mode 100644
index 11d4c81..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the desired classes and their dependencies.
- */
-public class AsmAnalyzer {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The input source JAR to parse. */
-    private final List<String> mOsSourceJar;
-    /** The generator to fill with the class list and dependency list. */
-    private final AsmGenerator mGen;
-    /** Keep all classes that derive from these one (these included). */
-    private final String[] mDeriveFrom;
-    /** Glob patterns of classes to keep, e.g. "com.foo.*" */
-    private final String[] mIncludeGlobs;
-    /** The set of classes to exclude.*/
-    private final Set<String> mExcludedClasses;
-    /** Glob patterns of files to keep as is. */
-    private final String[] mIncludeFileGlobs;
-    /** Internal names of classes that contain method calls that need to be rewritten. */
-    private final Set<String> mReplaceMethodCallClasses = new HashSet<>();
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     * @param osJarPath The input source JARs to parse.
-     * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included).
-     * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
-     *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
-     * @param includeFileGlobs Glob patterns of files which are kept as is. This is only for files
-     *        not ending in .class.
-     */
-    public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
-            String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses,
-            String[] includeFileGlobs) {
-        mLog = log;
-        mGen = gen;
-        mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
-        mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
-        mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
-        mExcludedClasses = excludeClasses;
-        mIncludeFileGlobs = includeFileGlobs != null ? includeFileGlobs : new String[0];
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     * Fills the generator with classes & dependencies found.
-     */
-    public void analyze() throws IOException, LogAbortException {
-
-        TreeMap<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        parseZip(mOsSourceJar, zipClasses, filesFound);
-        mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
-                mOsSourceJar.size() > 1 ? "s" : "");
-
-        Map<String, ClassReader> found = findIncludes(zipClasses);
-        Map<String, ClassReader> deps = findDeps(zipClasses, found);
-
-        if (mGen != null) {
-            mGen.setKeep(found);
-            mGen.setDeps(deps);
-            mGen.setCopyFiles(filesFound);
-            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
-        }
-    }
-
-    /**
-     * Parses a JAR file and adds all the classes found to <code>classes</code>
-     * and all other files to <code>filesFound</code>.
-     *
-     * @param classes The map of class name => ASM ClassReader. Class names are
-     *                in the form "android.view.View".
-     * @param filesFound The map of file name => InputStream. The file name is
-     *                  in the form "android/data/dataFile".
-     */
-    void parseZip(List<String> jarPathList, Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-        if (classes == null || filesFound == null) {
-            return;
-        }
-
-        Pattern[] includeFilePatterns = new Pattern[mIncludeFileGlobs.length];
-        for (int i = 0; i < mIncludeFileGlobs.length; ++i) {
-            includeFilePatterns[i] = getPatternFromGlob(mIncludeFileGlobs[i]);
-        }
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    for (Pattern includeFilePattern : includeFilePatterns) {
-                        if (includeFilePattern.matcher(entry.getName()).matches()) {
-                            filesFound.put(entry.getName(), zip.getInputStream(entry));
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Process the "includes" arrays.
-     * <p/>
-     * This updates the in_out_found map.
-     */
-    Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
-            throws LogAbortException {
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mLog.debug("Find classes to include.");
-
-        for (String s : mIncludeGlobs) {
-            findGlobs(s, zipClasses, found);
-        }
-        for (String s : mDeriveFrom) {
-            findClassesDerivingFrom(s, zipClasses, found);
-        }
-
-        return found;
-    }
-
-
-    /**
-     * Uses ASM to find the class reader for the given FQCN class name.
-     * If found, insert it in the in_out_found map.
-     * Returns the class reader object.
-     */
-    ClassReader findClass(String className, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        ClassReader classReader = zipClasses.get(className);
-        if (classReader == null) {
-            throw new LogAbortException("Class %s not found by ASM in %s",
-                    className, mOsSourceJar);
-        }
-
-        inOutFound.put(className, classReader);
-        return classReader;
-    }
-
-    /**
-     * Insert in the inOutFound map all classes found in zipClasses that match the
-     * given glob pattern.
-     * <p/>
-     * The glob pattern is not a regexp. It only accepts the "*" keyword to mean
-     * "anything but a period". The "." and "$" characters match themselves.
-     * The "**" keyword means everything including ".".
-     * <p/>
-     * Examples:
-     * <ul>
-     * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages.
-     * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class.
-     * </ul>
-     */
-    void findGlobs(String globPattern, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-
-        Pattern regexp = getPatternFromGlob(globPattern);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String class_name = entry.getKey();
-            if (regexp.matcher(class_name).matches() &&
-                    !mExcludedClasses.contains(getOuterClassName(class_name))) {
-                findClass(class_name, zipClasses, inOutFound);
-            }
-        }
-    }
-
-    Pattern getPatternFromGlob(String globPattern) {
-     // transforms the glob pattern in a regexp:
-        // - escape "." with "\."
-        // - replace "*" by "[^.]*"
-        // - escape "$" with "\$"
-        // - add end-of-line match $
-        globPattern = globPattern.replaceAll("\\$", "\\\\\\$");
-        globPattern = globPattern.replaceAll("\\.", "\\\\.");
-        // prevent ** from being altered by the next rule, then process the * rule and finally
-        // the real ** rule (which is now @)
-        globPattern = globPattern.replaceAll("\\*\\*", "@");
-        globPattern = globPattern.replaceAll("\\*", "[^.]*");
-        globPattern = globPattern.replaceAll("@", ".*");
-        globPattern += "$";
-
-        return Pattern.compile(globPattern);
-    }
-
-    /**
-     * Checks all the classes defined in the JarClassName instance and uses BCEL to
-     * determine if they are derived from the given FQCN super class name.
-     * Inserts the super class and all the class objects found in the map.
-     */
-    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        if (mExcludedClasses.contains(getOuterClassName(super_name))) {
-            return;
-        }
-        findClass(super_name, zipClasses, inOutFound);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String className = entry.getKey();
-            if (super_name.equals(className)) {
-                continue;
-            }
-            ClassReader classReader = entry.getValue();
-            ClassReader parent_cr = classReader;
-            while (parent_cr != null) {
-                String parent_name = internalToBinaryClassName(parent_cr.getSuperName());
-                if (parent_name == null) {
-                    // not found
-                    break;
-                } else if (super_name.equals(parent_name)) {
-                    inOutFound.put(className, classReader);
-                    break;
-                }
-                parent_cr = zipClasses.get(parent_name);
-            }
-        }
-    }
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inKeep,
-            Map<String, ClassReader> outKeep,
-            Map<String, ClassReader> inDeps,
-            Map<String, ClassReader> outDeps) {
-        return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps);
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutKeepClasses) {
-
-        TreeMap<String, ClassReader> deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> temp = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor(zipClasses,
-                inOutKeepClasses, new_keep,
-                deps, new_deps);
-
-        for (ClassReader cr : inOutKeepClasses.values()) {
-            visitor.setClassName(cr.getClassName());
-            cr.accept(visitor, 0 /* flags */);
-        }
-
-        while (new_deps.size() > 0 || new_keep.size() > 0) {
-            deps.putAll(new_deps);
-            inOutKeepClasses.putAll(new_keep);
-
-            temp.clear();
-            temp.putAll(new_deps);
-            temp.putAll(new_keep);
-            new_deps.clear();
-            new_keep.clear();
-            mLog.debug("Found %1$d to keep, %2$d dependencies.",
-                    inOutKeepClasses.size(), deps.size());
-
-            for (ClassReader cr : temp.values()) {
-                visitor.setClassName(cr.getClassName());
-                cr.accept(visitor, 0 /* flags */);
-            }
-        }
-
-        mLog.info("Found %1$d classes to keep, %2$d class dependencies.",
-                inOutKeepClasses.size(), deps.size());
-
-        return deps;
-    }
-
-    private String getOuterClassName(String className) {
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            return className.substring(0, pos);
-        }
-        return className;
-    }
-
-    // ----------------------------------
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        /** All classes found in the source JAR. */
-        private final Map<String, ClassReader> mZipClasses;
-        /** Classes from which dependencies are to be found. */
-        private final Map<String, ClassReader> mInKeep;
-        /** Dependencies already known. */
-        private final Map<String, ClassReader> mInDeps;
-        /** New dependencies found by this visitor. */
-        private final Map<String, ClassReader> mOutDeps;
-        /** New classes to keep as-is found by this visitor. */
-        private final Map<String, ClassReader> mOutKeep;
-
-        private String mClassName;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
-         * New dependencies are marked in outDeps.
-         *
-         * @param zipClasses All classes found in the source JAR.
-         * @param inKeep Classes from which dependencies are to be found.
-         * @param inDeps Dependencies already known.
-         * @param outDeps New dependencies found by this visitor.
-         */
-        public DependencyVisitor(Map<String, ClassReader> zipClasses,
-                Map<String, ClassReader> inKeep,
-                Map<String, ClassReader> outKeep,
-                Map<String,ClassReader> inDeps,
-                Map<String,ClassReader> outDeps) {
-            super(Main.ASM_VERSION);
-            mZipClasses = zipClasses;
-            mInKeep = inKeep;
-            mOutKeep = outKeep;
-            mInDeps = inDeps;
-            mOutDeps = outDeps;
-        }
-
-        private void setClassName(String className) {
-            mClassName = className;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         * If it does, add to the mOutDeps map.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            // exclude classes that have already been found or are marked to be excluded
-            if (mInKeep.containsKey(className) ||
-                    mOutKeep.containsKey(className) ||
-                    mInDeps.containsKey(className) ||
-                    mOutDeps.containsKey(className) ||
-                    mExcludedClasses.contains(getOuterClassName(className))) {
-                return;
-            }
-
-            // exclude classes that are not part of the JAR file being examined
-            ClassReader cr = mZipClasses.get(className);
-            if (cr == null) {
-                return;
-            }
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // accept this class:
-            // - android classes are added to dependencies
-            // - non-android classes are added to the list of classes to keep as-is (they don't need
-            //   to be stubbed).
-            if (className.contains("android")) {  // TODO make configurable
-                mOutDeps.put(className, cr);
-            } else {
-                mOutKeep.put(className, cr);
-            }
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public void considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    Type t = Type.getType(desc);
-                    considerType(t);
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-        }
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            considerName(name);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor(mClassName);
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            private String mOwnerClass;
-
-            public MyMethodVisitor(String ownerClass) {
-                super(Main.ASM_VERSION);
-                mOwnerClass = ownerClass;
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                considerName(owner);
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-
-
-                // Check if method needs to replaced by a call to a different method.
-                if (ReplaceMethodCallsAdapter.isReplacementNeeded(owner, name, desc, mOwnerClass)) {
-                    mReplaceMethodCallClasses.add(mOwnerClass);
-                }
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
deleted file mode 100644
index d59b419..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Class that generates a new JAR from a list of classes, some of which are to be kept as-is
- * and some of which are to be stubbed partially or totally.
- */
-public class AsmGenerator {
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The path of the destination JAR to create. */
-    private final String mOsDestJar;
-    /** List of classes to inject in the final JAR from _this_ archive. */
-    private final Class<?>[] mInjectClasses;
-    /** All classes to output as-is, except if they have native methods. */
-    private Map<String, ClassReader> mKeep;
-    /** All dependencies that must be completely stubbed. */
-    private Map<String, ClassReader> mDeps;
-    /** All files that are to be copied as-is. */
-    private Map<String, InputStream> mCopyFiles;
-    /** All classes where certain method calls need to be rewritten. */
-    private Set<String> mReplaceMethodCallsClasses;
-    /** Counter of number of classes renamed during transform. */
-    private int mRenameCount;
-    /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRenameClasses;
-    /** FQCN Names of "old" classes that were NOT renamed. This starts with the full list of
-     *  old-FQCN to rename and they get erased as they get renamed. At the end, classes still
-     *  left here are not in the code base anymore and thus were not renamed. */
-    private HashSet<String> mClassesNotRenamed;
-    /** A map { FQCN => set { list of return types to delete from the FQCN } }. */
-    private HashMap<String, Set<String>> mDeleteReturns;
-    /** A map { FQCN => set { method names } } of methods to rewrite as delegates.
-     *  The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
-    private final HashMap<String, Set<String>> mDelegateMethods;
-    /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
-     * map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRefactorClasses;
-    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
-     * the injection. */
-    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
-    /** A map { FQCN => set { field names } } which should be promoted to public visibility */
-    private final Map<String, Set<String>> mPromotedFields;
-    /** A list of classes to be promoted to public visibility */
-    private final Set<String> mPromotedClasses;
-
-    /**
-     * Creates a new generator that can generate the output JAR with the stubbed classes.
-     *
-     * @param log Output logger.
-     * @param osDestJar The path of the destination JAR to create.
-     * @param createInfo Creation parameters. Must not be null.
-     */
-    public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
-        mLog = log;
-        mOsDestJar = osDestJar;
-        ArrayList<Class<?>> injectedClasses =
-                new ArrayList<>(Arrays.asList(createInfo.getInjectedClasses()));
-        // Search for and add anonymous inner classes also.
-        ListIterator<Class<?>> iter = injectedClasses.listIterator();
-        while (iter.hasNext()) {
-            Class<?> clazz = iter.next();
-            try {
-                int i = 1;
-                while(i < 100) {
-                    iter.add(Class.forName(clazz.getName() + "$" + i));
-                    i++;
-                }
-            } catch (ClassNotFoundException ignored) {
-                // Expected.
-            }
-        }
-        mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
-
-        // Create the map/set of methods to change to delegates
-        mDelegateMethods = new HashMap<>();
-        addToMap(createInfo.getDelegateMethods(), mDelegateMethods);
-
-        for (String className : createInfo.getDelegateClassNatives()) {
-            className = binaryToInternalClassName(className);
-            Set<String> methods = mDelegateMethods.get(className);
-            if (methods == null) {
-                methods = new HashSet<>();
-                mDelegateMethods.put(className, methods);
-            }
-            methods.add(DelegateClassAdapter.ALL_NATIVES);
-        }
-
-        // Create the map of classes to rename.
-        mRenameClasses = new HashMap<>();
-        mClassesNotRenamed = new HashSet<>();
-        String[] renameClasses = Stream.concat(
-                Arrays.stream(createInfo.getRenamedClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        int n = renameClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            // The ASM class names uses "/" separators, whereas regular FQCN use "."
-            String oldFqcn = binaryToInternalClassName(renameClasses[i]);
-            String newFqcn = binaryToInternalClassName(renameClasses[i + 1]);
-            mRenameClasses.put(oldFqcn, newFqcn);
-            mClassesNotRenamed.add(oldFqcn);
-        }
-
-        // Create a map of classes to be refactored.
-        mRefactorClasses = new HashMap<>();
-        String[] refactorClasses = Stream.concat(
-                Arrays.stream(createInfo.getJavaPkgClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        n = refactorClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
-            String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
-            mRefactorClasses.put(oldFqcn, newFqcn);
-        }
-
-        // create the map of renamed class -> return type of method to delete.
-        mDeleteReturns = new HashMap<>();
-        String[] deleteReturns = createInfo.getDeleteReturns();
-        Set<String> returnTypes = null;
-        String renamedClass = null;
-        for (String className : deleteReturns) {
-            // if we reach the end of a section, add it to the main map
-            if (className == null) {
-                if (returnTypes != null) {
-                    mDeleteReturns.put(renamedClass, returnTypes);
-                }
-
-                renamedClass = null;
-                continue;
-            }
-
-            // if the renamed class is null, this is the beginning of a section
-            if (renamedClass == null) {
-                renamedClass = binaryToInternalClassName(className);
-                continue;
-            }
-
-            // just a standard return type, we add it to the list.
-            if (returnTypes == null) {
-                returnTypes = new HashSet<>();
-            }
-            returnTypes.add(binaryToInternalClassName(className));
-        }
-
-        mPromotedFields = new HashMap<>();
-        addToMap(createInfo.getPromotedFields(), mPromotedFields);
-
-        mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
-
-        mPromotedClasses =
-                Arrays.stream(createInfo.getPromotedClasses()).collect(Collectors.toSet());
-    }
-
-    /**
-     * For each value in the array, split the value on '#' and add the parts to the map as key
-     * and value.
-     */
-    private void addToMap(String[] entries, Map<String, Set<String>> map) {
-        for (String entry : entries) {
-            int pos = entry.indexOf('#');
-            if (pos <= 0 || pos >= entry.length() - 1) {
-                return;
-            }
-            String className = binaryToInternalClassName(entry.substring(0, pos));
-            String methodOrFieldName = entry.substring(pos + 1);
-            Set<String> set = map.get(className);
-            if (set == null) {
-                set = new HashSet<>();
-                map.put(className, set);
-            }
-            set.add(methodOrFieldName);
-        }
-    }
-
-    /**
-     * Returns the list of classes that have not been renamed yet.
-     * <p/>
-     * The names are "internal class names" rather than FQCN, i.e. they use "/" instead "."
-     * as package separators.
-     */
-    public Set<String> getClassesNotRenamed() {
-        return mClassesNotRenamed;
-    }
-
-    /**
-     * Utility that returns the internal ASM class name from a fully qualified binary class
-     * name. E.g. it returns android/view/View from android.view.View.
-     */
-    String binaryToInternalClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('.', '/');
-        }
-    }
-
-    /** Sets the map of classes to output as-is, except if they have native methods */
-    public void setKeep(Map<String, ClassReader> keep) {
-        mKeep = keep;
-    }
-
-    /** Sets the map of dependencies that must be completely stubbed */
-    public void setDeps(Map<String, ClassReader> deps) {
-        mDeps = deps;
-    }
-
-    /** Sets the map of files to output as-is. */
-    public void setCopyFiles(Map<String, InputStream> copyFiles) {
-        mCopyFiles = copyFiles;
-    }
-
-    public void setRewriteMethodCallClasses(Set<String> rewriteMethodCallClasses) {
-        mReplaceMethodCallsClasses = rewriteMethodCallClasses;
-    }
-
-    /** Generates the final JAR */
-    public void generate() throws IOException {
-        TreeMap<String, byte[]> all = new TreeMap<>();
-
-        for (Class<?> clazz : mInjectClasses) {
-            String name = classToEntryPath(clazz);
-            InputStream is = ClassLoader.getSystemResourceAsStream(name);
-            ClassReader cr = new ClassReader(is);
-            byte[] b = transform(cr, true);
-            name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mKeep.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, InputStream> entry : mCopyFiles.entrySet()) {
-            try {
-                byte[] b = inputStreamToByteArray(entry.getValue());
-                all.put(entry.getKey(), b);
-            } catch (IOException e) {
-                // Ignore.
-            }
-
-        }
-        mLog.info("# deps classes: %d", mDeps.size());
-        mLog.info("# keep classes: %d", mKeep.size());
-        mLog.info("# renamed     : %d", mRenameCount);
-
-        createJar(new FileOutputStream(mOsDestJar), all);
-        mLog.info("Created JAR file %s", mOsDestJar);
-    }
-
-    /**
-     * Writes the JAR file.
-     *
-     * @param outStream The file output stream were to write the JAR.
-     * @param all The map of all classes to output.
-     * @throws IOException if an I/O error has occurred
-     */
-    void createJar(FileOutputStream outStream, Map<String,byte[]> all) throws IOException {
-        JarOutputStream jar = new JarOutputStream(outStream);
-        for (Entry<String, byte[]> entry : all.entrySet()) {
-            String name = entry.getKey();
-            JarEntry jar_entry = new JarEntry(name);
-            jar.putNextEntry(jar_entry);
-            jar.write(entry.getValue());
-            jar.closeEntry();
-        }
-        jar.flush();
-        jar.close();
-    }
-
-    /**
-     * Utility method that converts a fully qualified java name into a JAR entry path
-     * e.g. for the input "android.view.View" it returns "android/view/View.class"
-     */
-    String classNameToEntryPath(String className) {
-        return className.replace('.', '/').concat(".class");
-    }
-
-    /**
-     * Utility method to get the JAR entry path from a Class name.
-     * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
-     */
-    private String classToEntryPath(Class<?> clazz) {
-        return classNameToEntryPath(clazz.getName());
-    }
-
-    /**
-     * Transforms a class.
-     * <p/>
-     * There are 3 kind of transformations:
-     *
-     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
-     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
-     * left intact. Modified classes must be overridable (non-private, non-final).
-     * Native methods must be made non-final, non-private.
-     *
-     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
-     * If a class has native methods, it must also be made non-private, non-final.
-     *
-     * Note that unfortunately static methods cannot be changed to non-static (since static and
-     * non-static are invoked differently.)
-     */
-    byte[] transform(ClassReader cr, boolean stubNativesOnly) {
-
-        boolean hasNativeMethods = hasNativeMethods(cr);
-
-        // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
-        String className = cr.getClassName();
-
-        String newName = transformName(className);
-        // transformName returns its input argument if there's no need to rename the class
-        if (!newName.equals(className)) {
-            mRenameCount++;
-            // This class is being renamed, so remove it from the list of classes not renamed.
-            mClassesNotRenamed.remove(className);
-        }
-
-        mLog.debug("Transform %s%s%s%s", className,
-                newName.equals(className) ? "" : " (renamed to " + newName + ")",
-                hasNativeMethods ? " -- has natives" : "",
-                stubNativesOnly ? " -- stub natives only" : "");
-
-        // Rewrite the new class from scratch, without reusing the constant pool from the
-        // original class reader.
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-        ClassVisitor cv = cw;
-
-        // FIXME Generify
-        if ("android/content/res/Resources".equals(className)) {
-            cv = new FieldInjectorAdapter(cv);
-        }
-        if (mReplaceMethodCallsClasses.contains(className)) {
-            cv = new ReplaceMethodCallsAdapter(cv, className);
-        }
-
-        cv = new RefactorClassAdapter(cv, mRefactorClasses);
-        if (!newName.equals(className)) {
-            cv = new RenameClassAdapter(cv, className, newName);
-        }
-
-        String binaryNewName = newName.replace('/', '.');
-        if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
-            cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
-        }
-        cv = new TransformClassAdapter(mLog, Collections.emptySet(), mDeleteReturns.get(className),
-                newName, cv, stubNativesOnly);
-
-        Set<String> delegateMethods = mDelegateMethods.get(className);
-        if (delegateMethods != null && !delegateMethods.isEmpty()) {
-            // If delegateMethods only contains one entry ALL_NATIVES and the class is
-            // known to have no native methods, just skip this step.
-            if (hasNativeMethods ||
-                    !(delegateMethods.size() == 1 &&
-                            delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
-                cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
-            }
-        }
-
-        Set<String> promoteFields = mPromotedFields.get(className);
-        if (promoteFields != null && !promoteFields.isEmpty()) {
-            cv = new PromoteFieldClassAdapter(cv, promoteFields);
-        }
-        if (!mPromotedClasses.isEmpty()) {
-            cv = new PromoteClassClassAdapter(cv, mPromotedClasses);
-        }
-        cr.accept(cv, 0);
-
-        return cw.toByteArray();
-    }
-
-    /**
-     * Should this class be renamed, this returns the new name. Otherwise it returns the
-     * original name.
-     *
-     * @param className The internal ASM name of the class that may have to be renamed
-     * @return A new transformed name or the original input argument.
-     */
-    String transformName(String className) {
-        String newName = mRenameClasses.get(className);
-        if (newName != null) {
-            return newName;
-        }
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            // Is this an inner class of a renamed class?
-            String base = className.substring(0, pos);
-            newName = mRenameClasses.get(base);
-            if (newName != null) {
-                return newName + className.substring(pos);
-            }
-        }
-
-        return className;
-    }
-
-    /**
-     * Returns true if a class has any native methods.
-     */
-    boolean hasNativeMethods(ClassReader cr) {
-        ClassHasNativeVisitor cv = new ClassHasNativeVisitor();
-        cr.accept(cv, 0);
-        return cv.hasNativeMethods();
-    }
-
-    private byte[] inputStreamToByteArray(InputStream is) throws IOException {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        byte[] data = new byte[8192];  // 8KB
-        int n;
-        while ((n = is.read(data, 0, data.length)) != -1) {
-            buffer.write(data, 0, n);
-        }
-        return buffer.toByteArray();
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
deleted file mode 100644
index 4748a7c..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Indicates if a class contains any native methods.
- */
-public class ClassHasNativeVisitor extends ClassVisitor {
-    public ClassHasNativeVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    private boolean mHasNativeMethods = false;
-
-    public boolean hasNativeMethods() {
-        return mHasNativeMethods;
-    }
-
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-        mHasNativeMethods = hasNativeMethods;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        // pass
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitAttribute(Attribute attr) {
-        // pass
-    }
-
-    @Override
-    public void visitEnd() {
-        // pass
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName,
-            String innerName, int access) {
-        // pass
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        if ((access & Opcodes.ACC_NATIVE) != 0) {
-            setHasNativeMethods(true, name);
-        }
-        return null;
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        // pass
-    }
-
-    @Override
-    public void visitSource(String source, String debug) {
-        // pass
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
deleted file mode 100644
index cb0bc6d..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.AutoCloseable;
-import com.android.tools.layoutlib.java.Charsets;
-import com.android.tools.layoutlib.java.IntegralToString;
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.Objects;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.tools.layoutlib.java.UnsafeByteSequence;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Describes the work to be done by {@link AsmGenerator}.
- */
-public final class CreateInfo implements ICreateInfo {
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return INJECTED_CLASSES;
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return DELEGATE_METHODS;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return DELEGATE_CLASS_NATIVES;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return RENAMED_CLASSES;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return DELETE_RETURNS;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-      return JAVA_PKG_CLASSES;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return REFACTOR_CLASSES;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        String[] refactoredClasses = getJavaPkgClasses();
-        int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length;
-        Set<String> excludedClasses = new HashSet<>(count);
-        for (int i = 0; i < refactoredClasses.length; i+=2) {
-            excludedClasses.add(refactoredClasses[i]);
-        }
-        excludedClasses.addAll(Arrays.asList(EXCLUDED_CLASSES));
-        return excludedClasses;
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return PROMOTED_FIELDS;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return PROMOTED_CLASSES;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return INJECTED_METHODS;
-    }
-
-    //-----
-
-    /**
-     * The list of class from layoutlib_create to inject in layoutlib.
-     */
-    private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
-            OverrideMethod.class,
-            MethodListener.class,
-            MethodAdapter.class,
-            ICreateInfo.class,
-            CreateInfo.class,
-            LayoutlibDelegate.class,
-            InjectMethodRunnable.class,
-            InjectMethodRunnables.class,
-            /* Java package classes */
-            IntegralToString.class,
-            UnsafeByteSequence.class,
-            System_Delegate.class,
-            LinkedHashMap_Delegate.class,
-        };
-
-    /**
-     * The list of methods to rewrite as delegates.
-     */
-    public final static String[] DELEGATE_METHODS = new String[] {
-        "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
-        "android.content.res.Resources#getAnimation",
-        "android.content.res.Resources#getBoolean",
-        "android.content.res.Resources#getColor",
-        "android.content.res.Resources#getColorStateList",
-        "android.content.res.Resources#getDimension",
-        "android.content.res.Resources#getDimensionPixelOffset",
-        "android.content.res.Resources#getDimensionPixelSize",
-        "android.content.res.Resources#getDrawable",
-        "android.content.res.Resources#getFont",
-        "android.content.res.Resources#getIntArray",
-        "android.content.res.Resources#getInteger",
-        "android.content.res.Resources#getLayout",
-        "android.content.res.Resources#getQuantityString",
-        "android.content.res.Resources#getQuantityText",
-        "android.content.res.Resources#getResourceEntryName",
-        "android.content.res.Resources#getResourceName",
-        "android.content.res.Resources#getResourcePackageName",
-        "android.content.res.Resources#getResourceTypeName",
-        "android.content.res.Resources#getString",
-        "android.content.res.Resources#getStringArray",
-        "android.content.res.Resources#getText",
-        "android.content.res.Resources#getTextArray",
-        "android.content.res.Resources#getValue",
-        "android.content.res.Resources#getXml",
-        "android.content.res.Resources#loadXmlResourceParser",
-        "android.content.res.Resources#obtainAttributes",
-        "android.content.res.Resources#obtainTypedArray",
-        "android.content.res.Resources#openRawResource",
-        "android.content.res.Resources#openRawResourceFd",
-        "android.content.res.Resources$Theme#obtainStyledAttributes",
-        "android.content.res.Resources$Theme#resolveAttribute",
-        "android.content.res.Resources$Theme#resolveAttributes",
-        "android.content.res.AssetManager#newTheme",
-        "android.content.res.AssetManager#deleteTheme",
-        "android.content.res.AssetManager#getAssignedPackageIdentifiers",
-        "android.content.res.TypedArray#getValueAt",
-        "android.content.res.TypedArray#obtain",
-        "android.graphics.BitmapFactory#finishDecode",
-        "android.graphics.BitmapFactory#setDensityFromOptions",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw",
-        "android.graphics.drawable.GradientDrawable#buildRing",
-        "android.graphics.FontFamily#addFont",
-        "android.graphics.Typeface#getSystemFontConfigLocation",
-        "android.graphics.Typeface#makeFamilyFromParsed",
-        "android.os.Handler#sendMessageAtTime",
-        "android.os.HandlerThread#run",
-        "android.preference.Preference#getView",
-        "android.text.format.DateFormat#is24HourFormat",
-        "android.text.Hyphenator#getSystemHyphenatorLocation",
-        "android.util.Xml#newPullParser",
-        "android.view.Choreographer#getInstance",
-        "android.view.Choreographer#getRefreshRate",
-        "android.view.Choreographer#scheduleVsyncLocked",
-        "android.view.Display#updateDisplayInfoLocked",
-        "android.view.Display#getWindowManager",
-        "android.view.HandlerActionQueue#postDelayed",
-        "android.view.LayoutInflater#rInflate",
-        "android.view.LayoutInflater#parseInclude",
-        "android.view.View#getWindowToken",
-        "android.view.View#isInEditMode",
-        "android.view.ViewRootImpl#isInTouchMode",
-        "android.view.WindowManagerGlobal#getWindowManagerService",
-        "android.view.inputmethod.InputMethodManager#getInstance",
-        "android.view.MenuInflater#registerMenu",
-        "android.view.RenderNode#getMatrix",
-        "android.view.RenderNode#nCreate",
-        "android.view.RenderNode#nGetNativeFinalizer",
-        "android.view.RenderNode#nSetElevation",
-        "android.view.RenderNode#nGetElevation",
-        "android.view.RenderNode#nSetTranslationX",
-        "android.view.RenderNode#nGetTranslationX",
-        "android.view.RenderNode#nSetTranslationY",
-        "android.view.RenderNode#nGetTranslationY",
-        "android.view.RenderNode#nSetTranslationZ",
-        "android.view.RenderNode#nGetTranslationZ",
-        "android.view.RenderNode#nSetRotation",
-        "android.view.RenderNode#nGetRotation",
-        "android.view.RenderNode#nSetLeft",
-        "android.view.RenderNode#nSetTop",
-        "android.view.RenderNode#nSetRight",
-        "android.view.RenderNode#nSetBottom",
-        "android.view.RenderNode#nSetLeftTopRightBottom",
-        "android.view.RenderNode#nSetPivotX",
-        "android.view.RenderNode#nGetPivotX",
-        "android.view.RenderNode#nSetPivotY",
-        "android.view.RenderNode#nGetPivotY",
-        "android.view.RenderNode#nSetScaleX",
-        "android.view.RenderNode#nGetScaleX",
-        "android.view.RenderNode#nSetScaleY",
-        "android.view.RenderNode#nGetScaleY",
-        "android.view.RenderNode#nIsPivotExplicitlySet",
-        "android.view.PointerIcon#loadResource",
-        "android.view.ViewGroup#drawChild",
-        "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
-        "com.android.internal.util.XmlUtils#convertValueToInt",
-        "dalvik.system.VMRuntime#newUnpaddedArray",
-        "libcore.io.MemoryMappedFile#mmapRO",
-        "libcore.io.MemoryMappedFile#close",
-        "libcore.io.MemoryMappedFile#bigEndianIterator",
-        "libcore.util.NativeAllocationRegistry#applyFreeFunction",
-    };
-
-    /**
-     * The list of classes on which to delegate all native methods.
-     */
-    public final static String[] DELEGATE_CLASS_NATIVES = new String[] {
-        "android.animation.PropertyValuesHolder",
-        "android.graphics.BaseCanvas",
-        "android.graphics.Bitmap",
-        "android.graphics.BitmapFactory",
-        "android.graphics.BitmapShader",
-        "android.graphics.BlurMaskFilter",
-        "android.graphics.Canvas",
-        "android.graphics.ColorFilter",
-        "android.graphics.ColorMatrixColorFilter",
-        "android.graphics.ComposePathEffect",
-        "android.graphics.ComposeShader",
-        "android.graphics.CornerPathEffect",
-        "android.graphics.DashPathEffect",
-        "android.graphics.DiscretePathEffect",
-        "android.graphics.DrawFilter",
-        "android.graphics.EmbossMaskFilter",
-        "android.graphics.FontFamily",
-        "android.graphics.LightingColorFilter",
-        "android.graphics.LinearGradient",
-        "android.graphics.MaskFilter",
-        "android.graphics.Matrix",
-        "android.graphics.NinePatch",
-        "android.graphics.Paint",
-        "android.graphics.PaintFlagsDrawFilter",
-        "android.graphics.Path",
-        "android.graphics.PathDashPathEffect",
-        "android.graphics.PathEffect",
-        "android.graphics.PathMeasure",
-        "android.graphics.PorterDuffColorFilter",
-        "android.graphics.RadialGradient",
-        "android.graphics.Region",
-        "android.graphics.Shader",
-        "android.graphics.SumPathEffect",
-        "android.graphics.SweepGradient",
-        "android.graphics.Typeface",
-        "android.graphics.drawable.AnimatedVectorDrawable",
-        "android.graphics.drawable.VectorDrawable",
-        "android.os.SystemClock",
-        "android.os.SystemProperties",
-        "android.text.AndroidBidi",
-        "android.text.StaticLayout",
-        "android.util.PathParser",
-        "android.view.Display",
-        "com.android.internal.util.VirtualRefBasePtr",
-        "com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
-        "libcore.icu.ICU",
-    };
-
-    /**
-     *  The list of classes to rename, must be an even list: the binary FQCN
-     *  of class to replace followed by the new FQCN.
-     */
-    private final static String[] RENAMED_CLASSES =
-        new String[] {
-            "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
-            "android.view.textservice.TextServicesManager",    "android.view.textservice._Original_TextServicesManager",
-            "android.util.LruCache",                           "android.util._Original_LruCache",
-            "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
-            "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
-            "android.webkit.WebView",                          "android.webkit._Original_WebView",
-        };
-
-    /**
-     * The list of class references to update, must be an even list: the binary
-     * FQCN of class to replace followed by the new FQCN. The classes to
-     * replace are to be excluded from the output.
-     */
-    private final static String[] JAVA_PKG_CLASSES =
-        new String[] {
-            "java.nio.charset.Charsets",                       "java.nio.charset.StandardCharsets",
-            "java.lang.IntegralToString",                      "com.android.tools.layoutlib.java.IntegralToString",
-            "java.lang.UnsafeByteSequence",                    "com.android.tools.layoutlib.java.UnsafeByteSequence",
-            // Use android.icu.text versions of DateFormat and SimpleDateFormat since the
-            // original ones do not match the Android implementation
-            "java.text.DateFormat",                            "android.icu.text.DateFormat",
-            "java.text.SimpleDateFormat",                      "android.icu.text.SimpleDateFormat",
-        };
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    private final static String[] REFACTOR_CLASSES =
-            new String[] {
-                    "android.os.Build",                                "android.os._Original_Build",
-            };
-
-    private final static String[] EXCLUDED_CLASSES =
-        new String[] {
-            "android.preference.PreferenceActivity",
-            "org.kxml2.io.KXmlParser",
-        };
-
-    /**
-     * List of fields for which we will update the visibility to be public. This is sometimes
-     * needed when access from the delegate classes is needed.
-     */
-    private final static String[] PROMOTED_FIELDS = new String[] {
-        "android.graphics.drawable.VectorDrawable#mVectorState",
-        "android.view.Choreographer#mLastFrameTimeNanos",
-        "android.graphics.FontFamily#mBuilderPtr",
-        "android.graphics.Typeface#sDynamicTypefaceCache"
-    };
-
-    /**
-     * List of classes to be promoted to public visibility. Prefer using PROMOTED_FIELDS to this
-     * if possible.
-     */
-    private final static String[] PROMOTED_CLASSES = new String[] {
-    };
-
-    /**
-     * List of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     */
-    private final static String[] DELETE_RETURNS =
-        new String[] {
-            null };                         // separator, for next class/methods list.
-
-    private final static Map<String, InjectMethodRunnable> INJECTED_METHODS =
-            new HashMap<String, InjectMethodRunnable>(1) {{
-                put("android.content.Context",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }};
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
deleted file mode 100644
index cbb3a8a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.util.Set;
-
-/**
- * A {@link DelegateClassAdapter} can transform some methods from a class into
- * delegates that defer the call to an associated delegate class.
- * <p/>
- * This is used to override specific methods and or all native methods in classes.
- */
-public class DelegateClassAdapter extends ClassVisitor {
-
-    /** Suffix added to original methods. */
-    private static final String ORIGINAL_SUFFIX = "_Original";
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    public static final String ALL_NATIVES = "<<all_natives>>";
-
-    private final String mClassName;
-    private final Set<String> mDelegateMethods;
-    private final Log mLog;
-    private boolean mIsStaticInnerClass;
-
-    /**
-     * Creates a new {@link DelegateClassAdapter} that can transform some methods
-     * from a class into delegates that defer the call to an associated delegate class.
-     * <p/>
-     * This is used to override specific methods and or all native methods in classes.
-     *
-     * @param log The logger object. Must not be null.
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param delegateMethods The set of method names to modify and/or the
-     *          special constant {@link #ALL_NATIVES} to convert all native methods.
-     */
-    public DelegateClassAdapter(Log log,
-            ClassVisitor cv,
-            String className,
-            Set<String> delegateMethods) {
-        super(Main.ASM_VERSION, cv);
-        mLog = log;
-        mClassName = className;
-        mDelegateMethods = delegateMethods;
-        // If this is an inner class, by default, we assume it's static. If it's not we will detect
-        // by looking at the fields (see visitField)
-        mIsStaticInnerClass = className.contains("$");
-    }
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mIsStaticInnerClass && "this$0".equals(name)) {
-            // Having a "this$0" field, proves that this class is not a static inner class.
-            mIsStaticInnerClass = false;
-        }
-
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        boolean isStaticMethod = (access & Opcodes.ACC_STATIC) != 0;
-        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-        boolean useDelegate = (isNative && mDelegateMethods.contains(ALL_NATIVES)) ||
-                              mDelegateMethods.contains(name);
-
-        if (!useDelegate) {
-            // Not creating a delegate for this method, pass it as-is from the reader to the writer.
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-
-        if (CONSTRUCTOR.equals(name) || CLASS_INIT.equals(name)) {
-            // We don't currently support generating delegates for constructors.
-            throw new UnsupportedOperationException(
-                String.format(
-                    "Delegate doesn't support overriding constructor %1$s:%2$s(%3$s)",  //$NON-NLS-1$
-                    mClassName, name, desc));
-        }
-
-        if (isNative) {
-            // Remove native flag
-            access = access & ~Opcodes.ACC_NATIVE;
-            MethodVisitor mwDelegate = super.visitMethod(access, name, desc, signature, exceptions);
-
-            DelegateMethodAdapter a = new DelegateMethodAdapter(
-                    mLog, null, mwDelegate, mClassName, name, desc, isStaticMethod,
-                    mIsStaticInnerClass);
-
-            // A native has no code to visit, so we need to generate it directly.
-            a.generateDelegateCode();
-
-            return mwDelegate;
-        }
-
-        // Given a non-native SomeClass.MethodName(), we want to generate 2 methods:
-        // - A copy of the original method named SomeClass.MethodName_Original().
-        //   The content is the original method as-is from the reader.
-        // - A brand new implementation of SomeClass.MethodName() which calls to a
-        //   non-existing method named SomeClass_Delegate.MethodName().
-        //   The implementation of this 'delegate' method is done in layoutlib_bridge.
-
-        int accessDelegate = access;
-        access = access & ~Opcodes.ACC_PRIVATE;  // If private, make it package protected.
-
-        MethodVisitor mwOriginal = super.visitMethod(access, name + ORIGINAL_SUFFIX,
-                                                     desc, signature, exceptions);
-        MethodVisitor mwDelegate = super.visitMethod(accessDelegate, name,
-                                                     desc, signature, exceptions);
-
-        return new DelegateMethodAdapter(
-                mLog, mwOriginal, mwDelegate, mClassName, name, desc, isStaticMethod,
-                mIsStaticInnerClass);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
deleted file mode 100644
index da8babc..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-
-/**
- * This method adapter generates delegate methods.
- * <p/>
- * Given a method {@code SomeClass.MethodName()}, this generates 1 or 2 methods:
- * <ul>
- * <li> A copy of the original method named {@code SomeClass.MethodName_Original()}.
- *   The content is the original method as-is from the reader.
- *   This step is omitted if the method is native, since it has no Java implementation.
- * <li> A brand new implementation of {@code SomeClass.MethodName()} which calls to a
- *   non-existing method named {@code SomeClass_Delegate.MethodName()}.
- *   The implementation of this 'delegate' method is done in layoutlib_brigde.
- * </ul>
- * A method visitor is generally constructed to generate a single method; however
- * here we might want to generate one or two depending on the context. To achieve
- * that, the visitor here generates the 'original' method and acts as a no-op if
- * no such method exists (e.g. when the original is a native method).
- * The delegate method is generated after the {@code visitEnd} of the original method
- * or by having the class adapter <em>directly</em> call {@link #generateDelegateCode()}
- * for native methods.
- * <p/>
- * When generating the 'delegate', the implementation generates a call to a class
- * class named <code>&lt;className&gt;_Delegate</code> with static methods matching
- * the methods to be overridden here. The methods have the same return type.
- * The argument type list is the same except the "this" reference is passed first
- * for non-static methods.
- * <p/>
- * A new annotation is added to these 'delegate' methods so that we can easily find them
- * for automated testing.
- * <p/>
- * This class isn't intended to be generic or reusable.
- * It is called by {@link DelegateClassAdapter}, which takes care of properly initializing
- * the two method writers for the original and the delegate class, as needed, with their
- * expected names.
- * <p/>
- * The class adapter also takes care of calling {@link #generateDelegateCode()} directly for
- * a native and use the visitor pattern for non-natives.
- * Note that native methods have, by definition, no code so there's nothing a visitor
- * can visit.
- * <p/>
- * Instances of this class are not re-usable.
- * The class adapter creates a new instance for each method.
- */
-class DelegateMethodAdapter extends MethodVisitor {
-
-    /** Suffix added to delegate classes. */
-    public static final String DELEGATE_SUFFIX = "_Delegate";
-
-    /** The parent method writer to copy of the original method.
-     *  Null when dealing with a native original method. */
-    private MethodVisitor mOrgWriter;
-    /** The parent method writer to generate the delegating method. Never null. */
-    private MethodVisitor mDelWriter;
-    /** The original method descriptor (return type + argument types.) */
-    private String mDesc;
-    /** True if the original method is static. */
-    private final boolean mIsStatic;
-    /** True if the method is contained in a static inner class */
-    private final boolean mIsStaticInnerClass;
-    /** The internal class name (e.g. <code>com/android/SomeClass$InnerClass</code>.) */
-    private final String mClassName;
-    /** The method name. */
-    private final String mMethodName;
-    /** Logger object. */
-    private final Log mLog;
-
-    /** Array used to capture the first line number information from the original method
-     *  and duplicate it in the delegate. */
-    private Object[] mDelegateLineNumber;
-
-    /**
-     * Creates a new {@link DelegateMethodAdapter} that will transform this method
-     * into a delegate call.
-     * <p/>
-     * See {@link DelegateMethodAdapter} for more details.
-     *
-     * @param log The logger object. Must not be null.
-     * @param mvOriginal The parent method writer to copy of the original method.
-     *          Must be {@code null} when dealing with a native original method.
-     * @param mvDelegate The parent method writer to generate the delegating method.
-     *          Must never be null.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param methodName The simple name of the method.
-     * @param desc A method descriptor (c.f. {@link Type#getReturnType(String)} +
-     *          {@link Type#getArgumentTypes(String)})
-     * @param isStatic True if the method is declared static.
-     */
-    public DelegateMethodAdapter(Log log,
-            MethodVisitor mvOriginal,
-            MethodVisitor mvDelegate,
-            String className,
-            String methodName,
-            String desc,
-            boolean isStatic,
-            boolean isStaticClass) {
-        super(Main.ASM_VERSION);
-        mLog = log;
-        mOrgWriter = mvOriginal;
-        mDelWriter = mvDelegate;
-        mClassName = className;
-        mMethodName = methodName;
-        mDesc = desc;
-        mIsStatic = isStatic;
-        mIsStaticInnerClass = isStaticClass;
-    }
-
-    /**
-     * Generates the new code for the method.
-     * <p/>
-     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
-     * (since they have no code to visit).
-     * <p/>
-     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
-     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
-     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
-     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
-     */
-    public void generateDelegateCode() {
-        /*
-         * The goal is to generate a call to a static delegate method.
-         * If this method is non-static, the first parameter will be 'this'.
-         * All the parameters must be passed and then the eventual return type returned.
-         *
-         * Example, let's say we have a method such as
-         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
-         *
-         * We'll want to create a body that calls a delegate method like this:
-         *   TheClass_Delegate.myMethod(this, a, b, c);
-         *
-         * If the method is non-static and the class name is an inner class (e.g. has $ in its
-         * last segment), we want to push the 'this' of the outer class first:
-         *   OuterClass_InnerClass_Delegate.myMethod(
-         *     OuterClass.this,
-         *     OuterClass$InnerClass.this,
-         *     a, b, c);
-         *
-         * Only one level of inner class is supported right now, for simplicity and because
-         * we don't need more.
-         *
-         * The generated class name is the current class name with "_Delegate" appended to it.
-         * One thing to realize is that we don't care about generics -- since generic types
-         * are erased at build time, they have no influence on the method name being called.
-         */
-
-        // Add our annotation
-        AnnotationVisitor aw = mDelWriter.visitAnnotation(
-                Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(),
-                true); // visible at runtime
-        if (aw != null) {
-            aw.visitEnd();
-        }
-
-        mDelWriter.visitCode();
-
-        if (mDelegateLineNumber != null) {
-            Object[] p = mDelegateLineNumber;
-            mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
-        }
-
-        ArrayList<Type> paramTypes = new ArrayList<>();
-        String delegateClassName = mClassName + DELEGATE_SUFFIX;
-        boolean pushedArg0 = false;
-        int maxStack = 0;
-
-        // Check if the last segment of the class name has inner an class.
-        // Right now we only support one level of inner classes.
-        Type outerType = null;
-        int slash = mClassName.lastIndexOf('/');
-        int dol = mClassName.lastIndexOf('$');
-        if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
-            String outerClass = mClassName.substring(0, dol);
-            outerType = Type.getObjectType(outerClass);
-
-            // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
-            delegateClassName = delegateClassName.replace('$', '_');
-        }
-
-        // For an instance method (e.g. non-static), push the 'this' preceded
-        // by the 'this' of any outer class, if any.
-        if (!mIsStatic) {
-
-            if (outerType != null && !mIsStaticInnerClass) {
-                // The first-level inner class has a package-protected member called 'this$0'
-                // that points to the outer class.
-
-                // Push this.getField("this$0") on the call stack.
-                mDelWriter.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
-                mDelWriter.visitFieldInsn(Opcodes.GETFIELD,
-                        mClassName,                 // class where the field is defined
-                        "this$0",                   // field name
-                        outerType.getDescriptor()); // type of the field
-                maxStack++;
-                paramTypes.add(outerType);
-
-            }
-
-            // Push "this" for the instance method, which is always ALOAD 0
-            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
-            maxStack++;
-            pushedArg0 = true;
-            paramTypes.add(Type.getObjectType(mClassName));
-        }
-
-        // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
-        Type[] argTypes = Type.getArgumentTypes(mDesc);
-        int maxLocals = pushedArg0 ? 1 : 0;
-        for (Type t : argTypes) {
-            int size = t.getSize();
-            mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
-            maxLocals += size;
-            maxStack += size;
-            paramTypes.add(t);
-        }
-
-        // Construct the descriptor of the delegate based on the parameters
-        // we pushed on the call stack. The return type remains unchanged.
-        String desc = Type.getMethodDescriptor(
-                Type.getReturnType(mDesc),
-                paramTypes.toArray(new Type[paramTypes.size()]));
-
-        // Invoke the static delegate
-        mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC,
-                delegateClassName,
-                mMethodName,
-                desc,
-                false);
-
-        Type returnType = Type.getReturnType(mDesc);
-        mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
-
-        mDelWriter.visitMaxs(maxStack, maxLocals);
-        mDelWriter.visitEnd();
-
-        // For debugging now. Maybe we should collect these and store them in
-        // a text file for helping create the delegates. We could also compare
-        // the text file to a golden and break the build on unsupported changes
-        // or regressions. Even better we could fancy-print something that looks
-        // like the expected Java method declaration.
-        mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitCode();
-        }
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMaxs(maxStack, maxLocals);
-        }
-    }
-
-    /** End of visiting. Generate the delegating code. */
-    @Override
-    public void visitEnd() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitEnd();
-        }
-        generateDelegateCode();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotation(desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotationDefault();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitParameterAnnotation(parameter, desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitAttribute(attr);
-        }
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        // Capture the first line values for the new delegate method
-        if (mDelegateLineNumber == null) {
-            mDelegateLineNumber = new Object[] { line, start };
-        }
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLineNumber(line, start);
-        }
-    }
-
-    @Override
-    public void visitInsn(int opcode) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitInsn(opcode);
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
deleted file mode 100644
index aa68ea0..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2012 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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the classes and their dependencies. A "dependency" is a class
- * used by another class.
- */
-public class DependencyFinder {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     */
-    public DependencyFinder(Log log) {
-        mLog = log;
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     *
-     * @param osJarPath The input source JARs to parse.
-     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
-     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
-     */
-    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
-
-        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
-        mLog.info("Found %d classes in input JAR%s.",
-                zipClasses.size(),
-                osJarPath.size() > 1 ? "s" : "");
-
-        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
-
-        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
-
-        List<Map<String, Set<String>>> result = new ArrayList<>(2);
-        result.add(deps);
-        result.add(missing);
-        return result;
-    }
-
-    /**
-     * Prints dependencies to the current logger, found stuff and missing stuff.
-     */
-    public void printAllDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        // Print all dependences found in the format:
-        // +Found: <FQCN from zip>
-        //     uses: FQCN
-
-        mLog.info("++++++ %d Entries found in source JARs", deps.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            mLog.info(    "+Found  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("    uses: %s", dep);
-            }
-
-            mLog.info("");
-        }
-
-
-        // Now print all missing dependences in the format:
-        // -Missing <FQCN>:
-        //     used by: <FQCN>
-
-        mLog.info("");
-        mLog.info("------ %d Entries missing from source JARs", missing.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : missing.entrySet()) {
-            mLog.info(    "-Missing  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("   used by: %s", dep);
-            }
-
-            mLog.info("");
-        }
-    }
-
-    /**
-     * Prints only a summary of the missing dependencies to the current logger.
-     */
-    public void printMissingDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        for (String fqcn : missing.keySet()) {
-            mLog.info("%s", fqcn);
-        }
-    }
-
-    // ----------------
-
-    /**
-     * Parses a JAR file and returns a list of all classes founds using a map
-     * class name => ASM ClassReader. Class names are in the form "android.view.View".
-     */
-    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<>();
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-        }
-
-        return classes;
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
-
-        // The dependencies that we'll collect.
-        // It's a map Class name => uses class names.
-        Map<String, Set<String>> dependencyMap = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor();
-
-        int count = 0;
-        try {
-            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-                String name = entry.getKey();
-
-                TreeSet<String> set = new TreeSet<>();
-                dependencyMap.put(name, set);
-                visitor.setDependencySet(set);
-
-                ClassReader cr = entry.getValue();
-                cr.accept(visitor, 0 /* flags */);
-
-                visitor.setDependencySet(null);
-
-                mLog.debugNoln("Visited %d classes\r", ++count);
-            }
-        } finally {
-            mLog.debugNoln("\n");
-        }
-
-        return dependencyMap;
-    }
-
-    /**
-     * Computes which classes FQCN were found as dependencies that are NOT listed
-     * in the original JAR classes.
-     *
-     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
-     * @param zipClasses The set of all classes FQCN found in the JAR files.
-     * @return A map { FQCN not found in the zipClasses => classes using it }
-     */
-    private Map<String, Set<String>> findMissingClasses(
-            Map<String, Set<String>> deps,
-            Set<String> zipClasses) {
-        Map<String, Set<String>> missing = new TreeMap<>();
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            String name = entry.getKey();
-
-            for (String dep : entry.getValue()) {
-                if (!zipClasses.contains(dep)) {
-                    // This dependency doesn't exist in the zip classes.
-                    Set<String> set = missing.get(dep);
-                    if (set == null) {
-                        set = new TreeSet<>();
-                        missing.put(dep, set);
-                    }
-                    set.add(name);
-                }
-            }
-
-        }
-
-        return missing;
-    }
-
-
-    // ----------------------------------
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    DependencyVisitor getVisitor() {
-        return new DependencyVisitor();
-    }
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        private Set<String> mCurrentDepSet;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         */
-        public DependencyVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        /**
-         * Sets the {@link Set} where to record direct dependencies for this class.
-         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
-         */
-        public void setDependencySet(Set<String> set) {
-            mCurrentDepSet = set;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                // or in java package (we won't be able to load them anyway).
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // Add it to the dependency set for the currently visited class, as needed.
-            assert mCurrentDepSet != null;
-            mCurrentDepSet.add(className);
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public boolean considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    if (desc.length() > 0 && desc.charAt(0) == '(') {
-                        // This is a method descriptor with arguments and a return type.
-                        Type t = Type.getReturnType(desc);
-                        considerType(t);
-
-                        for (Type arg : Type.getArgumentTypes(desc)) {
-                            considerType(arg);
-                        }
-
-                    } else {
-                        Type t = Type.getType(desc);
-                        considerType(t);
-                    }
-                    return true;
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-            return false;
-        }
-
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            // Note: outerName/innerName seems to be null when we're reading the
-            // _Original_ClassName classes generated by layoutlib_create.
-            if (outerName != null) {
-                considerName(name);
-            }
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor();
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            public MyMethodVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                if (!considerDesc(owner) && owner.indexOf('/') != -1) {
-                    considerName(owner);
-                }
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
deleted file mode 100644
index 4608a84..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
+++ /dev/null
@@ -1,40 +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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Injects fields in a class.
- * <p>
- * TODO: Generify
- */
-public class FieldInjectorAdapter extends ClassVisitor {
-    public FieldInjectorAdapter(ClassVisitor cv) {
-        super(Opcodes.ASM4, cv);
-    }
-
-    @Override
-    public void visitEnd() {
-        super.visitField(Opcodes.ACC_PUBLIC, "mLayoutlibCallback",
-                "Lcom/android/ide/common/rendering/api/LayoutlibCallback;", null, null);
-        super.visitField(Opcodes.ACC_PUBLIC, "mContext",
-                "Lcom/android/layoutlib/bridge/android/BridgeContext;", null, null);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
deleted file mode 100644
index eca1c07..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Interface describing the work to be done by {@link AsmGenerator}.
- */
-public interface ICreateInfo {
-
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
-    Class<?>[] getInjectedClasses();
-
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateMethods();
-
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateClassNatives();
-
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
-    String[] getRenamedClasses();
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    String[] getRefactoredClasses();
-
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
-    String[] getDeleteReturns();
-
-    /**
-     * Returns the list of classes to refactor, must be an even list: the
-     * binary FQCN of class to replace followed by the new FQCN. All references
-     * to the old class should be updated to the new class.
-     * The list can be empty but must not be null.
-     */
-    String[] getJavaPkgClasses();
-
-    Set<String> getExcludedClasses();
-
-    /**
-     * Returns a list of fields which should be promoted to public visibility. The array values
-     * are in the form of the binary FQCN of the class containing the field and the field name
-     * separated by a '#'.
-     */
-    String[] getPromotedFields();
-
-    /**
-     * Returns a list of classes to be promoted to public visibility.
-     */
-    String[] getPromotedClasses();
-
-    /**
-     * Returns a map from binary FQCN className to {@link InjectMethodRunnable} which will be
-     * called to inject methods into a class.
-     * Can be empty but must not be null.
-     */
-    Map<String, InjectMethodRunnable> getInjectedMethodsMap();
-
-    abstract class InjectMethodRunnable {
-        /**
-         * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
-         * loading the class, ClassVisitor is not loaded. This is because when injecting
-         * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
-         * asm classes also, but still keep CreateInfo loadable.
-         */
-        public abstract void generateMethods(Object cv);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
deleted file mode 100644
index 1941ab4..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ARETURN;
-import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-
-public class InjectMethodRunnables {
-    public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
-            = new InjectMethodRunnable() {
-        @Override
-        public void generateMethods(Object classVisitor) {
-            assert classVisitor instanceof ClassVisitor;
-            ClassVisitor cv = (ClassVisitor) classVisitor;
-            // generated by compiling the class:
-            // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
-            // and then running ASMifier on it:
-            // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo
-            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getFrameworkClassLoader",
-                    "()Ljava/lang/ClassLoader;", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass",
-                    "()Ljava/lang/Class;", false);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader",
-                    "()Ljava/lang/ClassLoader;", false);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(1, 1);
-            mv.visitEnd();
-            // generated code ends.
-        }
-    };
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
deleted file mode 100644
index c834808..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * Injects methods into some classes.
- */
-public class InjectMethodsAdapter extends ClassVisitor {
-
-    private final ICreateInfo.InjectMethodRunnable mRunnable;
-
-    public InjectMethodsAdapter(ClassVisitor cv, InjectMethodRunnable runnable) {
-        super(Main.ASM_VERSION, cv);
-        mRunnable = runnable;
-    }
-
-    @Override
-    public void visitEnd() {
-        mRunnable.generateMethods(this);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
deleted file mode 100644
index c3ba591..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class Log {
-
-    private boolean mVerbose = false;
-
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    public void debug(String format, Object... args) {
-        if (mVerbose) {
-            info(format, args);
-        }
-    }
-
-    /** Similar to debug() but doesn't do a \n automatically. */
-    public void debugNoln(String format, Object... args) {
-        if (mVerbose) {
-            String s = String.format(format, args);
-            System.out.print(s);
-        }
-    }
-
-    public void info(String format, Object... args) {
-        String s = String.format(format, args);
-        outPrintln(s);
-    }
-
-    public void error(String format, Object... args) {
-        String s = String.format(format, args);
-        errPrintln(s);
-    }
-
-    public void exception(Throwable t, String format, Object... args) {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        t.printStackTrace(pw);
-        pw.flush();
-        error(format + "\n" + sw.toString(), args);
-    }
-
-    /** for unit testing */
-    protected void errPrintln(String msg) {
-        System.err.println(msg);
-    }
-
-    /** for unit testing */
-    protected void outPrintln(String msg) {
-        System.out.println(msg);
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
deleted file mode 100644
index dc4b4a7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-public class LogAbortException extends Exception {
-
-    private final String mFormat;
-    private final Object[] mArgs;
-
-    public LogAbortException(String format, Object... args) {
-        mFormat = format;
-        mArgs = args;
-    }
-    
-    public void error(Log log) {
-        log.error(mFormat, mArgs);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
deleted file mode 100644
index 4b6cf43..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * Entry point for the layoutlib_create tool.
- * <p/>
- * The tool does not currently rely on any external configuration file.
- * Instead the configuration is mostly done via the {@link CreateInfo} class.
- * <p/>
- * For a complete description of the tool and its implementation, please refer to
- * the "README.txt" file at the root of this project.
- * <p/>
- * For a quick test, invoke this as follows:
- * <pre>
- * $ make layoutlib
- * </pre>
- * which does:
- * <pre>
- * $ make layoutlib_create &lt;bunch of framework jars&gt;
- * $ java -jar out/host/linux-x86/framework/layoutlib_create.jar \
- *        out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- * </pre>
- */
-public class Main {
-
-    public static class Options {
-        public boolean listAllDeps = false;
-        public boolean listOnlyMissingDeps = false;
-    }
-
-    public static final int ASM_VERSION = Opcodes.ASM5;
-
-    public static final Options sOptions = new Options();
-
-    public static void main(String[] args) {
-
-        Log log = new Log();
-
-        ArrayList<String> osJarPath = new ArrayList<>();
-        String[] osDestJar = { null };
-
-        if (!processArgs(log, args, osJarPath, osDestJar)) {
-            log.error("Usage: layoutlib_create [-v] output.jar input.jar ...");
-            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
-            System.exit(1);
-        }
-
-        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
-            System.exit(listDeps(osJarPath, log));
-
-        } else {
-            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
-        }
-
-
-        System.exit(1);
-    }
-
-    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
-        log.info("Output: %1$s", osDestJar);
-        for (String path : osJarPath) {
-            log.info("Input :      %1$s", path);
-        }
-
-        try {
-            CreateInfo info = new CreateInfo();
-            Set<String> excludeClasses = info.getExcludedClasses();
-            AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
-
-            AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
-                    new String[] {                          // derived from
-                        "android.view.View",
-                        "android.app.Fragment"
-                    },
-                    new String[] {                          // include classes
-                        "android.*", // for android.R
-                        "android.util.*",
-                        "com.android.internal.util.*",
-                        "android.view.*",
-                        "android.widget.*",
-                        "com.android.internal.widget.*",
-                        "android.text.**",
-                        "android.graphics.*",
-                        "android.graphics.drawable.**",
-                        "android.content.*",
-                        "android.content.res.*",
-                        "android.preference.*",
-                        "org.apache.harmony.xml.*",
-                        "com.android.internal.R**",
-                        "android.pim.*", // for datepicker
-                        "android.os.*",  // for android.os.Handler
-                        "android.database.ContentObserver", // for Digital clock
-                        "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
-                        "android.app.DatePickerDialog",     // b.android.com/28318
-                        "android.app.TimePickerDialog",     // b.android.com/61515
-                        "com.android.internal.view.menu.ActionMenu",
-                        "android.icu.**",                   // needed by LayoutLib
-                        "android.annotation.NonNull",       // annotations
-                        "android.annotation.Nullable",      // annotations
-                        "com.android.internal.transition.EpicenterTranslateClipReveal",
-                        "com.android.internal.graphics.drawable.AnimationScaleListDrawable",
-                    },
-                    excludeClasses,
-                    new String[] {
-                        "com/android/i18n/phonenumbers/data/*",
-                        "android/icu/impl/data/**"
-                    });
-            aa.analyze();
-            agen.generate();
-
-            // Throw an error if any class failed to get renamed by the generator
-            //
-            // IMPORTANT: if you're building the platform and you get this error message,
-            // it means the renameClasses[] array in AsmGenerator needs to be updated: some
-            // class should have been renamed but it was not found in the input JAR files.
-            Set<String> notRenamed = agen.getClassesNotRenamed();
-            if (notRenamed.size() > 0) {
-                // (80-column guide below for error formatting)
-                // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
-                log.error(
-                  "ERROR when running layoutlib_create: the following classes are referenced\n" +
-                  "by tools/layoutlib/create but were not actually found in the input JAR files.\n" +
-                  "This may be due to some platform classes having been renamed.");
-                for (String fqcn : notRenamed) {
-                    log.error("- Class not found: %s", fqcn.replace('/', '.'));
-                }
-                for (String path : osJarPath) {
-                    log.info("- Input JAR : %1$s", path);
-                }
-                return 1;
-            }
-
-            return 0;
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        } catch (LogAbortException e) {
-            e.error(log);
-        }
-
-        return 1;
-    }
-
-    private static int listDeps(ArrayList<String> osJarPath, Log log) {
-        DependencyFinder df = new DependencyFinder(log);
-        try {
-            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
-            if (sOptions.listAllDeps) {
-                df.printAllDeps(result);
-            } else if (sOptions.listOnlyMissingDeps) {
-                df.printMissingDeps(result);
-            }
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns true if args where properly parsed.
-     * Returns false if program should exit with command-line usage.
-     * <p/>
-     * Note: the String[0] is an output parameter wrapped in an array, since there is no
-     * "out" parameter support.
-     */
-    private static boolean processArgs(Log log, String[] args,
-            ArrayList<String> osJarPath, String[] osDestJar) {
-        boolean needs_dest = true;
-        for (String s : args) {
-            if (s.equals("-v")) {
-                log.setVerbose(true);
-            } else if (s.equals("--list-deps")) {
-                sOptions.listAllDeps = true;
-                needs_dest = false;
-            } else if (s.equals("--missing-deps")) {
-                sOptions.listOnlyMissingDeps = true;
-                needs_dest = false;
-            } else if (!s.startsWith("-")) {
-                if (needs_dest && osDestJar[0] == null) {
-                    osDestJar[0] = s;
-                } else {
-                    osJarPath.add(s);
-                }
-            } else {
-                log.error("Unknown argument: %s", s);
-                return false;
-            }
-        }
-
-        if (osJarPath.isEmpty()) {
-            log.error("Missing parameter: path to input jar");
-            return false;
-        }
-        if (needs_dest && osDestJar[0] == null) {
-            log.error("Missing parameter: path to output jar");
-            return false;
-        }
-
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
deleted file mode 100644
index 7d1e4cf..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-
-/**
- * An adapter to make it easier to use {@link MethodListener}.
- * <p/>
- * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener
- * for all types (I, L, F, D and A), returning 0 or null as appropriate.
- */
-public class MethodAdapter implements MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    @Override
-    public void onInvokeV(String signature, boolean isNative, Object caller) {
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    @Override
-    public int onInvokeI(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    @Override
-    public long onInvokeL(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    @Override
-    public float onInvokeF(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    @Override
-    public double onInvokeD(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    @Override
-    public Object onInvokeA(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
deleted file mode 100644
index faba4d7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-
-/**
- * Interface to allow a method invocation to be listened upon.
- * <p/>
- * This is used by {@link OverrideMethod} to register a listener for methods that
- * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a
- * default global listener or a specific listener based on the method signature.
- */
-public interface MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *  
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    void onInvokeV(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    int onInvokeI(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    long onInvokeL(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    float onInvokeF(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    double onInvokeD(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    Object onInvokeA(String signature, boolean isNative, Object caller);
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
deleted file mode 100644
index 7ccafc3..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import java.util.HashMap;
-
-/**
- * Allows stub methods from LayoutLib to be overriden at runtime.
- * <p/>
- * Implementation note: all types required by this class(inner/outer classes & interfaces)
- * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
- * Otherwise they won't be accessible in layoutlib.jar at runtime.
- */
-public final class OverrideMethod {
-
-    /** Map of method overridden. */
-    private static HashMap<String, MethodListener> sMethods = new HashMap<>();
-    /** Default listener for all method not listed in sMethods. Nothing if null. */
-    private static MethodListener sDefaultListener = null;
-    
-    /**
-     * Sets the default listener for all methods not specifically handled.
-     * Null means to do nothing.
-     */
-    @SuppressWarnings("UnusedDeclaration") // Used by Bridge by reflection for debug purposes.
-    public static void setDefaultListener(MethodListener listener) {
-        sDefaultListener = listener;
-    }
-
-    /**
-     * Defines or reset a listener for the given method signature.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
-     * @param listener The new listener. Removes it if null.
-     */
-    public static void setMethodListener(String signature, MethodListener listener) {
-        if (listener == null) {
-            sMethods.remove(signature);
-        } else {
-            sMethods.put(signature, listener);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the given signature or the default one if defined.
-     * <p/>
-     * This version invokes the method listener for the void return type. 
-     * <p/>
-     * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
-     * by the stubbed methods generated by the LayoutLib_create tool.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    public static void invokeV(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            i.onInvokeV(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            sDefaultListener.onInvokeV(signature, isNative, caller);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the int return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static int invokeI(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeI(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeI(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the long return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static long invokeL(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeL(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeL(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the float return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static float invokeF(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeF(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeF(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the double return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static double invokeD(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeD(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeD(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the object return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static Object invokeA(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeA(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeA(signature, isNative, caller);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
deleted file mode 100644
index 99e3089..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
+++ /dev/null
@@ -1,64 +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.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given classes to public visibility.
- */
-public class PromoteClassClassAdapter extends ClassVisitor {
-
-    private final Set<String> mClassNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteClassClassAdapter(ClassVisitor cv, Set<String> classNames) {
-        super(Main.ASM_VERSION, cv);
-        mClassNames =
-                classNames.stream().map(name -> name.replace(".", "/")).collect(Collectors.toSet());
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
deleted file mode 100644
index ba77860..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-
-import java.util.Set;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given fields to public visibility.
- */
-public class PromoteFieldClassAdapter extends ClassVisitor {
-
-    private final Set<String> mFieldNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
-        super(Main.ASM_VERSION, cv);
-        mFieldNames = fieldNames;
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mFieldNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-        return super.visitField(access, name, desc, signature, value);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
deleted file mode 100644
index 024e32f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
+++ /dev/null
@@ -1,104 +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.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-public class RefactorClassAdapter extends AbstractClassAdapter {
-
-    private final HashMap<String, String> mRefactorClasses;
-
-    RefactorClassAdapter(ClassVisitor cv, HashMap<String, String> refactorClasses) {
-        super(cv);
-        mRefactorClasses = refactorClasses;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-
-        return new RefactorStackMapAdapter(mw);
-    }
-
-    @Override
-    protected String renameInternalType(String oldClassName) {
-        if (oldClassName != null) {
-            String newName = mRefactorClasses.get(oldClassName);
-            if (newName != null) {
-                return newName;
-            }
-            int pos = oldClassName.indexOf('$');
-            if (pos > 0) {
-                newName = mRefactorClasses.get(oldClassName.substring(0, pos));
-                if (newName != null) {
-                    return newName + oldClassName.substring(pos);
-                }
-            }
-        }
-        return oldClassName;
-    }
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name in
-     * the stackmap of the method.
-     */
-    private class RefactorStackMapAdapter extends MethodVisitor {
-
-        private RefactorStackMapAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-
-        private Object[] renameFrame(Object[] elements) {
-            if (elements == null) {
-                return null;
-            }
-
-            // The input array cannot be modified. We only copy the source array on write
-            boolean copied = false;
-            for (int i = 0; i < elements.length; i++) {
-                if (!(elements[i] instanceof String)) {
-                    continue;
-                }
-
-                if (!copied) {
-                    elements = Arrays.copyOf(elements, elements.length);
-                    copied = true;
-                }
-
-                String type = (String)elements[i];
-                if (type.indexOf(';') > 0) {
-                    elements[i] = renameTypeDesc(type);
-                } else {
-                    elements[i] = renameInternalType(type);
-                }
-            }
-
-            return elements;
-        }
-
-        @Override
-        public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-            super.visitFrame(type, nLocal, renameFrame(local), nStack, renameFrame(stack));
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
deleted file mode 100644
index 40bd126..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * This class visitor renames a class from a given old name to a given new name.
- * The class visitor will also rename all inner classes and references in the methods.
- * <p/>
- *
- * For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same.
- */
-public class RenameClassAdapter extends AbstractClassAdapter {
-
-
-    private final String mOldName;
-    private final String mNewName;
-    private String mOldBase;
-    private String mNewBase;
-
-    /**
-     * Creates a class visitor that renames a class from a given old name to a given new name.
-     * The class visitor will also rename all inner classes and references in the methods.
-     * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-     */
-    public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) {
-        super(cv);
-        mOldBase = mOldName = oldName;
-        mNewBase = mNewName = newName;
-
-        int pos = mOldName.indexOf('$');
-        if (pos > 0) {
-            mOldBase = mOldName.substring(0, pos);
-        }
-        pos = mNewName.indexOf('$');
-        if (pos > 0) {
-            mNewBase = mNewName.substring(0, pos);
-        }
-
-        assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     * <p/>
-     * The internal type of some of the MethodVisitor turns out to be a type
-       descriptor sometimes so descriptors are renamed too.
-     */
-    @Override
-    protected String renameInternalType(String type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.equals(mOldName)) {
-            return mNewName;
-        }
-
-        if (!mOldBase.equals(mOldName) && type.equals(mOldBase)) {
-            return mNewBase;
-        }
-
-        int pos = type.indexOf('$');
-        if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
-            return mNewBase + type.substring(pos);
-        }
-        return type;
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
deleted file mode 100644
index bf94415..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
+++ /dev/null
@@ -1,292 +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.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Replaces calls to certain methods that do not exist in the Desktop VM. Useful for methods in the
- * "java" package.
- */
-public class ReplaceMethodCallsAdapter extends ClassVisitor {
-
-    /**
-     * Descriptors for specialized versions {@link System#arraycopy} that are not present on the
-     * Desktop VM.
-     */
-    private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<>(Arrays.asList(
-            "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V",
-            "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V"));
-
-    private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<>(5);
-
-    private static final String ANDROID_LOCALE_CLASS =
-            "com/android/layoutlib/bridge/android/AndroidLocale";
-
-    private static final String JAVA_LOCALE_CLASS = Type.getInternalName(java.util.Locale.class);
-    private static final Type STRING = Type.getType(String.class);
-
-    private static final String JAVA_LANG_SYSTEM = Type.getInternalName(System.class);
-
-    // Static initialization block to initialize METHOD_REPLACERS.
-    static {
-        // Case 1: java.lang.System.arraycopy()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && "arraycopy".equals(name) &&
-                        ARRAYCOPY_DESCRIPTORS.contains(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
-            }
-        });
-
-        // Case 2: java.util.Locale.toLanguageTag() and java.util.Locale.getScript()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String LOCALE_TO_STRING =
-                    Type.getMethodDescriptor(STRING, Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) && "()Ljava/lang/String;".equals(desc) &&
-                        ("toLanguageTag".equals(name) || "getScript".equals(name));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = ANDROID_LOCALE_CLASS;
-                mi.desc = LOCALE_TO_STRING;
-            }
-        });
-
-        // Case 3: java.util.Locale.adjustLanguageCode() or java.util.Locale.forLanguageTag() or
-        // java.util.Locale.getDefault()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String STRING_TO_STRING = Type.getMethodDescriptor(STRING, STRING);
-            private final String STRING_TO_LOCALE = Type.getMethodDescriptor(
-                    Type.getType(Locale.class), STRING);
-            private final String VOID_TO_LOCALE =
-                    Type.getMethodDescriptor(Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) &&
-                        ("adjustLanguageCode".equals(name) && desc.equals(STRING_TO_STRING) ||
-                        "forLanguageTag".equals(name) && desc.equals(STRING_TO_LOCALE) ||
-                        "getDefault".equals(name) && desc.equals(VOID_TO_LOCALE));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.owner = ANDROID_LOCALE_CLASS;
-            }
-        });
-
-        // Case 4: java.lang.System.log?()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.length() == 4
-                        && name.startsWith("log");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                assert mi.desc.equals("(Ljava/lang/String;Ljava/lang/Throwable;)V")
-                        || mi.desc.equals("(Ljava/lang/String;)V");
-                mi.name = "log";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 5: java.lang.System time calls
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("nanoTime");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "nanoTime";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("currentTimeMillis");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "currentTimeMillis";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 6: java.util.LinkedHashMap.eldest()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String VOID_TO_MAP_ENTRY =
-                    Type.getMethodDescriptor(Type.getType(Map.Entry.class));
-            private final String LINKED_HASH_MAP = Type.getInternalName(LinkedHashMap.class);
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return LINKED_HASH_MAP.equals(owner) &&
-                        "eldest".equals(name) &&
-                        VOID_TO_MAP_ENTRY.equals(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = Type.getInternalName(LinkedHashMap_Delegate.class);
-                mi.desc = Type.getMethodDescriptor(
-                        Type.getType(Map.Entry.class), Type.getType(LinkedHashMap.class));
-            }
-        });
-
-        // Case 7: android.content.Context.getClassLoader() in LayoutInflater
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            // When LayoutInflater asks for a class loader, we must return the class loader that
-            // cannot return app's custom views/classes. This is so that in case of any failure
-            // or exception when instantiating the views, the IDE can replace it with a mock view
-            // and have proper error handling. However, if a custom view asks for the class
-            // loader, we must return a class loader that can find app's custom views as well.
-            // Thus, we rewrite the call to get class loader in LayoutInflater to
-            // getFrameworkClassLoader and inject a new method in Context. This leaves the normal
-            // method: Context.getClassLoader() free to be used by the apps.
-            private final String VOID_TO_CLASS_LOADER =
-                    Type.getMethodDescriptor(Type.getType(ClassLoader.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return owner.equals("android/content/Context") &&
-                        sourceClass.equals("android/view/LayoutInflater") &&
-                        name.equals("getClassLoader") &&
-                        desc.equals(VOID_TO_CLASS_LOADER);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "getFrameworkClassLoader";
-            }
-        });
-    }
-
-    /**
-     * If a method some.package.Class.Method(args) is called from some.other.Class,
-     * @param owner some/package/Class
-     * @param name Method
-     * @param desc (args)returnType
-     * @param sourceClass some/other/Class
-     * @return if the method invocation needs to be replaced by some other class.
-     */
-    public static boolean isReplacementNeeded(String owner, String name, String desc,
-            String sourceClass) {
-        for (MethodReplacer replacer : METHOD_REPLACERS) {
-            if (replacer.isNeeded(owner, name, desc, sourceClass)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private final String mOriginalClassName;
-
-    public ReplaceMethodCallsAdapter(ClassVisitor cv, String originalClassName) {
-        super(Main.ASM_VERSION, cv);
-        mOriginalClassName = originalClassName;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
-    }
-
-    private class MyMethodVisitor extends MethodVisitor {
-
-        public MyMethodVisitor(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            for (MethodReplacer replacer : METHOD_REPLACERS) {
-                if (replacer.isNeeded(owner, name, desc, mOriginalClassName)) {
-                    MethodInformation mi = new MethodInformation(opcode, owner, name, desc);
-                    replacer.replace(mi);
-                    opcode = mi.opcode;
-                    owner = mi.owner;
-                    name = mi.name;
-                    desc = mi.desc;
-                    break;
-                }
-            }
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    private static class MethodInformation {
-        public int opcode;
-        public String owner;
-        public String name;
-        public String desc;
-
-        public MethodInformation(int opcode, String owner, String name, String desc) {
-            this.opcode = opcode;
-            this.owner = owner;
-            this.name = name;
-            this.desc = desc;
-        }
-    }
-
-    private interface MethodReplacer {
-        boolean isNeeded(String owner, String name, String desc, String sourceClass);
-
-        /**
-         * Updates the MethodInformation with the new values of the method attributes -
-         * opcode, owner, name and desc.
-         */
-        void replace(MethodInformation mi);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
deleted file mode 100644
index 4ba7237..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * This method adapter rewrites a method by discarding the original code and generating
- * a stub depending on the return type. Original annotations are passed along unchanged.
- */
-class StubMethodAdapter extends MethodVisitor {
-
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    /** The parent method writer */
-    private MethodVisitor mParentVisitor;
-    /** The method return type. Can be null. */
-    private Type mReturnType;
-    /** Message to be printed by stub methods. */
-    private String mInvokeSignature;
-    /** Flag to output the first line number. */
-    private boolean mOutputFirstLineNumber = true;
-    /** Flag that is true when implementing a constructor, to accept all original
-     *  code calling the original super constructor. */
-    private boolean mIsInitMethod = false;
-
-    private boolean mMessageGenerated;
-    private final boolean mIsStatic;
-    private final boolean mIsNative;
-
-    public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
-            String invokeSignature, boolean isStatic, boolean isNative) {
-        super(Main.ASM_VERSION);
-        mParentVisitor = mv;
-        mReturnType = returnType;
-        mInvokeSignature = invokeSignature;
-        mIsStatic = isStatic;
-        mIsNative = isNative;
-
-        if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
-            mIsInitMethod = true;
-        }
-    }
-
-    private void generateInvoke() {
-        /* Generates the code:
-         *  OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
-         */
-        mParentVisitor.visitLdcInsn(mInvokeSignature);
-        // push true or false
-        mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
-        // push null or this
-        if (mIsStatic) {
-            mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
-        }
-
-        int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
-        switch(sort) {
-        case Type.VOID:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeV",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)V",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.RETURN);
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeI",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)I",
-                    false);
-            switch(sort) {
-            case Type.BOOLEAN:
-                Label l1 = new Label();
-                mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
-                mParentVisitor.visitInsn(Opcodes.ICONST_1);
-                mParentVisitor.visitInsn(Opcodes.IRETURN);
-                mParentVisitor.visitLabel(l1);
-                mParentVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-                mParentVisitor.visitInsn(Opcodes.ICONST_0);
-                break;
-            case Type.CHAR:
-                mParentVisitor.visitInsn(Opcodes.I2C);
-                break;
-            case Type.BYTE:
-                mParentVisitor.visitInsn(Opcodes.I2B);
-                break;
-            case Type.SHORT:
-                mParentVisitor.visitInsn(Opcodes.I2S);
-                break;
-            }
-            mParentVisitor.visitInsn(Opcodes.IRETURN);
-            break;
-        case Type.LONG:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeL",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)J",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.LRETURN);
-            break;
-        case Type.FLOAT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeF",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)F",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.FRETURN);
-            break;
-        case Type.DOUBLE:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeD",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)D",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.DRETURN);
-            break;
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeA",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;",
-                    false);
-            mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
-            mParentVisitor.visitInsn(Opcodes.ARETURN);
-            break;
-        }
-
-    }
-
-    private void generatePop() {
-        /* Pops the stack, depending on the return type.
-         */
-        switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
-        case Type.VOID:
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-        case Type.FLOAT:
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitInsn(Opcodes.POP);
-            break;
-        case Type.LONG:
-        case Type.DOUBLE:
-            mParentVisitor.visitInsn(Opcodes.POP2);
-            break;
-        }
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        mParentVisitor.visitCode();
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-        }
-        mParentVisitor.visitMaxs(maxStack, maxLocals);
-    }
-
-    /**
-     * End of visiting.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitEnd() {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-            mParentVisitor.visitMaxs(1, 1);
-        }
-        mParentVisitor.visitEnd();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        return mParentVisitor.visitAnnotation(desc, visible);
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        return mParentVisitor.visitAnnotationDefault();
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        mParentVisitor.visitAttribute(attr);
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        if (mIsInitMethod || mOutputFirstLineNumber) {
-            mParentVisitor.visitLineNumber(line, start);
-            mOutputFirstLineNumber = false;
-        }
-    }
-
-    /**
-     * For non-constructor, rewrite existing "return" instructions to write the message.
-     */
-    @Override
-    public void visitInsn(int opcode) {
-        if (mIsInitMethod) {
-            switch (opcode) {
-            case Opcodes.RETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.DRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.IRETURN:
-            case Opcodes.LRETURN:
-                // Pop the last word from the stack since invoke will generate its own return.
-                generatePop();
-                generateInvoke();
-                mMessageGenerated = true;
-                //$FALL-THROUGH$
-            default:
-                mParentVisitor.visitInsn(opcode);
-            }
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
deleted file mode 100644
index a28ae69..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.Set;
-
-/**
- * Class adapter that can stub some or all of the methods of the class.
- */
-class TransformClassAdapter extends ClassVisitor {
-
-    /** True if all methods should be stubbed, false if only native ones must be stubbed. */
-    private final boolean mStubAll;
-    /** True if the class is an interface. */
-    private boolean mIsInterface;
-    private final String mClassName;
-    private final Log mLog;
-    private final Set<String> mStubMethods;
-    private Set<String> mDeleteReturns;
-
-    /**
-     * Creates a new class adapter that will stub some or all methods.
-     * @param stubMethods  list of method signatures to always stub out
-     * @param deleteReturns list of types that trigger the deletion of methods returning them.
-     * @param className The name of the class being modified
-     * @param cv The parent class writer visitor
-     * @param stubNativesOnly True if only native methods should be stubbed. False if all
-     *                        methods should be stubbed.
-     */
-    public TransformClassAdapter(Log logger, Set<String> stubMethods,
-            Set<String> deleteReturns, String className, ClassVisitor cv,
-            boolean stubNativesOnly) {
-        super(Main.ASM_VERSION, cv);
-        mLog = logger;
-        mStubMethods = stubMethods;
-        mClassName = className;
-        mStubAll = !stubNativesOnly;
-        mIsInterface = false;
-        mDeleteReturns = deleteReturns;
-    }
-
-    /* Visits the class header. */
-    @Override
-    public void visit(int version, int access, String name,
-            String signature, String superName, String[] interfaces) {
-
-        // This class might be being renamed.
-        name = mClassName;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    /* Visits the header of an inner class. */
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    /* Visits a method. */
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        if (mDeleteReturns != null) {
-            Type t = Type.getReturnType(desc);
-            if (t.getSort() == Type.OBJECT) {
-                String returnType = t.getInternalName();
-                if (returnType != null) {
-                    if (mDeleteReturns.contains(returnType)) {
-                        return null;
-                    }
-                }
-            }
-        }
-
-        String methodSignature = mClassName.replace('/', '.') + "#" + name;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-
-        // stub this method if they are all to be stubbed or if it is a native method
-        // and don't try to stub interfaces nor abstract non-native methods.
-        if (!mIsInterface &&
-            ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) &&
-            (mStubAll ||
-             (access & Opcodes.ACC_NATIVE) != 0) ||
-             mStubMethods.contains(methodSignature)) {
-
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-            // remove abstract, final and native
-            access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
-
-            String invokeSignature = methodSignature + desc;
-            mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
-
-            MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-            return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
-                    isStatic, isNative);
-
-        } else {
-            mLog.debug("  Keep: %s %s", name, desc);
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-    }
-
-    /**
-     * Extracts the return {@link Type} of this descriptor.
-     */
-    Type returnType(String desc) {
-        if (desc != null) {
-            try {
-                return Type.getReturnType(desc);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // ignore, not a valid type.
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
deleted file mode 100644
index 7d6c4ec..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
+++ /dev/null
@@ -1,32 +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.
- */
-
-package com.android.tools.layoutlib.java;
-
-/**
- * Defines the same interface as the java.lang.AutoCloseable which was added in
- * Java 7. This hack makes it possible to run the Android code which uses Java 7
- * features (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java
- */
-public interface AutoCloseable {
-    /**
-     * Closes the object and release any system resources it holds.
-     */
-    void close() throws Exception;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
deleted file mode 100644
index f73b06b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
+++ /dev/null
@@ -1,133 +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.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.nio.charset.Charsets which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. An implementation of the native methods in the original
- * class has been added.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/nio/charset/Charsets
- */
-public final class Charsets {
-    /**
-     * A cheap and type-safe constant for the ISO-8859-1 Charset.
-     */
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-    /**
-     * A cheap and type-safe constant for the US-ASCII Charset.
-     */
-    public static final Charset US_ASCII = Charset.forName("US-ASCII");
-
-    /**
-     * A cheap and type-safe constant for the UTF-8 Charset.
-     */
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toAsciiBytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return US_ASCII.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toIsoLatin1Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return ISO_8859_1.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-8. All characters are representable in UTF-8.
-     */
-    public static byte[] toUtf8Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return UTF_8.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-16BE. All characters are representable in UTF-16BE.
-     */
-    public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) {
-        byte[] result = new byte[length * 2];
-        int end = offset + length;
-        int resultIndex = 0;
-        for (int i = offset; i < end; ++i) {
-            char ch = chars[i];
-            result[resultIndex++] = (byte) (ch >> 8);
-            result[resultIndex++] = (byte) ch;
-        }
-        return result;
-    }
-
-    /**
-     * Decodes the given US-ASCII bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     char ch = (char) (data[start++] & 0xff);
-     *     value[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-     * }
-     */
-    public static void asciiBytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        final char REPLACEMENT_CHAR = (char)0xffd;
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            char ch = (char) (bytes[start++] & 0xff);
-            chars[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-        }
-    }
-
-    /**
-     * Decodes the given ISO-8859-1 bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     value[i] = (char) (data[start++] & 0xff);
-     * }
-     */
-    public static void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            chars[i] = (char) (bytes[start++] & 0xff);
-        }
-    }
-
-    private Charsets() {
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
deleted file mode 100644
index e6dd00a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
+++ /dev/null
@@ -1,537 +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.
- */
-
-package com.android.tools.layoutlib.java;
-
-/**
- * Defines the same class as the java.lang.IntegralToString which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. Since it's no longer in java.lang, access to package
- * private methods and classes has been replaced by the closes matching public
- * implementation.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java
- */
-public final class IntegralToString {
-    /**
-     * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid
-     * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder
-     * because it's almost as expensive to work out the exact length of the result as it is to
-     * do the formatting. We could try being conservative and "delete"-ing the unused space
-     * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share
-     * the code.)
-     */
-    private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
-        @Override protected char[] initialValue() {
-            return new char[20]; // Maximum length of a base-10 long.
-        }
-    };
-
-    /**
-     * These tables are used to special-case toString computation for
-     * small values.  This serves three purposes: it reduces memory usage;
-     * it increases performance for small values; and it decreases the
-     * number of comparisons required to do the length computation.
-     * Elements of this table are lazily initialized on first use.
-     * No locking is necessary, i.e., we use the non-volatile, racy
-     * single-check idiom.
-     */
-    private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100];
-    private static final String[] SMALL_NEGATIVE_VALUES = new String[100];
-
-    /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] TENS = {
-        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
-        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
-        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
-        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
-        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
-        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
-        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
-        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
-        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
-        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
-    };
-
-    /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] ONES = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    };
-
-    /**
-     * Table for MOD / DIV 10 computation described in Section 10-21
-     * of Hank Warren's "Hacker's Delight" online addendum.
-     * http://www.hackersdelight.org/divcMore.pdf
-     */
-    private static final char[] MOD_10_TABLE = {
-        0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0
-    };
-
-    /**
-     * The digits for every supported radix.
-     */
-    private static final char[] DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
-        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-        'u', 'v', 'w', 'x', 'y', 'z'
-    };
-
-    private static final char[] UPPER_CASE_DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-        'U', 'V', 'W', 'X', 'Y', 'Z'
-    };
-
-    private IntegralToString() {
-    }
-
-    /**
-     * Equivalent to Integer.toString(i, radix).
-     */
-    public static String intToString(int i, int radix) {
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return intToString(i);
-        }
-
-        /*
-         * If i is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (i < 0) {
-            negative = true;
-        } else {
-            i = -i;
-        }
-
-        int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            int q = i / radix;
-            buf[--cursor] = DIGITS[radix * q - i];
-            i = q;
-        } while (i != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Integer.toString(i).
-     */
-    public static String intToString(int i) {
-        return convertInt(null, i);
-    }
-
-    /**
-     * Equivalent to sb.append(Integer.toString(i)).
-     */
-    public static void appendInt(StringBuilder sb, int i) {
-        convertInt(sb, i);
-    }
-
-    /**
-     * Returns the string representation of i and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of i to sb if sb is non-null.
-     */
-    private static String convertInt(StringBuilder sb, int i) {
-        boolean negative = false;
-        String quickResult = null;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-            if (i < 100) {
-                if (i < 0) {
-                    // If -n is still negative, n is Integer.MIN_VALUE
-                    quickResult = "-2147483648";
-                } else {
-                    quickResult = SMALL_NEGATIVE_VALUES[i];
-                    if (quickResult == null) {
-                        SMALL_NEGATIVE_VALUES[i] = quickResult =
-                                i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
-                    }
-                }
-            }
-        } else {
-            if (i < 100) {
-                quickResult = SMALL_NONNEGATIVE_VALUES[i];
-                if (quickResult == null) {
-                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
-                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
-                }
-            }
-        }
-        if (quickResult != null) {
-            if (sb != null) {
-                sb.append(quickResult);
-                return null;
-            }
-            return quickResult;
-        }
-
-        int bufLen = 11; // Max number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-        int cursor = bufLen;
-
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while (i >= (1 << 16)) {
-            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
-            int q = (int) ((0x51EB851FL * i) >>> 37);
-            int r = i - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            i = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (i != 0) {
-            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * i) >>> 19;
-            int r = i - 10*q;
-            buf[--cursor] = DIGITS[r];
-            i = q;
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Equivalent to Long.toString(v, radix).
-     */
-    public static String longToString(long v, int radix) {
-        int i = (int) v;
-        if (i == v) {
-            return intToString(i, radix);
-        }
-
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return longToString(v);
-        }
-
-        /*
-         * If v is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (v < 0) {
-            negative = true;
-        } else {
-            v = -v;
-        }
-
-        int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            long q = v / radix;
-            buf[--cursor] = DIGITS[(int) (radix * q - v)];
-            v = q;
-        } while (v != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Long.toString(l).
-     */
-    public static String longToString(long l) {
-        return convertLong(null, l);
-    }
-
-    /**
-     * Equivalent to sb.append(Long.toString(l)).
-     */
-    public static void appendLong(StringBuilder sb, long l) {
-        convertLong(sb, l);
-    }
-
-    /**
-     * Returns the string representation of n and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of n to sb if sb is non-null.
-     */
-    private static String convertLong(StringBuilder sb, long n) {
-        int i = (int) n;
-        if (i == n) {
-            return convertInt(sb, i);
-        }
-
-        boolean negative = (n < 0);
-        if (negative) {
-            n = -n;
-            if (n < 0) {
-                // If -n is still negative, n is Long.MIN_VALUE
-                String quickResult = "-9223372036854775808";
-                if (sb != null) {
-                    sb.append(quickResult);
-                    return null;
-                }
-                return quickResult;
-            }
-        }
-
-        int bufLen = 20; // Maximum number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-
-        int low = (int) (n % 1000000000); // Extract low-order 9 digits
-        int cursor = intIntoCharArray(buf, bufLen, low);
-
-        // Zero-pad Low order part to 9 digits
-        while (cursor != (bufLen - 9)) {
-            buf[--cursor] = '0';
-        }
-
-        /*
-         * The remaining digits are (n - low) / 1,000,000,000.  This
-         * "exact division" is done as per the online addendum to Hank Warren's
-         * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
-         */
-        n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;
-
-        /*
-         * If the remaining digits fit in an int, emit them using a
-         * single call to intIntoCharArray. Otherwise, strip off the
-         * low-order digit, put it in buf, and then call intIntoCharArray
-         * on the remaining digits (which now fit in an int).
-         */
-        if ((n & (-1L << 32)) == 0) {
-            cursor = intIntoCharArray(buf, cursor, (int) n);
-        } else {
-            /*
-             * Set midDigit to n % 10
-             */
-            int lo32 = (int) n;
-            int hi32 = (int) (n >>> 32);
-
-            // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
-            int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];
-
-            // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
-            midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
-            if (midDigit < 0) {
-                midDigit += 10;
-            }
-            buf[--cursor] = DIGITS[midDigit];
-
-            // Exact division as per Warren 10-20
-            int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
-            cursor = intIntoCharArray(buf, cursor, rest);
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Inserts the unsigned decimal integer represented by n into the specified
-     * character array starting at position cursor.  Returns the index after
-     * the last character inserted (i.e., the value to pass in as cursor the
-     * next time this method is called). Note that n is interpreted as a large
-     * positive integer (not a negative integer) if its sign bit is set.
-     */
-    private static int intIntoCharArray(char[] buf, int cursor, int n) {
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while ((n & 0xffff0000) != 0) {
-            /*
-             * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
-             * This computation is slightly different from the corresponding
-             * computation in intToString: the shifts before and after
-             * multiply can't be combined, as that would yield the wrong result
-             * if n's sign bit were set.
-             */
-            int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
-            int r = n - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            n = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (n != 0) {
-            // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * n) >>> 19;
-            int r = n - 10*q;
-            buf[--cursor] = DIGITS[r];
-            n = q;
-        }
-        return cursor;
-    }
-
-    public static String intToBinaryString(int i) {
-        int bufLen = 32;  // Max number of binary digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 1];
-        }  while ((i >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToBinaryString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToBinaryString(i);
-        }
-
-        int bufLen = 64;  // Max number of binary digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 1];
-        }  while ((v >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        sb.append(digits[(b >> 4) & 0xf]);
-        sb.append(digits[b & 0xf]);
-        return sb;
-    }
-
-    public static String byteToHexString(byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[2]; // We always want two digits.
-        buf[0] = digits[(b >> 4) & 0xf];
-        buf[1] = digits[b & 0xf];
-        return new String(buf, 0, 2);
-    }
-
-    public static String bytesToHexString(byte[] bytes, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[bytes.length * 2];
-        int c = 0;
-        for (byte b : bytes) {
-            buf[c++] = digits[(b >> 4) & 0xf];
-            buf[c++] = digits[b & 0xf];
-        }
-        return new String(buf);
-    }
-
-    public static String intToHexString(int i, boolean upperCase, int minWidth) {
-        int bufLen = 8;  // Max number of hex digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        do {
-            buf[--cursor] = digits[i & 0xf];
-        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToHexString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToHexString(i, false, 0);
-        }
-
-        int bufLen = 16;  // Max number of hex digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 0xF];
-        } while ((v >>>= 4) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String intToOctalString(int i) {
-        int bufLen = 11;  // Max number of octal digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 7];
-        } while ((i >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToOctalString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToOctalString(i);
-        }
-        int bufLen = 22;  // Max number of octal digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 7];
-        } while ((v >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    private static String stringOf(char... args) {
-        return new String(args, 0, args.length);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
deleted file mode 100644
index 59cc75f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Provides alternate implementation to java.util.LinkedHashMap#eldest(), which is present as a
- * non-public method in the Android VM, but not present on the host VM. This is injected in the
- * layoutlib using {@link ReplaceMethodCallsAdapter}.
- */
-public class LinkedHashMap_Delegate {
-    public static <K,V> Map.Entry<K,V> eldest(LinkedHashMap<K,V> map) {
-        Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
-        return iterator.hasNext() ? iterator.next() : null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
deleted file mode 100644
index eb1ef72..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
+++ /dev/null
@@ -1,132 +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.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * Defines the same class as the java.util.Objects which is added in Java 7.
- * This hack makes it possible to run the Android code which uses Java 7 features
- * (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 19, file:
- * platform/libcore/luni/src/main/java/java/util/Objects.java
- */
-public final class Objects {
-  private Objects() {}
-
-  /**
-   * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
-   * That is, this makes {@code c} null-safe.
-   */
-  public static <T> int compare(T a, T b, Comparator<? super T> c) {
-    if (a == b) {
-      return 0;
-    }
-    return c.compare(a, b);
-  }
-
-  /**
-   * Returns true if both arguments are null,
-   * the result of {@link Arrays#equals} if both arguments are primitive arrays,
-   * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
-   * and the result of {@link #equals} otherwise.
-   */
-  public static boolean deepEquals(Object a, Object b) {
-    if (a == null || b == null) {
-      return a == b;
-    } else if (a instanceof Object[] && b instanceof Object[]) {
-      return Arrays.deepEquals((Object[]) a, (Object[]) b);
-    } else if (a instanceof boolean[] && b instanceof boolean[]) {
-      return Arrays.equals((boolean[]) a, (boolean[]) b);
-    } else if (a instanceof byte[] && b instanceof byte[]) {
-      return Arrays.equals((byte[]) a, (byte[]) b);
-    } else if (a instanceof char[] && b instanceof char[]) {
-      return Arrays.equals((char[]) a, (char[]) b);
-    } else if (a instanceof double[] && b instanceof double[]) {
-      return Arrays.equals((double[]) a, (double[]) b);
-    } else if (a instanceof float[] && b instanceof float[]) {
-      return Arrays.equals((float[]) a, (float[]) b);
-    } else if (a instanceof int[] && b instanceof int[]) {
-      return Arrays.equals((int[]) a, (int[]) b);
-    } else if (a instanceof long[] && b instanceof long[]) {
-      return Arrays.equals((long[]) a, (long[]) b);
-    } else if (a instanceof short[] && b instanceof short[]) {
-      return Arrays.equals((short[]) a, (short[]) b);
-    }
-    return a.equals(b);
-  }
-
-  /**
-   * Null-safe equivalent of {@code a.equals(b)}.
-   */
-  public static boolean equals(Object a, Object b) {
-    return (a == null) ? (b == null) : a.equals(b);
-  }
-
-  /**
-   * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
-   * This can be used to compute a hash code for an object's fields as follows:
-   * {@code Objects.hash(a, b, c)}.
-   */
-  public static int hash(Object... values) {
-    return Arrays.hashCode(values);
-  }
-
-  /**
-   * Returns 0 for null or {@code o.hashCode()}.
-   */
-  public static int hashCode(Object o) {
-    return (o == null) ? 0 : o.hashCode();
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}.
-   */
-  public static <T> T requireNonNull(T o) {
-    if (o == null) {
-      throw new NullPointerException();
-    }
-    return o;
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}
-   * with the given detail message.
-   */
-  public static <T> T requireNonNull(T o, String message) {
-    if (o == null) {
-      throw new NullPointerException(message);
-    }
-    return o;
-  }
-
-  /**
-   * Returns "null" for null or {@code o.toString()}.
-   */
-  public static String toString(Object o) {
-    return (o == null) ? "null" : o.toString();
-  }
-
-  /**
-   * Returns {@code nullString} for null or {@code o.toString()}.
-   */
-  public static String toString(Object o, String nullString) {
-    return (o == null) ? nullString : o.toString();
-  }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
deleted file mode 100644
index be93744..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
+++ /dev/null
@@ -1,68 +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.android.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provides dummy implementation of methods that don't exist on the host VM.
- * This also providers a time control that allows to set a specific system time.
- *
- * @see ReplaceMethodCallsAdapter
- */
-@SuppressWarnings("unused")
-public class System_Delegate {
-    // Current system time
-    private static AtomicLong mNanosTime = new AtomicLong(System.nanoTime());
-    // Time that the system booted up in nanos
-    private static AtomicLong mBootNanosTime = new AtomicLong(System.nanoTime());
-
-    public static void log(String message) {
-        // ignore.
-    }
-
-    public static void log(String message, Throwable th) {
-        // ignore.
-    }
-
-    public static void setNanosTime(long nanos) {
-        mNanosTime.set(nanos);
-    }
-
-    public static void setBootTimeNanos(long nanos) {
-        mBootNanosTime.set(nanos);
-    }
-
-    public static long nanoTime() {
-        return mNanosTime.get();
-    }
-
-    public static long currentTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mNanosTime.get());
-    }
-
-    public static long bootTime() {
-        return mBootNanosTime.get();
-    }
-
-    public static long bootTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mBootNanosTime.get());
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
deleted file mode 100644
index 0e09080..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
+++ /dev/null
@@ -1,81 +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.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.lang.UnsafeByteSequence which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/UnsafeByteSequence.java
- */
-public class UnsafeByteSequence {
-    private byte[] bytes;
-    private int count;
-
-    public UnsafeByteSequence(int initialCapacity) {
-        this.bytes = new byte[initialCapacity];
-    }
-
-    public int size() {
-        return count;
-    }
-
-    /**
-     * Moves the write pointer back to the beginning of the sequence,
-     * but without resizing or reallocating the buffer.
-     */
-    public void rewind() {
-        count = 0;
-    }
-
-    public void write(byte[] buffer, int offset, int length) {
-        if (count + length >= bytes.length) {
-            byte[] newBytes = new byte[(count + length) * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        System.arraycopy(buffer, offset, bytes, count, length);
-        count += length;
-    }
-
-    public void write(int b) {
-        if (count == bytes.length) {
-            byte[] newBytes = new byte[count * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        bytes[count++] = (byte) b;
-    }
-
-    public byte[] toByteArray() {
-        if (count == bytes.length) {
-            return bytes;
-        }
-        byte[] result = new byte[count];
-        System.arraycopy(bytes, 0, result, 0, count);
-        return result;
-    }
-
-    public String toString(Charset cs) {
-        return new String(bytes, 0, count, cs);
-    }
-}
diff --git a/tools/layoutlib/create/tests/Android.mk b/tools/layoutlib/create/tests/Android.mk
deleted file mode 100644
index 488d7d6..0000000
--- a/tools/layoutlib/create/tests/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)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, com)
-
-LOCAL_JAVA_RESOURCE_DIRS := data mock_data
-
-LOCAL_MODULE := layoutlib-create-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib_create junit-host
-LOCAL_STATIC_JAVA_LIBRARIES := asm-5.2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
deleted file mode 100644
index f86917a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Unit tests for some methods of {@link AsmAnalyzer}.
- */
-public class AsmAnalyzerTest {
-
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private AsmAnalyzer mAa;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        Set<String> excludeClasses = Collections.singleton("java.lang.JavaClass");
-
-        String[] includeFiles = new String[]{"mock_android/data/data*"};
-        mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */,
-                null /* includeGlobs */, excludeClasses, includeFiles);
-    }
-
-    @Test
-    public void testParseZip() throws IOException {
-
-        Map<String, ClassReader> map = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, map, filesFound);
-
-        assertArrayEquals(new String[] {
-                "java.lang.JavaClass",
-                "mock_android.dummy.InnerTest",
-                "mock_android.dummy.InnerTest$DerivingClass",
-                "mock_android.dummy.InnerTest$MyGenerics1",
-                "mock_android.dummy.InnerTest$MyIntEnum",
-                "mock_android.dummy.InnerTest$MyStaticInnerClass",
-                "mock_android.dummy.InnerTest$NotStaticInner1",
-                "mock_android.dummy.InnerTest$NotStaticInner2",
-                "mock_android.util.EmptyArray",
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.LinearLayout$LayoutParams",
-                "mock_android.widget.TableLayout",
-                "mock_android.widget.TableLayout$LayoutParams"
-            },
-            map.keySet().toArray());
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-            filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testFindClass() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
-                zipClasses, found);
-
-        assertNotNull(cr);
-        assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName());
-        assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" },
-                found.keySet().toArray());
-        assertArrayEquals(new ClassReader[] { cr }, found.values().toArray());
-    }
-
-    @Test
-    public void testFindGlobs() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        // this matches classes, a package match returns nothing
-        found.clear();
-        mAa.findGlobs("mock_android.view", zipClasses, found);
-
-        assertArrayEquals(new String[] { },
-            found.keySet().toArray());
-
-        // a complex glob search. * is a search pattern that matches names, not dots
-        mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // a complex glob search. ** is a search pattern that matches names including dots
-        mAa.findGlobs("mock_android.**Group*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // matches a single class
-        found.clear();
-        mAa.findGlobs("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View"
-            },
-            found.keySet().toArray());
-
-        // matches everyting inside the given package but not sub-packages
-        found.clear();
-        mAa.findGlobs("mock_android.view.*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testFindClassesDerivingFrom() throws LogAbortException, IOException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.TableLayout",
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testDependencyVisitor() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> keep = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> in_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> out_deps = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep);
-        DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);
-
-        // get first level dependencies
-        cr.accept(visitor, 0 /* flags */);
-
-        assertArrayEquals(new String[] {
-                "mock_android.util.EmptyArray",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout$LayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get second level dependencies
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get third level dependencies (there are none)
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-        keep.putAll(new_keep);
-
-        assertArrayEquals(new String[] { }, out_deps.keySet().toArray());
-        assertArrayEquals(new String[] {
-                "mock_android.widget.LinearLayout",
-        }, keep.keySet().toArray());
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
deleted file mode 100644
index e718fb9..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for some methods of {@link AsmGenerator}.
- */
-public class AsmGeneratorTest {
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private String mOsDestJar;
-    private File mTempFile;
-
-    // ASM internal name for the the class in java package that should be refactored.
-    private static final String JAVA_CLASS_NAME = "java/lang/JavaClass";
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        mTempFile = File.createTempFile("mock", ".jar");
-        mOsDestJar = mTempFile.getAbsolutePath();
-        mTempFile.deleteOnExit();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mTempFile != null) {
-            //noinspection ResultOfMethodCallIgnored
-            mTempFile.delete();
-            mTempFile = null;
-        }
-    }
-
-    @Test
-    public void testClassRenaming() throws IOException, LogAbortException {
-
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                        "not.an.actual.ClassName", "anoter.fake.NewClassName",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet() /* excluded classes */,
-                new String[]{} /* include files */);
-        aa.analyze();
-        agen.generate();
-
-        Set<String> notRenamed = agen.getClassesNotRenamed();
-        assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
-
-    }
-
-    @Test
-    public void testJavaClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-             // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass",
-                };
-            }
-
-            @Override
-            public Set<String> getExcludedClasses() {
-                return Collections.singleton("java.lang.JavaClass");
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet(),
-                new String[] {        /* include files */
-                    "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "com/android/tools/layoutlib/create/dataclass/JavaClass"));
-        assertFalse(cv.mVisitedClasses.contains(
-                JAVA_CLASS_NAME));
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getRefactoredClasses() {
-                // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                Collections.emptySet(),
-                new String[] {});
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        parseZip(mOsDestJar, output, new TreeMap<>());
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "mock_android/view/_Original_View"));
-        assertFalse(cv.mVisitedClasses.contains(
-                "mock_android/view/View"));
-    }
-
-    @Test
-    public void testClassExclusion() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Set<String> getExcludedClasses() {
-                Set<String> set = new HashSet<>(2);
-                set.add("mock_android.dummy.InnerTest");
-                set.add("java.lang.JavaClass");
-                return set;
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        Set<String> excludedClasses = ci.getExcludedClasses();
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                excludedClasses,
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        for (String s : output.keySet()) {
-            assertFalse(excludedClasses.contains(s));
-        }
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testMethodInjection() throws IOException, LogAbortException,
-            ClassNotFoundException, IllegalAccessException, InstantiationException,
-            NoSuchMethodException, InvocationTargetException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.singletonMap("mock_android.util.EmptyArray",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                ci.getExcludedClasses(),
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        final String modifiedClass = "mock_android.util.EmptyArray";
-        final String modifiedClassPath = modifiedClass.replace('.', '/').concat(".class");
-        ZipFile zipFile = new ZipFile(mOsDestJar);
-        ZipEntry entry = zipFile.getEntry(modifiedClassPath);
-        assertNotNull(entry);
-        final byte[] bytes;
-        try (InputStream inputStream = zipFile.getInputStream(entry)) {
-            bytes = getByteArray(inputStream);
-        }
-        ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) {
-            @Override
-            protected Class<?> findClass(String name) throws ClassNotFoundException {
-                if (name.equals(modifiedClass)) {
-                    return defineClass(null, bytes, 0, bytes.length);
-                }
-                throw new ClassNotFoundException(name + " not found.");
-            }
-        };
-        Class<?> emptyArrayClass = classLoader.loadClass(modifiedClass);
-        Object emptyArrayInstance = emptyArrayClass.newInstance();
-        Method method = emptyArrayClass.getMethod("getFrameworkClassLoader");
-        Object cl = method.invoke(emptyArrayInstance);
-        assertEquals(classLoader, cl);
-    }
-
-    private static byte[] getByteArray(InputStream stream) throws IOException {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int read;
-        while ((read = stream.read(buffer, 0, buffer.length)) > -1) {
-            bos.write(buffer, 0, read);
-        }
-        return bos.toByteArray();
-    }
-
-    private void parseZip(String jarPath,
-            Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    filesFound.put(entry.getName(), zip.getInputStream(entry));
-                }
-            }
-
-    }
-
-    private String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * {@link ClassVisitor} that records every class that sees.
-     */
-    private static class RecordingClassVisitor extends ClassVisitor {
-        private Set<String> mVisitedClasses = new HashSet<>();
-
-        private RecordingClassVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        private void addClass(String className) {
-            if (className == null) {
-                return;
-            }
-
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                // For inner classes, add also the base class
-                mVisitedClasses.add(className.substring(0, pos));
-            }
-            mVisitedClasses.add(className);
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            addClass(superName);
-            Arrays.stream(interfaces).forEach(this::addClass);
-        }
-
-        private void processType(Type type) {
-            switch (type.getSort()) {
-                case Type.OBJECT:
-                    addClass(type.getInternalName());
-                    break;
-                case Type.ARRAY:
-                    addClass(type.getElementType().getInternalName());
-                    break;
-                case Type.METHOD:
-                    processType(type.getReturnType());
-                    Arrays.stream(type.getArgumentTypes()).forEach(this::processType);
-                    break;
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc, String signature,
-                Object value) {
-            processType(Type.getType(desc));
-            return super.visitField(access, name, desc, signature, value);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-            return new MethodVisitor(Main.ASM_VERSION, mv) {
-
-                @Override
-                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitFieldInsn(opcode, owner, name, desc);
-                }
-
-                @Override
-                public void visitLdcInsn(Object cst) {
-                    if (cst instanceof Type) {
-                        processType((Type) cst);
-                    }
-                    super.visitLdcInsn(cst);
-                }
-
-                @Override
-                public void visitTypeInsn(int opcode, String type) {
-                    addClass(type);
-                    super.visitTypeInsn(opcode, type);
-                }
-
-                @Override
-                public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                        boolean itf) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitMethodInsn(opcode, owner, name, desc, itf);
-                }
-
-            };
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
deleted file mode 100644
index 0cdcdc0..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-
-/**
- * Tests {@link ClassHasNativeVisitor}.
- */
-public class ClassHasNativeVisitorTest {
-
-    @Test
-    public void testHasNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-                this.getClass().getCanonicalName() + "$" + ClassWithNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
-        assertTrue(cv.hasNativeMethods());
-    }
-
-    @Test
-    public void testHasNoNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-            this.getClass().getCanonicalName() + "$" + ClassWithoutNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[0], cv.getMethodsFound());
-        assertFalse(cv.hasNativeMethods());
-    }
-
-    //-------
-
-    /**
-     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
-     */
-    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
-        private ArrayList<String> mMethodsFound = new ArrayList<>();
-
-        public String[] getMethodsFound() {
-            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
-        }
-
-        @Override
-        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-            if (hasNativeMethods) {
-                mMethodsFound.add(methodName);
-            }
-            super.setHasNativeMethods(hasNativeMethods, methodName);
-        }
-    }
-
-    /**
-     * Dummy test class with a native method.
-     */
-    public static class ClassWithNative {
-        public ClassWithNative() {
-        }
-
-        public void callTheNativeMethod() {
-            native_method();
-        }
-
-        private native void native_method();
-    }
-
-    /**
-     * Dummy test class with no native method.
-     */
-    public static class ClassWithoutNative {
-        public ClassWithoutNative() {
-        }
-
-        public void someMethod() {
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
deleted file mode 100644
index ad7cb9a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
+++ /dev/null
@@ -1,80 +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.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-class CreateInfoAdapter implements ICreateInfo {
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return new Class<?>[0];
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return Collections.emptyMap();
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
deleted file mode 100644
index afaa399..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.tools.layoutlib.create.dataclass.ClassWithNative;
-import com.android.tools.layoutlib.create.dataclass.OuterClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class DelegateClassAdapterTest {
-
-    private MockLog mLog;
-
-    private static final String NATIVE_CLASS_NAME = ClassWithNative.class.getName();
-    private static final String OUTER_CLASS_NAME = OuterClass.class.getName();
-    private static final String INNER_CLASS_NAME = InnerClass.class.getName();
-    private static final String STATIC_INNER_CLASS_NAME = StaticInnerClass.class.getName();
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        mLog.setVerbose(true); // capture debug error too
-    }
-
-    /**
-     * Tests that a class not being modified still works.
-     */
-    @Test
-    public void testNoOp() throws Throwable {
-        // create an instance of the class that will be modified
-        // (load the class in a distinct class loader so that we can trash its definition later)
-        ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) { };
-        @SuppressWarnings("unchecked")
-        Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
-        ClassWithNative instance1 = clazz1.newInstance();
-        assertEquals(42, instance1.add(20, 22));
-        try {
-            instance1.callNativeInstance(10, 3.1415, new Object[0] );
-            fail("Test should have failed to invoke callTheNativeMethod [1]");
-        } catch (UnsatisfiedLinkError e) {
-            // This is expected to fail since the native method is not implemented.
-        }
-
-        // Now process it but tell the delegate to not modify any method
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it again
-
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                    try {
-                        callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
-                        fail("Test should have failed to invoke callTheNativeMethod [2]");
-                    } catch (InvocationTargetException e) {
-                        // This is expected to fail since the native method has NOT been
-                        // overridden here.
-                        assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
-                    }
-
-                    // Check that the native method does NOT have the new annotation
-                    Method[] m = clazz2.getDeclaredMethods();
-                    Method nativeInstanceMethod = null;
-                    for (Method method : m) {
-                        if ("native_instance".equals(method.getName())) {
-                            nativeInstanceMethod = method;
-                            break;
-                        }
-                    }
-                    assertNotNull(nativeInstanceMethod);
-                    assertTrue(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                    Annotation[] a = nativeInstanceMethod.getAnnotations();
-                    assertEquals(0, a.length);
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    /**
-     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
-     * so this should fail with an {@link UnsupportedOperationException}.
-     *
-     * Although not tested here, the message of the exception should contain the
-     * constructor signature.
-     */
-    @Test(expected=UnsupportedOperationException.class)
-    public void testConstructorsNotSupported() throws IOException {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("<init>");
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-    }
-
-    @Test
-    public void testDelegateNative() throws Throwable {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-
-                    // Use reflection to access inner methods
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                     Object[] objResult = new Object[] { null };
-                     int result = callCallNativeInstance(i2, 10, 3.1415, objResult);
-                     assertEquals((int)(10 + 3.1415), result);
-                     assertSame(i2, objResult[0]);
-
-                     // Check that the native method now has the new annotation and is not native
-                     Method[] m = clazz2.getDeclaredMethods();
-                     Method nativeInstanceMethod = null;
-                     for (Method method : m) {
-                         if ("native_instance".equals(method.getName())) {
-                             nativeInstanceMethod = method;
-                             break;
-                         }
-                     }
-                     assertNotNull(nativeInstanceMethod);
-                     assertFalse(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                     Annotation[] a = nativeInstanceMethod.getAnnotations();
-                     assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-        delegateMethods.add("privateMethod");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // The original Outer.get returns 1+10+20,
-                    // but the delegate makes it return 4+10+20
-                    assertEquals(4+10+20, callGet(o2, 10, 20));
-                    assertEquals(1+10+20, callGet_Original(o2, 10, 20));
-
-                    // The original Outer has a private method,
-                    // so by default we can't access it.
-                    boolean gotIllegalAccessException = false;
-                    try {
-                         callMethod(o2, "privateMethod", false /*makePublic*/);
-                    } catch(IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // The private method from original Outer has been
-                    // delegated. The delegate generated should have the
-                    // same access.
-                    gotIllegalAccessException = false;
-                    try {
-                        assertEquals("outerPrivateMethod",
-                                callMethod(o2, "privateMethod_Original", false /*makePublic*/));
-                    } catch (IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
-                    Object i2 = innerCons.newInstance(o2);
-                    assertNotNull(i2);
-
-                    // The original Inner.get returns 3+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(3+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateStaticInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the static inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = STATIC_INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(STATIC_INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(STATIC_INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor();
-                    Object i2 = innerCons.newInstance();
-                    assertNotNull(i2);
-
-                    // The original StaticInner.get returns 100+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(100+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(STATIC_INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    //-------
-
-    /**
-     * A class loader than can define and instantiate our modified classes.
-     * <p/>
-     * The trick here is that this class loader will test our <em>modified</em> version
-     * of the classes, the one with the delegate calls.
-     * <p/>
-     * Trying to do so in the original class loader generates all sort of link issues because
-     * there are 2 different definitions of the same class name. This class loader will
-     * define and load the class when requested by name and provide helpers to access the
-     * instance methods via reflection.
-     */
-    private abstract class ClassLoader2 extends ClassLoader {
-
-        private final Map<String, byte[]> mClassDefs = new HashMap<>();
-
-        public ClassLoader2() {
-            super(null);
-        }
-
-        public ClassLoader2 add(String className, byte[] definition) {
-            mClassDefs.put(className, definition);
-            return this;
-        }
-
-        public ClassLoader2 add(String className, ClassWriter rewrittenClass) {
-            mClassDefs.put(className, rewrittenClass.toByteArray());
-            return this;
-        }
-
-        private Set<Entry<String, byte[]>> getByteCode() {
-            return mClassDefs.entrySet();
-        }
-
-        @SuppressWarnings("unused")
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            try {
-                return super.findClass(name);
-            } catch (ClassNotFoundException e) {
-
-                byte[] def = mClassDefs.get(name);
-                if (def != null) {
-                    // Load the modified ClassWithNative from its bytes representation.
-                    return defineClass(name, def, 0, def.length);
-                }
-
-                try {
-                    // Load everything else from the original definition into the new class loader.
-                    ClassReader cr = new ClassReader(name);
-                    ClassWriter cw = new ClassWriter(0);
-                    cr.accept(cw, 0);
-                    byte[] bytes = cw.toByteArray();
-                    return defineClass(name, bytes, 0, bytes.length);
-
-                } catch (IOException ioe) {
-                    throw new RuntimeException(ioe);
-                }
-            }
-        }
-
-        /**
-         * Accesses {@link OuterClass#get} or {@link InnerClass#get}via reflection.
-         */
-        public int callGet(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the "_Original" methods for {@link OuterClass#get}
-         * or {@link InnerClass#get}via reflection.
-         */
-        public int callGet_Original(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get_Original",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the any declared method that takes no parameter via reflection.
-         */
-        @SuppressWarnings("unchecked")
-        public <T> T callMethod(Object instance, String methodName, boolean makePublic) throws Exception {
-            Method m = instance.getClass().getDeclaredMethod(methodName, (Class<?>[])null);
-
-            boolean wasAccessible = m.isAccessible();
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(true);
-            }
-
-            Object result = m.invoke(instance, (Object[])null);
-
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(false);
-            }
-
-            return (T) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#add(int, int)} via reflection.
-         */
-        public int callAdd(Object instance, int a, int b) throws Exception {
-            Method m = instance.getClass().getMethod("add",
-                    int.class, int.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#callNativeInstance(int, double, Object[])}
-         * via reflection.
-         */
-        public int callCallNativeInstance(Object instance, int a, double d, Object[] o)
-                throws Exception {
-            Method m = instance.getClass().getMethod("callNativeInstance",
-                    int.class, double.class, Object[].class);
-
-            Object result = m.invoke(instance, a, d, o);
-            return (Integer) result;
-        }
-
-        public abstract void testModifiedInstance() throws Exception;
-    }
-
-    /**
-     * For debugging, it's useful to dump the content of the generated classes
-     * along with the exception that was generated.
-     *
-     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
-     * class and associated utilities which are found in the ASM source jar. Since we don't
-     * want that dependency in the source code, we only put it manually for development and
-     * access the TraceClassVisitor via reflection if present.
-     *
-     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
-     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
-     * @return Either original {@code t} or a new wrapper {@link Throwable}
-     */
-    private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
-        try {
-            // For debugging, dump the bytecode of the class in case of unexpected error
-            // if we can find the TraceClassVisitor class.
-            Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('\n').append(t.getClass().getCanonicalName());
-            if (t.getMessage() != null) {
-                sb.append(": ").append(t.getMessage());
-              }
-
-            for (Entry<String, byte[]> entry : cl2.getByteCode()) {
-                String className = entry.getKey();
-                byte[] bytes = entry.getValue();
-
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
-                // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
-                Constructor<?> cons = tcvClass.getConstructor(pw.getClass());
-                Object tcv = cons.newInstance(pw);
-                ClassReader cr2 = new ClassReader(bytes);
-                cr2.accept((ClassVisitor) tcv, 0 /* flags */);
-
-                sb.append("\nBytecode dump: <").append(className).append(">:\n")
-                  .append(sw.toString());
-            }
-
-            // Re-throw exception with new message
-            return new RuntimeException(sb.toString(), t);
-        } catch (Throwable ignore) {
-            // In case of problem, just throw the original exception as-is.
-            return t;
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
deleted file mode 100644
index 1a5f653..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LogTest {
-
-    private MockLog mLog;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // pass
-    }
-
-    @Test
-    public void testDebug() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.setVerbose(false);
-        mLog.debug("Test %d", 42);
-        assertEquals("", mLog.getOut());
-
-        mLog.setVerbose(true);
-        mLog.debug("Test %d", 42);
-
-        assertEquals("Test 42\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testInfo() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.info("Test %d", 43);
-
-        assertEquals("Test 43\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testError() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.error("Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertEquals("Test 44\n", mLog.getErr());
-    }
-
-    @Test
-    public void testException() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        Exception e = new Exception("My Exception");
-        mLog.exception(e, "Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertTrue(mLog.getErr().startsWith("Test 44\njava.lang.Exception: My Exception"));
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
deleted file mode 100644
index de750a3..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-public class MockLog extends Log {
-    StringBuilder mOut = new StringBuilder();
-    StringBuilder mErr = new StringBuilder();
-
-    public String getOut() {
-        return mOut.toString();
-    }
-
-    public String getErr() {
-        return mErr.toString();
-    }
-
-    @Override
-    protected void outPrintln(String msg) {
-        mOut.append(msg);
-        mOut.append('\n');
-    }
-
-    @Override
-    protected void errPrintln(String msg) {
-        mErr.append(msg);
-        mErr.append('\n');
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
deleted file mode 100644
index eeb0b10..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
+++ /dev/null
@@ -1,170 +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.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringJoiner;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * {@link ClassVisitor} that logs all the calls to the different visit methods so they can be later
- * inspected.
- */
-class LoggingClassVisitor extends ClassVisitor {
-    List<String> mLog = new LinkedList<String>();
-
-    public LoggingClassVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    public LoggingClassVisitor(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    private static String formatAccess(int access) {
-        StringJoiner modifiers = new StringJoiner(",");
-
-        if ((access & Opcodes.ACC_PUBLIC) != 0) {
-            modifiers.add("public");
-        }
-        if ((access & Opcodes.ACC_PRIVATE) != 0) {
-            modifiers.add("private");
-        }
-        if ((access & Opcodes.ACC_PROTECTED) != 0) {
-            modifiers.add("protected");
-        }
-        if ((access & Opcodes.ACC_STATIC) != 0) {
-            modifiers.add("static");
-        }
-        if ((access & Opcodes.ACC_FINAL) != 0) {
-            modifiers.add("static");
-        }
-
-        return "[" + modifiers.toString() + "]";
-    }
-
-    private void log(String method, String format, Object...args) {
-        mLog.add(
-                String.format("[%s] - %s", method, String.format(format, (Object[]) args))
-        );
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        log(
-                "visitOuterClass",
-                "owner=%s, name=%s, desc=%s",
-                owner, name, desc
-        );
-
-        super.visitOuterClass(owner, name, desc);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        log(
-                "visitInnerClass",
-                "name=%s, outerName=%s, innerName=%s, access=%s",
-                name, outerName, innerName, formatAccess(access)
-        );
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        log(
-                "visit",
-                "version=%d, access=%s, name=%s, signature=%s, superName=%s, interfaces=%s",
-                version, formatAccess(access), name, signature, superName, Arrays.toString(interfaces)
-        );
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-}
-
-class PackageProtectedClass {}
-
-public class PromoteClassClassAdapterTest {
-    private static class PrivateClass {}
-    private static class ClassWithPrivateInnerClass {
-        private class InnerPrivateClass {}
-    }
-
-    @Test
-    public void testInnerClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PrivateClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PromoteClassClassAdapterTest$PrivateClass");
-                add("com.android.tools.layoutlib.create" +
-                        ".PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass");
-            }
-        });
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains(
-                "[visitInnerClass] - " +
-                        "name=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest$PrivateClass, " +
-                        "outerName=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest, innerName=PrivateClass, access=[public,static]"));
-
-        // Test inner of inner class
-        log.mLog.clear();
-        reader = new ClassReader(ClassWithPrivateInnerClass.class.getName());
-        reader.accept(adapter, 0);
-
-        assertTrue(log.mLog.contains("[visitInnerClass] - " +
-                "name=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass, " +
-                "outerName=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass, " +
-                "innerName=InnerPrivateClass, access=[public]"));
-
-    }
-
-    @Test
-    public void testProtectedClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PackageProtectedClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PackageProtectedClass");
-            }
-        });
-
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains("[visit] - version=52, access=[public], " +
-                "name=com/android/tools/layoutlib/create/PackageProtectedClass, signature=null, " +
-                "superName=java/lang/Object, interfaces=[]"));
-
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
deleted file mode 100644
index 6211e73..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008 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.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- *
- */
-public class RenameClassAdapterTest {
-
-    private RenameClassAdapter mOuter;
-    private RenameClassAdapter mInner;
-
-    @Before
-    public void setUp() throws Exception {
-        mOuter = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old",
-                                         "org.blah.New");
-
-        mInner = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old$Inner",
-                                         "org.blah.New$Inner");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    /**
-     * Renames a type, e.g. "Lcom.package.My;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameTypeDesc() {
-
-        // primitive types are left untouched
-        assertEquals("I", mOuter.renameTypeDesc("I"));
-        assertEquals("D", mOuter.renameTypeDesc("D"));
-        assertEquals("V", mOuter.renameTypeDesc("V"));
-
-        // object types that need no renaming are left untouched
-        assertEquals("Lcom.package.MyClass;", mOuter.renameTypeDesc("Lcom.package.MyClass;"));
-        assertEquals("Lcom.package.MyClass;", mInner.renameTypeDesc("Lcom.package.MyClass;"));
-
-        // object types that match the requirements
-        assertEquals("Lorg.blah.New;", mOuter.renameTypeDesc("Lcom.pack.Old;"));
-        assertEquals("Lorg.blah.New$Inner;", mInner.renameTypeDesc("Lcom.pack.Old$Inner;"));
-        // inner classes match the base type which is being renamed
-        assertEquals("Lorg.blah.New$Other;", mOuter.renameTypeDesc("Lcom.pack.Old$Other;"));
-        assertEquals("Lorg.blah.New$Other;", mInner.renameTypeDesc("Lcom.pack.Old$Other;"));
-
-        // arrays
-        assertEquals("[Lorg.blah.New;",  mOuter.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;"));
-
-        assertEquals("[Lorg.blah.New;",  mInner.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;"));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    @Test
-    public void testRenameType() {
-        // Skip. This is actually tested by testRenameTypeDesc above.
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameInternalType() {
-        // an actual FQCN
-        assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old"));
-        assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner"));
-
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    @Test
-    public void testRenameMethodDesc() {
-        assertEquals("(IDLorg.blah.New;[Lorg.blah.New$Inner;)Lorg.blah.New$Other;",
-               mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;"));
-    }
-
-
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
deleted file mode 100644
index 3db3e23..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
+++ /dev/null
@@ -1,132 +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.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.dataclass.StubClass;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.lang.reflect.Method;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-
-import static org.junit.Assert.*;
-
-public class StubMethodAdapterTest {
-
-    private static final String STUB_CLASS_NAME = StubClass.class.getName();
-
-    /**
-     * Load a dummy class, stub one of its method and ensure that the modified class works as
-     * intended.
-     */
-    @Test
-    public void testBoolean() throws Exception {
-        final String methodName = "returnTrue";
-        // First don't change the method and assert that it returns true
-        testBoolean((name, type) -> false, Assert::assertTrue, methodName);
-        // Change the method now and assert that it returns false.
-        testBoolean((name, type) -> methodName.equals(name) &&
-                Type.BOOLEAN_TYPE.equals(type.getReturnType()), Assert::assertFalse, methodName);
-    }
-
-    /**
-     * @param methodPredicate tests if the method should be replaced
-     */
-    private void testBoolean(BiPredicate<String, Type> methodPredicate, Consumer<Boolean> assertion,
-            String methodName) throws Exception {
-        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        // Always rename the class to avoid conflict with the original class.
-        String newClassName = STUB_CLASS_NAME + '_';
-        new ClassReader(STUB_CLASS_NAME).accept(
-                new ClassAdapter(newClassName, writer, methodPredicate), 0);
-        MyClassLoader myClassLoader = new MyClassLoader(newClassName, writer.toByteArray());
-        Class<?> aClass = myClassLoader.loadClass(newClassName);
-        assertTrue("StubClass not loaded by the classloader. Likely a bug in the test.",
-                myClassLoader.findClassCalled);
-        Method method = aClass.getMethod(methodName);
-        Object o = aClass.newInstance();
-        assertion.accept((Boolean) method.invoke(o));
-    }
-
-    private static class ClassAdapter extends ClassVisitor {
-
-        private final String mClassName;
-        private final BiPredicate<String, Type> mMethodPredicate;
-
-        private ClassAdapter(String className, ClassVisitor cv,
-                BiPredicate<String, Type> methodPredicate) {
-            super(Main.ASM_VERSION, cv);
-            mClassName = className.replace('.', '/');
-            mMethodPredicate = methodPredicate;
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            super.visit(version, access, mClassName, signature, superName,
-                    interfaces);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            // Copied partly from
-            // com.android.tools.layoutlib.create.DelegateClassAdapter.visitMethod()
-            // but not generating the _Original method.
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-            MethodVisitor originalMethod =
-                    super.visitMethod(access, name, desc, signature, exceptions);
-            Type descriptor = Type.getMethodType(desc);
-            if (mMethodPredicate.test(name, descriptor)) {
-                String methodSignature = mClassName + "#" + name;
-                String invokeSignature = methodSignature + desc;
-                return new StubMethodAdapter(originalMethod, name, descriptor.getReturnType(),
-                        invokeSignature, isStatic, isNative);
-            }
-            return originalMethod;
-        }
-    }
-
-    private static class MyClassLoader extends ClassLoader {
-        private final String mName;
-        private final byte[] mBytes;
-        private boolean findClassCalled;
-
-        private MyClassLoader(String name, byte[] bytes) {
-            mName = name;
-            mBytes = bytes;
-        }
-
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            if (name.equals(mName)) {
-                findClassCalled = true;
-                return defineClass(name, mBytes, 0, mBytes.length);
-            }
-            return super.findClass(name);
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
deleted file mode 100644
index c314853..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Dummy test class with a native method.
- * The native method is not defined and any attempt to invoke it will
- * throw an {@link UnsatisfiedLinkError}.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative {
-    public ClassWithNative() {
-    }
-
-    public int add(int a, int b) {
-        return a + b;
-    }
-
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-
-    public int callNativeInstance(int a, double d, Object[] o) {
-        return native_instance(a, d, o);
-    }
-
-    private native int native_instance(int a, double d, Object[] o);
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
deleted file mode 100644
index a3d4dc6..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * The delegate that receives the call to {@link ClassWithNative_Delegate}'s overridden methods.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative_Delegate {
-    public static int native_instance(ClassWithNative instance, int a, double d, Object[] o) {
-        if (o != null && o.length > 0) {
-            o[0] = instance;
-        }
-        return (int)(a + d);
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
deleted file mode 100644
index 9b5a918..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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.tools.layoutlib.create.dataclass;
-
-public final class JavaClass {
-
-    public static final String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
deleted file mode 100644
index 6dfb816..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Test class with an inner class.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass {
-    private int mOuterValue = 1;
-    public OuterClass() {
-    }
-
-    // Outer.get returns 1 + a + b
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-    public int get(int a, long b) {
-        return mOuterValue + a + (int) b;
-    }
-
-    public class InnerClass {
-        public InnerClass() {
-        }
-
-        // Inner.get returns 2 + 1 + a + b
-        public int get(int a, long b) {
-            return 2 + mOuterValue + a + (int) b;
-        }
-    }
-
-    public static class StaticInnerClass {
-        public StaticInnerClass() {
-        }
-
-        // StaticInnerClass.get returns 100 + a + b
-        public int get(int a, long b) {
-            return 100 + a + (int) b;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private String privateMethod() {
-        return "outerPrivateMethod";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
deleted file mode 100644
index 774be8e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2011 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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_Delegate {
-    // The delegate override of Outer.get returns 4 + a + b
-    public static int get(OuterClass instance, int a, long b) {
-        return 4 + a + (int) b;
-    }
-
-    public static String privateMethod(OuterClass instance) {
-        return "outerPrivate_Delegate";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
deleted file mode 100644
index b472220..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_InnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(OuterClass outer, InnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
deleted file mode 100644
index a29439e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_StaticInnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(StaticInnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
deleted file mode 100644
index 3ae8e47..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
+++ /dev/null
@@ -1,30 +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.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.StubMethodAdapterTest;
-
-/**
- * Used by {@link StubMethodAdapterTest}
- */
-@SuppressWarnings("unused")
-public class StubClass {
-
-    public boolean returnTrue() {
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar
deleted file mode 100644
index c6ca3c4..0000000
--- a/tools/layoutlib/create/tests/data/mock_android.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
deleted file mode 100644
index 59612e9..0000000
--- a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 java.lang;
-
-public class JavaClass {
-
-    public static String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
deleted file mode 100644
index ab29fbe..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should *not* be copied to the output jar.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
deleted file mode 100644
index 9b01893..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should be copied to the output jar unchanged.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
deleted file mode 100644
index d3a1d05..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.dummy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class InnerTest {
-
-    private int mSomeField;
-    private MyStaticInnerClass mInnerInstance;
-    private MyIntEnum mTheIntEnum;
-    private MyGenerics1<int[][], InnerTest, MyIntEnum, float[]> mGeneric1;
-
-    public class NotStaticInner2 extends NotStaticInner1 {
-
-    }
-
-    public class NotStaticInner1 {
-
-        public void someThing() {
-            mSomeField = 2;
-            mInnerInstance = null;
-        }
-
-    }
-
-    private static class MyStaticInnerClass {
-
-    }
-    
-    private static class DerivingClass extends InnerTest {
-        
-    }
-    
-    // enums are a kind of inner static class
-    public enum MyIntEnum {
-        VALUE0(0),
-        VALUE1(1),
-        VALUE2(2);
-
-        MyIntEnum(int myInt) {
-            this.myInt = myInt;
-        }
-        final int myInt;
-    }
-    
-    public static class MyGenerics1<T, U, V, W> {
-        public MyGenerics1() {
-            int a = 1;
-        }
-    }
-    
-    public <X> void genericMethod1(X a, X[] b) {
-    }
-
-    public <X, Y> void genericMethod2(X a, List<Y> b) {
-    }
-
-    public <X, Y extends InnerTest> void genericMethod3(X a, List<Y> b) {
-    }
-
-    public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) {
-        Iterator<T> i = b.iterator();
-    }
-
-    public void someMethod(InnerTest self) {
-        mSomeField = self.mSomeField;
-        MyStaticInnerClass m = new MyStaticInnerClass();
-        mInnerInstance = m;
-        mTheIntEnum = null;
-        mGeneric1 = new MyGenerics1();
-        genericMethod4(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>());
-    }
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java b/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
deleted file mode 100644
index aaeebf6..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.util;
-
-import java.lang.JavaClass;
-
-public class EmptyArray {
-
-        public static final Object[] OBJECT = new Object[0];
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
deleted file mode 100644
index 84ec8a9..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.view;
-
-import java.lang.JavaClass;
-
-public class View {
-
-        String x = JavaClass.test;
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
deleted file mode 100644
index 466470f..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.view;
-
-public class ViewGroup extends View {
-
-    public class MarginLayoutParams extends LayoutParams {
-
-    }
-
-    public class LayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
deleted file mode 100644
index af56c4b..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.widget;
-
-import mock_android.util.EmptyArray;
-import mock_android.view.ViewGroup;
-
-public class LinearLayout extends ViewGroup {
-
-    Object[] mObjects = EmptyArray.OBJECT;
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
deleted file mode 100644
index e455e7d..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * 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 mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class TableLayout extends ViewGroup {
-
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/legacy/Android.mk b/tools/layoutlib/legacy/Android.mk
deleted file mode 100644
index 5855f89..0000000
--- a/tools/layoutlib/legacy/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2008 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)
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt
-
-LOCAL_MODULE := layoutlib-legacy
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/legacy/legacy.iml b/tools/layoutlib/legacy/legacy.iml
deleted file mode 100644
index a167a75..0000000
--- a/tools/layoutlib/legacy/legacy.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 0cfc181..0000000
--- a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,75 +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.layoutlib.bridge;import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Legacy Bridge used in the SDK version of layoutlib
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-    private static final String SDK_NOT_SUPPORTED = "The SDK layoutlib version is not supported";
-    private static final Result NOT_SUPPORTED_RESULT =
-            Status.NOT_IMPLEMENTED.createResult(SDK_NOT_SUPPORTED);
-    private static BufferedImage sImage;
-
-    private static class BridgeRenderSession extends RenderSession {
-
-        @Override
-        public synchronized BufferedImage getImage() {
-            if (sImage == null) {
-                sImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
-                Graphics2D g = sImage.createGraphics();
-                g.clearRect(0, 0, 500, 500);
-                g.drawString(SDK_NOT_SUPPORTED, 20, 20);
-                g.dispose();
-            }
-
-            return sImage;
-        }
-
-        @Override
-        public Result render(long timeout, boolean forceMeasure) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result measure(long timeout) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result getResult() {
-            return NOT_SUPPORTED_RESULT;
-        }
-    }
-
-
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        return new BridgeRenderSession();
-    }
-
-    @Override
-    public int getApiLevel() {
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/rename_font/README b/tools/layoutlib/rename_font/README
deleted file mode 100644
index 600b756..0000000
--- a/tools/layoutlib/rename_font/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This tool is used to rename the PS name encoded inside the ttf font that we ship
-with the SDK. There is bug in Java that returns incorrect results for
-java.awt.Font#layoutGlyphVector() if two fonts with same name but differnt
-versions are loaded. As a workaround, we rename all the fonts that we ship with
-the SDK by appending the font version to its name.
-
-
-The build_font.py copies all files from input_dir to output_dir while renaming
-the font files (*.ttf) in the process.
diff --git a/tools/layoutlib/rename_font/Roboto-Regular.ttf b/tools/layoutlib/rename_font/Roboto-Regular.ttf
deleted file mode 100644
index 7469063..0000000
--- a/tools/layoutlib/rename_font/Roboto-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
deleted file mode 100755
index 9713a4c..0000000
--- a/tools/layoutlib/rename_font/build_font.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Rename the PS name of all fonts in the input directories and copy them to the
-output directory.
-
-Usage: build_font.py /path/to/input_fonts1/ /path/to/input_fonts2/ /path/to/output_fonts/
-
-"""
-
-import glob
-from multiprocessing import Pool
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-# global variable
-dest_dir = '/tmp'
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-
-def main(argv):
-  if len(argv) < 2:
-    sys.exit('Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/')
-  for directory in argv:
-    if not os.path.isdir(directory):
-      sys.exit(directory + ' is not a valid directory')
-  global dest_dir
-  dest_dir = argv[-1]
-  src_dirs = argv[:-1]
-  cwd = os.getcwd()
-  os.chdir(dest_dir)
-  files = glob.glob('*')
-  for filename in files:
-    os.remove(filename)
-  os.chdir(cwd)
-  input_fonts = list()
-  for src_dir in src_dirs:
-    for dirname, dirnames, filenames in os.walk(src_dir):
-      for filename in filenames:
-        input_path = os.path.join(dirname, filename)
-        extension = os.path.splitext(filename)[1].lower()
-        if extension == '.ttf':
-          input_fonts.append(input_path)
-        elif extension == '.xml':
-          shutil.copy(input_path, dest_dir)
-      if '.git' in dirnames:
-        # don't go into any .git directories.
-        dirnames.remove('.git')
-  # Create as many threads as the number of CPUs
-  pool = Pool(processes=None)
-  pool.map(convert_font, input_fonts)
-
-
-def convert_font(input_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = os.path.join(dest_dir, filename)
-  ttx_path = ttx_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-d', dest_dir, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-d', dest_dir, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_dir)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/build_font_single.py b/tools/layoutlib/rename_font/build_font_single.py
deleted file mode 100755
index 4245cdc..0000000
--- a/tools/layoutlib/rename_font/build_font_single.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Rename the PS name of the input font.
-
-OpenType fonts (*.otf) are not currently supported. They are copied to the destination without renaming.
-XML files are also copied in case they are passed there by mistake.
-
-Usage: build_font_single.py /path/to/input_font.ttf /path/to/output_font.ttf
-
-"""
-
-import glob
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# A constant to copy the font without modifying. This is useful when running
-# locally and speed up the time to build the SDK.
-COPY_ONLY = False
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-# A list of extensions to process.
-EXTENSIONS = ['.ttf', '.otf', '.xml']
-
-def main(argv):
-  if len(argv) < 2:
-    print 'Incorrect usage: ' + str(argv)
-    sys.exit('Usage: build_font_single.py /path/to/input/font.ttf /path/to/out/font.ttf')
-  dest_path = argv[-1]
-  input_path = argv[0]
-  extension = os.path.splitext(input_path)[1].lower()
-  if extension in EXTENSIONS:
-    if not COPY_ONLY and extension == '.ttf':
-      convert_font(input_path, dest_path)
-      return
-    shutil.copy(input_path, dest_path)
-
-
-def convert_font(input_path, dest_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = dest_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-o', ttx_path, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-o', dest_path, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_path)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
deleted file mode 100755
index 2ffddf4..0000000
--- a/tools/layoutlib/rename_font/test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-"""Tests build_font.py by renaming a font.
-
-The test copies Roboto-Regular.ttf to a tmp directory and ask build_font.py to rename it and put in another dir.
-We then use ttx to dump the new font to its xml and check if rename was successful
-
-To test locally, use:
-PYTHONPATH="$PYTHONPATH:/path/to/android/checkout/external/fonttools/Lib" ./test.py
-"""
-
-import unittest
-import build_font
-
-from fontTools import ttx
-import os
-import xml.etree.ElementTree as etree
-import shutil
-import tempfile
-
-class MyTest(unittest.TestCase):
-  def test(self):
-    font_name = "Roboto-Regular.ttf"
-    srcdir = tempfile.mkdtemp()
-    print "srcdir: " + srcdir
-    shutil.copy(font_name, srcdir)
-    destdir = tempfile.mkdtemp()
-    print "destdir: " + destdir
-    self.assertTrue(build_font.main([srcdir, destdir]) is None)
-    out_path = os.path.join(destdir, font_name)
-    ttx.main([out_path])
-    ttx_path = out_path[:-1] + "x"
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    name_tag = root.find('name')
-    fonts = build_font.get_font_info(name_tag)
-    shutil.rmtree(srcdir)
-    shutil.rmtree(destdir)
-    self.assertEqual(fonts[0].family, "Roboto1200310")
-    self.assertEqual(fonts[0].fullname, "Roboto1200310 Regular")
-
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
deleted file mode 100644
index ecf39b3..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * {@link ViewGroup} that wraps another view and catches any possible exceptions that the child view
- * might generate.
- * This is used by the theme editor to stop custom views from breaking the preview.
- */
-// TODO: This view is just a temporary solution that will be replaced by adding a try / catch
-// for custom views in the ClassConverter
-public class ErrorCatcher extends ViewGroup {
-    public ErrorCatcher(Context context) {
-        super(context);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            measureChild(child, widthMeasureSpec, heightMeasureSpec);
-
-            setMeasuredDimension(resolveSize(child.getMeasuredWidth(), widthMeasureSpec),
-                    resolveSize(child.getMeasuredHeight(), heightMeasureSpec));
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onMeasure for view " +
-                    child.getClass().getCanonicalName(), t);
-            setMeasuredDimension(resolveSize(0, widthMeasureSpec),
-                    resolveSize(0, heightMeasureSpec));
-        }
-    }
-
-    @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        try {
-            return super.drawChild(canvas, child, drawingTime);
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to draw for view " +
-                    child.getClass().getCanonicalName(), t);
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
-        } catch (Throwable e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onLayout for view " +
-                    child.getClass().getCanonicalName(), e);
-        }
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
deleted file mode 100644
index 4320157..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-@SuppressWarnings("unused")
-public class PressedButton extends Button {
-    public PressedButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setPressed(true);
-        jumpDrawablesToCurrentState();
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
deleted file mode 100644
index af89910..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Custom layout used in the theme editor to display the component preview. It arranges the child
- * Views as a grid of cards.
- * <p/>
- * The Views are measured and the maximum width and height are used to dimension all the child
- * components. Any margin attributes from the children are ignored and only the item_margin element
- * is used.
- */
-@SuppressWarnings("unused")
-public class ThemePreviewLayout extends ViewGroup {
-    private final int mMaxColumns;
-    private final int mMaxColumnWidth;
-    private final int mMinColumnWidth;
-    private final int mItemHorizontalMargin;
-    private final int mItemVerticalMargin;
-
-    /** Item width to use for every card component. This includes margins. */
-    private int mItemWidth;
-    /** Item height to use for every card component. This includes margins. */
-    private int mItemHeight;
-
-    /** Calculated number of columns */
-    private int mNumColumns;
-
-    public ThemePreviewLayout(Context context) {
-        this(context, null);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        if (attrs == null) {
-            mMaxColumnWidth = Integer.MAX_VALUE;
-            mMinColumnWidth = 0;
-            mMaxColumns = Integer.MAX_VALUE;
-            mItemHorizontalMargin = 0;
-            mItemVerticalMargin = 0;
-            return;
-        }
-
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxColumnWidth = attrs.getAttributeIntValue(null, "max_column_width", Integer
-                .MAX_VALUE);
-        int minColumnWidth = attrs.getAttributeIntValue(null, "min_column_width", 0);
-        int itemHorizontalMargin = attrs.getAttributeIntValue(null, "item_horizontal_margin", 0);
-        int itemVerticalMargin = attrs.getAttributeIntValue(null, "item_vertical_margin", 0);
-
-        mMaxColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                maxColumnWidth,
-                dm);
-        mMinColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                minColumnWidth,
-                dm);
-        mItemHorizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemHorizontalMargin,
-                dm);
-        mItemVerticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemVerticalMargin,
-                dm);
-        mMaxColumns = attrs.getAttributeIntValue(null, "max_columns", Integer.MAX_VALUE);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Measure the column size.
-        // The column has a minimum width that will be used to calculate the maximum number of
-        // columns that we can fit in the available space.
-        //
-        // Once we have the maximum number of columns, we will span all columns width evenly to fill
-        // all the available space.
-        int wSize = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
-
-        // Calculate the desired width of all columns and take the maximum.
-        // This step can be skipped if we have a fixed column height so we do not have to
-        // dynamically calculate it.
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int itemWidth = 0;
-        int itemHeight = 0;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-
-            itemWidth = Math.max(itemWidth, v.getMeasuredWidth());
-            itemHeight = Math.max(itemHeight, v.getMeasuredHeight());
-        }
-
-        itemWidth = Math.min(Math.max(itemWidth, mMinColumnWidth), mMaxColumnWidth);
-        mNumColumns = Math.min((int) Math.ceil((double) wSize / itemWidth), mMaxColumns);
-
-        // Check how much space this distribution would take taking into account the margins.
-        // If it's bigger than what we have, remove one column.
-        int wSizeNeeded = mNumColumns * itemWidth + (mNumColumns - 1) * mItemHorizontalMargin;
-        if (wSizeNeeded > wSize && mNumColumns > 1) {
-            mNumColumns--;
-        }
-
-        if (getChildCount() < mNumColumns) {
-            mNumColumns = getChildCount();
-        }
-        if (mNumColumns == 0) {
-            mNumColumns = 1;
-        }
-
-        // Inform each child of the measurement
-        childWidthSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
-        childHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-        }
-
-        // Calculate the height of the first column to measure our own size
-        int firstColumnItems = getChildCount() / mNumColumns + ((getChildCount() % mNumColumns) > 0
-                ? 1 : 0);
-
-        int horizontalMarginsTotalWidth = (mNumColumns - 1) * mItemHorizontalMargin;
-        int verticalMarginsTotalHeight = (firstColumnItems - 1) * mItemVerticalMargin;
-        int totalWidth = mNumColumns * itemWidth + horizontalMarginsTotalWidth +
-                mPaddingRight + mPaddingLeft;
-        int totalHeight = firstColumnItems * itemHeight + verticalMarginsTotalHeight +
-                mPaddingBottom + mPaddingTop;
-
-        setMeasuredDimension(resolveSize(totalWidth, widthMeasureSpec),
-                resolveSize(totalHeight, heightMeasureSpec));
-
-        mItemWidth = itemWidth;
-        mItemHeight = itemHeight;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int itemsPerColumn = getChildCount() / mNumColumns;
-        // The remainder items are distributed one per column.
-        int remainderItems = getChildCount() % mNumColumns;
-
-        int x = mPaddingLeft;
-        int y = mPaddingTop;
-        int position = 1;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-            v.layout(x,
-                    y,
-                    x + mItemWidth,
-                    y + mItemHeight);
-
-            if (position == itemsPerColumn + (remainderItems > 0 ? 1 : 0)) {
-                // Break column
-                position = 1;
-                remainderItems--;
-                x += mItemWidth + mItemHorizontalMargin;
-                y = mPaddingTop;
-            } else {
-                position++;
-                y += mItemHeight + mItemVerticalMargin;
-            }
-        }
-    }
-}
-
-
diff --git a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml b/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
deleted file mode 100644
index b0363d7..0000000
--- a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module" module-name="bridge" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 088cbc6..7972d06 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -19,6 +19,7 @@
 
 import android.content.pm.ParceledListSlice;
 
+import android.net.wifi.hotspot2.OsuProvider;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 
 import android.net.wifi.WifiConfiguration;
@@ -61,6 +62,8 @@
 
     WifiConfiguration getMatchingWifiConfig(in ScanResult scanResult);
 
+    List<OsuProvider> getMatchingOsuProviders(in ScanResult scanResult);
+
     int addOrUpdateNetwork(in WifiConfiguration config);
 
     boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 91fc2f7..e7fbe4f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -891,9 +891,13 @@
          */
         public static final int DISABLED_DUE_TO_USER_SWITCH = 11;
         /**
+         * This network is disabled due to wrong password
+         */
+        public static final int DISABLED_BY_WRONG_PASSWORD = 12;
+        /**
          * This Maximum disable reason value
          */
-        public static final int NETWORK_SELECTION_DISABLED_MAX = 12;
+        public static final int NETWORK_SELECTION_DISABLED_MAX = 13;
 
         /**
          * Quality network selection disable reason String (for debug purpose)
@@ -910,7 +914,8 @@
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
                 "NETWORK_SELECTION_DISABLED_NO_INTERNET",
                 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
-                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH"
+                "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH",
+                "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD"
         };
 
         /**
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index e48f7bd..476ef97 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -105,34 +105,43 @@
     private boolean mEphemeral;
 
     /**
+     * Running total count of lost (not ACKed) transmitted unicast data packets.
      * @hide
      */
     public long txBad;
     /**
+     * Running total count of transmitted unicast data retry packets.
      * @hide
      */
     public long txRetries;
     /**
+     * Running total count of successfully transmitted (ACKed) unicast data packets.
      * @hide
      */
     public long txSuccess;
     /**
+     * Running total count of received unicast data packets.
      * @hide
      */
     public long rxSuccess;
+
     /**
+     * Average rate of lost transmitted packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txBadRate;
     /**
+     * Average rate of transmitted retry packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txRetriesRate;
     /**
+     * Average rate of successfully transmitted unicast packets, in units of packets per 5 seconds.
      * @hide
      */
     public double txSuccessRate;
     /**
+     * Average rate of received unicast data packets, in units of packets per 5 seconds.
      * @hide
      */
     public double rxSuccessRate;
@@ -142,8 +151,9 @@
     /**
      * This factor is used to adjust the rate output under the new algorithm
      * such that the result is comparable to the previous algorithm.
+     * This actually converts from unit 'packets per second' to 'packets per 5 seconds'.
      */
-    private static final long OUTPUT_SCALE_FACTOR = 5000;
+    private static final long OUTPUT_SCALE_FACTOR = 5;
     private long mLastPacketCountUpdateTimeStamp;
 
     /**
@@ -189,16 +199,16 @@
                     double currentSampleWeight = 1.0 - lastSampleWeight;
 
                     txBadRate = txBadRate * lastSampleWeight
-                        + (txbad - txBad) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txbad - txBad) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     txSuccessRate = txSuccessRate * lastSampleWeight
-                        + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txgood - txSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     rxSuccessRate = rxSuccessRate * lastSampleWeight
-                        + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (rxgood - rxSuccess) * OUTPUT_SCALE_FACTOR * 1000 / timeDelta
                         * currentSampleWeight;
                     txRetriesRate = txRetriesRate * lastSampleWeight
-                        + (txretries - txRetries) * OUTPUT_SCALE_FACTOR / timeDelta
+                        + (txretries - txRetries) * OUTPUT_SCALE_FACTOR * 1000/ timeDelta
                         * currentSampleWeight;
             } else {
                 txBadRate = 0;
@@ -438,6 +448,22 @@
     }
 
     /**
+     * @hide
+     * This returns txSuccessRate in packets per second.
+     */
+    public double getTxSuccessRatePps() {
+        return txSuccessRate / OUTPUT_SCALE_FACTOR;
+    }
+
+    /**
+     * @hide
+     * This returns rxSuccessRate in packets per second.
+     */
+    public double getRxSuccessRatePps() {
+        return rxSuccessRate / OUTPUT_SCALE_FACTOR;
+    }
+
+    /**
      * Record the MAC address of the WLAN interface
      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
      * @hide
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index c89a9a4..4684c77 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -30,6 +30,7 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.wifi.hotspot2.OsuProvider;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.os.Binder;
 import android.os.Build;
@@ -675,16 +676,28 @@
     @SystemApi
     public static final int CHANGE_REASON_CONFIG_CHANGE = 2;
     /**
-     * An access point scan has completed, and results are available from the supplicant.
-     * Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED}
-     * indicates if the scan was completed successfully.
+     * An access point scan has completed, and results are available.
+     * Call {@link #getScanResults()} to obtain the results.
+     * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED}
+     * and a {@code boolean} value indicating if the scan was successful.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
 
     /**
-     * Lookup key for a {@code boolean} representing the result of previous {@link #startScan}
-     * operation, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}.
+     * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION}
+     * representing if the scan was successful or not.
+     * Scans may fail for multiple reasons, these may include:
+     * <ol>
+     * <li>A non-privileged app requested too many scans in a certain period of time.
+     * This may lead to additional scan request rejections via "scan throttling".
+     * See
+     * <a href="https://developer.android.com/preview/features/background-location-limits.html">
+     * here</a> for details.
+     * </li>
+     * <li>The device is idle and scanning is disabled.</li>
+     * <li>Wifi hardware reported a scan failure.</li>
+     * </ol>
      * @return true scan was successful, results are updated
      * @return false scan was not successful, results haven't been updated since previous scan
      */
@@ -1000,11 +1013,9 @@
     /**
      * Returns a WifiConfiguration matching this ScanResult
      *
-     * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
-     * on the device.
-     *
      * @param scanResult scanResult that represents the BSSID
      * @return {@link WifiConfiguration} that matches this BSSID or null
+     * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
      * @hide
      */
     public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) {
@@ -1016,6 +1027,24 @@
     }
 
     /**
+     * Returns a list of Hotspot 2.0 OSU (Online Sign-Up) providers associated with the given AP.
+     *
+     * An empty list will be returned if no match is found.
+     *
+     * @param scanResult scanResult that represents the BSSID
+     * @return list of {@link OsuProvider}
+     * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
+     * @hide
+     */
+    public List<OsuProvider> getMatchingOsuProviders(ScanResult scanResult) {
+        try {
+            return mService.getMatchingOsuProviders(scanResult);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Add a new network description to the set of configured networks.
      * The {@code networkId} field of the supplied configuration object
      * is ignored.
@@ -1382,6 +1411,8 @@
     public static final int WIFI_FEATURE_IE_WHITELIST     = 0x1000000; // Probe IE white listing
     /** @hide */
     public static final int WIFI_FEATURE_SCAN_RAND        = 0x2000000; // Random MAC & Probe seq
+    /** @hide */
+    public static final int WIFI_FEATURE_TX_POWER_LIMIT   = 0x4000000; // Set Tx power limit
 
 
     private int getSupportedFeatures() {
@@ -1724,9 +1755,18 @@
 
     /**
      * Enable or disable Wi-Fi.
+     *
+     * Note: This method will return false if wifi cannot be enabled (e.g., an incompatible mode
+     * where the user has enabled tethering or Airplane Mode).
+     *
+     * Applications need to have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
+     * permission to toggle wifi. Callers without the permissions will trigger a
+     * {@link java.lang.SecurityException}.
+     *
      * @param enabled {@code true} to enable, {@code false} to disable.
      * @return {@code true} if the operation succeeds (or if the existing state
-     *         is the same as the requested state).
+     *         is the same as the requested state). False if wifi cannot be toggled on/off when the
+     *         request is made.
      */
     public boolean setWifiEnabled(boolean enabled) {
         try {
@@ -2273,12 +2313,20 @@
      */
     @SystemApi
     public interface ActionListener {
-        /** The operation succeeded */
+        /**
+         * The operation succeeded.
+         * This is called when the scan request has been validated and ready
+         * to sent to driver.
+         */
         public void onSuccess();
         /**
-         * The operation failed
-         * @param reason The reason for failure could be one of
-         * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY}
+         * The operation failed.
+         * This is called when the scan request failed.
+         * @param reason The reason for failure could be one of the following:
+         * {@link #REASON_INVALID_REQUEST}} is specified when scan request parameters are invalid.
+         * {@link #REASON_NOT_AUTHORIZED} is specified when requesting app doesn't have the required
+         * permission to request a scan.
+         * {@link #REASON_UNSPECIFIED} is specified when driver reports a scan failure.
          */
         public void onFailure(int reason);
     }
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index 7a3cddf..5deb80a 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -26,6 +26,7 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
 import java.util.Locale;
 
 /**
@@ -189,6 +190,23 @@
         return out.toString();
     }
 
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof WifiSsid)) {
+            return false;
+        }
+        WifiSsid that = (WifiSsid) thatObject;
+        return Arrays.equals(octets.toByteArray(), that.octets.toByteArray());
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(octets.toByteArray());
+    }
+
     private boolean isArrayAllZeroes(byte[] ssidBytes) {
         for (int i = 0; i< ssidBytes.length; i++) {
             if (ssidBytes[i] != 0) return false;
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index c7e1fc7..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");
     }
 
     /**
@@ -130,8 +130,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (!mTerminated) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (!mTerminated) {
                 close();
             }
         } finally {
@@ -339,8 +342,8 @@
      */
     public NetworkSpecifier createNetworkSpecifierPassphrase(
             @Nullable PeerHandle peerHandle, @NonNull String passphrase) {
-        if (passphrase == null || passphrase.length() == 0) {
-            throw new IllegalArgumentException("Passphrase must not be null or empty");
+        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
+            throw new IllegalArgumentException("Passphrase must meet length requirements");
         }
 
         if (mTerminated) {
@@ -402,8 +405,8 @@
     @SystemApi
     public NetworkSpecifier createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
             @NonNull byte[] pmk) {
-        if (pmk == null || pmk.length == 0) {
-            throw new IllegalArgumentException("PMK must not be null or empty");
+        if (!WifiAwareUtils.validatePmk(pmk)) {
+            throw new IllegalArgumentException("PMK must 32 bytes");
         }
 
         if (mTerminated) {
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
index d8667e6..115b86d 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -100,7 +100,12 @@
      * @param serviceSpecificInfo The service specific information (arbitrary
      *            byte array) provided by the peer as part of its discovery
      *            configuration.
-     * @param matchFilter The filter which resulted in this service discovery.
+     * @param matchFilter The filter which resulted in this service discovery. For
+     * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED},
+     * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} discovery sessions this is the publisher's
+     *                    match filter. For {@link PublishConfig#PUBLISH_TYPE_SOLICITED},
+     *                    {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE} discovery sessions this
+     *                    is the subscriber's match filter.
      */
     public void onServiceDiscovered(PeerHandle peerHandle,
             byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 0f1e992..d018620 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -93,12 +93,17 @@
 
     @Override
     public String toString() {
-        return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mPublishType=" + mPublishType
-                + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
-                + mEnableTerminateNotification + "]";
+        return "PublishConfig [mServiceName='" + (mServiceName == null ? "<null>" : String.valueOf(
+                HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mPublishType=" + mPublishType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 31e7e8e..4bf2fb6 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -92,13 +92,17 @@
 
     @Override
     public String toString() {
-        return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
-                + ", mTtlSec=" + mTtlSec
-                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
-                + "]";
+        return "SubscribeConfig [mServiceName='" + (mServiceName == null ? "<null>"
+                : String.valueOf(HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mSubscribeType=" + mSubscribeType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index e152f6c..eeabbfa 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -161,6 +161,16 @@
                 }
             };
 
+    /**
+     * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a
+     * data-path created without a corresponding Aware discovery session.
+     *
+     * @hide
+     */
+    public boolean isOutOfBand() {
+        return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 4e060d5..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");
     }
 
     /**
@@ -67,6 +67,7 @@
      * An application may re-attach after a destroy using
      * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
      */
+    @Override
     public void close() {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
@@ -83,8 +84,11 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            if (!mTerminated) {
+            if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
+            }
+
+            if (!mTerminated) {
                 close();
             }
         } finally {
@@ -266,9 +270,10 @@
             Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
             return null;
         }
-        if (passphrase == null || passphrase.length() == 0) {
-            throw new IllegalArgumentException("Passphrase must not be null or empty");
+        if (!WifiAwareUtils.validatePassphrase(passphrase)) {
+            throw new IllegalArgumentException("Passphrase must meet length requirements");
         }
+
         return mgr.createNetworkSpecifier(mClientId, role, peer, null, passphrase);
     }
 
@@ -316,8 +321,8 @@
             Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
             return null;
         }
-        if (pmk == null || pmk.length == 0) {
-            throw new IllegalArgumentException("PMK must not be null or empty");
+        if (!WifiAwareUtils.validatePmk(pmk)) {
+            throw new IllegalArgumentException("PMK must 32 bytes");
         }
         return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
     }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
index 4083388..fda7a9a 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.aware;
 
+import android.hardware.wifi.V1_0.Constants;
+
 /**
  * Provides utilities for the Wifi Aware manager/service.
  *
@@ -51,4 +53,35 @@
             ++index;
         }
     }
+
+    /**
+     * Validates that the passphrase is a non-null string of the right size (per the HAL min/max
+     * length parameters).
+     *
+     * @param passphrase Passphrase to test
+     * @return true if passphrase is valid, false if not
+     */
+    public static boolean validatePassphrase(String passphrase) {
+        if (passphrase == null
+                || passphrase.length() < Constants.NanParamSizeLimits.MIN_PASSPHRASE_LENGTH
+                || passphrase.length() > Constants.NanParamSizeLimits.MAX_PASSPHRASE_LENGTH) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Validates that the PMK is a non-null byte array of the right size (32 bytes per spec).
+     *
+     * @param pmk PMK to test
+     * @return true if PMK is valid, false if not
+     */
+    public static boolean validatePmk(byte[] pmk) {
+        if (pmk == null || pmk.length != 32) {
+            return false;
+        }
+
+        return true;
+    }
 }
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
new file mode 100644
index 0000000..23d0f22
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.wifi.hotspot2;
+
+parcelable OsuProvider;
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
new file mode 100644
index 0000000..25dcdd8
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
@@ -0,0 +1,231 @@
+/*
+ * 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.wifi.hotspot2;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Contained information for a Hotspot 2.0 OSU (Online Sign-Up provider).
+ *
+ * @hide
+ */
+public final class OsuProvider implements Parcelable {
+    /**
+     * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management).
+     * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification.
+     */
+    public static final int METHOD_OMA_DM = 0;
+
+    /**
+     * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol).
+     * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification.
+     */
+    public static final int METHOD_SOAP_XML_SPP = 1;
+
+    /**
+     * SSID of the network to connect for service sign-up.
+     */
+    private final WifiSsid mOsuSsid;
+
+    /**
+     * Friendly name of the OSU provider.
+     */
+    private final String mFriendlyName;
+
+    /**
+     * Description of the OSU provider.
+     */
+    private final String mServiceDescription;
+
+    /**
+     * URI to browse to for service sign-up.
+     */
+    private final Uri mServerUri;
+
+    /**
+     * Network Access Identifier used for authenticating with the OSU network when OSEN is used.
+     */
+    private final String mNetworkAccessIdentifier;
+
+    /**
+     * List of OSU (Online Sign-Up) method supported.
+     */
+    private final List<Integer> mMethodList;
+
+    /**
+     * Icon data for the OSU (Online Sign-Up) provider.
+     */
+    private final Icon mIcon;
+
+    public OsuProvider(WifiSsid osuSsid, String friendlyName, String serviceDescription,
+            Uri serverUri, String nai, List<Integer> methodList, Icon icon) {
+        mOsuSsid = osuSsid;
+        mFriendlyName = friendlyName;
+        mServiceDescription = serviceDescription;
+        mServerUri = serverUri;
+        mNetworkAccessIdentifier = nai;
+        if (methodList == null) {
+            mMethodList = new ArrayList<>();
+        } else {
+            mMethodList = new ArrayList<>(methodList);
+        }
+        mIcon = icon;
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param source The source to copy from
+     */
+    public OsuProvider(OsuProvider source) {
+        if (source == null) {
+            mOsuSsid = null;
+            mFriendlyName = null;
+            mServiceDescription = null;
+            mServerUri = null;
+            mNetworkAccessIdentifier = null;
+            mMethodList = new ArrayList<>();
+            mIcon = null;
+            return;
+        }
+
+        mOsuSsid = source.mOsuSsid;
+        mFriendlyName = source.mFriendlyName;
+        mServiceDescription = source.mServiceDescription;
+        mServerUri = source.mServerUri;
+        mNetworkAccessIdentifier = source.mNetworkAccessIdentifier;
+        if (source.mMethodList == null) {
+            mMethodList = new ArrayList<>();
+        } else {
+            mMethodList = new ArrayList<>(source.mMethodList);
+        }
+        mIcon = source.mIcon;
+    }
+
+    public WifiSsid getOsuSsid() {
+        return mOsuSsid;
+    }
+
+    public String getFriendlyName() {
+        return mFriendlyName;
+    }
+
+    public String getServiceDescription() {
+        return mServiceDescription;
+    }
+
+    public Uri getServerUri() {
+        return mServerUri;
+    }
+
+    public String getNetworkAccessIdentifier() {
+        return mNetworkAccessIdentifier;
+    }
+
+    public List<Integer> getMethodList() {
+        return Collections.unmodifiableList(mMethodList);
+    }
+
+    public Icon getIcon() {
+        return mIcon;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mOsuSsid, flags);
+        dest.writeString(mFriendlyName);
+        dest.writeString(mServiceDescription);
+        dest.writeParcelable(mServerUri, flags);
+        dest.writeString(mNetworkAccessIdentifier);
+        dest.writeList(mMethodList);
+        dest.writeParcelable(mIcon, flags);
+    }
+
+    @Override
+    public boolean equals(Object thatObject) {
+        if (this == thatObject) {
+            return true;
+        }
+        if (!(thatObject instanceof OsuProvider)) {
+            return false;
+        }
+        OsuProvider that = (OsuProvider) thatObject;
+        return (mOsuSsid == null ? that.mOsuSsid == null : mOsuSsid.equals(that.mOsuSsid))
+                && TextUtils.equals(mFriendlyName, that.mFriendlyName)
+                && TextUtils.equals(mServiceDescription, that.mServiceDescription)
+                && (mServerUri == null ? that.mServerUri == null
+                            : mServerUri.equals(that.mServerUri))
+                && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier)
+                && (mMethodList == null ? that.mMethodList == null
+                            : mMethodList.equals(that.mMethodList))
+                && (mIcon == null ? that.mIcon == null : mIcon.sameAs(that.mIcon));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mOsuSsid, mFriendlyName, mServiceDescription, mServerUri,
+                mNetworkAccessIdentifier, mMethodList, mIcon);
+    }
+
+    @Override
+    public String toString() {
+        return "OsuProvider{mOsuSsid=" + mOsuSsid
+                + " mFriendlyName=" + mFriendlyName
+                + " mServiceDescription=" + mServiceDescription
+                + " mServerUri=" + mServerUri
+                + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier
+                + " mMethodList=" + mMethodList
+                + " mIcon=" + mIcon;
+    }
+
+    public static final Creator<OsuProvider> CREATOR =
+        new Creator<OsuProvider>() {
+            @Override
+            public OsuProvider createFromParcel(Parcel in) {
+                WifiSsid osuSsid = (WifiSsid) in.readParcelable(null);
+                String friendlyName = in.readString();
+                String serviceDescription = in.readString();
+                Uri serverUri = (Uri) in.readParcelable(null);
+                String nai = in.readString();
+                List<Integer> methodList = new ArrayList<>();
+                in.readList(methodList, null);
+                Icon icon = (Icon) in.readParcelable(null);
+                return new OsuProvider(osuSsid, friendlyName, serviceDescription, serverUri,
+                        nai, methodList, icon);
+            }
+
+            @Override
+            public OsuProvider[] newArray(int size) {
+                return new OsuProvider[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index 8b1cfae..bfdd45d 100644
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -25,8 +25,9 @@
  */
 interface IWifiP2pManager
 {
-    Messenger getMessenger();
+    Messenger getMessenger(in IBinder binder);
     Messenger getP2pStateMachineMessenger();
+    oneway void close(in IBinder binder);
     void setMiracastMode(int mode);
     void checkConfigureWifiDisplayPermission();
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 95d0a79..0d4359e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -28,6 +28,7 @@
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -668,11 +669,12 @@
      * by doing a call on {@link #initialize}
      */
     public static class Channel {
-        Channel(Context context, Looper looper, ChannelListener l) {
+        Channel(Context context, Looper looper, ChannelListener l, Binder binder) {
             mAsyncChannel = new AsyncChannel();
             mHandler = new P2pHandler(looper);
             mChannelListener = l;
             mContext = context;
+            mBinder = binder;
         }
         private final static int INVALID_LISTENER_KEY = 0;
         private ChannelListener mChannelListener;
@@ -681,9 +683,11 @@
         private DnsSdTxtRecordListener mDnsSdTxtListener;
         private UpnpServiceResponseListener mUpnpServRspListener;
         private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
-        private Object mListenerMapLock = new Object();
+        private final Object mListenerMapLock = new Object();
         private int mListenerKey = 0;
 
+        /* package */ final Binder mBinder;
+
         private AsyncChannel mAsyncChannel;
         private P2pHandler mHandler;
         Context mContext;
@@ -889,7 +893,10 @@
      * @return Channel instance that is necessary for performing any further p2p operations
      */
     public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getMessenger());
+        Binder binder = new Binder();
+        Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
+                binder);
+        return channel;
     }
 
     /**
@@ -898,14 +905,15 @@
      */
     public Channel initializeInternal(Context srcContext, Looper srcLooper,
                                       ChannelListener listener) {
-        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger());
+        return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
+                null);
     }
 
     private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
-                                     Messenger messenger) {
+                                     Messenger messenger, Binder binder) {
         if (messenger == null) return null;
 
-        Channel c = new Channel(srcContext, srcLooper, listener);
+        Channel c = new Channel(srcContext, srcLooper, listener, binder);
         if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
                 == AsyncChannel.STATUS_SUCCESSFUL) {
             return c;
@@ -1385,12 +1393,14 @@
      * Get a reference to WifiP2pService handler. This is used to establish
      * an AsyncChannel communication with WifiService
      *
+     * @param binder A binder for the service to associate with this client.
+     *
      * @return Messenger pointing to the WifiP2pService handler
      * @hide
      */
-    public Messenger getMessenger() {
+    public Messenger getMessenger(Binder binder) {
         try {
-            return mService.getMessenger();
+            return mService.getMessenger(binder);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1412,6 +1422,24 @@
     }
 
     /**
+     * Close the current P2P connection and clean-up any configuration requested by the
+     * current app. Takes same action as taken when the app dies.
+     *
+     * @param c is the channel created at {@link #initialize}
+     *
+     * @hide
+     */
+    public void close(Channel c) {
+        try {
+            if (c != null) {
+                mService.close(c.mBinder);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Get a handover request message for use in WFA NFC Handover transfer.
      * @hide
      */
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index c30dcea..764eb2b 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <option name="test-suite-tag" value="apct" />
     <option name="test-tag" value="FrameworksWifiApiTests" />
-    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.wifi.test" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
     </test>
diff --git a/wifi/tests/src/android/net/wifi/WifiSsidTest.java b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
index c7bdb7b..e5794c5 100644
--- a/wifi/tests/src/android/net/wifi/WifiSsidTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiSsidTest.java
@@ -16,25 +16,43 @@
 
 package android.net.wifi;
 
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
 
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
 /**
  * Unit tests for {@link android.net.wifi.WifiSsid}.
  */
 public class WifiSsidTest {
 
-    private static final byte[] TEST_SSID =
-            new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
+    private static final String TEST_SSID = "Test SSID";
+    private static final byte[] TEST_SSID_BYTES = TEST_SSID.getBytes(StandardCharsets.US_ASCII);
+
     /**
      * Check that createFromByteArray() works.
      */
     @Test
     public void testCreateFromByteArray() {
-        WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID);
+        WifiSsid wifiSsid = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
         assertTrue(wifiSsid != null);
-        assertEquals(new String(TEST_SSID), wifiSsid.toString());
+        assertEquals(TEST_SSID, wifiSsid.toString());
+    }
+
+    /**
+     * Verify that SSID created from byte array and string with the same content are equal.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testEquals() throws Exception {
+        WifiSsid fromBytes = WifiSsid.createFromByteArray(TEST_SSID_BYTES);
+        WifiSsid fromString = WifiSsid.createFromAsciiEncoded(TEST_SSID);
+        assertTrue(fromBytes != null);
+        assertTrue(fromString != null);
+        assertEquals(fromBytes, fromString);
     }
 }
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 694b911..d9433c5 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -32,6 +32,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -938,7 +939,7 @@
         final int sessionId = 123;
         final PeerHandle peerHandle = new PeerHandle(123412);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-        final byte[] pmk = "Some arbitrary byte array".getBytes();
+        final byte[] pmk = "01234567890123456789012345678901".getBytes();
         final String passphrase = "A really bad password";
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final PublishConfig publishConfig = new PublishConfig.Builder().build();
@@ -1019,7 +1020,7 @@
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-        final byte[] pmk = "Some arbitrary pmk data".getBytes();
+        final byte[] pmk = "01234567890123456789012345678901".getBytes();
         final String passphrase = "A really bad password";
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
@@ -1070,4 +1071,162 @@
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);
     }
+
+    /**
+     * Validate that a null PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientNullPmk() throws Exception {
+        executeNetworkSpecifierWithClient(true, null, null);
+    }
+
+    /**
+     * Validate that a non-32-bytes PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
+        executeNetworkSpecifierWithClient(true, "012".getBytes(), null);
+    }
+
+    /**
+     * Validate that a null Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientNullPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null, null);
+    }
+
+    /**
+     * Validate that a too short Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientShortPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null, "012");
+    }
+
+    /**
+     * Validate that a too long Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierWithClientLongPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(false, null,
+                "0123456789012345678901234567890123456789012345678901234567890123456789");
+    }
+
+    private void executeNetworkSpecifierWithClient(boolean doPmk, byte[] pmk, String passphrase)
+            throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final PeerHandle peerHandle = new PeerHandle(123412);
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
+                WifiAwareSession.class);
+        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareEventCallback.class);
+        ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareDiscoverySessionCallback.class);
+        ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+                .forClass(PublishDiscoverySession.class);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
+                mockPublishSession, mockRttListener);
+
+        // (1) connect successfully
+        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
+        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+                eq(configRequest), eq(false));
+        clientProxyCallback.getValue().onConnectSuccess(clientId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
+        WifiAwareSession session = sessionCaptor.getValue();
+
+        // (2) publish successfully
+        session.publish(publishConfig, mockSessionCallback, mMockLooperHandler);
+        inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        // (3) create network specifier
+        if (doPmk) {
+            publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
+        } else {
+            publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle, passphrase);
+        }
+    }
+
+    /**
+     * Validate that a null PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectNullPmk() throws Exception {
+        executeNetworkSpecifierDirect(true, null, null);
+    }
+
+    /**
+     * Validate that a non-32-bytes PMK triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
+        executeNetworkSpecifierDirect(true, "012".getBytes(), null);
+    }
+
+    /**
+     * Validate that a null Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null, null);
+    }
+
+    /**
+     * Validate that a too short Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectShortPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null, "012");
+    }
+
+    /**
+     * Validate that a too long Passphrase triggers an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectLongPassphrase() throws Exception {
+        executeNetworkSpecifierDirect(false, null,
+                "0123456789012345678901234567890123456789012345678901234567890123456789");
+    }
+
+    private void executeNetworkSpecifierDirect(boolean doPmk, byte[] pmk, String passphrase)
+            throws Exception {
+        final int clientId = 134;
+        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
+        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
+                WifiAwareSession.class);
+        ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiAwareEventCallback.class);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
+                mockPublishSession, mockRttListener);
+
+        // (1) connect successfully
+        mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
+        inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(),
+                eq(configRequest), eq(false));
+        clientProxyCallback.getValue().onConnectSuccess(clientId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
+
+        // (2) create network specifier
+        if (doPmk) {
+            sessionCaptor.getValue().createNetworkSpecifierPmk(role, someMac, pmk);
+        } else {
+            sessionCaptor.getValue().createNetworkSpecifierPassphrase(role, someMac, passphrase);
+        }
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
new file mode 100644
index 0000000..9670bfa
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.wifi.hotspot2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.OsuProvider}.
+ */
+@SmallTest
+public class OsuProviderTest {
+    private static final WifiSsid TEST_SSID =
+            WifiSsid.createFromByteArray("TEST SSID".getBytes(StandardCharsets.UTF_8));
+    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+    private static final String TEST_NAI = "test.access.com";
+    private static final List<Integer> TEST_METHOD_LIST =
+            Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);
+    private static final Icon TEST_ICON = Icon.createWithData(new byte[10], 0, 10);
+
+    /**
+     * Verify parcel write and read consistency for the given {@link OsuProvider}.
+     *
+     * @param writeInfo The {@link OsuProvider} to verify
+     * @throws Exception
+     */
+    private static void verifyParcel(OsuProvider writeInfo) throws Exception {
+        Parcel parcel = Parcel.obtain();
+        writeInfo.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
+        OsuProvider readInfo = OsuProvider.CREATOR.createFromParcel(parcel);
+        assertEquals(writeInfo, readInfo);
+    }
+
+    /**
+     * Verify parcel read/write for an OSU provider containing no information.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyParcelWithEmptyProviderInfo() throws Exception {
+        verifyParcel(new OsuProvider(null, null, null, null, null, null, null));
+    }
+
+    /**
+     * Verify parcel read/write for an OSU provider containing full information.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyParcelWithFullProviderInfo() throws Exception {
+        verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+                TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON));
+    }
+
+    /**
+     * Verify copy constructor with a null source.
+     * @throws Exception
+     */
+    @Test
+    public void verifyCopyConstructorWithNullSource() throws Exception {
+        OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null);
+        assertEquals(expected, new OsuProvider(null));
+    }
+
+    /**
+     * Verify copy constructor with a valid source.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyCopyConstructorWithValidSource() throws Exception {
+        OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+                TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+        assertEquals(source, new OsuProvider(source));
+    }
+
+    /**
+     * Verify getter methods.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void verifyGetters() throws Exception {
+        OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME,
+                TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+        assertTrue(TEST_SSID.equals(provider.getOsuSsid()));
+        assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName()));
+        assertTrue(TEST_SERVICE_DESCRIPTION.equals(provider.getServiceDescription()));
+        assertTrue(TEST_SERVER_URI.equals(provider.getServerUri()));
+        assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier()));
+        assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList()));
+        assertTrue(TEST_ICON.sameAs(provider.getIcon()));
+    }
+}